If the UARTE interrupt service routine is delayed from running more than 1 byte's worth of time, then APP UART FIFO does not see all bytes queued in the UARTE's easyDMA buffer.
In file app_uart_fifo.c in function uart_event_handler, the event handler for NRF_DRV_EVT_RX_DONE only removes the first byte from the UARTE buffer and ignores any remaining bytes in the buffer. Function uart_event_handler is called from function rx_done_event in file nrfx_uarte.c where it passes a pointer to the buffer and number of bytes in the buffer in the event variable. So the issue is really in function uart_event_handler where it is ignoring the number of bytes being passed in variable event.
Below is part of the original code with the problem:
static void uart_event_handler(nrf_drv_uart_event_t * p_event, void* p_context)
{
app_uart_evt_t app_uart_event;
uint32_t err_code;
switch (p_event->type)
{
case NRF_DRV_UART_EVT_RX_DONE:
// Write received byte to FIFO.
err_code = app_fifo_put(&m_rx_fifo, p_event->data.rxtx.p_data[0]);
if (err_code != NRF_SUCCESS)
Below are the changes I made to fix the issue in my system:
static void uart_event_handler(nrf_drv_uart_event_t * p_event, void* p_context)
{
app_uart_evt_t app_uart_event;
uint32_t err_code;
uint8_t byte;
switch (p_event->type)
{
case NRF_DRV_UART_EVT_RX_DONE:
// Write received byte to FIFO.
err_code = NRF_SUCCESS;
byte = p_event->data.rxtx.bytes;
while ((err_code == NRF_SUCCESS) && (byte--))
{
err_code = app_fifo_put(&m_rx_fifo, p_event->data.rxtx.p_data[0]);
p_event->data.rxtx.p_data++;
}
if (err_code != NRF_SUCCESS)
I found the issue in SDK 15.0.0. The issue surfaced when I was trying to constantly send data over the BLE at the same time receive several hundred bytes over UARTE.