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 Reply Children
  • Issue facing in Reading data from BG95 at all baud rates

    1. At 115200 baud rate, Tx is fine but at Rx 15+ packets found corrupted out of 140 packets
    2. At 460800 baud rate, Tx is fine but at Rx 56+ packets corrupted out of 140 Packets
    3. At 921600 baud rate, Tx is fine but at Rx corruption of data is higher, command response’s are getting corrupted

    libUARTE Integartion:

    void uart_event_handler(void * context, nrf_libuarte_async_evt_t * p_evt)
    {
        nrf_libuarte_async_t * p_libuarte = (nrf_libuarte_async_t *)context;
        ret_code_t ret;
    
        switch (p_evt->type)
        {
            case NRF_LIBUARTE_ASYNC_EVT_RX_DATA:
                uart_rx_done = true;
                if (p_evt->data.rxtx.length <= sizeof(data_array)) {
                    memset(data_array, 0x00, sizeof(data_array));
                    memcpy(data_array, p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
                    data_len = p_evt->data.rxtx.length;
                }
                //print(LL_INFO, "len:%d - data: %s\n", p_evt->data.rxtx.length, data_array);
                break;
            case NRF_LIBUARTE_ASYNC_EVT_TX_DONE:
                //NRF_LOG_RAW_INFO("Tx!\n");
                    /*nrf_libuarte_async_rx_free(p_libuarte, p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
                    if (!nrf_queue_is_empty(&m_buf_queue))
                    {
                        buffer_t buf;
                        ret = nrf_queue_pop(&m_buf_queue, &buf);
                        APP_ERROR_CHECK(ret);
                        UNUSED_RETURN_VALUE(nrf_libuarte_async_tx(p_libuarte, buf.p_data, buf.length));
                    }*/
                break;
             default:
                print(LL_INFO, "\nUE:%d\n\n", (int)p_evt->type);
                break;
        }
    }

  • ret_code_t uartInit(nrf_uarte_baudrate_t baud_rate)
    {
    ret_code_t err_code = NRF_SUCCESS;
    
    if (uartAlreadyInit == 0) {
    nrf_libuarte_async_config_t config;
    config.tx_pin = BG_TX_PIN;
    config.rx_pin = BG_RX_PIN;
    config.baudrate = baud_rate;
    config.parity = NRF_UARTE_PARITY_EXCLUDED;
    config.hwfc = NRF_UARTE_HWFC_DISABLED;
    config.timeout_us = 100000;
    config.int_prio = APP_IRQ_PRIORITY_LOW;
    
    err_code = nrf_libuarte_async_init(&libuarte, &config, uart_event_handler, (void *)&libuarte);
    nrf_libuarte_async_enable(&libuarte);
    uartAlreadyInit = 1;
    }
    
    return err_code;
    }

  • Where are you freeing the RX buffer? If you do not free the RX buffers fast enough, libUARTE will eventually not have any new buffers to assign to the UARTE peripheral, preventing it from receiving more data. If you have a very high baudrate and do lots of processing on the incoming data before the buffer can be freed, you should consider increasing the number of or size of buffers for libUARTE (see NRF_LIBUARTE_ASYNC_DEFINE()).

Related