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(); } } }
/*! * This is the State Machine of the Demo Application. */ void StateMachine(void) { switch (DEMO_SR) { case DEMO_BOOT: BoardInit(); ENABLE_GLOBAL_INTERRUPTS(); EZMacPRO_Init(); /* Wait until device goes to Sleep. */ WAIT_FLAG_TRUE(fEZMacPRO_StateSleepEntered); /* Clear State transition flags. */ fEZMacPRO_StateWakeUpEntered = 0; vP2P_demo_TxInit(); // Point to point demo initialisation. DEMO_SR = DEMO_TX; // Go to TX state. break; case DEMO_TX: // LFT expired, send next packet. if (fEZMacPRO_LFTimerExpired) { fEZMacPRO_LFTimerExpired = 0; // Send packet then place the radio to sleep. vP2P_demo_SendPacketGoToSleep(); DEMO_SR = DEMO_TX_WF_ACK; // Go to TX wait for acknowledgement state. } break; case DEMO_TX_WF_ACK: // Auto-acknowledgement has arrived. if (fEZMacPRO_PacketSent) { fEZMacPRO_PacketSent = 0; LED1_TOGGLE(); DEMO_SR = DEMO_TX; // Go to TX state. } // Auto-acknowledgement has not arrived. if (fEZMacPRO_AckTimeout) { fEZMacPRO_AckTimeout = 0; DEMO_SR = DEMO_TX; // Go to TX state. } break; default: break; } }
/** * @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 }
/*! \brief Disables processor rewrite mode This function also enables global interrupts. \param void \return void */ void disable_df_write(void) { fmr01 = 0; ENABLE_GLOBAL_INTERRUPTS(); } // disable_df_write //