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

Very rare error in ESB, Enhanced ShockBurst

Hi

One of our customers have complained, that our sensors are making occasional errors. 

I have looked at it, and they are correct. About 1 in 8 Million packets send by ESB are received in error.

The CRC check is set to 2 bytes and the address is set to 5 bytes. So I think it is as good as it can be for the nRF24LE1 (it is not getting better with nRF5, right?)

In the attachment you can see some examples of packets that have been received in error. At this moment the transmitter is sending counting data non-stop, to detect the problem.

The it is as if, the ESB of PTX re-transmits a single packet, that has already been received.

In about 24 hours of transmission there was 3 errors. During this time the TX FIFO is normally not used. The firmware just uploads a new packet (32 bytes) every 15ms, and therefore in line of sight the TX FIFO has fully finished transmitting one packet and received the ACK packet before the firmware uploads a new packet to the TX FIFP. For this latest 24 hour test the TX FIFO was only used about 0.8% of the time, but the 3 errors all occurred here. The errors came in hours apart, but only when the ESB was catching up after transmission interruption. The tests where conducted in a very WiFi/Bluetooth/etc noisy environment.

The firmware uploads the packets with this routine:

RADIO_INTERRUPT_DISABLE;

            while (nrf_tx_fifo_full() == 0 && ram_full > 0)
            {
                write_tx_payload(ram_packet[ram_read], RF_PAYLOAD_LENGTH_DATA);
                ram_read = (ram_read + 1) % BUFFERS;
                ram_full = ram_full - 1;
            }
RADIO_INTERRUPT_ENABLE;

...

//Hi speed version of nrf_write_tx_payload
void write_tx_payload(uint8_t *tmp, uint8_t length)
{
    uint8_t i;
    NRF_CSN_LOW;

    SPIRDAT = W_TX_PAYLOAD;

    while (length--)
    {
        while (NRF_SPI_RX_FULL);
        SPIRDAT = *(tmp++);
        i = SPIRDAT;
    }

    while ( NRF_SPI_TX_EMPTY == 0 );  // wait for byte transfer finished

    i = SPIRDAT;
    NRF_CSN_HIGH;
}

...

At about 500us after the TX FIFO has been filled up, the transmission is started:

void startTransmit(uint8_t i)
{
    if (i == (id +1) ) {
        // MAX_RT flags has to be cleared, to re-start transmission.
        nrf_get_clear_irq_flags();
        NRF_CE_PULSE();
    }
}

Do you have any idea why this can happen?

er_understanding.xlsx

Parents
  • Hi,

     

    The CRC check is set to 2 bytes and the address is set to 5 bytes. So I think it is as good as it can be for the nRF24LE1 (it is not getting better with nRF5, right?)

    Hardware-wise, the nRF5 devices can do 3 byte CRC, but the "nrf_esb" library is made for backwards compatibility, so it does not have support for 3 byte crc.

     

    In about 24 hours of transmission there was 3 errors. During this time the TX FIFO is normally not used. The firmware just uploads a new packet (32 bytes) every 15ms, and therefore in line of sight the TX FIFO has fully finished transmitting one packet and received the ACK packet before the firmware uploads a new packet to the TX FIFP. For this latest 24 hour test the TX FIFO was only used about 0.8% of the time, but the 3 errors all occurred here. The errors came in hours apart, but only when the ESB was catching up after transmission interruption. The tests where conducted in a very WiFi/Bluetooth/etc noisy environment.

     Looking at the packets, it looks like most of them are corrupted payloads that by chance has passed the CRC detection. How does your RX readout routine look like?

    I would strongly recommend that you always check the length of the payload prior to reading from the RX_FIFO.

    You can read the length using command "R_RX_PL_WID" (hal_nrf.c::hal_nrf_read_rx_payload_width()).

     

    Ensure the payload length is not 0 and not larger than 32 bytes:

    len = hal_nrf_read_rx_payload_width();
    
    if (len == 0 || len > 32)
        flush_rx_fifo();
    else {
        /* Proceed as normal */
    }

     

    Could you also check if there are any data overlays that needs to be handled in your compiler? I assume you use Keil C51?

    You'll need warning L15 enabled in order to see the potential functions that overlay in memory. If you get any L15 warnings when you recompile (rebuild the whole project, not incremental build), please post them here.

     

    Kind regards,

    Håkon

Reply
  • Hi,

     

    The CRC check is set to 2 bytes and the address is set to 5 bytes. So I think it is as good as it can be for the nRF24LE1 (it is not getting better with nRF5, right?)

    Hardware-wise, the nRF5 devices can do 3 byte CRC, but the "nrf_esb" library is made for backwards compatibility, so it does not have support for 3 byte crc.

     

    In about 24 hours of transmission there was 3 errors. During this time the TX FIFO is normally not used. The firmware just uploads a new packet (32 bytes) every 15ms, and therefore in line of sight the TX FIFO has fully finished transmitting one packet and received the ACK packet before the firmware uploads a new packet to the TX FIFP. For this latest 24 hour test the TX FIFO was only used about 0.8% of the time, but the 3 errors all occurred here. The errors came in hours apart, but only when the ESB was catching up after transmission interruption. The tests where conducted in a very WiFi/Bluetooth/etc noisy environment.

     Looking at the packets, it looks like most of them are corrupted payloads that by chance has passed the CRC detection. How does your RX readout routine look like?

    I would strongly recommend that you always check the length of the payload prior to reading from the RX_FIFO.

    You can read the length using command "R_RX_PL_WID" (hal_nrf.c::hal_nrf_read_rx_payload_width()).

     

    Ensure the payload length is not 0 and not larger than 32 bytes:

    len = hal_nrf_read_rx_payload_width();
    
    if (len == 0 || len > 32)
        flush_rx_fifo();
    else {
        /* Proceed as normal */
    }

     

    Could you also check if there are any data overlays that needs to be handled in your compiler? I assume you use Keil C51?

    You'll need warning L15 enabled in order to see the potential functions that overlay in memory. If you get any L15 warnings when you recompile (rebuild the whole project, not incremental build), please post them here.

     

    Kind regards,

    Håkon

Children
No Data
Related