static void RADIO_HandleStateMachine(void) { uint8_t status; for(;;) { /* will break/return */ switch (RADIO_AppStatus) { case RADIO_INITIAL_STATE: RF1_StopRxTx(); /* will send/receive data later */ RADIO_AppStatus = RADIO_RECEIVER_ALWAYS_ON; /* turn receive on */ break; /* process switch again */ case RADIO_RECEIVER_ALWAYS_ON: /* turn receive on */ RX_POWERUP(); RF1_StartRxTx(); /* Listening for packets */ RADIO_AppStatus = RADIO_READY_FOR_TX_RX_DATA; break; /* process switch again */ case RADIO_READY_FOR_TX_RX_DATA: /* we are ready to receive/send data data */ if (RADIO_isrFlag) { /* Rx interrupt? */ RADIO_isrFlag = FALSE; /* reset interrupt flag */ (void)CheckRx(); /* get message */ RADIO_AppStatus = RADIO_RECEIVER_ALWAYS_ON; /* continue listening */ break; /* process switch again */ } if (CheckTx()==ERR_OK) { /* there was data and it has been sent */ RADIO_AppStatus = RADIO_WAITING_DATA_SENT; break; /* process switch again */ } return; case RADIO_WAITING_DATA_SENT: if (RADIO_isrFlag) { /* check if we have received an interrupt: this is either timeout or low level ack */ RADIO_isrFlag = FALSE; /* reset interrupt flag */ status = RF1_GetStatus(); if (status&RF1_STATUS_RX_DR) { /* data received interrupt */ RF1_ResetStatusIRQ(RF1_STATUS_RX_DR); /* clear bit */ } if (status&RF1_STATUS_TX_DS) { /* data sent interrupt */ RF1_ResetStatusIRQ(RF1_STATUS_TX_DS); /* clear bit */ } if (status&RF1_STATUS_MAX_RT) { /* retry timeout interrupt */ RF1_ResetStatusIRQ(RF1_STATUS_MAX_RT); /* clear bit */ RF1_Write(RF1_FLUSH_TX); /* flush old data */ RADIO_AppStatus = RADIO_TIMEOUT; /* timeout */ } else { RADIO_AppStatus = RADIO_RECEIVER_ALWAYS_ON; /* turn receive on */ } break; /* process switch again */ } return; case RADIO_TIMEOUT: Err((unsigned char*)"ERR: Timeout\r\n"); RADIO_AppStatus = RADIO_RECEIVER_ALWAYS_ON; /* turn receive on */ break; /* process switch again */ default: /* should not happen! */ return; } /* switch */ } /* for */ }
/*! * Physical layer state machine implementation */ static void HandleStateMachine() { uint8_t result; for ( ;; ) { switch ( phyStatus ) { case PHY_INITIAL_STATE: LOG_TRACE("Radio reset."); Radio.Reset(); /* Random seed initialization */ srand1(Radio.Random()); if ( pLoRaDevice->devClass != CLASS_C ) { LOG_TRACE("Radio idle."); phyStatus = PHY_IDLE; } else { LOG_TRACE("Radio receiving."); phyStatus = PHY_RECEIVING; } break; case PHY_POWER_DOWN: Radio.Sleep(); LOG_TRACE("Radio idle."); phyStatus = PHY_IDLE; return; case PHY_IDLE: { result = CheckTx(); if ( result == ERR_OK ) { /* there was data and it has been sent */ phyStatus = PHY_WAIT_FOR_TXDONE; LOG_TRACE("Radio wait tx done."); break; /* process switch again */ } return; } case PHY_WAIT_FOR_TXDONE: if ( phyFlags.Bits.TxDone == 1 ) { phyFlags.Bits.TxDone = 0; if ( pLoRaDevice->devClass != CLASS_C ) { LOG_TRACE("Tx done. Radio power down."); phyStatus = PHY_POWER_DOWN; } else { LOG_TRACE("Radio receiving."); phyStatus = PHY_RECEIVING; } break; } return; case PHY_RECEIVING: if ( phyFlags.Bits.RxDone == 1 ) { phyFlags.Bits.RxDone = 0; LOG_TRACE("Rx done. Radio power down."); phyStatus = PHY_POWER_DOWN; break; } /* Reception window open */ return; case PHY_ADVERTISING: return; case PHY_TIMEOUT: phyStatus = PHY_POWER_DOWN; LOG_TRACE("Radio timeout. Radio power down."); break; case PHY_ERROR: phyStatus = PHY_POWER_DOWN; LOG_TRACE("Radio error. Radio power down."); break; default: return; } } }