void aux_isr() { switch (status) { case state::writing_sending_address: status = state::writing_sending_data; regs.data = data; break; case state::writing_sending_data: status = state::idle; if (event) ctl_events_set_clear(event, idle_mask, 0); break; case state::reading_sending_address: regs.control.rxtx = 0; // we want to receive data with this access status = state::reading_data_ready_sending_dummy; regs.data = 0x0000; // data is ready at other end. trigger a write (what is actually written is out of our control) break; case state::reading_data_ready_sending_dummy: regs.control.shift_off = true; // we don't want to trigger a transfer on the SPI bus, we just want to get the cached value data = regs.data; regs.control.shift_off = false; // we're done regs.control.rxtx = 1; status = state::idle; if (event) ctl_events_set_clear(event, idle_mask, 0); break; default: break; } // no need to tell the peer to reset its interrupt pin, we are positive edge triggered }
//handle ACDS specific commands int SUB_parseCmd(unsigned char src,unsigned char cmd,unsigned char *dat,unsigned short len){ int i; unsigned long block_id; unsigned long sector; switch(cmd){ case CMD_MAG_DATA: //check packet length if(len!=sizeof(magData)){ //length incorrect, report error and exit report_error(ERR_LEV_ERROR,ACDS_ERR_SRC_SENSORS,ACDS_ERR_SEN_BAD_PACKET_LENGTH,len); return ERR_PK_LEN; } memcpy(&magData,dat,sizeof(magData)); //sensor data recieved set event ctl_events_set_clear(&ACDS_evt,ACDS_EVT_DAT_REC,0); return RET_SUCCESS; case CMD_SPI_DATA_ACTION: if(len==0){ return ERR_PK_LEN; } switch(dat[0]){ case SPI_DAT_ACTION_SD_WRITE: if(len!=5){ return ERR_PK_LEN; } sector=((unsigned long)dat[1]<<24)|((unsigned long)dat[2]<<16)|((unsigned long)dat[3]<<8)|((unsigned long)dat[4]); //get lock on action if(!ctl_mutex_lock(&spi_action.lock,CTL_TIMEOUT_DELAY,10)){ return ERR_SPI_BUSY; } spi_action.action=dat[0]; spi_action.parm.sector=sector; ctl_mutex_unlock(&spi_action.lock); break; default: return ERR_UNKNOWN_CMD; } return RET_SUCCESS; case CMD_ACDS_READ_BLOCK: if(len!=3){ return ERR_PK_LEN; } block_id =((unsigned long)dat[0])<<16; block_id|=((unsigned long)dat[1])<<8; block_id|=((unsigned long)dat[2]); //check range if(block_id>LOG_IDX_MAX){ //index is out of range return ERR_PK_BAD_PARM; } //set SD address SD_read_addr=LOG_ADDR_START+block_id; //trigger event ctl_events_set_clear(&ACDS_evt,ACDS_EVT_SEND_DAT,0); } //Return Error return ERR_UNKNOWN_CMD; }
// receive UART ISR void USB_rx(void) __ctl_interrupt[USCIAB1RX_VECTOR]{ unsigned char flags=UC1IFG&(UC1IE); unsigned char I2Cstate=UCB1STAT;//was added from the libraries I2C interrupts //=================[I2C Status Handler]=============================//added from I2C UCint.c libraries if(I2Cstate&UCNACKIFG){ //Not-Acknowledge received #ifndef SCCB //clear Tx interrupt flag see USCI25 in "MSP430F261x, MSP430F241x Device Erratasheet (Rev. J)" UC1IFG&= ~UCB1TXIFG; //set NACK error event ctl_events_set_clear(&I2C_stat.events,I2C_EV_ERR_NACK,0); #endif //clear interrupt flag UCB1STAT&=~UCNACKIFG; #ifndef SCCB //disable I2C Tx and Rx Interrupts UC1IE&=~(UCB1TXIE|UCB1RXIE); //generate stop condition UCB1CTL1|=UCTXSTP; #endif } if(I2Cstate&UCSTPIFG){ //Stop condition received, not used in master mode } if(I2Cstate&UCSTTIFG){ //Start condition received, not used in master mode } if(I2Cstate&UCALIFG){ //Arbitration Lost, not used in master mode } //================================================================== }
//become master on the I2C bus and transmit len bytes pointed to by dat to address addr short BUS_i2c_tx(unsigned short addr,const unsigned char *dat,unsigned short len){ unsigned int e; int i; //check for zero length if(len==0){ return ERR_BAD_LEN; } //TODO: replace with mutex or something that actually works //wait for until not transmitting or receiving for(i=0;arcBus_stat.i2c_stat.mode!=I2C_IDLE && i<10;i++){ ctl_timeout_wait(ctl_get_current_time()+3); } if(arcBus_stat.i2c_stat.mode!=I2C_IDLE){ return ERR_TIMEOUT; } //wait for the bus to become free /*while(UCB0STAT&UCBBUSY || arcBus_stat.i2c_stat.mode!=I2C_IDLE){ ctl_timeout_wait(ctl_get_current_time()+3); } ctl_timeout_wait(ctl_get_current_time()+3);*/ //Setup for I2C transaction //set slave address UCB0I2CSA=addr; //set index arcBus_stat.i2c_stat.tx.idx=0; //set mode arcBus_stat.i2c_stat.mode=I2C_TX; //set length arcBus_stat.i2c_stat.tx.len=len; //set data arcBus_stat.i2c_stat.tx.ptr=(unsigned char*)dat; //reset peripheral to switch to master mode UCB0CTL1|=UCSWRST; //set master mode UCB0CTL0|=UCMST; //set transmit mode UCB0CTL1|=UCTR; //take peripheral out of reset UCB0CTL1&=~UCSWRST; //clear master I2C flags ctl_events_set_clear(&arcBus_stat.events,0,BUS_EV_I2C_MASTER); for(;;){ if(!(UCB0STAT&UCBBUSY)){ ctl_timeout_wait(ctl_get_current_time()+3); if(!(UCB0STAT&UCBBUSY)){ break; } } ctl_timeout_wait(ctl_get_current_time()+3); } //enable I2C Tx Interrupt UC0IE|=UCB0TXIE; //generate start condition UCB0CTL1|=UCTXSTT; //sending started return success return RET_SUCCESS; }
//reset timeout timer void mag_timeout_reset(void){ //disable timer interrupt TACCTL1=0; //initialize interrupt count int_count=mag_time.n; //set interupt time TACCR1=readTA()+mag_time.T; //clear event flag ctl_events_set_clear(&ACDS_evt,0,ACDS_EVT_DAT_TIMEOUT); //enable timer interrupt TACCTL1=CCIE; }
//ISR HANDLER CTL_ISR_FN_t buttons_isr_handler(void) { int32u int_status; int_status = GPIOPinIntStatus( PUSHBUTTON_PORT, 1 ); GPIOPinIntClear( PUSHBUTTON_PORT, int_status ); if(int_status & LEFT_SWITCH) { if(GPIOPinRead(PUSHBUTTON_PORT, LEFT_SWITCH) == LEFT_SWITCH) ctl_events_set_clear(&button_events,0,L_BTN_PUSHED); else ctl_events_set_clear(&button_events,L_BTN_PUSHED,0); } if(int_status & RIGHT_SWITCH) { if(GPIOPinRead(PUSHBUTTON_PORT, RIGHT_SWITCH) == RIGHT_SWITCH) ctl_events_set_clear(&button_events,0, R_BTN_PUSHED); else ctl_events_set_clear(&button_events,R_BTN_PUSHED,0); } }
int takePicTask(char **argv,unsigned short argc) { unsigned short e; int tmp; //get the slot where the picture wil be written tmp=writePic; //Trigger the takepic event and clear pic taken event ctl_events_set_clear(&IMG_events, IMG_EV_TAKEPIC,IMG_EV_PIC_TAKEN); //wait for picture to complete, set a timeout of 15 sec e=ctl_events_wait(CTL_EVENT_WAIT_ANY_EVENTS_WITH_AUTO_CLEAR,&IMG_events,IMG_EV_PIC_TAKEN,CTL_TIMEOUT_DELAY,30*1024); //check if picture was taken if(!(e&IMG_EV_PIC_TAKEN)){ //print error message printf("Error timeout occoured\r\n"); } //set picture slot cmdPic=tmp; return 0; }
//Timer A1 interrupt void timerA1(void) __ctl_interrupt[TIMERA1_VECTOR]{ switch(TAIV){ //CCR1 : used for sensor data timeout case TAIV_TACCR1: //setup next interrupt TACCR1+=mag_time.T; //decremint count int_count--; if(int_count<=0){ ctl_events_set_clear(&ACDS_evt,ACDS_EVT_DAT_TIMEOUT,0); int_count=mag_time.n; } break; //CCR2 : Unused case TAIV_TACCR2: break; //TAINT : unused case TAIV_TAIFG: break; } }
//handle subsystem specific commands int SUB_parseCmd(unsigned char src,unsigned char cmd,unsigned char *dat,unsigned short len){ int i; switch(cmd){ //Handle Print String Command case 6: //check packet length if(len>sizeof(buffer)){ //return error return ERR_PK_LEN; } //copy to temporary buffer for(i=0;i<len;i++){ buffer[i]=dat[i]; } //terminate string buffer[i]=0; //set event ctl_events_set_clear(&cmd_parse_evt,0x01,0); //Return Success return RET_SUCCESS; } //Return Error return ERR_UNKNOWN_CMD; }
//UART TX ISR called to transmit UART data void USB_TX(void) __ctl_interrupt[USCIAB1TX_VECTOR]{ unsigned char flags=UC1IFG&(UC1IE); //===============[I2C data Tx/Rx handler]================//I added this section from UCint.c from libraries in addition to the UART for terra term //check if data was received if(flags&UCB1RXIFG){ //receive data I2C_stat.rx.ptr[I2C_stat.rx.idx]=UCB1RXBUF; //increment index I2C_stat.rx.idx++; //check if this is the 2nd to last byte if(I2C_stat.rx.len==(I2C_stat.rx.idx+1)){ if(I2C_stat.mode==I2C_RXTX){ //set transmit mode UCB1CTL1|=UCTR; //generate repeated start condition UCB1CTL1|=UCTXSTT; //enable Tx interrupt UC1IE|= UCB1TXIE; }else{ //generate stop condition UCB1CTL1|=UCTXSTP; } //one more interrupt to go } //check if this was the last byte if(I2C_stat.rx.idx>=I2C_stat.rx.len && I2C_stat.mode!=I2C_RXTX){ //set complete event ctl_events_set_clear(&I2C_stat.events,I2C_EV_COMPLETE,0); } } //check if data needs to be transmitted if(flags&UCB1TXIFG){ //check if there are more bytes if(I2C_stat.tx.len>I2C_stat.tx.idx){ //transmit data UCB1TXBUF=I2C_stat.tx.ptr[I2C_stat.tx.idx++]; }else{ if(I2C_stat.mode==I2C_TXRX){ //set receive mode UCB1CTL1&=~UCTR; //generate start condition UCB1CTL1|=UCTXSTT; //clear interrupt flag UC1IFG&= ~UCB1TXIFG; //clear Tx enable UC1IE&= ~UCB1TXIE; //enable Rx interrupt UC1IE|= UCB1RXIE; //one byte receive needs special treatment if(I2C_stat.rx.len==1){ //set complete event ctl_events_set_clear(&I2C_stat.events,I2C_EV_COMPLETE,0); } }else{ //generate stop condition UCB1CTL1|=UCTXSTP; //clear interrupt flag UC1IFG&= ~UCB1TXIFG; //set complete event ctl_events_set_clear(&I2C_stat.events,I2C_EV_COMPLETE,0); } } } //============================================================== }
//stop timeout timer void mag_timeout_stop(void){ //disable interrupt TACCTL1=0; //clear event flag ctl_events_set_clear(&ACDS_evt,0,ACDS_EVT_DAT_TIMEOUT); }
void Port2_ISR (void) __ctl_interrupt[PORT2_VECTOR] { if (P2IFG & CC1101_GDO0) { switch(state) { case IDLE: ctl_events_set_clear(&radio_event_flags,CC1101_EV_RX_SYNC,0); state = RX_START; RxBufferPos = 0; break; case RX_START: ctl_events_set_clear(&radio_event_flags,CC1101_EV_RX_END,0); small_packet = 1; P2IFG &= ~CC1101_GDO0; break; case RX_RUNNING: ctl_events_set_clear(&radio_event_flags,CC1101_EV_RX_END,0); break; case TX_START: ctl_events_set_clear(&radio_event_flags,CC1101_EV_TX_END,0); state = IDLE; P2IFG &= ~CC1101_GDO0; break; case TX_RUNNING: ctl_events_set_clear(&radio_event_flags,CC1101_EV_TX_END,0); state = IDLE; P2IFG &= ~CC1101_GDO0; break; } P2IFG &= ~(CC1101_GDO0); } if (P2IFG & CC1101_GDO2) { switch(state) { case IDLE: break; case TX_START: ctl_events_set_clear(&radio_event_flags,CC1101_EV_TX_THR,0); state = TX_RUNNING; break; case TX_RUNNING: ctl_events_set_clear(&radio_event_flags,CC1101_EV_TX_THR,0); break; case RX_START: ctl_events_set_clear(&radio_event_flags,CC1101_EV_RX_THR,0); state = RX_RUNNING; break; case RX_RUNNING: ctl_events_set_clear(&radio_event_flags,CC1101_EV_RX_THR,0); state = RX_RUNNING; break; } uhf = 1; P2IFG &= ~CC1101_GDO2; } if (P2IFG & CC2500_GDO0) { switch(state){ case IDLE: ctl_events_set_clear(&radio_event_flags,CC2500_EV_RX_SYNC,0); state = RX_START; RxBufferPos = 0; break; case TX_START: P2IFG &= ~CC2500_GDO0; break; case RX_START: break; } P2IFG &= ~CC2500_GDO0; } if (P2IFG & CC2500_GDO2) { switch(state) { case IDLE: break; case TX_START: ctl_events_set_clear(&radio_event_flags,CC2500_EV_TX_THR,0); state = TX_RUNNING; break; case RX_START: ctl_events_set_clear(&radio_event_flags,CC2500_EV_RX_THR,0); state = RX_RUNNING; break; } uhf = 0; P2IFG &= ~CC2500_GDO2; } //P2IFG = 0; }
int dumpPicTask(char **argv,unsigned short argc) { //Trigger the load picture event ctl_events_set_clear(&IMG_events, IMG_EV_LOADPIC,0); return 0; }