isr + uart + thread testing
This commit is contained in:
3
prj.conf
3
prj.conf
@@ -3,5 +3,6 @@ CONFIG_GPIO=y
|
|||||||
CONFIG_SERIAL=y
|
CONFIG_SERIAL=y
|
||||||
CONFIG_CONSOLE=y
|
CONFIG_CONSOLE=y
|
||||||
CONFIG_UART_CONSOLE=y
|
CONFIG_UART_CONSOLE=y
|
||||||
CONFIG_PRINTK=y
|
|
||||||
CONFIG_UART_INTERRUPT_DRIVEN=y
|
CONFIG_UART_INTERRUPT_DRIVEN=y
|
||||||
|
CONFIG_RING_BUFFER=y
|
||||||
|
CONFIG_PRINTK=y
|
||||||
127
src/main.c
127
src/main.c
@@ -1,37 +1,130 @@
|
|||||||
#include <zephyr/devicetree.h>
|
|
||||||
#include <zephyr/drivers/gpio.h>
|
|
||||||
#include <zephyr/kernel.h>
|
#include <zephyr/kernel.h>
|
||||||
|
#include <zephyr/device.h>
|
||||||
|
#include <zephyr/devicetree.h>
|
||||||
#include <zephyr/drivers/uart.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)
|
#define LED_NODE DT_ALIAS(led0)
|
||||||
#if !DT_NODE_HAS_STATUS(LED_NODE, okay)
|
|
||||||
#error "led0 not enabled in devicetree"
|
#define UART_DEVICE_NODE DT_CHOSEN(zephyr_shell_uart)
|
||||||
#endif
|
|
||||||
|
#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 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)
|
int main(void)
|
||||||
{
|
{
|
||||||
printk("app started\n");
|
if (!device_is_ready(uart))
|
||||||
|
|
||||||
if (!gpio_is_ready_dt(&led))
|
|
||||||
{
|
{
|
||||||
printk("LED GPIO not ready\n");
|
printk("UART not ready\n");
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
|
// Set up interrupt-driven RX
|
||||||
if (ret < 0)
|
uart_irq_callback_set(uart, uart_cb);
|
||||||
{
|
uart_irq_rx_enable(uart);
|
||||||
printk("LED GPIO configure failed: %d\n", ret);
|
|
||||||
|
// 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;
|
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))
|
||||||
|
{
|
||||||
|
if (uart_fifo_read(dev, &byte, 1) == 1)
|
||||||
|
{
|
||||||
|
ring_buf_put(&rx_buf, &byte, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char incoming;
|
// wake up thread
|
||||||
int i = 0;
|
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)
|
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