diff --git a/extras/stdin_uart_interrupt/stdin_uart_interrupt.c b/extras/stdin_uart_interrupt/stdin_uart_interrupt.c index 194fdda..71d2efc 100644 --- a/extras/stdin_uart_interrupt/stdin_uart_interrupt.c +++ b/extras/stdin_uart_interrupt/stdin_uart_interrupt.c @@ -43,6 +43,8 @@ static SemaphoreHandle_t uart0_sem = NULL; static bool inited = false; static void uart0_rx_init(void); +static int uart0_nonblock; +static TickType_t uart0_vtime; IRAM void uart0_rx_handler(void *arg) { @@ -75,6 +77,20 @@ uint32_t uart0_num_char(void) return count; } +int uart0_set_nonblock(int nonblock) +{ + int current = uart0_nonblock; + uart0_nonblock = nonblock; + return current; +} + +TickType_t uart0_set_vtime(TickType_t ticks) +{ + TickType_t current = uart0_vtime; + uart0_vtime = ticks; + return current; +} + // _read_stdin_r in core/newlib_syscalls.c will be skipped by the linker in favour // of this function long _read_stdin_r(struct _reent *r, int fd, char *ptr, int len) @@ -83,7 +99,21 @@ long _read_stdin_r(struct _reent *r, int fd, char *ptr, int len) for(int i = 0; i < len; i++) { if (!(UART(UART0).STATUS & (UART_STATUS_RXFIFO_COUNT_M << UART_STATUS_RXFIFO_COUNT_S))) { _xt_isr_unmask(1 << INUM_UART); - if (!xSemaphoreTake(uart0_sem, portMAX_DELAY)) { + if (uart0_nonblock) { + if (i > 0) { + return i; + } + r->_errno = EAGAIN; + return -1; + } + if (uart0_vtime) { + if (!xSemaphoreTake(uart0_sem, uart0_vtime)) { + if (i > 0) { + return i; + } + return 0; + } + } else if (!xSemaphoreTake(uart0_sem, portMAX_DELAY)) { printf("\nFailed to get sem\n"); } } diff --git a/extras/stdin_uart_interrupt/stdin_uart_interrupt.h b/extras/stdin_uart_interrupt/stdin_uart_interrupt.h index 05652bb..b15278b 100644 --- a/extras/stdin_uart_interrupt/stdin_uart_interrupt.h +++ b/extras/stdin_uart_interrupt/stdin_uart_interrupt.h @@ -27,6 +27,16 @@ #include -// Return number of characters waiting in UART0 +/* Return number of characters waiting in UART0. */ uint32_t uart0_num_char(void); + +/* Set UART0 input to nonblocking or blocking, returning the old state. */ +int uart0_set_nonblock(int); + +/* Set the UART0 input wait time in ticks, or zero to wait indefinitely, + * returning the old wait time. The wait time is only used when the input is + * blocking. + */ +TickType_t uart0_set_vtime(TickType_t ticks); + #endif