diff --git a/subsys/console/getchar.c b/subsys/console/getchar.c index e351d23b370..564f99c5cc8 100644 --- a/subsys/console/getchar.c +++ b/subsys/console/getchar.c @@ -11,27 +11,31 @@ #include #include -#if (CONFIG_CONSOLE_GETCHAR_BUFSIZE & (CONFIG_CONSOLE_GETCHAR_BUFSIZE - 1)) != 0 -#error CONFIG_CONSOLE_GETCHAR_BUFSIZE must be power of 2 -#endif +struct tty_serial { + struct device *uart_dev; -#if (CONFIG_CONSOLE_PUTCHAR_BUFSIZE & (CONFIG_CONSOLE_PUTCHAR_BUFSIZE - 1)) != 0 -#error CONFIG_CONSOLE_PUTCHAR_BUFSIZE must be power of 2 -#endif + struct k_sem rx_sem; + u8_t *rx_ringbuf; + u32_t rx_ringbuf_sz; + u16_t rx_get, rx_put; -static K_SEM_DEFINE(rx_sem, 0, UINT_MAX); -static u8_t rx_ringbuf[CONFIG_CONSOLE_GETCHAR_BUFSIZE]; -static u8_t rx_get, rx_put; + u8_t *tx_ringbuf; + u32_t tx_ringbuf_sz; + u16_t tx_get, tx_put; +}; -static u8_t tx_ringbuf[CONFIG_CONSOLE_PUTCHAR_BUFSIZE]; -static u8_t tx_get, tx_put; +static u8_t console_rxbuf[CONFIG_CONSOLE_GETCHAR_BUFSIZE]; +static u8_t console_txbuf[CONFIG_CONSOLE_PUTCHAR_BUFSIZE]; -static struct device *uart_dev; +static int tty_irq_input_hook(struct tty_serial *tty, u8_t c); -static int console_irq_input_hook(u8_t c); +static struct tty_serial console_serial; -static void uart_isr(struct device *dev) +static void tty_uart_isr(void *user_data) { + struct tty_serial *tty = user_data; + struct device *dev = tty->uart_dev; + uart_irq_update(dev); if (uart_irq_rx_ready(dev)) { @@ -41,78 +45,119 @@ static void uart_isr(struct device *dev) if (uart_fifo_read(dev, &c, 1) == 0) { break; } - console_irq_input_hook(c); + tty_irq_input_hook(tty, c); } } if (uart_irq_tx_ready(dev)) { - if (tx_get == tx_put) { + if (tty->tx_get == tty->tx_put) { /* Output buffer empty, don't bother * us with tx interrupts */ uart_irq_tx_disable(dev); } else { - uart_fifo_fill(dev, &tx_ringbuf[tx_get++], 1); - tx_get &= CONFIG_CONSOLE_PUTCHAR_BUFSIZE - 1; + uart_fifo_fill(dev, &tty->tx_ringbuf[tty->tx_get++], 1); + if (tty->tx_get >= tty->tx_ringbuf_sz) { + tty->tx_get = 0; + } } } } -static int console_irq_input_hook(u8_t c) +static int tty_irq_input_hook(struct tty_serial *tty, u8_t c) { - int rx_next = (rx_put + 1) & (CONFIG_CONSOLE_GETCHAR_BUFSIZE - 1); + int rx_next = tty->rx_put + 1; + if (rx_next >= tty->rx_ringbuf_sz) { + rx_next = 0; + } - if (rx_next == rx_get) { + if (rx_next == tty->rx_get) { /* Try to give a clue to user that some input was lost */ console_putchar('~'); console_putchar('\n'); return 1; } - rx_ringbuf[rx_put] = c; - rx_put = rx_next; - k_sem_give(&rx_sem); + tty->rx_ringbuf[tty->rx_put] = c; + tty->rx_put = rx_next; + k_sem_give(&tty->rx_sem); return 1; } -int console_putchar(char c) +int tty_putchar(struct tty_serial *tty, char c) { unsigned int key; int tx_next; key = irq_lock(); - tx_next = (tx_put + 1) & (CONFIG_CONSOLE_PUTCHAR_BUFSIZE - 1); - if (tx_next == tx_get) { + tx_next = tty->tx_put + 1; + if (tx_next >= tty->tx_ringbuf_sz) { + tx_next = 0; + } + if (tx_next == tty->tx_get) { irq_unlock(key); return -1; } - tx_ringbuf[tx_put] = (u8_t)c; - tx_put = tx_next; + tty->tx_ringbuf[tty->tx_put] = (u8_t)c; + tty->tx_put = tx_next; irq_unlock(key); - uart_irq_tx_enable(uart_dev); + uart_irq_tx_enable(tty->uart_dev); return 0; } -u8_t console_getchar(void) +u8_t tty_getchar(struct tty_serial *tty) { unsigned int key; u8_t c; - k_sem_take(&rx_sem, K_FOREVER); + k_sem_take(&tty->rx_sem, K_FOREVER); + key = irq_lock(); - c = rx_ringbuf[rx_get++]; - rx_get &= CONFIG_CONSOLE_GETCHAR_BUFSIZE - 1; + c = tty->rx_ringbuf[tty->rx_get++]; + if (tty->rx_get >= tty->rx_ringbuf_sz) { + tty->rx_get = 0; + } irq_unlock(key); return c; } -void console_init(void) +void tty_init(struct tty_serial *tty, struct device *uart_dev, + u8_t *rxbuf, u16_t rxbuf_sz, + u8_t *txbuf, u16_t txbuf_sz) { - uart_dev = device_get_binding(CONFIG_UART_CONSOLE_ON_DEV_NAME); - uart_irq_callback_set(uart_dev, uart_isr); + tty->uart_dev = uart_dev; + tty->rx_ringbuf = rxbuf; + tty->rx_ringbuf_sz = rxbuf_sz; + tty->tx_ringbuf = txbuf; + tty->tx_ringbuf_sz = txbuf_sz; + tty->rx_get = tty->rx_put = tty->tx_get = tty->tx_put = 0; + k_sem_init(&tty->rx_sem, 0, UINT_MAX); + + uart_irq_callback_user_data_set(uart_dev, tty_uart_isr, tty); uart_irq_rx_enable(uart_dev); } + + +int console_putchar(char c) +{ + return tty_putchar(&console_serial, c); +} + +u8_t console_getchar(void) +{ + return tty_getchar(&console_serial); +} + +void console_init(void) +{ + struct device *uart_dev; + + uart_dev = device_get_binding(CONFIG_UART_CONSOLE_ON_DEV_NAME); + tty_init(&console_serial, uart_dev, + console_rxbuf, sizeof(console_rxbuf), + console_txbuf, sizeof(console_txbuf)); +}