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

802.15.4 Packet Size

Hello,

I've been testing 802.15.4 single PHY (no softdevice) and analyzing packets on a TI CC2531, just to check interoperability. Things seem to work well when the packet size is at most 29 bytes. When I increase the packet size to 30 or more, the packet reception is poor (maybe some packets get through, many get CRC errors). I had thought that the limitation was 127 bytes for the 802.15.4 standard. 

In a way, 29 bytes makes sense: considering the first byte (not in the packet) is the length, then the two auto-generated CRC bytes as the footer, we get the magic number of 32 bytes. Is that what's going on, 32 bytes is the actual limit?

Thanks,

Ted 

Parents Reply Children
  • I ran such an experiment earlier, but to be certain I will run another one later and post the code and results; if I recall correctly, the direction external 802.15.4 -> nRF was flawless for larger packet sizes. I also updated the code/experiment in the nRF -> cc2531 direction with a larger packet, shown below (this one implements the transmitted_raw callback, after I read the raw transmission is preferred now). Each transmit from the nRF does trigger the SFD event on the cc2531, so at least each start-of-frame is detected. Some percent of the larger packets are fully and correctly (passing CRC tests) received on the cc2531, perhaps around 25% or so. 

    #include <stdbool.h>
    #include <stddef.h>
    #include <stdint.h>
    
    #include "nrf_802154.h"
    #include "boards.h"
    #include "nrf_delay.h"
    #include "IEEE802154.h"
    
    #define MAX_MESSAGE_SIZE 37 
    #define CHANNEL 26
    #define PACKET_MAX_PAYLOAD 26 
    
    typedef uint16_t mac_addr_t;
    struct motepacket {
      uint8_t length;
      uint16_t fcf;
      uint8_t data_seq_no;
      mac_addr_t pan;
      mac_addr_t dest;
      mac_addr_t src;
      uint8_t iframe;    // field for 6lowpan, is 0x3f for TinyOS
      uint8_t type;
      uint8_t data[PACKET_MAX_PAYLOAD];
      uint8_t fcs[2];    // will become CRC, don't count this in length.
      };
    typedef struct motepacket motepacket_t;
    
    static volatile bool m_tx_in_progress; 
    static volatile bool m_tx_done;
    uint8_t seqno = 0; 
    uint8_t buffer[sizeof(motepacket_t)];
    motepacket_t * p = (motepacket_t *)buffer;
    
    //int main(int argc, char *argv[])
    int main(void)
    {
        bsp_board_init(BSP_INIT_LEDS);
        bsp_board_led_invert(0);
    
        p->fcf = 0x0000;
        // the following FCF lines are copied from TinyOS CC2420 driver
        p->fcf &= 1 << IEEE154_FCF_ACK_REQ;
        p->fcf |= ( ( IEEE154_TYPE_DATA << IEEE154_FCF_FRAME_TYPE )
                      |  ( 1 << IEEE154_FCF_INTRAPAN )
                      |  ( IEEE154_ADDR_SHORT << IEEE154_FCF_DEST_ADDR_MODE )
                      |  ( IEEE154_ADDR_SHORT << IEEE154_FCF_SRC_ADDR_MODE ) );
        p->data_seq_no = 0;
        p->pan = 0x22;     // GROUP
        p->dest = 0xFFFF;  // BCAST_ADDR
        p->src = 99;       // ID of sender
        p->iframe = 0x3f;  // 6LowPan designator 
        p->type = 0x37;    // (bogus for now, could have meaning later)
        // -1 for length, +2 for unknown reason - seems to sort of work, 
        // perhaps because of the CRC bytes in the fcs?
        p->length =  offsetof(motepacket_t,data) + 2 + PACKET_MAX_PAYLOAD - 1;
        m_tx_in_progress = false;
        m_tx_done        = true;
    
        nrf_802154_init();
        nrf_802154_channel_set(CHANNEL);
        nrf_802154_receive();
    
        while (1) {
            p->data_seq_no = seqno++;
            for (int i=0; i<PACKET_MAX_PAYLOAD; i++) p->data[i] = seqno+i;
    	if (!m_tx_done || m_tx_in_progress) {
    	  nrf_delay_ms(3000);
    	  continue;
              }
            bsp_board_led_invert(0);
            if (!m_tx_in_progress) {
              m_tx_in_progress = nrf_802154_transmit_raw(buffer, true);
              bsp_board_led_invert(1);
              }
            }
        return 0;
        }
    
    void nrf_802154_transmitted_raw(const uint8_t * p_frame, uint8_t * p_ack, int8_t power, uint8_t lqi) {
        (void) p_frame;
        (void) power;
        (void) lqi;
        m_tx_done = true;
        m_tx_in_progress = false;
        bsp_board_led_invert(2);
        if (p_ack != NULL) {
            nrf_802154_buffer_free_raw(p_ack);
            }
        }

  • I was unable to get the standard rx example to work, using the 802.15.4 git repo (https://github.com/NordicSemiconductor/nRF-IEEE-802.15.4-radio-driver) of  Tue Feb 12 2019 (c0114b43bb222f55c5d4b22d4d144210df4cb1cc). However I was able to run the rx example using an early version of the same repo, from commit d049e668a055d114f956fd389349cd3f16b99399, Date: Wed Nov 14 2018. Here is sample output below. Two packets are shown, one from the Nordix tx demo, the other from a cc2531 device, and the total packet length exceeds 32 - so I think this is working properly. I am uncertain why, with the newest version of the 802.15.4 driver, that the rx program does not work. I had to make some minimal changes in the Makefile due to changes in the stack, otherwise it seems the same. 

    <info> app: Packet
    <info> app:  27 41 88 35 22 00 FF FF|'A.5"...
    <info> app:  01 00 3F 06 02 02 03 04|..?.....
    <info> app:  05 06 07 08 09 0A 0B 0C|........
    <info> app:  0D 0E 0F 10 11 12 13 14|........
    <info> app:  15 16 17 18 19 1A 41 00|......A.
    <info> app:  00 00 00 00            |....    
    <info> app: Packet
    <info> app:  1D 41 98 31 32 33 34 35|.A.12345
    <info> app:  36 37 38 39 3A 3B 3C 3D|6789:;<=
    <info> app:  3E 3F 40 41 42 43 44 45|>?@ABCDE
    <info> app:  46 47 48 49 23 00 00 00|FGHI#...
    <info> app:  00 00 00 00 00 00 00 00|........
    <info> app:  00 00 00 00            |....    

  • I will try to reproduce this behavior, and check with the developer what is happening, if I'm able to reproduce it.

  • I have made some progress on this, and will update status I hope in one more day.

  • I rewrote my testing program carefully preparing the sdk_config.h and Makefile. Now it runs with the latest Nordic 802.15.4 git repo. When I use two nRF52840 dev boards, packets can be larger without error between xmit and recv, though I did not test very large (127 byte) packets. However, the problem of interoperation remains, packets larger than 29-32 bytes, depending how things are counted, likely get CRC errors or frame truncation. Not all packets fail, just the majority. This occurs only in the nRF -> cc2531 direction. I do not have RF equipment to check further. 

Related