isr + uart + thread testing
This commit is contained in:
129
src/main.c
129
src/main.c
@@ -1,37 +1,130 @@
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/drivers/uart.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/sys/ring_buffer.h>
|
||||
|
||||
#define SLEEP_MS 2000
|
||||
#include <string.h>
|
||||
|
||||
#define LED_NODE DT_ALIAS(led0)
|
||||
#if !DT_NODE_HAS_STATUS(LED_NODE, okay)
|
||||
#error "led0 not enabled in devicetree"
|
||||
#endif
|
||||
|
||||
#define UART_DEVICE_NODE DT_CHOSEN(zephyr_shell_uart)
|
||||
|
||||
#define RX_BUF_SIZE 256
|
||||
#define LINE_BUF_SIZE 128
|
||||
#define THREAD_STACK 1024
|
||||
#define THREAD_PRIO 5
|
||||
|
||||
// Ring buffer: callback writes, thread reads (could probably be a msg_queue too)
|
||||
RING_BUF_DECLARE(rx_buf, RX_BUF_SIZE);
|
||||
|
||||
// Semaphore to wake the thread (name, initial count, max count)
|
||||
K_SEM_DEFINE(rx_sem, 0, 1);
|
||||
|
||||
K_THREAD_STACK_DEFINE(rx_stack, THREAD_STACK);
|
||||
static struct k_thread rx_thread_data;
|
||||
|
||||
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED_NODE, gpios);
|
||||
static const struct device *uart = DEVICE_DT_GET(DT_NODELABEL(lpuart1));
|
||||
|
||||
void uart_print(const char buffer[]);
|
||||
void uart_println(const char buffer[]);
|
||||
void uart_cb(const struct device *dev, void *user_data);
|
||||
static void rx_thread(void *p1, void *p2, void *p3);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printk("app started\n");
|
||||
|
||||
if (!gpio_is_ready_dt(&led))
|
||||
if (!device_is_ready(uart))
|
||||
{
|
||||
printk("LED GPIO not ready\n");
|
||||
return 0;
|
||||
printk("UART not ready\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
|
||||
if (ret < 0)
|
||||
// Set up interrupt-driven RX
|
||||
uart_irq_callback_set(uart, uart_cb);
|
||||
uart_irq_rx_enable(uart);
|
||||
|
||||
// Spawn the processing thread
|
||||
k_thread_create(&rx_thread_data, rx_stack,
|
||||
THREAD_STACK,
|
||||
rx_thread, NULL, NULL, NULL,
|
||||
THREAD_PRIO, 0, K_NO_WAIT);
|
||||
|
||||
printk("UART ready — type something!\r\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ============= Helpers =============
|
||||
|
||||
void uart_print(const char buffer[])
|
||||
{
|
||||
size_t len = strlen(buffer);
|
||||
for (size_t i = 0; i < len; i++)
|
||||
uart_poll_out(uart, buffer[i]);
|
||||
}
|
||||
|
||||
void uart_println(const char buffer[])
|
||||
{
|
||||
uart_print(buffer);
|
||||
uart_poll_out(uart, '\r');
|
||||
uart_poll_out(uart, '\n');
|
||||
}
|
||||
|
||||
// ============= Callbacks =============
|
||||
void uart_cb(const struct device *dev, void *user_data)
|
||||
{
|
||||
uint8_t byte;
|
||||
while (uart_irq_update(dev) && uart_irq_rx_ready(dev))
|
||||
{
|
||||
printk("LED GPIO configure failed: %d\n", ret);
|
||||
return 0;
|
||||
if (uart_fifo_read(dev, &byte, 1) == 1)
|
||||
{
|
||||
ring_buf_put(&rx_buf, &byte, 1);
|
||||
}
|
||||
}
|
||||
|
||||
char incoming;
|
||||
int i = 0;
|
||||
// wake up thread
|
||||
k_sem_give(&rx_sem);
|
||||
}
|
||||
|
||||
// ============= Threads =============
|
||||
static void rx_thread(void *p1, void *p2, void *p3)
|
||||
{
|
||||
char line[LINE_BUF_SIZE];
|
||||
size_t pos = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
k_sem_take(&rx_sem, K_FOREVER);
|
||||
|
||||
uint8_t byte;
|
||||
while (ring_buf_get(&rx_buf, &byte, 1) == 1)
|
||||
{
|
||||
|
||||
// Echo the character back
|
||||
uart_poll_out(uart, byte);
|
||||
|
||||
if (byte == '\r' || byte == '\n')
|
||||
{
|
||||
if (pos > 0)
|
||||
{
|
||||
line[pos] = '\0';
|
||||
|
||||
printk("\r\n");
|
||||
printk("─────────────────────────────\r\n");
|
||||
printk("│ RX: %-24s \r\n", line);
|
||||
printk("│ Len: %-3d, Time: %-10u \r\n",
|
||||
pos, k_uptime_get_32());
|
||||
printk("─────────────────────────────\r\n");
|
||||
|
||||
pos = 0;
|
||||
}
|
||||
}
|
||||
else if (pos < LINE_BUF_SIZE - 1)
|
||||
{
|
||||
line[pos++] = byte;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user