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

How to avoid RF CRC Error with ESB protocal

Protocal:ESB

Devices: 1:central(PTX)  2:peripheral(PRX)

Description:

1、Central transmits data to Peripheral,and then Central receives respond data from Peripheral

2、CRC mode:NRF_ESB_CRC_16BIT

    tx_mode:NRF_ESB_TXMODE_MANUAL

    retransmit_count:0

   selective_auto_ack:false

   protocal:NRF_ESB_PROTOCOL_ESB_DPL

3、When central get the response of the peripheral,the crc error will occur,the code like this,

static void on_radio_disabled_tx_wait_for_ack()
{
    // This marks the completion of a TX_RX sequence (TX with ACK)
	nrf_gpio_pin_set(DATA_SENDING_P2);
	nrf_gpio_pin_clear(DATA_SENDING_P2);

    // Make sure the timer will not deactivate the radio if a packet is received
    NRF_PPI->CHENCLR = (1 << NRF_ESB_PPI_TIMER_START) |
                       (1 << NRF_ESB_PPI_RX_TIMEOUT)  |
                       (1 << NRF_ESB_PPI_TIMER_STOP);

    // If the radio has received a packet and the CRC status is OK
    if (NRF_RADIO->EVENTS_END && (NRF_RADIO->CRCSTATUS != 0))
    {
        NRF_ESB_SYS_TIMER->TASKS_SHUTDOWN = 1;
        NRF_PPI->CHENCLR = (1 << NRF_ESB_PPI_TX_START);
        m_interrupt_flags |= NRF_ESB_INT_TX_SUCCESS_MSK;
        m_last_tx_attempts = m_config_local.retransmit_count - m_retransmits_remaining + 1;

        (void) nrf_esb_skip_tx();

        if (m_config_local.protocol != NRF_ESB_PROTOCOL_ESB && m_rx_payload_buffer[0] > 0)
        {
            if (rx_fifo_push_rfbuf((uint8_t)NRF_RADIO->TXADDRESS, m_rx_payload_buffer[1] >> 1))
            {
                m_interrupt_flags |= NRF_ESB_INT_RX_DATA_RECEIVED_MSK;
            }
        }

        if ((m_tx_fifo.count == 0) || (m_config_local.tx_mode == NRF_ESB_TXMODE_MANUAL))
        {
            m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE;
            NVIC_SetPendingIRQ(ESB_EVT_IRQ);		
        }
        else
        {
            NVIC_SetPendingIRQ(ESB_EVT_IRQ);
            start_tx_transaction();
        }
    }
    else
    {
        if (m_retransmits_remaining-- == 0)
        {
            NRF_ESB_SYS_TIMER->TASKS_SHUTDOWN = 1;
            NRF_PPI->CHENCLR = (1 << NRF_ESB_PPI_TX_START);
            // All retransmits are expended, and the TX operation is suspended
            m_last_tx_attempts = m_config_local.retransmit_count + 1;
            m_interrupt_flags |= NRF_ESB_INT_TX_FAILED_MSK;

            m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE;
            NVIC_SetPendingIRQ(ESB_EVT_IRQ);

			if(NRF_RADIO->CRCSTATUS != 0)
			{
				nrf_gpio_pin_set(DATA_SENDING_P2);
				nrf_gpio_pin_clear(DATA_SENDING_P2);
			}
        }
        else
        {
            // There are still more retransmits left, TX mode should be
            // entered again as soon as the system timer reaches CC[1].
            NRF_RADIO->SHORTS = m_radio_shorts_common | RADIO_SHORTS_DISABLED_RXEN_Msk;
			
			
            update_rf_payload_format(mp_current_payload->length);
            NRF_RADIO->PACKETPTR = (uint32_t)m_tx_payload_buffer;
            on_radio_disabled = on_radio_disabled_tx;
            m_nrf_esb_mainstate = NRF_ESB_STATE_PTX_TX_ACK;
            NRF_ESB_SYS_TIMER->TASKS_START = 1;
            NRF_PPI->CHENSET = (1 << NRF_ESB_PPI_TX_START);
            if (NRF_ESB_SYS_TIMER->EVENTS_COMPARE[1])
            {
                NRF_RADIO->TASKS_TXEN = 1;
            }
        }
    }

}

when the crc error occur,the indication will be shown like this:

" if(NRF_RADIO->CRCSTATUS != 0)
{
nrf_gpio_pin_set(DATA_SENDING_P2);
nrf_gpio_pin_clear(DATA_SENDING_P2);
}" 

4、Is there some way to avoid the CRC error occurred?

Thanks

Parents
  • Hi,

     

    Usually, CRC errors are quite normal. How many are you seeing?

     

    That being said: the RF address has a huge impact on the amount of "unwanted packets" you receive. Could you ensure that this does not start with 0x55/0xAA and does not contain longer periods of 0xFF/0x00 ?

    " if(NRF_RADIO->CRCSTATUS != 0)
    {
    nrf_gpio_pin_set(DATA_SENDING_P2);
    nrf_gpio_pin_clear(DATA_SENDING_P2);
    }" 

    Note that CRCSTATUS=1 means CRC OK. Do you have a similar routine to test CRCSTATUS==0?

     

    Kind regards,

    Håkon

      

  • Dear Alseth,

    1)The distance between Central and peripheral is about 80cm.I use a timer to statistic the packet loss,it is true with the discription

    3)I use logicanalyzer to monitor the io change,when the packet loss occured, the logiclyzer will show the truth.

    4)The Ptx configration like this:

    The Macros:
    #define NRF_ESB_DEFAULT_CONFIG {.protocol               = NRF_ESB_PROTOCOL_ESB_DPL,         \
                                    .mode                   = NRF_ESB_MODE_PTX,                 \
                                    .event_handler          = 0,                                \
                                    .bitrate                = NRF_ESB_BITRATE_2MBPS_BLE,        \
                                    .crc                    = NRF_ESB_CRC_16BIT,                \
                                    .tx_output_power        = NRF_ESB_TX_POWER_0DBM,            \
                                    .retransmit_delay       = 85,                               \
                                    .retransmit_count       = 3,                                \
                                    .tx_mode                = NRF_ESB_TXMODE_AUTO,              \
                                    .radio_irq_priority     = 1,                                \
                                    .event_irq_priority     = 2,                                \
                                    .payload_length         = 0,                                \
                                    .selective_auto_ack     = false,                            \
    								.ru_time                = NRF_ESB_RAMP_TIME                 \
    }
    
    #define	RETRAN_CNT								0
    
    The configuration:
    
    	nrf_esb_config_t nrf_esb_config         = NRF_ESB_DEFAULT_CONFIG;
    	nrf_esb_config.protocol                 = NRF_ESB_PROTOCOL_ESB_DPL;
    	nrf_esb_config.bitrate                  = NRF_ESB_BITRATE_2MBPS_BLE;
    	nrf_esb_config.event_handler            = (is_central)?nrf_esb_ptx_event_handler:nrf_esb_prx_event_handler;
    	nrf_esb_config.mode                     = (is_central)?NRF_ESB_MODE_PTX:NRF_ESB_MODE_PRX;
    	nrf_esb_config.selective_auto_ack       = false;
    	nrf_esb_config.tx_output_power					= (nrf_esb_tx_power_t) tx_power;
    	nrf_esb_config.retransmit_count					= RETRAN_CNT;
    	nrf_esb_config.retransmit_delay					= 200;
    	nrf_esb_config.tx_mode									= NRF_ESB_TXMODE_MANUAL;  //JS Modify: 1/20/2021 , USe manual tx start
    	
    //	nrf_esb_config.crc						=NRF_ESB_CRC_8BIT;
    	
    	nrf_esb_init(&nrf_esb_config);
    	
    	nrf_esb_set_base_address_0(m_system_address);
    	
    //	nrf_esb_set_rf_channel(m_radio_chan_tab[0]);
    	
    	if(!is_central)
    	{
    		addr_prefix[DATA_PIPE] = periph_num;
    	}
    	
    	nrf_esb_set_prefixes(addr_prefix, sizeof(addr_prefix));
    	
    	
    	nrf_esb_enable_pipes(1<< DATA_PIPE);  //only enabled pipe 0 and 1

    The Prx configuration like this:

    The macros:
    #define NRF_ESB_DEFAULT_CONFIG {.protocol               = NRF_ESB_PROTOCOL_ESB_DPL,         \
                                    .mode                   = NRF_ESB_MODE_PTX,                 \
                                    .event_handler          = 0,                                \
                                    .bitrate                = NRF_ESB_BITRATE_2MBPS_BLE,        \
                                    .crc                    = NRF_ESB_CRC_16BIT,                \
                                    .tx_output_power        = NRF_ESB_TX_POWER_0DBM,            \
                                    .retransmit_delay       = 85,                               \
                                    .retransmit_count       = 3,                                \
                                    .tx_mode                = NRF_ESB_TXMODE_AUTO,              \
                                    .radio_irq_priority     = 1,                                \
                                    .event_irq_priority     = 2,                                \
                                    .payload_length         = 0,                                \
                                    .selective_auto_ack     = false,                            \
    								.ru_time                = NRF_ESB_RAMP_TIME                 \
    }
    #define	RETRAN_CNT								0
    The configuration:
    	nrf_esb_config_t nrf_esb_config         = NRF_ESB_DEFAULT_CONFIG;
    	nrf_esb_config.protocol                 = NRF_ESB_PROTOCOL_ESB_DPL;
    	nrf_esb_config.bitrate                  = NRF_ESB_BITRATE_2MBPS_BLE;
    	nrf_esb_config.event_handler            = (is_central)?nrf_esb_ptx_event_handler:nrf_esb_prx_event_handler;
    	nrf_esb_config.mode                     = (is_central)?NRF_ESB_MODE_PTX:NRF_ESB_MODE_PRX;
    	nrf_esb_config.selective_auto_ack       = false;
    	nrf_esb_config.tx_output_power					= (nrf_esb_tx_power_t) tx_power;
    	nrf_esb_config.retransmit_count					= RETRAN_CNT;
    	nrf_esb_config.retransmit_delay					= 200;
    	nrf_esb_config.tx_mode									= NRF_ESB_TXMODE_MANUAL;  //JS Modify: 1/20/2021 , USe manual tx start
    
    //	nrf_esb_config.crc						=NRF_ESB_CRC_8BIT;
    	
    	nrf_esb_init(&nrf_esb_config);
    	
    	nrf_esb_set_base_address_0(m_system_address);
    	
    //	nrf_esb_set_rf_channel(m_radio_chan_tab[0]);
    	
    	if(!is_central)
    	{
    		addr_prefix[DATA_PIPE] = periph_num;
    	}
    	
    	nrf_esb_set_prefixes(addr_prefix, sizeof(addr_prefix));
    	
    	
    	nrf_esb_enable_pipes(1<< DATA_PIPE);  //only enabled pipe 0 and 1
    

