LIBUARTE+ESB_PRX<------>ESB_PTX+SPI communication phenomenon: data duplication or loss (ESB seems unable to handle too much data from libuarte)

Hello, Nordic team.
We are using two nrf52833 DK boards to build an ESB master-slave communication link. We are debugging the example program based on the nRF5_SDK_17.1.0 folder provided,
Link setup is:
Android SOC <--SPI--> nRF52833_PTX nRF52833_PRX <--LIBUARTE--> External IMU。
However, in practical applications, it has been found that communication phenomena: Data duplication or loss, IMU data cannot be received completely due to wireless communication transmission limitations. Please help investigate the reasons for data reception failure and see if there are any optimization solutions available for reference? Thank you.
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "nrf_libuarte_async.h"
#include "nrf_drv_clock.h"
#include <bsp.h>
#include "nrf_queue.h"

#include "SEGGER_RTT.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"


#include "sdk_common.h"
#include "nrf.h"
#include "nrf_esb.h"
#include "nrf_esb_error_codes.h"
#include "nrf_delay.h"
#include "nrf_gpio.h"
#include "nrf_error.h"
#include "boards.h"
#include "app_util.h"   //esb low power ??//

#define LED_ON          0
#define LED_OFF         1
//////*********************************** 
#include <nrf.h>
#include <nrf_delay.h>
#include <stdio.h>
#include "app_uart.h"


static nrf_esb_payload_t tx_payload;
static nrf_esb_payload_t rx_payload;


static uint8_t m_state[4];
uint8_t led_nr;


NRF_LIBUARTE_ASYNC_DEFINE(libuarte, 0, 0, 0, NRF_LIBUARTE_PERIPHERAL_NOT_USED, 255, 3);


static uint8_t text[] = "UART example started.\r\n Loopback:\r\n";
static uint8_t text_size = sizeof(text);


uint8_t  IMU_rx_buf[43];
uint8_t  IMU_ack_buf[43] ={0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEF};
uint8_t  IMU_rx_bufCRC = 0;

static volatile bool m_loopback_phase;

typedef struct {
    uint8_t * p_data;
    uint32_t length;
} buffer_t;

NRF_QUEUE_DEF(buffer_t, m_buf_queue, 10, NRF_QUEUE_MODE_NO_OVERFLOW);

