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?

Parents
  • In what way does the devices fail?

    Could it be an overflow? What would happen to /* SOME CODE THAT PROCESS THE CONTENT OF radioPacketBuffer */ if the length is too long?

  • Hi Edvin,

    As you expected, our processing of the code was failing as we were not expecting frames bigger than 127 bytes... actually radioPacketBuffer provided to the Radio driver is 128 bytes long...

    Right now, in our processing we are discarting any frame that is bigger than 127 bytes, with which we haven't had any assert and the application is still alive.

    We have some concerns if the radio is actually receiving such frames...

    1.- Is the radio writing on invalid memory as radioPacketBuffer is not big enough?

    2.- Is the frame indication from the radio an actual frame and the 8th bit is meant to be ignored (PHR in O-QPSK modulation is 7 bits)?

    3.- If the radio is configured in 802.15.4 shouldn't it be discarding such frames as those are invalid?

    In general, what is happening with these frame indications?, or do we have some configuration wrong?

    Thanks!

  • What SDK version do you use?

    Is there a way for me to reproduce this?

    You aren't using the drivers for 802.15.4 from any of the SDKs? Is there a reason for this?

  • Hi I'm using SDK v16.0.0 released in Oct. 2019 according to release notes...

    I took as example radio peripheral example (examples\peripheral\radio\receiver\pca10056\blank\ses) and replace the radio configuration and implemented the Interrupt handlers seen in the code in my post.

    Replace my comment  "SOME CODE THAT PROCESS THE CONTENT OF radioPacketBuffer" with

    if(radioPacketBuffer[0] >127)

    {

      //break here statement.

    }

    to replicate the issue. I see it happen when I have a high traffic network, but as I do not know what causes the radio driver to accept packets biggers than 127 and those packets somehow have the CRC passed (very strange behavior... ) I'm not sure if you will see the same...

    Regarding the drivers, yes I saw the repo, but I'm not implementing a 802.15.4 compliant device as I need to do some tricky things such as listening to multiple addresses at the same time for instance...

    Pretty much I have completed my work by just using the radio registers... if I have this packets issue solved, then I'm done for now with this part of the project.

    Thanks for your help Edvin!

  • Are the packets you are receiving that are >127 bytes coming from your own network? Or is it a packet that is sniffed up from a nearby device? What does it look like? Is there actually more than 127 bytes? What is radioPacketBuffer[0]? Is it correct? (the same as the size of the packet?)

    What happens if you just ignore these packets?

    BR,
    Edvin

Reply Children
  • 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