Created
December 4, 2021 05:46
-
-
Save fabiojmendes/ba2111d82d95177585e222b72518514d to your computer and use it in GitHub Desktop.
Playing around with interrupt driver uarts in Zephyr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string.h> | |
#include <zephyr.h> | |
#include <console/console.h> | |
#include <drivers/uart.h> | |
/* size of stack area used by each thread */ | |
#define STACKSIZE 1024 | |
#define UART_1 "UART_1" | |
#define TTY_BUF_SZ 512 | |
struct tty { | |
struct k_sem rx_sem; | |
size_t rx_put; | |
size_t rx_get; | |
size_t rx_buf_sz; | |
uint8_t rx_buf[TTY_BUF_SZ]; | |
}; | |
struct tty uart1_tty = {.rx_buf_sz = TTY_BUF_SZ}; | |
static void tty_uart_isr(const struct device *dev, void *user_data) { | |
struct tty *tty = user_data; | |
uart_irq_update(dev); | |
if (uart_irq_rx_ready(dev)) { | |
uint8_t c; | |
while (1) { | |
int read = uart_fifo_read(dev, &c, 1); | |
if (read == 0) { | |
break; | |
} | |
tty->rx_buf[tty->rx_put++] = c; | |
if (tty->rx_put >= tty->rx_buf_sz) { | |
tty->rx_put = 0; | |
} | |
k_sem_give(&tty->rx_sem); | |
} | |
} | |
} | |
static int tty_read_line(struct tty *tty, unsigned char *buf, size_t size) { | |
int bytes = 0; | |
for (int i = 0; i < size; i++) { | |
int res = k_sem_take(&tty->rx_sem, K_FOREVER); | |
if (res < 0) { | |
return res; | |
} | |
buf[i] = tty->rx_buf[tty->rx_get++]; | |
bytes++; | |
if (tty->rx_get >= tty->rx_buf_sz) { | |
tty->rx_get = 0; | |
} | |
if (buf[i] == '\n') { | |
break; | |
} | |
} | |
return bytes; | |
} | |
void main() { | |
const struct device *uart1 = device_get_binding(UART_1); | |
console_getline_init(); | |
k_sem_init(&uart1_tty.rx_sem, 0, K_SEM_MAX_LIMIT); | |
uart_irq_callback_user_data_set(uart1, tty_uart_isr, &uart1_tty); | |
uart_irq_rx_enable(uart1); | |
char rline[256]; | |
char *reset = "AT+RST\r\n"; | |
for (int i = 0; i < strlen(reset); i++) { | |
uart_poll_out(uart1, reset[i]); | |
} | |
while (true) { | |
int size = tty_read_line(&uart1_tty, rline, 256); | |
if (size) { | |
rline[size] = '\0'; | |
printk("%s", rline); | |
if (strcmp(rline, "ready\r\n") == 0) { | |
break; | |
} | |
} else { | |
k_yield(); | |
} | |
} | |
char *echo_off = "ATE0\r\n"; | |
for (int i = 0; i < strlen(echo_off); i++) { | |
uart_poll_out(uart1, echo_off[i]); | |
} | |
while (true) { | |
int size = tty_read_line(&uart1_tty, rline, 256); | |
if (size) { | |
rline[size] = '\0'; | |
printk("%s", rline); | |
if (strcmp(rline, "OK\r\n") == 0) { | |
break; | |
} | |
} else { | |
k_yield(); | |
} | |
} | |
printk("\n"); | |
while (true) { | |
printk("$ "); | |
char *line = console_getline(); | |
for (int i = 0; i < strlen(line); i++) { | |
uart_poll_out(uart1, line[i]); | |
} | |
uart_poll_out(uart1, '\r'); | |
uart_poll_out(uart1, '\n'); | |
while (true) { | |
int size = tty_read_line(&uart1_tty, rline, 256); | |
if (size) { | |
rline[size] = '\0'; | |
printk("%s", rline); | |
if (strcmp(rline, "OK\r\n") == 0 || strcmp(rline, "ERROR\r\n") == 0) { | |
break; | |
} | |
} else { | |
k_yield(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment