diff options
-rw-r--r-- | chip/host/uart.c | 60 | ||||
-rw-r--r-- | core/host/main.c | 3 |
2 files changed, 60 insertions, 3 deletions
diff --git a/chip/host/uart.c b/chip/host/uart.c index cbae79974b..9add50d4d2 100644 --- a/chip/host/uart.c +++ b/chip/host/uart.c @@ -5,10 +5,14 @@ /* UART driver for emulator */ +#include <pthread.h> #include <stdio.h> +#include <termio.h> +#include <unistd.h> #include "board.h" #include "config.h" +#include "queue.h" #include "task.h" #include "uart.h" @@ -16,8 +20,24 @@ static int stopped; static int int_disabled; static int init_done; +static pthread_t input_thread; + +#define INPUT_BUFFER_SIZE 16 +/* TODO: Guard these data with mutex lock when we have interrupt support. */ +static int char_available; +static char cached_char_buf[INPUT_BUFFER_SIZE]; +static struct queue cached_char = { + .buf_bytes = INPUT_BUFFER_SIZE, + .unit_bytes = sizeof(char), + .buf = cached_char_buf, +}; + static void trigger_interrupt(void) { + /* + * TODO: Check global interrupt status when we have + * interrupt support. + */ if (!int_disabled) uart_process(); } @@ -55,7 +75,7 @@ int uart_tx_ready(void) int uart_rx_available(void) { - return 0; + return char_available; } void uart_write_char(char c) @@ -66,8 +86,10 @@ void uart_write_char(char c) int uart_read_char(void) { - /* Should never be called for now */ - return 0; + char ret; + queue_remove_unit(&cached_char, &ret); + --char_available; + return ret; } void uart_disable_interrupt(void) @@ -80,7 +102,39 @@ void uart_enable_interrupt(void) int_disabled = 0; } +void *uart_monitor_stdin(void *d) +{ + struct termios org_settings, new_settings; + char buf[INPUT_BUFFER_SIZE]; + int rv; + + tcgetattr(0, &org_settings); + new_settings = org_settings; + new_settings.c_lflag &= ~(ECHO | ICANON); + new_settings.c_cc[VTIME] = 0; + new_settings.c_cc[VMIN] = 1; + + printf("Console input initialized\n"); + while (1) { + tcsetattr(0, TCSANOW, &new_settings); + rv = read(0, buf, INPUT_BUFFER_SIZE); + if (queue_has_space(&cached_char, rv)) + queue_add_units(&cached_char, buf, rv); + char_available = rv; + tcsetattr(0, TCSANOW, &org_settings); + /* + * TODO: Trigger emulated interrupt when we have + * interrupt support. Also, we will need a condition + * variable to indicate the character has been read. + */ + trigger_interrupt(); + } + + return 0; +} + void uart_init(void) { + pthread_create(&input_thread, NULL, uart_monitor_stdin, NULL); init_done = 1; } diff --git a/core/host/main.c b/core/host/main.c index ba8ec95dcf..f69107af4a 100644 --- a/core/host/main.c +++ b/core/host/main.c @@ -9,6 +9,7 @@ #include "hooks.h" #include "task.h" #include "timer.h" +#include "uart.h" int main(void) { @@ -18,6 +19,8 @@ int main(void) hook_init(); + uart_init(); + task_start(); return 0; |