Reply
  • Dear Alseth,

    1)The distance between Central and peripheral is about 80cm.I use a timer to statistic the packet loss,it is true with the discription

    3)I use logicanalyzer to monitor the io change,when the packet loss occured, the logiclyzer will show the truth.

    4)The Ptx configration like this:

    The Macros:
    #define NRF_ESB_DEFAULT_CONFIG {.protocol               = NRF_ESB_PROTOCOL_ESB_DPL,         \
                                    .mode                   = NRF_ESB_MODE_PTX,                 \
                                    .event_handler          = 0,                                \
                                    .bitrate                = NRF_ESB_BITRATE_2MBPS_BLE,        \
                                    .crc                    = NRF_ESB_CRC_16BIT,                \
                                    .tx_output_power        = NRF_ESB_TX_POWER_0DBM,            \
                                    .retransmit_delay       = 85,                               \
                                    .retransmit_count       = 3,                                \
                                    .tx_mode                = NRF_ESB_TXMODE_AUTO,              \
                                    .radio_irq_priority     = 1,                                \
                                    .event_irq_priority     = 2,                                \
                                    .payload_length         = 0,                                \
                                    .selective_auto_ack     = false,                            \
    								.ru_time                = NRF_ESB_RAMP_TIME                 \
    }
    
    #define	RETRAN_CNT								0
    
    The configuration:
    
    	nrf_esb_config_t nrf_esb_config         = NRF_ESB_DEFAULT_CONFIG;
    	nrf_esb_config.protocol                 = NRF_ESB_PROTOCOL_ESB_DPL;
    	nrf_esb_config.bitrate                  = NRF_ESB_BITRATE_2MBPS_BLE;
    	nrf_esb_config.event_handler            = (is_central)?nrf_esb_ptx_event_handler:nrf_esb_prx_event_handler;
    	nrf_esb_config.mode                     = (is_central)?NRF_ESB_MODE_PTX:NRF_ESB_MODE_PRX;
    	nrf_esb_config.selective_auto_ack       = false;
    	nrf_esb_config.tx_output_power					= (nrf_esb_tx_power_t) tx_power;
    	nrf_esb_config.retransmit_count					= RETRAN_CNT;
    	nrf_esb_config.retransmit_delay					= 200;
    	nrf_esb_config.tx_mode									= NRF_ESB_TXMODE_MANUAL;  //JS Modify: 1/20/2021 , USe manual tx start
    	
    //	nrf_esb_config.crc						=NRF_ESB_CRC_8BIT;
    	
    	nrf_esb_init(&nrf_esb_config);
    	
    	nrf_esb_set_base_address_0(m_system_address);
    	
    //	nrf_esb_set_rf_channel(m_radio_chan_tab[0]);
    	
    	if(!is_central)
    	{
    		addr_prefix[DATA_PIPE] = periph_num;
    	}
    	
    	nrf_esb_set_prefixes(addr_prefix, sizeof(addr_prefix));
    	
    	
    	nrf_esb_enable_pipes(1<< DATA_PIPE);  //only enabled pipe 0 and 1

    The Prx configuration like this:

    The macros:
    #define NRF_ESB_DEFAULT_CONFIG {.protocol               = NRF_ESB_PROTOCOL_ESB_DPL,         \
                                    .mode                   = NRF_ESB_MODE_PTX,                 \
                                    .event_handler          = 0,                                \
                                    .bitrate                = NRF_ESB_BITRATE_2MBPS_BLE,        \
                                    .crc                    = NRF_ESB_CRC_16BIT,                \
                                    .tx_output_power        = NRF_ESB_TX_POWER_0DBM,            \
                                    .retransmit_delay       = 85,                               \
                                    .retransmit_count       = 3,                                \
                                    .tx_mode                = NRF_ESB_TXMODE_AUTO,              \
                                    .radio_irq_priority     = 1,                                \
                                    .event_irq_priority     = 2,                                \
                                    .payload_length         = 0,                                \
                                    .selective_auto_ack     = false,                            \
    								.ru_time                = NRF_ESB_RAMP_TIME                 \
    }
    #define	RETRAN_CNT								0
    The configuration:
    	nrf_esb_config_t nrf_esb_config         = NRF_ESB_DEFAULT_CONFIG;
    	nrf_esb_config.protocol                 = NRF_ESB_PROTOCOL_ESB_DPL;
    	nrf_esb_config.bitrate                  = NRF_ESB_BITRATE_2MBPS_BLE;
    	nrf_esb_config.event_handler            = (is_central)?nrf_esb_ptx_event_handler:nrf_esb_prx_event_handler;
    	nrf_esb_config.mode                     = (is_central)?NRF_ESB_MODE_PTX:NRF_ESB_MODE_PRX;
    	nrf_esb_config.selective_auto_ack       = false;
    	nrf_esb_config.tx_output_power					= (nrf_esb_tx_power_t) tx_power;
    	nrf_esb_config.retransmit_count					= RETRAN_CNT;
    	nrf_esb_config.retransmit_delay					= 200;
    	nrf_esb_config.tx_mode									= NRF_ESB_TXMODE_MANUAL;  //JS Modify: 1/20/2021 , USe manual tx start
    
    //	nrf_esb_config.crc						=NRF_ESB_CRC_8BIT;
    	
    	nrf_esb_init(&nrf_esb_config);
    	
    	nrf_esb_set_base_address_0(m_system_address);
    	
    //	nrf_esb_set_rf_channel(m_radio_chan_tab[0]);
    	
    	if(!is_central)
    	{
    		addr_prefix[DATA_PIPE] = periph_num;
    	}
    	
    	nrf_esb_set_prefixes(addr_prefix, sizeof(addr_prefix));
    	
    	
    	nrf_esb_enable_pipes(1<< DATA_PIPE);  //only enabled pipe 0 and 1
    

Children
Related