This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Radio configure as Rx with 802.15.4 mode receives more than 127 bytes

Hi all,

I'm working with the reception of 802.15.4 packets on nRF52840 for which I have configure the radio as follows:

//PHR length in bits
#define PACKET_LENGTH_FIELD_SIZE  (8UL) 
//Max ota frame size for O-QPSK modulation
#define MAX_OTA_FRAME_SIZE            127

//Buffer for frames to be received: 127 MAX PSDU size + PHR size
static uint8_t  radioPacketBuffer[MAX_OTA_FRAME_SIZE + 1];   

void RADIO_IRQHandler(void)
{
    //Is the radio ready
    if(NRF_RADIO->EVENTS_READY == 1U)
    {
      NRF_RADIO->EVENTS_READY = 0;

      NRF_RADIO->EVENTS_END = 0U;
      // Start listening and wait for end of reception event
      NRF_RADIO->TASKS_START = 1U;
    }

    if(NRF_RADIO->EVENTS_END == 1U)
    {
      NRF_RADIO->EVENTS_END = 0;
      //Get the timestamp
      NRF_TIMER1->TASKS_CAPTURE[0] = 1;
      //Check if the checksum is correct
      if (NRF_RADIO->CRCSTATUS == 1U)
      {
        OTAFrameValidReceivedFlag = true;
      }
      StartRxRadioFlag = true;
    }
}

void radioInit(void)
{
    // Set radio configuration parameters
    NRF_RADIO->SHORTS = 0;   
    NRF_RADIO->TXPOWER = 0;
    NRF_RADIO->MODE      = (RADIO_MODE_MODE_Ieee802154_250Kbit << RADIO_MODE_MODE_Pos);

    // Packet configuration
    NRF_RADIO->PCNF0 = (PACKET_LENGTH_FIELD_SIZE << RADIO_PCNF0_LFLEN_Pos)    |
                       (RADIO_PCNF0_CRCINC_Include << RADIO_PCNF0_CRCINC_Pos) |  
                       (RADIO_PCNF0_PLEN_32bitZero << RADIO_PCNF0_PLEN_Pos) ; 

    // Packet configuration
    NRF_RADIO->PCNF1 = MAX_OTA_FRAME_SIZE;

    // Radio address config
    NRF_RADIO->BASE0 = 0;
    NRF_RADIO->BASE1 = 0;
    NRF_RADIO->PREFIX0 = 0;
    NRF_RADIO->PREFIX1 = 0;

    // CRC Config
    NRF_RADIO->CRCCNF = (RADIO_CRCCNF_LEN_Two << RADIO_CRCCNF_LEN_Pos)  |
                        (RADIO_CRCCNF_SKIPADDR_Ieee802154 << RADIO_CRCCNF_SKIPADDR_Pos); // Number of checksum bits

    NRF_RADIO->CRCINIT = 0;          // Initial value
    NRF_RADIO->CRCPOLY = 0x11021UL;  // CRC poly: x^16 + x^12^x^5 + 1


    NRF_RADIO->TIFS = 0;
    //NRF_RADIO->DATAWHITEIV = 0x40;  
    NRF_RADIO->BCC = 0x18;            
    NRF_RADIO->DACNF = 0;
    NRF_RADIO->MHRMATCHCONF = 0;          //This was taken from ZR on running state, not really sure what it does... nrf spec does not provide help about it...
    NRF_RADIO->MHRMATCHMAS = 0xff000700;  //This was taken from ZR on running state, not really sure what it does... nrf spec does not provide help about it...
    
    NRF_RADIO->MODECNF0 = (RADIO_MODECNF0_RU_Fast << RADIO_MODECNF0_RU_Pos)   |
                          (RADIO_MODECNF0_DTX_Center << RADIO_MODECNF0_DTX_Pos);

    //802.15.4 configration
    NRF_RADIO->SFD = 0xA7;
    NRF_RADIO->EDCNT = 0;
    NRF_RADIO->EDSAMPLE = 0;
    NRF_RADIO->CCACTRL = 0x02141400;  //From ZR configuration...
    NRF_RADIO->POWER = 1;
    
    NRF_RADIO->PACKETPTR = (uint32_t)&radioPacketBuffer;
    NRF_RADIO->FREQUENCY = 5UL;    



    NRF_RADIO->INTENSET = RADIO_INTENSET_READY_Enabled << RADIO_INTENSET_READY_Pos | 
                          RADIO_INTENSET_END_Enabled << RADIO_INTENSET_END_Pos;
    
    NVIC_SetPriority(RADIO_IRQn, 1);
    NVIC_ClearPendingIRQ(RADIO_IRQn);
    NVIC_EnableIRQ(RADIO_IRQn);
}

