Buffer Uart bytes when not reading?

I have a task reading from the uart and handling data.  I'm using the uart adapter async api.

At first I was missing data at the process step pretty regularly so I enabled:

#define dg_configUART_RX_CIRCULAR_DMA (1)
#define dg_configUART2_RX_CIRCULAR_DMA_BUF_SIZE (128)

This seemed to help significantly.  At the time I enabled the dma buffer, my read task was similar to the following psuedo code:

while (1):
  read data (async) -> callback sets condition
  wait for condition:
   if timeout:
     quick check minor other items
   else:
     process data.

In this version, the task was waiting for ad_uart_read_async so the task was almost always in uart read state and then each timeout it did a quick loop and started waiting again.

But I need more time processing data so I was hoping to add a check to see if there was any pending data on the UART instead of waiting in the read function:

Psuedo code as follows:

while (1):
  if (UART has data):
   read data
   process data
  else:
   quick check minor other items.

In this version, I'm missing data again.  I used the function hw_uart_read_buf_empty to determine if there was any data but I'm not sure that is working properly.  I was under the impression that even while I'm not in the ad_uart_read function, the dma channel would add new uart data to the dma buffer and then next time around the loop the hw_uart_read_buf_empty would return false and I would know to call read instead of doing some processing work.

Am I going about this wrong?  Maybe I have a misunderstanding of the dma buffer.  I didn't see any way to get the information on buffer status from the adapter layer. 

Thank you for input.

-Dennis
SDK10.1.4.104

Parents Reply Children
  • Thank you for the reply,

    We are trying to integrate an erpc based communication protocol between two or more embedded processors.  ERPC uses a server::poll() function at a higher level and inside the server there is a transport class that calls a receive method with a raw byte buffer and a length.  So I was trying to call one of the uart receive methods in that function to fill the buffer.

    The problem is, when the buffer is returned, and before the next time the receive method is called, it seems we miss data.

    I'm interested using the async callback to simply copy incoming data to a different buffer and do that in a loop.  Thus far, it seems like you can't restart the callback from within the existing callback though.  I may need a seperate task anyway.

  • Try to undefind the dg_configUART_RX_CIRCULAR_DMA. 

  • I'd like to understand this more.  I was under the impression the circular buffer would help buffer data during the interim period between my reads.  Is this not the case?

    In the meantime, I replaced the ERPC method that reads from the uart directly with a task that puts incoming data in a queue and it works much more reliably. It requires an extra task but that is acceptable opposed to missing data.  In the read task I stopped using the async api and have a simple loop that calls ad_uart_read to read the header, parses the length, then read the message.

  • Hi Dennis,

    The ad_uart_read is block function. let me test on async way, will back to you with updates.

    BR,

    JH_Renesas