diff --git a/chip/g/uartn.c b/chip/g/uartn.c index c534705eb3..a2d29e8053 100644 --- a/chip/g/uartn.c +++ b/chip/g/uartn.c @@ -147,6 +147,15 @@ void uartn_init(int uart) */ GR_UART_FIFO(uart) = 0x63; + /* + * To reduce the number of UART RX interrupts on the peripheral UARTS, + * set the FIFO RXILVL to only trigger rx interrupts every 4 characters. + * + * Reset the RX FIFO. + */ + if (uart) + GR_UART_FIFO(uart) |= 0x7; + /* enable RX interrupts in block */ /* Note: doesn't do anything unless turned on in NVIC */ GR_UART_ICTRL(uart) = 0x02; diff --git a/chip/g/usart.c b/chip/g/usart.c index 0d22b94bfc..6c39701178 100644 --- a/chip/g/usart.c +++ b/chip/g/usart.c @@ -5,6 +5,7 @@ #include "queue.h" #include "queue_policies.h" +#include "timer.h" #include "uartn.h" #include "usart.h" #include "usb-stream.h" @@ -29,12 +30,15 @@ static struct queue const ec_uart_to_usb = static struct queue const ec_usb_to_uart = QUEUE_DIRECT(QUEUE_SIZE, uint8_t, ec_usb.producer, ec_uart.consumer); -struct usart_config const ap_uart = USART_CONFIG(UART_AP, - ap_uart_to_usb, - ap_usb_to_uart); -struct usart_config const ec_uart = USART_CONFIG(UART_EC, - ec_uart_to_usb, - ec_usb_to_uart); +USART_CONFIG(ec_uart, + UART_EC, + ec_uart_to_usb, + ec_usb_to_uart); +USART_CONFIG(ap_uart, + UART_AP, + ap_uart_to_usb, + ap_usb_to_uart); + USB_STREAM_CONFIG(ap_usb, USB_IFACE_AP, USB_STR_AP_NAME, @@ -64,6 +68,13 @@ void get_data_from_usb(struct usart_config const *config) /* If output buffer is empty, disable transmit interrupt */ if (!queue_count(uart_out)) uartn_tx_stop(config->uart); + + /* + * Make sure rx fifo is cleared after any input to the console to ensure + * user will be able to see their input as they are typing instead of + * only when the RX FIFO reaches the level set by RXILVL. + */ + hook_call_deferred(config->deferred, 1 * MSEC); } void send_data_to_usb(struct usart_config const *config) diff --git a/chip/g/usart.h b/chip/g/usart.h index 79616a48e0..133dc7a3af 100644 --- a/chip/g/usart.h +++ b/chip/g/usart.h @@ -16,6 +16,8 @@ struct usart_config { struct producer const producer; struct consumer const consumer; + + const struct deferred_data *deferred; }; extern struct consumer_ops const uart_consumer_ops; @@ -41,14 +43,17 @@ extern struct producer_ops const uart_producer_ops; GR_UART_ISTATECLR(NAME.uart) = \ GC_UART_ISTATECLR_RX_MASK; \ /* Read input FIFO until empty */ \ - send_data_to_usb(&NAME); \ + hook_call_deferred(NAME.deferred, 0); \ } -#define USART_CONFIG(UART, \ +#define USART_CONFIG(NAME, \ + UART, \ RX_QUEUE, \ TX_QUEUE) \ - ((struct usart_config const) { \ + static void CONCAT2(NAME, _deferred_)(void); \ + DECLARE_DEFERRED(CONCAT2(NAME, _deferred_)); \ + struct usart_config const NAME = { \ .uart = UART, \ .consumer = { \ .queue = &TX_QUEUE, \ @@ -58,7 +63,12 @@ extern struct producer_ops const uart_producer_ops; .queue = &RX_QUEUE, \ .ops = &uart_producer_ops, \ }, \ - }) + .deferred = &CONCAT2(NAME, _deferred__data), \ + }; \ + static void CONCAT2(NAME, _deferred_)(void) \ + { \ + send_data_to_usb(&NAME); \ + } \ /* Read data from UART and add it to the producer queue */