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

Recieving data with libuarte

Hi,

I am going to transmit and receive data with libuarte. I read the libuarte example, but I am not quite sure my understanding of the data transfer process is correct.

In my opinion, it looks like "nrf_libuarte_async_tx" can do both transmitting and receiving data, the received data will be first pushed to the queue. Then when we want to process it, we just pop the data out. Is my understanding is correct? So based on this, I modified the uarte event handler as followed, which I use to get the received data and process it. Do you think my implementation is reasonable?

Please let me know if the initialization of my libuarte is needed, and thanks in advance for your help:D

static 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:
        break;
    case NRF_LIBUARTE_ASYNC_EVT_RX_DATA:
        //recieve the data?
        ret = nrf_libuarte_async_tx(p_libuarte, p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
        if (ret == NRF_ERROR_BUSY)
        {
            RxBuffer buf = {
                .p_data = p_evt->data.rxtx.p_data,
                .length = p_evt->data.rxtx.length,
            };
            //push the data to the queue
            ret = nrf_queue_push(&RxBufferQueue, &buf);
            APP_ERROR_CHECK(ret);
        }
        else
        {
            APP_ERROR_CHECK(ret);
        }
        if (nrf_queue_is_empty(&RxBufferQueue) == false) 
        {
            RxBuffer buf;
            //pop the data from queue
            nrf_queue_pop(&RxBufferQueue, &buf);
            //Reset the queue
            nrf_queue_reset(&RxBufferQueue);
            //get the received data
            memcpy(rxdata, buf.p_data, buf.length);
            //process the received data
            processB2B(rxdata);
        }
    }
}

Parents
  • Hi Leogean,

    nrf_libuarte_async_enable is the API that enables and starts the receiver and most likely you should start this along with the tx by calling nrf_libuarte_async_tx, which will work only with the transmitter.
    In your uart_event_handler. When you get an event that there is a new RX_DATA available, you are starting the next transaction of the TX and also checking to see if there is any data in the buffer queue (which most likely there will as you are processing EVT_RX_DATA). 
    It looks like your state machine does not depend on the EVT_TX_DONE. This could work as long as you are sure that the peer will transmit data so that your application will process it and kick the next TX transaction.
  • Thanks for your reply, the information is very helpful. In my uarte handler, do you mean if I only want to process the received data, line 12 is actually not necessary? Or the queue push is also not necessary and I only need to start from line 27 to check if there is data in the rx buffer and process it?

Reply Children
  • Leogean said:
    In my uarte handler, do you mean if I only want to process the received data, line 12 is actually not necessary? Or the queue push is also not necessary and I only need to start from line 27 to check if there is data in the rx buffer and process it?

    What I mean to say is that when processing NRF_LIBUARTE_ASYNC_EVT_RX_DATA event, you are pushing the received data to the end of the queue using nrf_queue_push. And at line 27, you are checking if the queue is empty. The queue will never be empty at this instance, since you just pushed the received data to the queue. And you pop the queue immediately.

    I do not think you need to push and pop the data to the queue at this instance. The reference code that you took from SDK\examples\peripheral\libuarte shows you a a loop back data through uarte. So the processing of uart_event_handle in that example is not something you would like to use as it is.

    In your case, you do not need to use nrf_queue_xxx at all, since you are processing the incoming data immediately.

  • Thanks for your detailed explanation. So in my handler, because I do not want to send the received data back to the transmitter, the "nrf_uarte_async_tx" function is not necessary. Also, because I process the received data immediately, the queue functions are also not necessary. Am I right? I have one last question. I guess the data I receive is "p_evt->data.rxtx.p_data". Is the data type of it is "char*", so that I can directly set "rxdata = p_evt->data.rxtx.p_data"  (which rxdata is "char*"), and process it?

    Thanks again for the help you provide.

  • Ah, the data type of the received data is "uint8_t*", I have just realized that, sorry.

  • Leogean said:
    Thanks for your detailed explanation. So in my handler, because I do not want to send the received data back to the transmitter, the "nrf_uarte_async_tx" function is not necessary. Also, because I process the received data immediately, the queue functions are also not necessary. Am I right?

     Yes , your understanding is correct.

     

    Leogean said:
    Ah, the data type of the received data is "uint8_t*", I have just realized that, sorry.

     No worries. Good luck with your project.

Related