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;
}
}