/*********************************************************************************** * @fn basicRfRxFrmDoneIsr * * @brief Interrupt service routine for received frame from radio * (either data or acknowlegdement) * * @param rxi - file scope variable info extracted from the last incoming * frame * txState - file scope variable that keeps tx state info * * @return none */ static void basicRfRxFrmDoneIsr(void) { basicRfPktHdr_t *pHdr; uint8 *pStatusWord; #ifdef SECURITY_CCM uint8 authStatus=0; #endif // Map header to packet buffer pHdr= (basicRfPktHdr_t*)rxMpdu; // Clear interrupt and disable new RX frame done interrupt halRfDisableRxInterrupt(); // Enable all other interrupt sources (enables interrupt nesting) halIntOn(); // Read payload length. halRfReadRxBuf(&pHdr->packetLength,1); pHdr->packetLength &= BASIC_RF_PLD_LEN_MASK; // Ignore MSB // Is this an acknowledgment packet? // Only ack packets may be 5 bytes in total. if (pHdr->packetLength == BASIC_RF_ACK_PACKET_SIZE) { // Read the packet halRfReadRxBuf(&rxMpdu[1], pHdr->packetLength); // Make sure byte fields are changed from network to host byte order UINT16_NTOH(pHdr->panId); UINT16_NTOH(pHdr->destAddr); UINT16_NTOH(pHdr->srcAddr); #ifdef SECURITY_CCM UINT32_NTOH(pHdr->frameCounter); #endif rxi.ackRequest = !!(pHdr->fcf0 & BASIC_RF_FCF_ACK_BM_L); // Read the status word and check for CRC OK pStatusWord= rxMpdu + 4; // Indicate the successful ACK reception if CRC and sequence number OK if ((pStatusWord[1] & BASIC_RF_CRC_OK_BM) && (pHdr->seqNumber == txState.txSeqNumber)) { txState.ackReceived = TRUE; } // No, it is data } else { // It is assumed that the radio rejects packets with invalid length. // Subtract the number of bytes in the frame overhead to get actual payload. rxi.length = pHdr->packetLength - BASIC_RF_PACKET_OVERHEAD_SIZE; #ifdef SECURITY_CCM rxi.length -= (BASIC_RF_AUX_HDR_LENGTH + BASIC_RF_LEN_MIC); authStatus = halRfReadRxBufSecure(&rxMpdu[1], pHdr->packetLength, rxi.length, BASIC_RF_LEN_AUTH, BASIC_RF_SECURITY_M); #else halRfReadRxBuf(&rxMpdu[1], pHdr->packetLength); #endif // Make sure byte fields are changed from network to host byte order UINT16_NTOH(pHdr->panId); UINT16_NTOH(pHdr->destAddr); UINT16_NTOH(pHdr->srcAddr); #ifdef SECURITY_CCM UINT32_NTOH(pHdr->frameCounter); #endif rxi.ackRequest = !!(pHdr->fcf0 & BASIC_RF_FCF_ACK_BM_L); // Read the source address rxi.srcAddr= pHdr->srcAddr; // Read the packet payload rxi.pPayload = rxMpdu + BASIC_RF_HDR_SIZE; // Read the FCS to get the RSSI and CRC pStatusWord= rxi.pPayload+rxi.length; #ifdef SECURITY_CCM pStatusWord+= BASIC_RF_LEN_MIC; #endif rxi.rssi = pStatusWord[0]; // Notify the application about the received data packet if the CRC is OK // Throw packet if the previous packet had the same sequence number if( (pStatusWord[1] & BASIC_RF_CRC_OK_BM) && (rxi.seqNumber != pHdr->seqNumber) ) { // If security is used check also that authentication passed #ifdef SECURITY_CCM if( authStatus==SUCCESS ) { if ( (pHdr->fcf0 & BASIC_RF_FCF_BM_L) == (BASIC_RF_FCF_NOACK_L | BASIC_RF_SEC_ENABLED_FCF_BM_L)) { rxi.isReady = TRUE; } } #else if ( ((pHdr->fcf0 & (BASIC_RF_FCF_BM_L)) == BASIC_RF_FCF_NOACK_L) ) { rxi.isReady = TRUE; } #endif } rxi.seqNumber = pHdr->seqNumber; } // Enable RX frame done interrupt again halIntOff(); halRfEnableRxInterrupt(); }
int main(void) { #error "Hi, Currently not working, still to be tested! - I didn't find time to debug it! " //halIntOn(); unsigned long pktsSent = 0; perConfig.mode = PER_MODE_TX; perConfig.state = PER_IDLE; perConfig.channel = 26; perConfig.txPower = 0; // Index 0. Max output perConfig.burstSize = 1000000; // Max value perConfig.pktRate = 20; // 20 pkts per second perConfig.gainMode = PER_GAIN_MODE_NONE; // No PA/LNA // // Config basicRF // basicRfConfig.panId = PAN_ID; basicRfConfig.ackRequest = false; if(basicRfInit(&basicRfConfig) == FAILED) { while(1); } basicRfReceiveOff(); halRfSetTxPower(0); // appTimerConfig(20); halTimer32kInit(32768/20); halTimer32kIntConnect(&appTimerIsr); // Connect ISR halTimer32kIntEnable(); // Enable interrupts while(1) { if(perConfig.state == PER_TRANSMIT) { if(pktsSent < perConfig.burstSize) { // // Make sure sequence number has network byte order // UINT32_HTON(tTxPacket.seqNumber); basicRfSendPacket(RX_ADDR, (unsigned char*)&tTxPacket, PACKET_SIZE); // // Change byte order back to host order before increment // UINT32_NTOH(tTxPacket.seqNumber); // // Update variables // tTxPacket.seqNumber++; pktsSent++; perConfig.state = PER_PACKET_RECEIVED; // // Update LED // // bspLedToggle(BSP_LED_1); } else { // // Done sending packets, exit TX loop // break; } } } }