Issue with UART RX data transmission at high baud rates

I am facing an issue with UART communication at high baud rates. The transmission of data from the transmitting device (TX) to the receiving device (RX) works fine, but when the baud rate is increased beyond a certain threshold, I observe that the RX data transmission is not working as expected. Specifically, I am seeing that the received data is incorrect, and there are missing bytes in the received data stream.

Code: Here is the initialization code for the UART communication:

ret_code_t uartInit(nrf_uarte_baudrate_t baud_rate)
{
        nrf_drv_uart_config_t config = NRF_DRV_UART_DEFAULT_CONFIG;
        config.pseltxd = BG_TX_PIN;
        config.pselrxd = BG_RX_PIN;
        config.hwfc = NRF_UART_HWFC_DISABLED;
        config.parity = NRF_UART_PARITY_EXCLUDED;
        config.baudrate = baud_rate;
        config.interrupt_priority = APP_IRQ_PRIORITY_LOW;
        uint32_t err_code = nrf_drv_uart_init(&uart_nrf, &config, uart_event_handle);

    }
}

Reproduction steps:

  1. Initialize UART communication as shown above.
  2. Transmit data from the TX device at high baud rates (e.g. 921600 bps).
  3. Observe that the RX data transmission is incorrect and missing bytes.

SDK: 17.1 
IDE : Segger Embedded Studio

I am using an NRF52840 microcontroller and a BG95 modem for UART communication. The issue is observed when the baud rate is increased beyond 921600 bps. The TX data transmission is working fine, but the RX data transmission is not reliable.

I would appreciate any insights or suggestions on how to resolve this issue. Thank you.

Parents
  • Hi,

    It is more interesting to see how you start the UART RX than how you initialized the driver. If you call nrf_drv_uart_rx() with a low value in the length parameter, you will struggle to handle the interrupts fast enough to provide a new buffer to store the received data, when HW flow control is disabled. The UARTE HW has a RX FIFO, but this can only hold 4 bytes. 

    If your connected device cannot support HW flow control pins, I would recommend you to consider using the libUARTE library in your application. This handles multiple RX buffers for you at a configurable length, along with RX timeouts for notifying application of received data before the whole buffer have been filled. The nRF52840 can support up to 65535 byte receptions directly to RAM when using the UARTE peripheral with EasyDMA.

    Best regards,
    Jørgen

Reply
  • Hi,

    It is more interesting to see how you start the UART RX than how you initialized the driver. If you call nrf_drv_uart_rx() with a low value in the length parameter, you will struggle to handle the interrupts fast enough to provide a new buffer to store the received data, when HW flow control is disabled. The UARTE HW has a RX FIFO, but this can only hold 4 bytes. 

    If your connected device cannot support HW flow control pins, I would recommend you to consider using the libUARTE library in your application. This handles multiple RX buffers for you at a configurable length, along with RX timeouts for notifying application of received data before the whole buffer have been filled. The nRF52840 can support up to 65535 byte receptions directly to RAM when using the UARTE peripheral with EasyDMA.

    Best regards,
    Jørgen

Children
Related