Skip to content

Instantly share code, notes, and snippets.

@fabiojmendes
Created December 4, 2021 05:46
Show Gist options
  • Save fabiojmendes/ba2111d82d95177585e222b72518514d to your computer and use it in GitHub Desktop.
Save fabiojmendes/ba2111d82d95177585e222b72518514d to your computer and use it in GitHub Desktop.
Playing around with interrupt driver uarts in Zephyr
#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