|
| 1 | +/* |
| 2 | + * Copyright (c) 2024 STMicroelectronics |
| 3 | + * |
| 4 | + * SPDX-License-Identifier: Apache-2.0 |
| 5 | + */ |
| 6 | + |
| 7 | +#include <zephyr/kernel.h> |
| 8 | +#include <zephyr/device.h> |
| 9 | +#include <zephyr/devicetree.h> |
| 10 | +#include <zephyr/drivers/uart.h> |
| 11 | +#include <zephyr/sys/ring_buffer.h> |
| 12 | +#include <zephyr/sys/printk.h> |
| 13 | +#include <string.h> |
| 14 | + |
| 15 | +#define RING_BUF_SIZE 1000 |
| 16 | +#define RX_BUF_SIZE 10 |
| 17 | + |
| 18 | +#define RECEIVE_TIMEOUT 0 |
| 19 | + |
| 20 | +#define STACK_SIZE 1024 |
| 21 | + |
| 22 | +#define UART_DEVICE_NODE DT_CHOSEN(zephyr_shell_uart) |
| 23 | + |
| 24 | +static const struct device *const uart_dev = DEVICE_DT_GET(UART_DEVICE_NODE); |
| 25 | + |
| 26 | +/* uart configuration structure */ |
| 27 | +const struct uart_config uart_cfg = {.baudrate = 115200, |
| 28 | + .parity = UART_CFG_PARITY_NONE, |
| 29 | + .stop_bits = UART_CFG_STOP_BITS_1, |
| 30 | + .data_bits = UART_CFG_DATA_BITS_8, |
| 31 | + .flow_ctrl = UART_CFG_FLOW_CTRL_NONE}; |
| 32 | + |
| 33 | +/* define a ring buffer to get raw bytes*/ |
| 34 | +RING_BUF_DECLARE(ring_buf, RING_BUF_SIZE); |
| 35 | + |
| 36 | +/* define uart rx buffer */ |
| 37 | +static uint8_t rx_buffer[RX_BUF_SIZE]; |
| 38 | + |
| 39 | +/* define thread stack size */ |
| 40 | +static K_THREAD_STACK_DEFINE(uart_rx_stack, STACK_SIZE); |
| 41 | + |
| 42 | +/* struct uart_event async_evt */ |
| 43 | +static struct k_thread uart_rx_thread_data = {0}; |
| 44 | + |
| 45 | +void print_uart(char *buf, int len) |
| 46 | +{ |
| 47 | + for (int i = 0; i < len; i++) { |
| 48 | + |
| 49 | + if ((buf[i] == '\n' || buf[i] == '\r')) { |
| 50 | + uart_poll_out(uart_dev, '\n'); |
| 51 | + } else { |
| 52 | + uart_poll_out(uart_dev, buf[i]); |
| 53 | + } |
| 54 | + } |
| 55 | +} |
| 56 | + |
| 57 | +/* Data processing thread */ |
| 58 | +static void uart_rx_thread(void *p1, void *p2, void *p3) |
| 59 | +{ |
| 60 | + uint8_t rx_data[RX_BUF_SIZE]; |
| 61 | + size_t len; |
| 62 | + |
| 63 | + while (1) { |
| 64 | + |
| 65 | + /* Check if there's data in the ring buffer */ |
| 66 | + len = ring_buf_get(&ring_buf, rx_data, sizeof(rx_data)); |
| 67 | + |
| 68 | + if (len > 0) { |
| 69 | + |
| 70 | + /* Process `len` bytes of data */ |
| 71 | + print_uart(rx_data, len); |
| 72 | + } |
| 73 | + } |
| 74 | +} |
| 75 | + |
| 76 | +void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data) |
| 77 | +{ |
| 78 | + switch (evt->type) { |
| 79 | + case UART_RX_RDY: |
| 80 | + /* Data received; place into ring buffer */ |
| 81 | + ring_buf_put(&ring_buf, evt->data.rx.buf + evt->data.rx.offset, evt->data.rx.len); |
| 82 | + |
| 83 | + break; |
| 84 | + |
| 85 | + case UART_RX_DISABLED: |
| 86 | + /* Re-enable RX */ |
| 87 | + uart_rx_enable(uart_dev, rx_buffer, sizeof(rx_buffer), RECEIVE_TIMEOUT); |
| 88 | + |
| 89 | + break; |
| 90 | + |
| 91 | + default: |
| 92 | + break; |
| 93 | + } |
| 94 | +} |
| 95 | + |
| 96 | +int main(void) |
| 97 | +{ |
| 98 | + if (!uart_dev) { |
| 99 | + printk("Failed to get UART device"); |
| 100 | + return 1; |
| 101 | + } |
| 102 | + |
| 103 | + /* uart configuration parameters */ |
| 104 | + int err = uart_configure(uart_dev, &uart_cfg); |
| 105 | + |
| 106 | + if (err == -ENOSYS) { |
| 107 | + printk("Configuration is not supported by device or driver," |
| 108 | + " check the UART settings configuration\n"); |
| 109 | + return -ENOSYS; |
| 110 | + } |
| 111 | + |
| 112 | + /* Configure uart callback */ |
| 113 | + uart_callback_set(uart_dev, uart_cb, NULL); |
| 114 | + |
| 115 | + /* enable uart reception */ |
| 116 | + uart_rx_enable(uart_dev, rx_buffer, sizeof(rx_buffer), RECEIVE_TIMEOUT); |
| 117 | + |
| 118 | + printk("\n Enter message to fill RX buffer size :\n"); |
| 119 | + |
| 120 | + /* start uart data processing thread */ |
| 121 | + k_tid_t tid = k_thread_create(&uart_rx_thread_data, uart_rx_stack, |
| 122 | + K_THREAD_STACK_SIZEOF(uart_rx_stack), uart_rx_thread, NULL, |
| 123 | + NULL, NULL, 5, 0, K_NO_WAIT); |
| 124 | + k_thread_name_set(tid, "RX_thread"); |
| 125 | +} |
0 commit comments