This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF9160 UARTE communication between 91 and 52 is unreliable

I have a setup where nRF91 and nRF52 on nRF9160 DK have to exchange ASCII strings over UART. nRF91 runs Zephyr and nRF52 - nRF SDK for Mesh.

When nRF52 is unprovisioned, there is a 50%..75% data loss in nRF91 to nRF52 direction (no RX event is fired for UARTE on nRF52, although nRF91 believes that it transmits data). Once nRF52 is provisioned the situation drastically improves and maybe less than 5% of data is lost in what seems to be a regular time pattern.

I am using UARTE on both ends with HW flow control turned on. This doesn't seem to be a transmission speed issue, as I have tried all the speeds from 9600 up to a million, as well as inserting a pause of several seconds in the TX thread on nRF91. None of it helps.

Here are some more details:

Board: PCA10090 version 0.8.3
nRF91:  Zephyr version: 2.0.99

nRF91 UARTE Config:

&uart2 {
current-speed = <115200>;
status = "okay";
tx-pin = <18>;
rx-pin = <17>;
rts-pin = <21>;
cts-pin = <19>;
};

CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_UART_LINE_CTRL=y
CONFIG_UART_2_NRF_UARTE=y
CONFIG_UART_2_NRF_FLOW_CONTROL=y

The data is sent from a separate thread in blocks of up to 32 bytes (changing TX block size in the range of 4..255 did not make a difference):

static void mqtt_to_uart_thread(void *p1, void *p2, void *p3)
{
       struct net_buf *buf;
       while (1) {
                buf = net_buf_get(&m_queue_to_uart, K_FOREVER);
                while (*buf->data)
                        uart_poll_out(uart, *buf->data++);
                net_buf_unref(buf);
// optional k_sleep(K_SECONDS(5));
        }
}

nRF52:
1. nrf5 SDK for Mesh v4.1.0
2. nRF5 SDK 16.0.0
3. s140_nrf52_7.0.1_softdevice
4. Serial App

#define RX_PIN_NUMBER 14
#define TX_PIN_NUMBER 15
#define CTS_PIN_NUMBER 16
#define RTS_PIN_NUMBER 17

NRF_SERIAL_DRV_UART_CONFIG_DEF(m_driver_config,
RX_PIN_NUMBER,
TX_PIN_NUMBER,
RTS_PIN_NUMBER,
CTS_PIN_NUMBER,
NRF_UART_HWFC_ENABLED,
NRF_UART_PARITY_EXCLUDED,
UART_BAUDRATE_BAUDRATE_Baud115200,
UART_DEFAULT_CONFIG_IRQ_PRIORITY);

NRF_SERIAL_QUEUES_DEF(m_fifo,
OUTGOING_MSG_MAX_LEN * 16,
INCOMING_MSG_MAX_LEN * 4);

NRF_SERIAL_BUFFERS_DEF(m_buffer,
OUTGOING_MSG_MAX_LEN,
1 /* incoming buffer - frame length */);

NRF_SERIAL_UART_DEF(m_serial, 0);

NRF_SERIAL_CONFIG_DEF(m_serial_config,
NRF_SERIAL_MODE_DMA,
&m_fifo,
&m_buffer,
event_handler,
NULL /* sleep handler */);


static void event_handler (struct nrf_serial_s const * p_serial,
nrf_serial_event_t event)
{
switch (event){
case NRF_SERIAL_EVENT_RX_DATA:
process_received(false);
break;

case NRF_SERIAL_EVENT_DRV_ERR:
__LOG(LOG_SRC_APP,
LOG_LEVEL_ERROR,
"Internal UARTE driver error!\n");
nrf_serial_uninit(p_serial);
initialise_serial();
__LOG(LOG_SRC_APP,
LOG_LEVEL_ERROR,
"UARTE driver has been restarted.\n");
break;

case NRF_SERIAL_EVENT_FIFO_ERR:
__LOG(LOG_SRC_APP,
LOG_LEVEL_ERROR,
"UARTE RX FIFO overrun: increase RX queue size!\n");
break;
}
}
Parents Reply Children
  • Ah, I should have read the code more thoroughly.

    Just to test could you rewrite your nRF9160 .overlay like this:

    &uart2 {
          compatible = "nordic,nrf-uarte";
          current-speed = <115200>;
          status = "okay";
          tx-pin = <10>;
          rx-pin = <11>;
          rts-pin = <12>;
          cts-pin = <13>;
          hw-flow-control;
    };


    In addition, do you have a logic analyzer available? It could help to see what's happening on the different pins. 

    Lastly, this seems to be a timing issue of some sort (as you suggest). I have read through some old cases regarding data loss over UARTE on the nRF52840 and found that it could be problems with the clock. Could you try the fix in this thread too?

    Best regards,
    Carl Richard

     

Related