diff options
-rw-r--r-- | board/cr50/board.c | 13 | ||||
-rw-r--r-- | chip/g/usart.c | 33 | ||||
-rw-r--r-- | chip/g/usart.h | 26 |
3 files changed, 42 insertions, 30 deletions
diff --git a/board/cr50/board.c b/board/cr50/board.c index ba09d5ad32..ab976dc29b 100644 --- a/board/cr50/board.c +++ b/board/cr50/board.c @@ -32,6 +32,7 @@ #include "trng.h" #include "uart_bitbang.h" #include "uartn.h" +#include "usart.h" #include "usb_descriptor.h" #include "usb_hid.h" #include "usb_i2c.h" @@ -103,12 +104,18 @@ struct uart_bitbang_properties bitbang_config = { .rx_pinmux_regval = GC_PINMUX_GPIO1_GPIO4_SEL, }; -extern struct deferred_data ec_uart_deferred__data; void ec_tx_cr50_rx(enum gpio_signal signal) { uart_bitbang_receive_char(UART_EC); - /* Let the USART module know that there's new bits to consume. */ - hook_call_deferred(&ec_uart_deferred__data, 0); + /* + * Let the USART module know that there's new bits to consume. + * + * When programming the EC in bitbang mode the rest of the system is + * shut down, there not much else to do, so this could be processed + * directly on interrupt context the same way it is done with EC + * console output. + */ + send_data_to_usb(&ec_uart); } const char *device_state_names[] = { diff --git a/chip/g/usart.c b/chip/g/usart.c index 5236acf202..6580ca9eb0 100644 --- a/chip/g/usart.c +++ b/chip/g/usart.c @@ -15,6 +15,11 @@ #define USE_UART_INTERRUPTS (!(defined(CONFIG_CUSTOMIZED_RO) && \ defined(SECTION_IS_RO))) #define QUEUE_SIZE 64 +/* + * Want to be able to accumulate larger amounts of data while USB is + * momentarily stalled for whatever reason. + */ +#define QUEUE_SIZE_UART_RX 512 #ifdef CONFIG_STREAM_SIGNATURE /* @@ -57,7 +62,8 @@ SIGNER_CONFIG(sig, stream_uart, sig_to_usb, ap_uart_output); #else /* Not CONFIG_STREAM_SIGNATURE */ static struct queue const ap_uart_output = - QUEUE_DIRECT(QUEUE_SIZE, uint8_t, ap_uart.producer, ap_usb.consumer); + QUEUE_DIRECT(QUEUE_SIZE_UART_RX, uint8_t, + ap_uart.producer, ap_usb.consumer); #endif static struct queue const ap_usb_to_uart = @@ -100,7 +106,8 @@ struct usb_stream_config const ec_usb; struct usart_config const ec_uart; static struct queue const ec_uart_to_usb = - QUEUE_DIRECT(QUEUE_SIZE, uint8_t, ec_uart.producer, ec_usb.consumer); + QUEUE_DIRECT(QUEUE_SIZE_UART_RX, uint8_t, + ec_uart.producer, ec_usb.consumer); static struct queue const ec_usb_to_uart = QUEUE_DIRECT(QUEUE_SIZE, uint8_t, ec_usb.producer, ec_uart.consumer); @@ -135,14 +142,26 @@ void get_data_from_usb(struct usart_config const *config) void send_data_to_usb(struct usart_config const *config) { + /* + * UART RX FIFO is 32 bytes in size, let's have little extra room so + * that we could catch up if we are draining the FIFO while the chip + * keeps receiving. + */ + uint8_t buffer[50]; + uint32_t i; + uint32_t room; struct queue const *uart_in = config->producer.queue; + int uart = config->uart; + + + i = 0; + room = MIN(sizeof(buffer), queue_space(uart_in)); - /* Copy input from buffer until RX fifo empty or the queue is full */ - while (uartn_rx_available(config->uart) && queue_space(uart_in)) { - int c = uartn_read_char(config->uart); + while ((i < room) && uartn_rx_available(uart)) + buffer[i++] = uartn_read_char(uart); - QUEUE_ADD_UNITS(uart_in, &c, 1); - } + if (i) + QUEUE_ADD_UNITS(uart_in, buffer, i); } static void uart_read(struct producer const *producer, size_t count) diff --git a/chip/g/usart.h b/chip/g/usart.h index 0be7a920bb..dacd7d1850 100644 --- a/chip/g/usart.h +++ b/chip/g/usart.h @@ -12,24 +12,13 @@ #ifndef __CROS_FORWARD_UART_H #define __CROS_FORWARD_UART_H -#ifdef CONFIG_STREAM_SIGNATURE -/* - * When configured for signing over streaming data, call the consumer handler - * directly to help avoid incoming uart overruns. - * Note this will run under interrupt handler so consumer beware. - */ #define CONFIGURE_INTERRUPTS__rx_int(NAME) send_data_to_usb(&NAME) -#else -#define CONFIGURE_INTERRUPTS__rx_int(NAME) hook_call_deferred(NAME.deferred, 0) -#endif struct usart_config { int uart; struct producer const producer; struct consumer const consumer; - - const struct deferred_data *deferred; }; extern struct consumer_ops const uart_consumer_ops; @@ -39,7 +28,7 @@ extern struct producer_ops const uart_producer_ops; TXINT) \ void CONCAT2(NAME, _rx_int_)(void); \ void CONCAT2(NAME, _tx_int_)(void); \ - DECLARE_IRQ(RXINT, CONCAT2(NAME, _rx_int_), 1); \ + DECLARE_IRQ(RXINT, CONCAT2(NAME, _rx_int_), 0); \ DECLARE_IRQ(TXINT, CONCAT2(NAME, _tx_int_), 1); \ void CONCAT2(NAME, _tx_int_)(void) \ { \ @@ -63,8 +52,6 @@ extern struct producer_ops const uart_producer_ops; UART, \ RX_QUEUE, \ TX_QUEUE) \ - static void CONCAT2(NAME, _deferred_)(void); \ - DECLARE_DEFERRED(CONCAT2(NAME, _deferred_)); \ struct usart_config const NAME = { \ .uart = UART, \ .consumer = { \ @@ -75,12 +62,7 @@ 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 */ @@ -88,4 +70,8 @@ void send_data_to_usb(struct usart_config const *config); /* Read data from the consumer queue and send it to the UART */ void get_data_from_usb(struct usart_config const *config); + +/* Helper for UART bitbang mode. */ +extern struct usart_config const ec_uart; + #endif /* __CROS_FORWARD_UART_H */ |