Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Reliable UARTE reception with active softdevice

Hi

I've done a few attempts in the last years to implement a reliable reception by using the UARTE. In the past we used the UART periphery from the nRF51, but we thought it should be the right way to use the new UARTE that comes with the nRF52. There are multiple threads in the DevZone that show that implementing reception with UARTE is difficult if it is not known when and how much bytes you will receive.

Last week we started a new project that will use the nRF52810 und will need UART communication. As the nRF52810 doesn't have the legacy UART we need to switch to the UARTE peripheral. So we did a new attempt and found the libuarte module in the SDK15. It seemed to be the solution for us to use the UARTE. The usage of 10(!!!) PPI channels for implementing a UART function seems a bit odd to me, but if it works we could live with that.

We testet the functionality with a modified "experimental_libuarte" example and it works as expected. Bytes come in immediately after reception and all bytes are received.

To test this I've written a C# tool SerialTest, that sends bytes to a Comport in random interval. Any byte that is sent is increased by one. The test program is attached to this issue. The firmware tests any incoming byte if it is equal to a increased last byte. After the first byte has been received LED4 is enabled. As soon as a followed byte is not equal to the previous byte plus 1 the LED3 is enabled. In a sucessfull test the LED4 is on but LED3 remains off during the sending of all 10000 test bytes. 

In a second step I've modified the libuarte example to run in parallel with a BLE advertising. This would somehow be near my real use case. Now the test fails in most cases. If the debugger is used I can seen that some bytes are lost in these cases. The example for this test is also attached to this issue. The attached files need to be extracted in the "\examples\peripheral" folder of the SDK15.

My question is:
- Can the libuarte be fixed to work reliable if BLE is enabled?
- How should we realize UART communication with the UARTE peripheral?

Regards
Adrian

SerialTest.zipuarte_test.zip

Parents
  • Hi Adrian,

    I turned of HW flow control (assuming you won't be using this) and tested your application. As far as I can see you have set up the maxcnt to 1 which means the cpu will have to interact with the uarte on every byte, this will not be possible while running Bluetooth so you will lose bytes (looks like I am loosing 3-4 bytes). The Legacy uart has buffer space for 6 bytes.

    The async uart driver was designed with the assumption that you cannot use HW flow control, and that the other end would be aware of the limitations of the async driver. I have only tested the driver with 255 byte (max size) buffers and sending chunks of data. And with this configuration I have been able to send data for hours without loss, BLE->UARTE and UARTE->BLE. (If I remember correctly) The driver is designed so it will change over to the secondary (free) buffer, either on max_cnt or when the timer expires (in case of shorter transmits). The recommended operation is to copy the received data to a secondary buffer, e.g a ringbuffer in the uarte handler, and handle the data in main context later. Also possible to handle in uart handler, but be aware that if you get a max_cnt packet followed by a short packet you should be finished processing before the timeout of the short packet (and BLE events will interrupt this...).

  • Hi

    I can confirm that the usage of the libuarte/libuarte_async solves the problem if they are used with a correct chunk size. In my example I used 1 which surely doesn't work. I've increased the number to 32 and it now works.

    The solution with with libuarte/libuarte_async  works, but somehow it gives me a bad feeling if I need two timers and 10 PPI channels to implement a UART communication...

    I think we can close the issue here. Thanks for your help!

    Regards Adrian

Reply
  • Hi

    I can confirm that the usage of the libuarte/libuarte_async solves the problem if they are used with a correct chunk size. In my example I used 1 which surely doesn't work. I've increased the number to 32 and it now works.

    The solution with with libuarte/libuarte_async  works, but somehow it gives me a bad feeling if I need two timers and 10 PPI channels to implement a UART communication...

    I think we can close the issue here. Thanks for your help!

    Regards Adrian

Children
No Data
Related