Clear Uarte Rx Buffer

Hi, I am using libuartes to comunicate with gps and I get the Rx buffer
like a problem already asked in this thread

when I send a text "abc"

the first 3 times : everything is fine (9 bytes)
on the 4th time : my application call 2 NRF_LIBUARTE_ASYNC_EVT_RX_DATA event

- the first event show it receive "a" (10th byte => full)

- the second event show it receive "bc"
because in uarte define I define _rx_buf_size = 10
I think nrf_libuarte_async_rx_free() function will free each NRF_LIBUARTE_ASYNC_EVT_RX_DATA was called. And the next time nRF receive data from GPS, data I received will be put at the start of rx_buffer
So how can I solve this problem ? I want each time I receive data from GPS, the received data buffer will be put at the start of uarte's rx_buffer

Here is my uarte define, and uarte handle, debug terminal

NRF_LIBUARTE_ASYNC_DEFINE(libuarte1, 0, 0, 0, NRF_LIBUARTE_PERIPHERAL_NOT_USED, 10, 3);

void send_Uart1(char *sdata, int len)
{
    ret_code_t ret;
    ret = nrf_libuarte_async_tx(&libuarte1, sdata, len);
    // Fixing issue text was sent too fast
    if (ret == NRF_ERROR_BUSY)
    {
        buffer_t buf = {
            .p_data = sdata,
            .length = len,
        };
        ret = nrf_queue_push(&m_buf_queue, &buf);
        APP_ERROR_CHECK(ret);
    }
    else
    {
        APP_ERROR_CHECK(ret);
    }
}

// Function to handle uart1 event
void uart_event_handler1(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:
        break;
    case NRF_LIBUARTE_ASYNC_EVT_RX_DATA:
    NRF_LOG_INFO("text in RX = %s  length = %d",p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
        memcpy(textReceived_Uart1, p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
        NRF_LOG_INFO("call RX_DATA event UART1\n=============");
        nrf_libuarte_async_rx_free(p_libuarte, p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
        send_Uart1(textReceived_Uart1, sizeof(textReceived_Uart1));
        m_loopback_phase = true;
        break;
    case NRF_LIBUARTE_ASYNC_EVT_TX_DONE:
        if (m_loopback_phase)
        {
            if (!nrf_queue_is_empty(&m_buf_queue))
            {
                NRF_LOG_INFO("call !nrf_queue_is_empty(&m_buf_queue)\n");
                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));
            }
        }
        break;
    default:
        break;
    }
}

Parents
  • Hi,

    Like I already told you before, this is not how libUARTE works. The library will not stop the transfer on a timeout, it will only report the number of received bytes to the application. The buffer is still in use by the UART peripheral, waiting for more data to fill the requested number of bytes in the buffer. When the full buffer size is received, the library will immediately switch to the next buffer to avoid losing data. At this point, the buffer can be freed and reused by the library at a later point. As you can understand, it is not possible to start the reception at the start of the buffer with the current architecture.

    Instead of using the events as the indicator that a transfer is completed, you should use some string termination character (\0, \r, \n, etc) or the string length if that is fixed/known.

    If you require the transfer to start at the beginning of the buffer on each receive operation, you can use the UART driver directly. Note that this does not support any timeouts, so you need to handle that yourself. You may also risk losing data when using this approach, as you need to stop the reception before being able to set a new buffer. I would much rather recommend using libUARTE with the above described suggestions.

    Best regards,
    Jørgen

  • Pham Tam said:
    In step 4 the 2nd buffer will be used ?

    In step 4, both 1st and 2nd buffer will be used. 1st buffer will hold the first received byte, while the two next bytes that did not fit in the rest of the 1st buffer will be stored in 2nd buffer.

    Pham Tam said:
    And when the 3th buffer full, the 1st buffer will be reused because it's freed in step 1, 2, 3  ?

    Yes, as long as all the bytes in first buffer is freed, the buffer will be reused when the 3rd buffer have been filled.

Reply
  • Pham Tam said:
    In step 4 the 2nd buffer will be used ?

    In step 4, both 1st and 2nd buffer will be used. 1st buffer will hold the first received byte, while the two next bytes that did not fit in the rest of the 1st buffer will be stored in 2nd buffer.

    Pham Tam said:
    And when the 3th buffer full, the 1st buffer will be reused because it's freed in step 1, 2, 3  ?

    Yes, as long as all the bytes in first buffer is freed, the buffer will be reused when the 3rd buffer have been filled.

Children
Related