In the application loop we have:

      if(OTAFrameValidReceivedFlag)
      {
        timestamp = NRF_TIMER1->CC[0];
        OTAFrameValidReceivedFlag = false;

        /*  ...
        
        SOME CODE THAT PROCESS THE CONTENT OF radioPacketBuffer
        
        ... */
        
        memset(radioPacketBuffer,0,sizeof(radioPacketBuffer));
        
        //valid frame received!
        bsp_board_led_invert(0);
      }
      if(radioActive & StartRxRadioFlag)
      {
        // Start listening again
        NRF_RADIO->TASKS_START = 1U;
      }

we receive frames and transmit frames properly, but there is sometimes in which we receive frames in radioPacketBuffer, which payload is bigger than 127, this is readed in radioPacketBuffer[0].

According to 802.15.4 for O-QPSK the max payload is 127 bytes, all the frames we received seems fine, but as soon we start capturing on populated networks we see this kind of behavior which is causing the device to fail. 

Has this happened to anyone?, do we have a wrong configuration to capture packets?

  • I use Zigbee Certified devices in the network which are 802.15.4 compliant, I do not know the exact packet frames those devices do send, but I'm sure that those are not bigger than 127 bytes...

    I do not have a frame example at the moment I can try to get one later, but as my buffer is 128 bytes, I'm not sure if the radio driver is writing the rest of the memory or what is actually doing... I will try increasing the buffer size to... 257 bytes? (0xFF + the byte for the length)

    What you mean by: What is radioPacketBuffer[0]? Is it correct?

    As I understand, the Radio driver will write the length of the packet at the byte[0] of the buffer provided which in my case is radioPacketBuffer... so I expect that radioPacketBuffer[0] has the length of the packet received by the radio, which according to 802.15.4 can't be bigger than 127 bytes... so when I see it being bigger than that I know:

    1.- Is not any of the devices in the network.

    2.- The CRC is supposed to has passed otherwise I should not get a radio indication.

    3.- The notification of the radio is wrong as there cant be > 127 bytes packets (either because of an issue in the radio driver, or I have something configured incorrectly...)

    If I ignore those frames the application runs correctly, but what I intent to get from this support ticket is why those are happening... is that an expected issue from the radio driver so I should ignore those? or is just the length that is wrong and it should be another value, or may be I have something wrong in the radio configuration ?

    Thanks!

  • Hello,

    I asked some guys working with our radio peripheral for the 802.15.4 drivers. They say that the Radio peripheral itself doesn't check if the frame length is valid. It only limits the size of DMA transfers. It is possible that the peripheral interprets noise as a valid frame, and that this may be longer than 127 bytes, but it would store a maximum of 127 bytes into the ram (to prevent memory corruption). 

    In the nRF 802.15.4 drivers they check the frame length field in SW to discard too short and too long frames, which you can see here:

    https://github.com/NordicSemiconductor/nRF-IEEE-802.15.4-radio-driver/blob/61bc74d7fb420779e58795581c0b53a0531c89c1/src/mac_features/nrf_802154_filter.c#L449

    So I would say that it is safe to discard these messages. You can of course see whether the packets looks like something valid, or if it looks like noise, if you are curious. But as you say, no valid packets should be more than 127 bytes. 

    Best regards,

    Edvin

Related