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.
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.
Good.
Don't hesitate to create a new ticket if you are facing any problems.
Is it okay to you to close this case now?
Regards
Runar
yes you can close this, thankyou.
PS i have a new case here
yes you can close this, thankyou.
PS i have a new case here