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
  • Hi,

    I understand your concern about when the number of byte received doesn't reach the MAXCNT and we won't able to know how many byte we receive until we trigger a STOPRX task. And then if we trigger the task we may interrupt reception. But what if we have a SHORT to connect ENDRX with STARTRX, we can restart receive mode. It's the same when we reach MAXCNT and receive ENDRX. Note that when ENDRX-STARTR short is triggered, there will be no RXTO event (I couldn't find documentation about this, need to double check)

    I implemented a small example. That I use an app timer to trigger a STOPRX task every second. I am not 100% sure there will be no glitch since there is a chance that the STOPRX task happens at the same time with the ENDRX from MAXCOUNT reached event. It could be a race condition there. A small modification in nrf_drv_uart.c added, I commented out if (amount == m_cb.rx_buffer_length) in uarte_irq_handler(). Could you try the example and let me know if it works for you? (SDK v11)

    uart - EasyDMA.zip

    (Posted this without reading the previous answers, I agree with puz_md and bat13 )

Reply
  • Hi,

    I understand your concern about when the number of byte received doesn't reach the MAXCNT and we won't able to know how many byte we receive until we trigger a STOPRX task. And then if we trigger the task we may interrupt reception. But what if we have a SHORT to connect ENDRX with STARTRX, we can restart receive mode. It's the same when we reach MAXCNT and receive ENDRX. Note that when ENDRX-STARTR short is triggered, there will be no RXTO event (I couldn't find documentation about this, need to double check)

    I implemented a small example. That I use an app timer to trigger a STOPRX task every second. I am not 100% sure there will be no glitch since there is a chance that the STOPRX task happens at the same time with the ENDRX from MAXCOUNT reached event. It could be a race condition there. A small modification in nrf_drv_uart.c added, I commented out if (amount == m_cb.rx_buffer_length) in uarte_irq_handler(). Could you try the example and let me know if it works for you? (SDK v11)

    uart - EasyDMA.zip

    (Posted this without reading the previous answers, I agree with puz_md and bat13 )

Children
  • Hi Hung, that's just what I wrote in my reply 4 hours ago. I agree, it could come to glitches when ENDRX is triggered both by MAXCOUNT and STOPRX within a short intervall, without enough time to update the RX buffer in the event handler before the next ENDRX is triggered.

    Maybe bat13 has some time to try your code, I'm currently pretty busy with my project, using the classic app_uart for the time being. Further, I have old nRF52-DK's that seem to be not 100% compatible with the official releases when using the timers. In my case, I wouldn't use the timer to trigger the stop task, but the function call that tries to read data, using two RX buffers that create something like a circular FIFO.

    One more question about the FLUSHRX task: What happens if this task is triggert while receive operation is active? Might this task help to prevent glitches?

  • I don't think FLUSHRX task would work when the UARTE is still active in receiving mode.

  • ...then I think the UARTE device cannot be used for 100% reliable asynchronous (low latency) data reception the way it is currently designed :(

    It would be much easier if we could just access the current state of the receive buffer (RXD.AMOUNT), but I remember somebody saying this value would ony be valid when the ENDRX event has been triggered.

Related