Usage of nrf_libuarte_async_rx_free()

Hi,

I'm using an nrf52833 with SDK 17.1.0 and was looking at the peripheral/libuarte example. I have a question regarding the following code snippet

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);
            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;
    }
}
 

Can someone explain to my why the RX buffer is freed in the TX_DONE case? And why is the function for clearing the RX buffer used with the event data (p_evt->data.rxtx.p_data) which comes for the TX_DONE event? Do I also have to clear the TX buffer?

Best regards,

Christian

  • Hi,

    Due to the Easter holidays in Norway, we are less staffed than usual. You can expect an answer sometime next week,

    Sorry for the inconvenience and thanks for your patience. 

    Regards, 
    Amanda

  • Hi,

    The reason for freeing the buffer in TX_DONE case is that the example works as a loopback example by default. Whatever is received on RX pin is transmitted back on TX pin. The received data either needs to be copied to a new buffer in the RX_DATA case, or the same buffer can be used as the TX buffer, to avoid duplicating/copying data (time-consuming process). How you should handle the buffers in your application depends on your use-case. As soon as processing of RX data is done, the buffer portion should be released back to the library for next RX operation.

    And why is the function for clearing the RX buffer used with the event data (p_evt->data.rxtx.p_data) which comes for the TX_DONE event?

    This is done as a simplification to avoid storing the buffer pointer and length in the application. All data received in RX_DATA event is transmitted back and the buffer pointer/length returned in the TX_DONE event structure will correspond to the data transmitted in RX_DATA event. It is critical that exactly all parts of the RX buffer is freed after processing, as failure to free the full buffer will lead to library running out of buffers.

    Do I also have to clear the TX buffer?

    No, TX buffers are considered free as soon as TX operation is done.

    Best regards,
    Jørgen

Related