Hello, I'm developing on an application which requires to catch high speed, variable size and bursty (~0.5 Mbit/s) data from a sensor connected to a nRF9161DK trough a UART without flow control.
This is the code of the very simple application making use of Async UART API ...
/* * Copyright (c) 2019 Tavish Naruka <[email protected]> * Copyright (c) 2023 Nordic Semiconductor ASA * Copyright (c) 2023 Antmicro <www.antmicro.com> * * SPDX-License-Identifier: Apache-2.0 */ /* Sample which uses the filesystem API and SDHC driver */ #include <zephyr/kernel.h> #include <zephyr/device.h> #include <zephyr/logging/log.h> #include <stdlib.h> #include <zephyr/drivers/uart.h> LOG_MODULE_REGISTER(main); #define UART_BUF_SIZE 512 #define UART_RX_TIMEOUT_MS 10000 // UART RX primary buffers uint8_t uart_double_buffer[2][UART_BUF_SIZE]; uint8_t *uart_buf_next = uart_double_buffer[1]; uint8_t complete_message[UART_BUF_SIZE]; uint8_t complete_message_counter = 0; bool currently_active_buffer = 1; // 0 - uart_double_buffer[0] is active, 1 - uart_double_buffer[1] is active static const struct device *dev_uart; static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data) { switch (evt->type) { case UART_TX_DONE: LOG_DBG("UART_TX_DONE"); break; case UART_TX_ABORTED: LOG_DBG("UART_TX_ABORTED"); break; case UART_RX_RDY: LOG_DBG("UART_RX_RDY: received %i bytes, Offset = %i ", evt->data.rx.len,evt->data.rx.offset); break; case UART_RX_BUF_REQUEST: uart_rx_buf_rsp(dev_uart, uart_buf_next, UART_BUF_SIZE); currently_active_buffer = !currently_active_buffer; if (currently_active_buffer == 0) { LOG_DBG("UART_RX_BUF_REQUEST: current active buffer uart_double_buffer[0] "); } else { LOG_DBG("UART_RX_BUF_REQUEST: current active buffer uart_double_buffer[1] "); } break; case UART_RX_BUF_RELEASED: LOG_DBG("UART_RX_BUF_RELEASED"); uart_buf_next = evt->data.rx_buf.buf; break; case UART_RX_DISABLED: LOG_DBG("UART_RX_DISABLED"); k_sem_give(&rx_disabled); break; case UART_RX_STOPPED: switch (evt->data.rx_stop.reason) { case UART_ERROR_OVERRUN: { LOG_DBG("UART_RX_STOPPED UART_ERROR_OVERRUN"); break; } case UART_ERROR_PARITY: { LOG_DBG("UART_RX_STOPPED UART_ERROR_PARITY"); break; } case UART_ERROR_FRAMING: { LOG_DBG("UART_RX_STOPPED UART_ERROR_FRAMING"); break; } case UART_BREAK: { LOG_DBG("UART_RX_STOPPED UART_BREAK"); break; } case UART_ERROR_COLLISION: { LOG_DBG("UART_RX_STOPPED UART_ERROR_COLLISION"); break; } case UART_ERROR_NOISE: { LOG_DBG("UART_RX_STOPPED UART_ERROR_NOISE"); break; } } break; default: break; } } TStationConfig StationConfig; int app_uart_init() { dev_uart = DEVICE_DT_GET(DT_NODELABEL(uart1)); if (!device_is_ready(dev_uart)) { return 0; } int err; err = uart_callback_set(dev_uart, uart_cb, NULL); if (err) { return err; } LOG_DBG("UART1 RX enabled"); uart_rx_enable(dev_uart, uart_double_buffer[0], UART_BUF_SIZE, UART_RX_TIMEOUT_MS); return 0; } int main(void) { while (1) { k_sleep(K_MSEC(10000)); } return 0; }
As long as there is data coming from the external sensor things seems to work as expected:
*** Booting nRF Connect SDK v3.0.2-89ba1294ac9b ***
*** Using Zephyr OS v4.0.99-f791c49f492c ***
[00:00:00.252,868] <dbg> os: k_sched_unlock: scheduler unlocked (0x20000960:0)
[00:00:00.252,899] <dbg> main: app_uart_init: UART1 RX enabled
[00:00:00.252,929] <dbg> main: uart_cb: UART_RX_BUF_REQUEST: current active buffer uart_double_buffer[0]
[00:00:00.252,929] <dbg> os: z_tick_sleep: thread 0x20000960 for 327680 ticks
[00:00:01.240,051] <dbg> main: uart_cb: UART_RX_RDY: received 512 bytes, Offset = 0
[00:00:01.240,081] <dbg> main: uart_cb: UART_RX_BUF_RELEASED
[00:00:01.240,112] <dbg> main: uart_cb: UART_RX_BUF_REQUEST: current active buffer uart_double_buffer[1]
[00:00:01.250,396] <dbg> main: uart_cb: UART_RX_RDY: received 88 bytes, Offset = 0
[00:00:01.250,396] <dbg> main: uart_cb: UART_RX_BUF_RELEASED
[00:00:01.250,427] <dbg> main: uart_cb: UART_RX_BUF_REQUEST: current active buffer uart_double_buffer[0]
[00:00:02.239,685] <dbg> main: uart_cb: UART_RX_RDY: received 512 bytes, Offset = 0
[00:00:02.239,715] <dbg> main: uart_cb: UART_RX_BUF_RELEASED
[00:00:02.239,715] <dbg> main: uart_cb: UART_RX_BUF_REQUEST: current active buffer uart_double_buffer[1]
[00:00:02.252,014] <dbg> main: uart_cb: UART_RX_RDY: received 185 bytes, Offset = 0
[00:00:02.252,044] <dbg> main: uart_cb: UART_RX_BUF_RELEASED
[00:00:02.252,075] <dbg> main: uart_cb: UART_RX_BUF_REQUEST: current active buffer uart_double_buffer[0]
[00:00:03.241,882] <dbg> main: uart_cb: UART_RX_RDY: received 512 bytes, Offset = 0
[00:00:03.241,912] <dbg> main: uart_cb: UART_RX_BUF_RELEASED
[00:00:03.241,943] <dbg> main: uart_cb: UART_RX_BUF_REQUEST: current active buffer uart_double_buffer[1]
[00:00:03.256,225] <dbg> main: uart_cb: UART_RX_RDY: received 201 bytes, Offset = 0
[00:00:03.256,225] <dbg> main: uart_cb: UART_RX_BUF_RELEASED
[00:00:03.256,256] <dbg> main: uart_cb: UART_RX_BUF_REQUEST: current active buffer uart_double_buffer[0]
Instead, when I power off the external sensor and e reboot the nRF9161DK board I get the following sequence:
*** Booting nRF Connect SDK v3.0.2-89ba1294ac9b ***
*** Using Zephyr OS v4.0.99-f791c49f492c ***
[00:00:00.353,332] <dbg> os: k_sched_unlock: scheduler unlocked (0x20000960:0)
[00:00:00.353,363] <dbg> main: app_uart_init: UART1 RX enabled
[00:00:00.353,393] <dbg> main: uart_cb: UART_RX_BUF_REQUEST: current active buffer uart_double_buffer[0]
[00:00:00.353,424] <dbg> main: uart_cb: UART_RX_STOPPED UART_ERROR_FRAMING
[00:00:00.353,424] <dbg> os: z_tick_sleep: thread 0x20000960 for 327680 ticks
[00:00:00.353,454] <dbg> main: uart_cb: UART_RX_STOPPED UART_ERROR_FRAMING
[00:00:00.353,485] <dbg> main: uart_cb: UART_RX_STOPPED UART_ERROR_FRAMING
[00:00:00.353,515] <dbg> main: uart_cb: UART_RX_STOPPED UART_ERROR_FRAMING
[00:00:00.353,546] <dbg> main: uart_cb: UART_RX_STOPPED UART_ERROR_FRAMING
[00:00:00.353,576] <dbg> main: uart_cb: UART_RX_BUF_RELEASED
[00:00:00.353,607] <dbg> main: uart_cb: UART_RX_BUF_RELEASED
[00:00:00.353,607] <dbg> main: uart_cb: UART_RX_DISABLED
[00:00:00.353,637] <dbg> main: uart_cb: UART_RX_STOPPED UART_ERROR_FRAMING
What is the meaning of UART_ERROR_FRAMING (I was expecting a timeout instead)?
What is causing UART_RX_DISABLED ?
Joel