void sched(void) { ENABLE_GLOBAL_INTERRUPTS(); ker_log_start(); for(;;){ SOS_MEASUREMENT_IDLE_END(); DISABLE_GLOBAL_INTERRUPTS(); if (int_ready != 0) { ENABLE_GLOBAL_INTERRUPTS(); handle_callback(); } else if( schedpq.msg_cnt != 0 ) { ENABLE_GLOBAL_INTERRUPTS(); do_dispatch(); } else { SOS_MEASUREMENT_IDLE_START(); ENABLE_GLOBAL_INTERRUPTS(); } } }
/** * @brief ISR for reception * This is the writer of rx_queue. */ uart_recv_interrupt() { #ifdef SOS_USE_PREEMPTION HAS_PREEMPTION_SECTION; DISABLE_PREEMPTION(); #endif uint8_t err; uint8_t byte_in; static uint16_t crc_in; static uint8_t saved_state; SOS_MEASUREMENT_IDLE_END() LED_DBG(LED_YELLOW_TOGGLE); //! NOTE that the order has to be this in AVR err = uart_checkError(); byte_in = uart_getByte(); //DEBUG("uart_recv_interrupt... %d %d %d %d %d\n", byte_in, err, // state[RX].state, state[RX].msg_state, state[RX].hdlc_state); switch (state[RX].state) { case UART_IDLE: if ((err != 0) || (byte_in != HDLC_FLAG)) { break; } state[RX].state = UART_HDLC_START; break; case UART_HDLC_START: case UART_PROTOCOL: if (err != 0) { uart_reset_recv(); break; } switch (byte_in) { //! ignore repeated start symbols case HDLC_FLAG: state[RX].state = UART_HDLC_START; break; case HDLC_SOS_MSG: if(state[RX].msgHdr == NULL) { state[RX].msgHdr = msg_create(); } else { if((state[RX].msgHdr->data != NULL) && (flag_msg_release(state[RX].msgHdr->flag))){ ker_free(state[RX].msgHdr->data); state[RX].msgHdr->flag &= ~SOS_MSG_RELEASE; } } if(state[RX].msgHdr != NULL) { state[RX].msg_state = SOS_MSG_RX_HDR; state[RX].crc = crcByte(0, byte_in); state[RX].flags |= UART_SOS_MSG_FLAG; state[RX].idx = 0; state[RX].state = UART_DATA; state[RX].hdlc_state = HDLC_DATA; } else { // need to generate no mem error uart_reset_recv(); } break; case HDLC_RAW: if ((state[RX].buff = ker_malloc(UART_MAX_MSG_LEN, UART_PID)) != NULL) { state[RX].msg_state = SOS_MSG_RX_RAW; if (state[RX].flags & UART_CRC_FLAG) { state[RX].crc = crcByte(0, byte_in); } state[RX].state = UART_DATA; state[RX].hdlc_state = HDLC_DATA; } else { uart_reset_recv(); } state[RX].idx = 0; break; default: uart_reset_recv(); break; } break; case UART_DATA: if (err != 0) { uart_reset_recv(); break; } // recieve an escape byte, wait for next byte if (byte_in == HDLC_CTR_ESC) { saved_state = state[RX].hdlc_state; state[RX].hdlc_state = HDLC_ESCAPE; break; } if (byte_in == HDLC_FLAG) { // got an end of message symbol /* if (state[RX].msg_state == SOS_MSG_RX_RAW) { // end of raw recieve // should bundle and send off // trash for now state[RX].hdlc_state = HDLC_IDLE; state[RX].state = UART_IDLE; state[RX].flags |= UART_DATA_RDY_FLAG; uart_read_done(state[RX].idx, 0); } else { // got an end of message symbol early */ uart_reset_recv(); //} break; } if (state[RX].hdlc_state == HDLC_ESCAPE) { byte_in ^= 0x20; state[RX].hdlc_state = saved_state; } switch (state[RX].msg_state) { case SOS_MSG_RX_HDR: if (byte_in == HDLC_FLAG) { // got an end of message symbol uart_reset_recv(); break; } uint8_t *tmpPtr = (uint8_t*)(state[RX].msgHdr); tmpPtr[state[RX].idx++] = byte_in; state[RX].crc = crcByte(state[RX].crc, byte_in); if (state[RX].idx == SOS_MSG_HEADER_SIZE) { // if (state[RX].msgLen != state[RX].msgHdr->len) ???????? state[RX].msgLen = state[RX].msgHdr->len; if (state[RX].msgLen < UART_MAX_MSG_LEN) { if (state[RX].msgLen != 0) { state[RX].buff = (uint8_t*)ker_malloc(state[RX].msgLen, UART_PID); if (state[RX].buff != NULL) { state[RX].msgHdr->data = state[RX].buff; state[RX].msgHdr->flag = SOS_MSG_RELEASE; state[RX].msg_state = SOS_MSG_RX_DATA; state[RX].idx = 0; } else { uart_reset_recv(); } } else { // 0 length packet go straight to crc state[RX].msgHdr->flag &= ~SOS_MSG_RELEASE; state[RX].msgHdr->data = NULL; state[RX].msg_state = SOS_MSG_RX_CRC_LOW; } } else { // invalid msg length uart_reset_recv(); } } break; case SOS_MSG_RX_RAW: case SOS_MSG_RX_DATA: if (err != 0) { uart_reset_recv(); return; } state[RX].buff[state[RX].idx++] = byte_in; if (state[RX].flags & UART_CRC_FLAG) { state[RX].crc = crcByte(state[RX].crc, byte_in); } if (state[RX].idx == state[RX].msgLen) { if (state[RX].flags & UART_SOS_MSG_FLAG) { state[RX].hdlc_state = HDLC_CRC; state[RX].msg_state = SOS_MSG_RX_CRC_LOW; } else { // rx buffer overflow uart_reset_recv(); } } break; case SOS_MSG_RX_CRC_LOW: crc_in = byte_in; state[RX].msg_state = SOS_MSG_RX_CRC_HIGH; break; case SOS_MSG_RX_CRC_HIGH: crc_in |= ((uint16_t)(byte_in) << 8); state[RX].hdlc_state = HDLC_PADDING; state[RX].msg_state = SOS_MSG_RX_END; state[RX].state = UART_HDLC_STOP; break; case SOS_MSG_RX_END: // should never get here default: uart_reset_recv(); break; } break; case UART_HDLC_STOP: if (byte_in != HDLC_FLAG) { // silently drop until hdlc stop symbol break; } else { // sos msg rx done state[RX].hdlc_state = HDLC_IDLE; if(crc_in == state[RX].crc) { #ifndef NO_SOS_UART_MGR set_uart_address(entohs(state[RX].msgHdr->saddr)); #endif if(state[RX].msgHdr->type == MSG_TIMESTAMP){ uint32_t timestp = ker_systime32(); memcpy(((uint8_t*)(state[RX].msgHdr->data) + sizeof(uint32_t)),(uint8_t*)(×tp),sizeof(uint32_t)); } handle_incoming_msg(state[RX].msgHdr, SOS_MSG_UART_IO); state[RX].msgHdr = NULL; } else { msg_dispose(state[RX].msgHdr); state[RX].msgHdr = NULL; } state[RX].state = UART_IDLE; state[RX].msg_state = SOS_MSG_NO_STATE; state[RX].hdlc_state = HDLC_IDLE; //uart_reset_recv(); //state[RX].msg_state = SOS_MSG_NO_STATE; //state[RX].state = UART_HDLC_START; } break; // XXX fall through default: uart_reset_recv(); break; } // state[RX].state #ifdef SOS_USE_PREEMPTION // enable interrupts because // enabling preemption can cause one to occur ENABLE_GLOBAL_INTERRUPTS(); // enable preemption ENABLE_PREEMPTION(NULL); #endif }
uart_send_interrupt() { #ifdef SOS_USE_PREEMPTION HAS_PREEMPTION_SECTION; DISABLE_PREEMPTION(); #endif SOS_MEASUREMENT_IDLE_END(); LED_DBG(LED_GREEN_TOGGLE); //DEBUG("uart_send_interrupt %d %d %d\n", state[TX].state, state[TX].msg_state, // state[TX].hdlc_state); switch (state[TX].state) { case UART_HDLC_START: uart_setByte((state[TX].flags & UART_SOS_MSG_FLAG)?HDLC_SOS_MSG:HDLC_RAW); state[TX].hdlc_state = HDLC_DATA; state[TX].state = UART_PROTOCOL; if (state[TX].flags & UART_CRC_FLAG) { state[TX].crc = crcByte(0, (state[TX].flags & UART_SOS_MSG_FLAG)?HDLC_SOS_MSG:HDLC_RAW); } break; case UART_PROTOCOL: state[TX].state = UART_DATA; if (state[TX].flags & UART_SOS_MSG_FLAG) { state[TX].msg_state = SOS_MSG_TX_HDR; } else { state[TX].msg_state = SOS_MSG_TX_RAW; } // set state and fall through case UART_DATA: switch (state[TX].msg_state) { case SOS_MSG_TX_HDR: uart_send_byte(((uint8_t*)(state[TX].msgHdr))[state[TX].idx]); if ((state[TX].idx == SOS_MSG_HEADER_SIZE) && (state[TX].hdlc_state != HDLC_ESCAPE)) { state[TX].idx = 0; if (state[TX].msgHdr->len != 0) { state[TX].msg_state = SOS_MSG_TX_DATA; } else { state[TX].hdlc_state = HDLC_CRC; state[TX].msg_state = SOS_MSG_TX_CRC_LOW; } } break; case SOS_MSG_TX_DATA: case SOS_MSG_TX_RAW: uart_send_byte(state[TX].buff[state[TX].idx]); if ((state[TX].idx == state[TX].msgLen) && (state[TX].hdlc_state != HDLC_ESCAPE)) { if (state[TX].flags & UART_CRC_FLAG) { state[TX].hdlc_state = HDLC_CRC; state[TX].msg_state = SOS_MSG_TX_CRC_LOW; } else { // no crc state[TX].state = UART_END; uart_setByte(HDLC_FLAG); } } break; case SOS_MSG_TX_CRC_LOW: uart_send_byte((uint8_t)(state[TX].crc)); if (state[TX].hdlc_state != HDLC_ESCAPE) { //! crc was escaped, resend state[TX].msg_state = SOS_MSG_TX_CRC_HIGH; } break; case SOS_MSG_TX_CRC_HIGH: uart_send_byte((uint8_t)(state[TX].crc >> 8)); if (state[TX].hdlc_state != HDLC_ESCAPE) { //! resend low byte state[TX].msg_state = SOS_MSG_TX_END; state[TX].state = UART_HDLC_STOP; } break; default: break; } break; case UART_HDLC_STOP: uart_setByte(HDLC_FLAG); state[TX].state = UART_END; state[TX].msg_state = SOS_MSG_NO_STATE; break; case UART_END: //DEBUG("disable Tx in uart.c\n"); uart_disable_tx(); state[TX].state = UART_IDLE; state[TX].hdlc_state = HDLC_IDLE; uart_send_done(state[TX].flags & ~UART_ERROR_FLAG); //DEBUG("uart_disable_tx\n"); break; default: //DEBUG("In Default...\n"); //DEBUG("disable Tx in uart.c\n"); uart_disable_tx(); state[TX].flags |= UART_ERROR_FLAG; state[TX].state = UART_IDLE; state[TX].hdlc_state = HDLC_IDLE; uart_send_done(state[TX].flags & ~UART_ERROR_FLAG); break; } //DEBUG("end uart_send_interrupt %d %d %d\n", state[TX].state, state[TX].msg_state, // state[TX].hdlc_state); #ifdef SOS_USE_PREEMPTION // enable interrupts because // enabling preemption can cause one to occur ENABLE_GLOBAL_INTERRUPTS(); // enable preemption ENABLE_PREEMPTION(NULL); #endif }
i2c_interrupt() { static uint8_t addrFailCnt; SOS_MEASUREMENT_IDLE_END(); // TWSR & TW_STATUS_MASK switch (TWSR) { /************************* * Master General States * *************************/ case TWI_START: /* 0x08 */ addrFailCnt = 0; i2c.idx = 0; // Fall through! case TWI_REP_START: /* 0x10 */ i2c_setByte(i2c.addr|((i2c.flags & I2C_TX_FLAG)?0:1)); // only set R/W bit if reading i2c_setCtrlReg((1<<TWINT)|(1<<TWEN)|(1<<TWIE)); break; case TWI_ARB_LOST: /* 0x38 */ i2c_setCtrlReg((1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE)); // Initate a (RE)START condition // TWI hardware will resend start when bus is free and signal TWI_RESTART break; /***************************** * Master Transmitter States * *****************************/ case TWI_MTX_ADR_ACK: /* 0x18 */ i2c.state = I2C_MASTER_TX; if (i2c.flags & I2C_SOS_MSG_FLAG) { // this is a difference between the i2c and uart // uart uses a protocol byte for BOTH raw and sos_msgs // i2c ONLY sends a protocol byte in the case of a sos_msg i2c_setByte(HDLC_SOS_MSG); i2c.msg_state = SOS_MSG_TX_HDR; // this is a sos_msg so a crc is required i2c.crc = crcByte(0, HDLC_SOS_MSG); i2c_setCtrlReg((1<<TWINT)|(1<<TWEN)|(1<<TWIE)); break; } else { i2c.msg_state = SOS_MSG_TX_RAW; } // fall through case TWI_MTX_DATA_ACK: /* 0x28 */ switch (i2c.msg_state) { case SOS_MSG_TX_HDR: i2c_setByte(((uint8_t*)(i2c.msgBuf))[i2c.idx]); // this is a sos_msg so a crc is required i2c.crc = crcByte(i2c.crc, ((uint8_t*)(i2c.msgBuf))[i2c.idx]); i2c.idx++; if (i2c.idx == SOS_MSG_HEADER_SIZE) { i2c.idx = 0; i2c.txPending = i2c.msgLen + SOS_MSG_CRC_SIZE; i2c.msg_state = SOS_MSG_TX_DATA; } break; case SOS_MSG_TX_RAW: case SOS_MSG_TX_DATA: i2c_setByte(i2c.dataBuf[i2c.idx]); if (i2c.flags & I2C_CRC_FLAG) { i2c.crc = crcByte(i2c.crc, i2c.dataBuf[i2c.idx]); } i2c.idx++; if (i2c.idx == i2c.msgLen) { if (!(i2c.flags & I2C_CRC_FLAG)) { // send stop bit and reset interface to ready state i2c.txPending = 0; i2c.msg_state = SOS_MSG_TX_END; } else { i2c.txPending = SOS_MSG_CRC_SIZE; // no unsent bytes i2c.msg_state = SOS_MSG_TX_CRC_LOW; } } break; case SOS_MSG_TX_CRC_LOW: i2c_setByte((uint8_t)(i2c.crc)); i2c.txPending--; i2c.msg_state = SOS_MSG_TX_CRC_HIGH; break; case SOS_MSG_TX_CRC_HIGH: i2c_setByte((uint8_t)(i2c.crc>>8)); i2c.txPending--; i2c.msg_state = SOS_MSG_TX_END; break; case SOS_MSG_TX_END: // send stop bit and reset interface to ready state i2c_setCtrlReg((1<<TWINT)|(1<<TWEA)|(1<<TWSTO)|(1<<TWEN)|(1<<TWIE)); i2c_send_done(i2c.flags); i2c.state = restoreState(); return; default: break; } // normal send byte all stop conditions must return and not get here i2c_setCtrlReg((1<<TWINT)|(1<<TWEN)|(1<<TWIE)); break; case TWI_MTX_ADR_NACK: /* 0x20 */ if (addrFailCnt++ < MAX_ADDR_FAIL) { // try restarting MAX_ADDR_FAIL times then fail i2c_setCtrlReg((1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE)); } else { // reset i2c and send msg fail to process i2c_setCtrlReg((1<<TWINT)|(1<<TWEA)|(1<<TWSTO)|(1<<TWEN)|(1<<TWIE)); i2c_send_done(i2c.flags|I2C_ERROR_FLAG); i2c.state = restoreState(); } break; case TWI_MTX_DATA_NACK: /* 0x30 */ // reset i2c and send msg fail to process i2c_setCtrlReg((1<<TWINT)|(1<<TWEA)|(1<<TWSTO)|(1<<TWEN)|(1<<TWIE)); i2c.txPending = i2c.txPending - i2c.idx + 1; // last byte failed i2c_send_done(i2c.flags|I2C_BUFF_ERR_FLAG); i2c.state = restoreState(); break; /*************************** * Master Receiver States * ***************************/ case TWI_MRX_ADR_ACK: /* 0x40 */ i2c.state = I2C_MASTER_RX; i2c.rxStatus = i2c.flags; // all master rx are done in raw mode with NO protocol byte i2c.msg_state = SOS_MSG_RX_RAW; // a sos message will never be recieved as a manster if (i2c.msgLen == 1) { i2c.msg_state = SOS_MSG_RX_END; i2c_setCtrlReg((1<<TWINT)|(1<<TWEN)|(1<<TWIE)); } else { i2c_setCtrlReg((1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE)); } break; case TWI_MRX_DATA_ACK: /* 0x50 */ i2c.dataBuf[i2c.idx++] = i2c_getByte(); if (i2c.idx < (i2c.msgLen-1)) { i2c_setCtrlReg((1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE)); } else { // unset TWEA (Send NACK after next/last byte) i2c.msg_state = SOS_MSG_RX_END; i2c_setCtrlReg((1<<TWINT)|(1<<TWEN)|(1<<TWIE)); } break; case TWI_MRX_ADR_NACK: /* 0x48 */ if (addrFailCnt++ < MAX_ADDR_FAIL) { // tryrestarting MAX_ADDR_FAIL times then fail i2c_setCtrlReg((1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE)); break; } i2c_setCtrlReg((1<<TWINT)|(1<<TWEA)|(1<<TWSTO)|(1<<TWEN)|(1<<TWIE)); // return data i2c_read_done(i2c.dataBuf, i2c.idx, i2c.rxStatus); i2c.idx = 0; i2c.rxStatus = 0; i2c.state = restoreState(); break; case TWI_MRX_DATA_NACK: /* 0x58 */ i2c.dataBuf[i2c.idx++] = i2c_getByte(); if (i2c.idx < i2c.msgLen) { // nack from master indication rx done // send stop bit, clear interrupt and reset interface to ready state i2c.rxStatus |= I2C_BUFF_ERR_FLAG; } // set flags and return data i2c.rxStatus |= I2C_BUFF_DIRTY_FLAG; i2c_setCtrlReg((1<<TWINT)|(1<<TWEA)|(1<<TWSTO)|(1<<TWEN)|(1<<TWIE)); i2c_read_done(i2c.dataBuf, i2c.idx, i2c.rxStatus); i2c.idx = 0; i2c.rxStatus = 0; i2c.state = restoreState(); break; /**************************** * Slave Transmitter States * ****************************/ case TWI_STX_ADR_ACK: /* 0xA8 */ case TWI_STX_ADR_ACK_M_ARB_LOST: /* 0xB0 */ if (i2c.state != I2C_SLAVE_WAIT) { i2c_send_done(i2c.flags|I2C_ERROR_FLAG); break; } else { saveState(i2c.state); i2c.state = I2C_SLAVE_TX; i2c.msg_state = SOS_MSG_TX_RAW; } // fall through case TWI_STX_DATA_ACK: /* 0xB8 */ if (i2c.msg_state == SOS_MSG_TX_RAW) { i2c_setByte(i2c.dataBuf[i2c.idx++]); // unset TWEA (Send NACK after next/last byte) if (i2c.msgLen == i2c.idx) { i2c_setCtrlReg((1<<TWINT)|(1<<TWEN)|(1<<TWIE)); i2c.txPending = 1; // last byte failed i2c.msg_state = SOS_MSG_TX_END; } else { // Reset the TWI Interupt to wait to ack next byte i2c_setCtrlReg((1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE)); } } break; case TWI_STX_DATA_NACK: /* 0xC0 */ // Master has sent a NACK before expected amount of data was sent. // set dirty bit on send buffer go to end state and issue send done if (i2c.msg_state != SOS_MSG_TX_END) { i2c.txPending = i2c.txPending - i2c.idx + 1; // last byte failed i2c.msg_state = SOS_MSG_TX_END; } else { i2c.txPending = 0; } i2c_setCtrlReg((1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE)); if (i2c.msg_state == SOS_MSG_TX_END) { i2c.msg_state = SOS_MSG_NO_STATE; i2c_send_done(i2c.flags); } break; case TWI_STX_DATA_ACK_LAST_BYTE: /* 0xC8 */ i2c.msg_state = SOS_MSG_NO_STATE; i2c_setCtrlReg((1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE)); i2c_send_done(i2c.flags|I2C_BUFF_ERR_FLAG); break; /************************* * Slave Receiver States * *************************/ // all receptions are done in a raw mode // if it is a sos message it it will be packed later case TWI_SRX_GEN_ACK: /* 0x70 */ case TWI_SRX_GEN_ACK_M_ARB_LOST: /* 0x78 */ i2c.rxStatus = I2C_GEN_ADDR_FLAG; // fall through case TWI_SRX_ADR_ACK: /* 0x60 */ case TWI_SRX_ADR_ACK_M_ARB_LOST: /* 0x68 */ saveState(i2c.state); i2c.state = I2C_SLAVE_RX; i2c.msg_state = SOS_MSG_RX_RAW; i2c.idx = 0; i2c_setCtrlReg((1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE)); break; case TWI_SRX_ADR_DATA_ACK: /* 0x80 */ case TWI_SRX_GEN_DATA_ACK: /* 0x90 */ if (i2c.msg_state == SOS_MSG_RX_RAW) { i2c.rxDataBuf[i2c.idx++] = i2c_getByte(); if (i2c.idx >= I2C_MAX_MSG_LEN) { // buffer overflow i2c.msg_state = SOS_MSG_RX_END; // set flags and return data i2c.rxStatus |= (I2C_BUFF_DIRTY_FLAG|I2C_BUFF_ERR_FLAG); i2c_read_done(i2c.rxDataBuf, i2c.idx, i2c.rxStatus); i2c.idx = 0; i2c.rxStatus = 0; } } i2c_setCtrlReg((1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE)); break; case TWI_SRX_ADR_DATA_NACK: /* 0x88 */ case TWI_SRX_GEN_DATA_NACK: /* 0x98 */ // switch to not addressed mode if (i2c.msg_state == SOS_MSG_RX_RAW) { // set flags and return data i2c.rxStatus |= I2C_BUFF_DIRTY_FLAG; i2c_read_done(i2c.rxDataBuf, i2c.idx, i2c.rxStatus); i2c.idx = 0; i2c.rxStatus = 0; i2c.msg_state = SOS_MSG_RX_END; } i2c_setCtrlReg((1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE)); break; case TWI_SRX_STOP_RESTART: /* 0xA0 */ // reset reciever i2c.msg_state = SOS_MSG_NO_STATE; if (i2c.idx > 0) { // need to make sure data has been read i2c.rxStatus |= I2C_BUFF_DIRTY_FLAG; i2c_read_done(i2c.rxDataBuf, i2c.idx, i2c.rxStatus); i2c.idx = 0; i2c.rxStatus = 0; } i2c_setCtrlReg((1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE)); i2c.state = restoreState(); break; /*************** * Misc States * ***************/ //case TWI_NO_STATE: /* 0xF8 */ case TWI_BUS_ERROR: /* 0x00 */ default: { uint8_t twiStatus=0; // Store TWSR and automatically sets clears noErrors bit. twiStatus = TWSR; // Clear TWINT and reset TWI Interface i2c_setCtrlReg((1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE)); i2c.state = I2C_IDLE; // should really be i2c_error i2c_send_done(I2C_NULL_FLAG); break; } } }