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
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, ""); } } }
Hi,
It looks fine to me other then I can't see that you are calling your init functions anywhere.
Regards
Runar
gnss_init() is called from C main.