void uart_event_handler(void * context, nrf_libuarte_async_evt_t * p_evt)
{
    nrf_libuarte_async_t * p_libuarte = (nrf_libuarte_async_t *)context;
    ret_code_t ret;

    switch (p_evt->type)
    {
        case NRF_LIBUARTE_ASYNC_EVT_ERROR:
            bsp_board_led_invert(0);
            break;
        case NRF_LIBUARTE_ASYNC_EVT_RX_DATA:						
            ret = nrf_libuarte_async_tx(p_libuarte,p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
						//NRF_LOG_INFO("IMU_rx_bufCRC:",IMU_rx_bufCRC);
						if(p_evt->data.rxtx.length == 43)
						{
							for(int i=0;i<43;i++)            IMU_rx_buf[i] = *(p_evt->data.rxtx.p_data++);
							
							for(int i=1;i<41;i++)            IMU_rx_bufCRC = IMU_rx_bufCRC^IMU_rx_buf[i];
							
							if(IMU_rx_buf[41] == IMU_rx_bufCRC)
							{
								bsp_board_led_invert(1);
							}
							IMU_rx_bufCRC = 0;
						}
            
						if (ret == NRF_ERROR_BUSY)
            {
                buffer_t buf = {
                    .p_data = p_evt->data.rxtx.p_data,
                    .length = p_evt->data.rxtx.length,
                };

                ret = nrf_queue_push(&m_buf_queue, &buf);
                APP_ERROR_CHECK(ret);
            }
            else
            {
                APP_ERROR_CHECK(ret);
            }
//            bsp_board_led_invert(1);
            m_loopback_phase = true;
            break;
        case NRF_LIBUARTE_ASYNC_EVT_TX_DONE:
            if (m_loopback_phase)
            {
                nrf_libuarte_async_rx_free(p_libuarte, p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
                if (!nrf_queue_is_empty(&m_buf_queue))
                {
                    buffer_t buf;
                    ret = nrf_queue_pop(&m_buf_queue, &buf);
                    APP_ERROR_CHECK(ret);
                    UNUSED_RETURN_VALUE(nrf_libuarte_async_tx(p_libuarte, buf.p_data, buf.length));
                }
            }
            bsp_board_led_invert(2);
            break;
        default:
            break;
    }
}

uint8_t i = 0x01;

//***********************************
void nrf_esb_event_handler(nrf_esb_evt_t const * p_event)
{
    
    switch (p_event->evt_id)
    {
        case NRF_ESB_EVENT_TX_SUCCESS:
					//NRF_LOG_DEBUG("SUCCESS");
            break;
        case NRF_ESB_EVENT_TX_FAILED:
						NRF_LOG_DEBUG("FAILED");
            (void) nrf_esb_flush_tx();
            break;
        case NRF_ESB_EVENT_RX_RECEIVED:
						//NRF_LOG_DEBUG("RECEIVED");
            while (nrf_esb_read_rx_payload(&rx_payload) == NRF_SUCCESS){
						memcpy(tx_payload.data,IMU_rx_buf,tx_payload.length);
							//NRF_LOG_INFO("IMU_rx_buf1 %02X %02X %02X %02X %02X",IMU_rx_buf[31],IMU_rx_buf[32],IMU_rx_buf[33],IMU_rx_buf[34],IMU_rx_buf[35]);
							//NRF_LOG_INFO("IMU_rx_buf2 %02X %02X %02X %02X %02X",IMU_rx_buf[36],IMU_rx_buf[37],IMU_rx_buf[38],IMU_rx_buf[39],IMU_rx_buf[40]);

							//tx_payload.data[0]=IMU_rx_buf[0];
							//tx_payload.data[42]=IMU_rx_buf[42];
							nrf_esb_write_payload(&tx_payload);
							
							//*****simulated data test start***************
							//IMU_ack_buf[0]=i++;
							//tx_payload.data[0]=IMU_ack_buf[0];
							//tx_payload.data[42]=IMU_ack_buf[42];
							//nrf_esb_write_payload(&tx_payload);
							//*****simulated data test end***************
						}


            break;
    }
}


void clocks_start( void )
{
    // Start HFCLK and wait for it to start.
    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
    NRF_CLOCK->TASKS_HFCLKSTART = 1;
    while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);
}


uint32_t esb_init( void )
{
    uint32_t err_code;
    uint8_t base_addr_0[4] = {0xE7, 0xE7, 0xE7, 0xE7};
    uint8_t base_addr_1[4] = {0xC2, 0xC2, 0xC2, 0xC2};
    uint8_t addr_prefix[8] = {0xE7, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8 };

#ifndef NRF_ESB_LEGACY
    nrf_esb_config_t nrf_esb_config         = NRF_ESB_DEFAULT_CONFIG;
#else // NRF_ESB_LEGACY
    nrf_esb_config_t nrf_esb_config         = NRF_ESB_LEGACY_CONFIG;
#endif // NRF_ESB_LEGACY
    nrf_esb_config.selective_auto_ack       = true; //
    nrf_esb_config.payload_length           = 43;
    nrf_esb_config.bitrate                  = NRF_ESB_BITRATE_2MBPS;
		nrf_esb_config.tx_output_power					= NRF_ESB_TX_POWER_8DBM; //MAX
		nrf_esb_config.retransmit_count					= 0;
    nrf_esb_config.mode                     = NRF_ESB_MODE_PRX;
    nrf_esb_config.event_handler            = nrf_esb_event_handler;

    err_code = nrf_esb_init(&nrf_esb_config);
    VERIFY_SUCCESS(err_code);

    err_code = nrf_esb_set_base_address_0(base_addr_0);
    VERIFY_SUCCESS(err_code);

    err_code = nrf_esb_set_base_address_1(base_addr_1);
    VERIFY_SUCCESS(err_code);

    err_code = nrf_esb_set_prefixes(addr_prefix, 8);
    VERIFY_SUCCESS(err_code);

    return NRF_SUCCESS;
}

void gpio_init( void )
{
    m_state[0] = LED_OFF;
    m_state[1] = LED_OFF;
    m_state[2] = LED_OFF;
    m_state[3] = LED_OFF;

    bsp_board_init(BSP_INIT_LEDS);

    nrf_gpio_pin_write(LED_1, m_state[0]);
    nrf_gpio_pin_write(LED_2, m_state[1]);
    nrf_gpio_pin_write(LED_3, m_state[2]);
    nrf_gpio_pin_write(LED_4, m_state[3]);
}


uint32_t logging_init( void )
{
	uint32_t err_code;
	err_code = NRF_LOG_INIT(NULL);
	NRF_LOG_DEFAULT_BACKENDS_INIT();
	return err_code;
}



void power_manage( void )
{
    // WFE - SEV - WFE sequence to wait until a radio event require further actions.
    __WFE();
    __SEV();
    __WFE();
}



static nrf_esb_payload_t        tx_payload = NRF_ESB_CREATE_PAYLOAD(0, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00);
/**
 * @brief Function for main application entry.
 */
int main(void)
{
	
	tx_payload.length = 43;				
//  ESB***********************************		
	
	uint32_t err_code;	
	err_code = logging_init();
	APP_ERROR_CHECK(err_code);
	
	clocks_start();
	
	//GPIO and ESB
	//gpio_init();
	err_code = esb_init();
	APP_ERROR_CHECK(err_code);
	err_code = nrf_esb_start_rx();
	APP_ERROR_CHECK(err_code);
	
	//NRF_LOG_INFO("Enhanced ShockBurst Receiver Example started.");
	
	//ret_code_t ret = nrf_drv_clock_init();
	//APP_ERROR_CHECK(ret);
	
  nrf_drv_clock_lfclk_request(NULL);
	ret_code_t ect = NRF_LOG_INIT(app_timer_cnt_get);
	APP_ERROR_CHECK(ect);
	
	
	nrf_libuarte_async_config_t nrf_libuarte_async_config = {
            .tx_pin     = TX_PIN_NUMBER,
            .rx_pin     = RX_PIN_NUMBER,
			      .baudrate   = NRF_UARTE_BAUDRATE_921600,
            .parity     = NRF_UARTE_PARITY_EXCLUDED,
            .hwfc       = NRF_UARTE_HWFC_DISABLED,
            .timeout_us = 100,
            .int_prio   = APP_IRQ_PRIORITY_LOW_MID  //APP_IRQ_PRIORITY_LOW
		};
	
	
		err_code = nrf_libuarte_async_init(&libuarte, &nrf_libuarte_async_config, uart_event_handler, (void *)&libuarte);
		APP_ERROR_CHECK(err_code);
		nrf_libuarte_async_enable(&libuarte);
    
		err_code = nrf_libuarte_async_tx(&libuarte, text, text_size);
		APP_ERROR_CHECK(err_code);
		//NRF_LOG_INFO("libuart Example started.");

 
		while(true){
			NRF_LOG_PROCESS();
			//IMU_ack_buf[0]++;
			//NRF_LOG_INFO("IMU_ack_buf %u",IMU_ack_buf[0]);
			//nrf_delay_us(1000);
			
				
			}
		 
	
}
main-ptx+prx.zip
Related