Hi
I'm using the UART async API and want to pass the received data to a fifo or workqueue to them process this received data.
There does not seem to be any examples of doing this with the async API, so where can i find something ?
KR
Hi
I'm using the UART async API and want to pass the received data to a fifo or workqueue to them process this received data.
There does not seem to be any examples of doing this with the async API, so where can i find something ?
KR
Hi Lee,
You can have a look at our peripheral_uart exampel
Here you can see we how it is putting the received datainto a FIFO https://github.com/nrfconnect/sdk-nrf/blob/main/samples/bluetooth/peripheral_uart/src/main.c#L182
Regards
Runar
do you not have a simpler example ?
i only need to worry about receive data. This data is from a GPS receiver, data should be out in fifo and then processed is worker/separate thread.
i found this, much easier example, might be of interest to others.
Just remember is based on an old version of NCS so it will not work out of the box
Regards
Runar
What needs to be changed ?
From the top of my head, the include paths is wrong. I would recommend comparing them to one of the examples I have linked you. In NCS 2.0 Zephyr 3.0 was introduced and with it:
"All Zephyr public headers have been moved to include/zephyr, meaning they must be prefixed with <zephyr/...> when included. Because this change can potentially break many applications or libraries, CONFIG_LEGACY_INCLUDE_PATH is provided to allow using the old include path."
You might be lucky and that is the only thing you have to care about.
Regards
Runar
this is my code, it seems to work, can you check to see if you think i'm missing anything ?
#include <stdio.h> #include <string.h> #include <zephyr/device.h> #include <zephyr/drivers/uart.h> #include <zephyr/kernel.h> #include <zephyr/sys/ring_buffer.h> #include <zephyr/usb/usb_device.h> #include <zephyr/logging/log.h> #include <zephyr/drivers/gpio.h> #include <zephyr/sys/util.h> //https://github.com/too1/ncs-uart-async-count-rx/blob/master/src/main.c #define UART_BUF_SIZE 500 //#define UART_TX_TIMEOUT_MS 100 #define UART_RX_TIMEOUT_MS 100*1000 #define UART_RX_MSG_QUEUE_SIZE 8 #define GNSS_THREAD_PRIORITY 2 #define GNSS_THREAD_STACK_SIZE 1024 LOG_MODULE_REGISTER(gnss, LOG_LEVEL_DBG); static const struct device *uart = DEVICE_DT_GET(DT_NODELABEL(uart0)); static uint8_t uart_double_buffer[2][UART_BUF_SIZE]; static uint8_t *uart_buf_next = uart_double_buffer[0]; static uint8_t *uart_buf_prev = uart_double_buffer[1]; struct uart_msg_queue_item { uint8_t bytes[UART_BUF_SIZE]; uint32_t length; }; const struct uart_config uart_cfg = { .baudrate = 9600, .parity = UART_CFG_PARITY_NONE, .stop_bits = UART_CFG_STOP_BITS_1, .data_bits = UART_CFG_DATA_BITS_8, .flow_ctrl = UART_CFG_FLOW_CTRL_NONE }; static void gnss_thread(void *unused1, void *unused2, void *unused3); static void uart_callback_handler(const struct device *dev, struct uart_event *evt, void *user_data); //K_SEM_DEFINE(rx_disabled, 0, 1); K_MSGQ_DEFINE(uart_rx_msgq, sizeof(struct uart_msg_queue_item), UART_RX_MSG_QUEUE_SIZE, 4); K_THREAD_DEFINE(gnss_thread_id, GNSS_THREAD_STACK_SIZE, gnss_thread, NULL, NULL, NULL, GNSS_THREAD_PRIORITY, 0, 0); void gns_init(void) { int result; if (!device_is_ready(uart)) { LOG_DBG("UART device not ready"); return; } result = uart_configure(uart, &uart_cfg); if (result != 0) { LOG_DBG("UART configuration error %i", result); return; } uart_callback_set(uart, uart_callback_handler, NULL); uart_rx_enable(uart, uart_double_buffer[0], UART_BUF_SIZE, UART_RX_TIMEOUT_MS); } static void uart_callback_handler(const struct device *dev, struct uart_event *evt, void *user_data) { int result; static int toggle = 0; static struct uart_msg_queue_item new_message; ARG_UNUSED(dev); switch (evt->type) { case UART_TX_DONE: LOG_DBG("tx done"); break; case UART_TX_ABORTED: LOG_DBG("tx aborted"); break; case UART_RX_STOPPED: LOG_DBG("rx stopped"); break; case UART_RX_DISABLED: // k_sem_give(&rx_disabled); LOG_DBG("rx disabled"); break; default: LOG_ERR("unhandled case!"); break; case UART_RX_BUF_RELEASED: uart_buf_prev = evt->data.rx_buf.buf; LOG_DBG("rx buffer release @ 0x%p size %i", (void *)&uart_buf_prev, UART_BUF_SIZE); break; case UART_RX_BUF_REQUEST: toggle = (toggle ^ 1); uart_buf_next = uart_double_buffer[toggle]; LOG_DBG("rx buffer request @ 0x%p size %i", (void *)&uart_buf_next, UART_BUF_SIZE); uart_rx_buf_rsp(uart, uart_buf_next, UART_BUF_SIZE); break; case UART_RX_RDY: new_message.length = evt->data.rx.len; memcpy(new_message.bytes, (evt->data.rx.buf + evt->data.rx.offset), evt->data.rx.len); LOG_DBG("rx ready %i byte(s) offset %i", evt->data.rx.len, evt->data.rx.offset); result = k_msgq_put(&uart_rx_msgq, &new_message, K_NO_WAIT); if(result != 0) { LOG_ERR("rx message queue full!"); } break; } } void gnss_thread(void *unused1, void *unused2, void *unused3) { int result; struct uart_msg_queue_item rx_message; ARG_UNUSED(unused1); ARG_UNUSED(unused2); ARG_UNUSED(unused3); //k_sem_take(&ble_init_ok, K_FOREVER); while(1) { // k_sleep(K_MSEC(2000)); // LOG_DBG("this is gnss_thread!"); result = k_msgq_get(&uart_rx_msgq, &rx_message, K_FOREVER); if(result == 0) { LOG_DBG("reading %i byte(s) from buffer", rx_message.length); LOG_HEXDUMP_DBG(&rx_message.bytes[0], rx_message.length, ""); } } }