I know this has been asked a couple of times, but I haven't been able to find a straight forward answer.
I have a GPS module that spits out data via UART (no flow control). I would like to have the data stored into a buffer until I am ready to ready read it. The buffer might still be empty, partially filled, or full when I read it. Doesn't matter, I just want to read whatever is there whenever I want. If the buffer gets filled, it's fine if the data gets dropped. I plan to make the buffer big enough that that shouldn't happen, but if it does, doesn't matter.
If it makes a difference, I am running the nRF52840 in a mesh network (Mesh SDK 4.1.0 / SDK 16.0.0). Working off the light switch example.
I've read about using app_uart.c, app_uart_fifo.c, the serial library, etc and am just not sure what to use to accomplish this.
Then there is UART vs UARTE. If I understand what I read correctly, UARTE with EasyDMA can directly put the data in a buffer, but I can't go read it until the buffer is full and not before?
I want to start with sorting out a few things first.
1. There are several SW libraries for handling UART communication. For instance, the app_uart library handles the buffering of arbitrary sized UART buffers. This may be relevant to you.
2. There are two types of UART peripherals: The UART peripheral, which does not use DMA (so SW must handle every incoming byte), and the UARTE peripheral which uses DMA (so that SW gets an event after receiving the specified amount of bytes). You are correct though, that the UARTE peripheral has a limitation that it will not let you know how many bytes are received, so it is difficult to read half-full buffers. Therefor an option is to use Libuarte, but this tends to complicate things a bit, and is heavy on PPI resources. The libuarte library is essentially a library that works around the limitation of reading less than full UARTE DMA buff
What to use depends on your requirements. If you just receive single bytes and are happy with the driver doing a bit of work now and then behind the scenes, you can use app_uarte and get the data whenever you want. Seen from you application logic you will not need to care about the fact that some short interrupts are handled upon every received byte. But if that is a problem for you, then the libuarte is perhaps better.
I think using the "UARTE peripheral which uses DMA (so that SW gets an event after receiving the specified amount of bytes)" would work fine. I'll just size the buffer to fit at least one full transmission so that on every 'buffer full' event I know that valid data is there.
What driver or library would be best for this? I read that app_uart doesn't really use DMA since it's only doing a single byte at a time. Is this correct? What about the serial port library?
If you are happy to receive a fixed size buffer over DMA every time, then I suggest you just use a UARTE driver. Either using the nrf_drv_uart, or nrfx_uarte (which is used by nrf_drv_uart when DMA is enabled in the driver configuration).
(Regarding the serial port library, this has been removed from SDK 17, but it is present in SDK 16).
Are there any examples showing the use of either the nrf_drv_uart driver or nrfx_uarte directly?
There are no official examples, but you can refer to other SDK modules that use it, for instance. You can also just refer to the documentation, which covers most aspects (though itis slime on actual code examples).