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

UART receive in background without callback on nRF52 SDK11

Hi, I'm looking for an easy way to use the UART in blocking mode (or something similiar) with a receive buffer that is filled in background:

  • If possible using EasyDMA for better performance and easier software design
  • TX data may either block until all data has been sent or may return immediately and provide an additional function call to check if all data has been sent successfully.
  • RX data shall received in background and stored in a buffer/FIFO. It shall be possible to read data of arbitrary size from the receive buffer without stopping reception.
  • No callbacks or event handlers shall be used (synchroneous control flow in application).

In the past, on the nRF51, we used the app_uart library with FIFO support. Looking at the SDK11 documentation on infocenter.nordicsemi.com, I couldn't find any information about this library (although the directory is still there in the SDK11 archive). Is app_fifo still working on SDK11 on nRF52? Does it take advantage of the EasyDMA feature?

Looking at nrf_drv_uart.h, double buffering is mentioned to provide support for continuous data reception in non-bocking mode. But what does happen if the last received data byte does not fill the buffer to 100%? Will the driver wait for more bytes until the buffer is full, not giving any opportunity to receive data from the partially filled buffer? In other words, is there any possibility to receive "byte streams" of arbitrary length using UART with EasyDMA (something like app_uart with FIFO feature using EasyDMA)?

Parents
  • This post contains some information about the UART peripheral and example with the nRF52. See the @hungbui 's answer.

    In SDK11, two issues with the UART have been fixed:

    • UART: Fixed a glitch on TX pin when initializing the driver
    • UART: Fixed the problem that TX bytes were sent in wrong order in app_uart_fifo

    The documentation about the FIFO implementation is available in the "SDK common libraries" section, see this link. The FIFO API has a new function in SDK11.

  • @maxv: No real solution. You could trigger a buffer change with the STOP_RX task (in combination with the END_RX - START_RX shortcut), which should return the current buffer even if it is not full, and continue with the next buffer. But there is a small chance that, if STOP_RX is called around the same time when the buffer actually becomes full, the buffer may be switched twice, before the next buffer has been set by the interrupt handler. In this case, it might come unpredictable behavior and/or data corruption. Just hoping for some more feedback from the Nordic employees if switching the buffer without this kind of glitch is supported by the hardware.

    One Idea I just had: You could configure a very large buffer and periodically trigger the STOP_RX task, just making sure that the buffer can never become full within the interval. This way, it should be pretty safe.

Reply
  • @maxv: No real solution. You could trigger a buffer change with the STOP_RX task (in combination with the END_RX - START_RX shortcut), which should return the current buffer even if it is not full, and continue with the next buffer. But there is a small chance that, if STOP_RX is called around the same time when the buffer actually becomes full, the buffer may be switched twice, before the next buffer has been set by the interrupt handler. In this case, it might come unpredictable behavior and/or data corruption. Just hoping for some more feedback from the Nordic employees if switching the buffer without this kind of glitch is supported by the hardware.

    One Idea I just had: You could configure a very large buffer and periodically trigger the STOP_RX task, just making sure that the buffer can never become full within the interval. This way, it should be pretty safe.

Children
No Data
Related