nrf52810 with nrf52SDK 17.1 S113,can't receive a whole packet at a time with LIBUARTE

Now I can use LIBUARTE to receive data from MCU, but have a trouble: it can't receive a whole packet sometime,and return it with 2 parts.

UARTE : 115200/8/1

receive buffer : 104 bytes * 3

MCU send : 28 bytes a time every 5 seconds;

nrf52810 receive: 80% packets received at a time,rest will break into 2 parts.

Have tried:

1) increase timeout_us to 10000us;

2) decrease speed to NRF_UARTE_BAUDRATE_76800;

I thought it should return a whole packet at a time,that's why I turn to LIBUARTE.

The buffer size/speed/timeout_us should be big enough,what make it interrupt?

The SD task interrupt it?

Parents
  • Hello,

    receive buffer : 104 bytes * 3

    MCU send : 28 bytes a time every 5 seconds;

    This sounds a bit overkill. If the MCU always sends 28 bytes every 5 seconds, I would recommend that you are looking into the UART implementation from SDK\examples\ble_peripheral\ble_app_uart. That should be more than enough to handle this amount of data.

    Note that the libuarte library is very resource heavy. Requiring a lot of peripherals running for it's functionality. 

    If you do, however, insist in using libuarte, can you check, the times where your packet is split up, is it coming from the nrf_libuarte_async_timeout_handler(), or uart_evt_handler() -> case NRF_LIBUARTE_DRV_EVT_RX_DATA ?

    Best regards,

    Edvin

  • Hello,

    I did not get your meaning,this is my code:

    #include "nrf_libuarte_async.h"
    #include "app_uarte.h"
    #include "nrf_queue.h"
    #include "nrfx_log.h"
    #include "nrf_assert.h"
    #include "sdk_config.h"
    
    //create uarte instance
    /*#define NRF_LIBUARTE_ASYNC_DEFINE(_name, _uarte_idx, _timer0_idx,\
                                      _rtc1_idx, _timer1_idx,\
                                      _rx_buf_size, _rx_buf_cnt) 
    								  */
    NRF_LIBUARTE_ASYNC_DEFINE(	m_libuarte, 0, 1,    
    							NRF_LIBUARTE_PERIPHERAL_NOT_USED, 2,  
    							NRF_SDH_BLE_GATT_MAX_MTU_SIZE * 2, 3);
    
    
    //use queue as TX buffer
    // BLE -> TX buffer -> UART -> MCU
    NRF_QUEUE_DEF(buffer_to_uart_struct_t, m_uart_tx_queue,  BUFFER_UP_QUEUE_SIZE, BUFFER_UP_QUEUE_MODE );
    
    
    static app_uarte_rx_handler_t m_rx_handler = NULL;
    
    static volatile bool m_tx_in_progress = false;
    
    static void process_tx_fifo(void);
    
    void libuarte_event_handler(void * context, nrf_libuarte_async_evt_t * p_event){
        nrf_libuarte_async_t * p_libuarte = (nrf_libuarte_async_t *)context;
       
        switch (p_event->type)
        {
            case NRF_LIBUARTE_ASYNC_EVT_RX_DATA:
                if (m_rx_handler) {
                    m_rx_handler(p_event->data.rxtx.p_data, p_event->data.rxtx.length);
    				//must release rx buffer
                    nrf_libuarte_async_rx_free(p_libuarte, p_event->data.rxtx.p_data, p_event->data.rxtx.length);
                }
                break;
            case NRF_LIBUARTE_ASYNC_EVT_TX_DONE:
                if (m_tx_in_progress){
    				//pop record has been sent
    				nrf_queue_generic_pop_with_no_data_return(&m_uart_tx_queue);
                    m_tx_in_progress = false;
                }
    			//try to send next record from buffer
                process_tx_fifo();
                break;
            case NRF_LIBUARTE_ASYNC_EVT_ERROR:
                NRF_LOG_ERROR("UARTE error occurred,error source:%d",p_event->data.errorsrc);
                break;
            case NRF_LIBUARTE_ASYNC_EVT_OVERRUN_ERROR:
                NRF_LOG_ERROR("UARTE overrun error occurred,lost:%d bytes.",p_event->data.overrun_err.overrun_length);
                break;
            default:
                break;
        }
    }
    
    
    static void process_tx_fifo(void) {
        if (m_tx_in_progress) {
            return; 
        }
    	if(nrf_queue_is_empty(&m_uart_tx_queue)){
    		return;
    	}
    	
    	ret_code_t err_code;
        buffer_to_uart_struct_t* p;
    	
      get_head_element:
    	p = nrf_queue_generic_get_head_element(&m_uart_tx_queue);
    	if(NULL == p){
    		NRF_LOG_DEBUG("No data to send.");
    		return;
    	}
    	
    	if(0 == p->actual_data_len){
    		nrf_queue_generic_pop_with_no_data_return(&m_uart_tx_queue);
    		NRF_LOG_DEBUG("record's actual_data_len = 0,delete it");
    		goto get_head_element;
    	}
    
    	//try to send 1st record
    	err_code = nrf_libuarte_async_tx(&m_libuarte, p->data, p->actual_data_len);
        if (err_code == NRFX_SUCCESS) {
    		m_tx_in_progress = true;
    	} else {
    		NRF_LOG_ERROR("Failed to start LIBUARTE TX, error code: %d(%s)", err_code,NRFX_LOG_ERROR_STRING_GET(err_code));
    	}
    }
    
    
    void app_uarte_init(uint32_t tx_pin, uint32_t rx_pin, nrf_uarte_baudrate_t baudrate, app_uarte_rx_handler_t rx_handler) {
        ASSERT(rx_handler);
    	
        m_rx_handler = rx_handler;
        ret_code_t err_code;
    
    	nrf_libuarte_async_config_t nrf_libuarte_async_config = {
                .tx_pin     = tx_pin,
                .rx_pin     = rx_pin,
                .baudrate   = baudrate,
                .parity     = NRF_UARTE_PARITY_EXCLUDED,
                .hwfc       = NRF_UARTE_HWFC_DISABLED,
                .timeout_us = 500,
                .int_prio   = APP_IRQ_PRIORITY_LOW
        };
    	
    	err_code = nrf_libuarte_async_init(&m_libuarte, &nrf_libuarte_async_config, libuarte_event_handler, (void *)&m_libuarte);
        APP_ERROR_CHECK(err_code);
    
        nrf_libuarte_async_enable(&m_libuarte);
    
    }
    
    // called while BLE received data
    // server data -> BLE -> uart queue -> UART.TxD -> MCU
    bool app_uarte_send_buffer_push(const uint8_t *data, size_t length) {
    	if((NULL == data) || (length == 0) )
    			return false;
        
    	//push into queue 
    	buffer_to_uart_struct_t bu;
    	bu.actual_data_len = length;
    	memcpy(bu.data,data,length);
    	
    	ret_code_t ret;
    	ret = nrf_queue_push_bytes(&m_uart_tx_queue,(const void*)&bu, 
    					bu.actual_data_len + sizeof(bu.actual_data_len)); 
    	if (NRF_SUCCESS != ret){
    		NRF_LOG_DEBUG("push into UART TxD buffer failed,ret = %d",ret);
    	}else{
    		NRF_LOG_DEBUG("push into UART TxD buffer success.");
    	}
    	
        //try to send
        process_tx_fifo();
        
        return true;
    }
    
    

    Now I have added the function to re-compose the packets at UART.Rx side.

  • OldXiao said:
    Now I have added the function to re-compose the packets at UART.Rx side

    Does this mean that it is working now?

    BR,
    Edvin

Reply Children
Related