diff --git a/include/console.h b/include/console.h index 437609fe3c..599036bdc7 100644 --- a/include/console.h +++ b/include/console.h @@ -21,6 +21,7 @@ struct tty_serial { u8_t *rx_ringbuf; u32_t rx_ringbuf_sz; u16_t rx_get, rx_put; + s32_t rx_timeout; u8_t *tx_ringbuf; u32_t tx_ringbuf_sz; @@ -47,13 +48,28 @@ 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); +/** + * @brief Set receive timeout for tty device. + * + * Set timeout for getchar() operation. Default timeout after + * device initialization is K_FOREVER. + * + * @param tty tty device structure + * @param timeout timeout in milliseconds, or K_FOREVER, or K_NO_WAIT + */ +static inline void tty_set_rx_timeout(struct tty_serial *tty, s32_t timeout) +{ + tty->rx_timeout = timeout; +} /** * @brief Input a character from a tty device. * * @param tty tty device structure + * @return >=0, an input character + * <0, an error (e.g. -EAGAIN if timeout expired) */ -u8_t tty_getchar(struct tty_serial *tty); +int tty_getchar(struct tty_serial *tty); /** * @brief Output a character from to tty device. diff --git a/subsys/console/getchar.c b/subsys/console/getchar.c index 6b36d12a35..6b313563be 100644 --- a/subsys/console/getchar.c +++ b/subsys/console/getchar.c @@ -20,7 +20,8 @@ int console_putchar(char c) u8_t console_getchar(void) { - return tty_getchar(&console_serial); + /* Console works in blocking mode, so we don't expect an error here */ + return (u8_t)tty_getchar(&console_serial); } void console_init(void) diff --git a/subsys/console/tty.c b/subsys/console/tty.c index 5f004f542b..0d916c7d92 100644 --- a/subsys/console/tty.c +++ b/subsys/console/tty.c @@ -91,12 +91,16 @@ int tty_putchar(struct tty_serial *tty, u8_t c) return 0; } -u8_t tty_getchar(struct tty_serial *tty) +int tty_getchar(struct tty_serial *tty) { unsigned int key; u8_t c; + int res; - k_sem_take(&tty->rx_sem, K_FOREVER); + res = k_sem_take(&tty->rx_sem, tty->rx_timeout); + if (res < 0) { + return res; + } key = irq_lock(); c = tty->rx_ringbuf[tty->rx_get++]; @@ -120,6 +124,8 @@ void tty_init(struct tty_serial *tty, struct device *uart_dev, tty->rx_get = tty->rx_put = tty->tx_get = tty->tx_put = 0; k_sem_init(&tty->rx_sem, 0, UINT_MAX); + tty->rx_timeout = K_FOREVER; + uart_irq_callback_user_data_set(uart_dev, tty_uart_isr, tty); uart_irq_rx_enable(uart_dev); }