diff options
author | Nicolas Boichat <drinkcat@chromium.org> | 2018-08-27 16:05:09 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-08-29 11:15:45 -0700 |
commit | 7eb9ff3cfcf4b96356050da66bd957225bef6044 (patch) | |
tree | 62b5f35d135e99fa14e582d3487fabb6fa41aab2 | |
parent | 63fd7e18588023b2940167b686611e609354b78a (diff) | |
download | chrome-ec-7eb9ff3cfcf4b96356050da66bd957225bef6044.tar.gz |
servo_micro: Allow setting the baud rate for usart
We set the baud rate in increments of 100 baud, to avoid
overflowing the 16-bit wValue integer (921600 is the highest we
are likely to use).
Also, increment the buffer size for USART3 to 1024 bytes. That
helps a bit to avoid losing characters, but we still can't keep
up if the host is printing at maximum speed.
BRANCH=servo
BUG=chromium:876651
TEST=baud usart2/3/4 115200 in servo_micro console
TEST=dut-control cpu_uart_baudrate:921600
seq 1 1000 shows numbers 1 to 226 before buffer overflows
Change-Id: Ifca266189f93def493f207dd29d2cceca4d8d68f
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1189782
Reviewed-by: Nick Sanders <nsanders@chromium.org>
-rw-r--r-- | board/servo_micro/board.c | 35 | ||||
-rw-r--r-- | chip/stm32/usart-stm32f0.c | 10 | ||||
-rw-r--r-- | chip/stm32/usart-stm32f3.c | 2 | ||||
-rw-r--r-- | chip/stm32/usart-stm32l.c | 5 | ||||
-rw-r--r-- | chip/stm32/usart.c | 10 | ||||
-rw-r--r-- | chip/stm32/usart.h | 13 | ||||
-rw-r--r-- | chip/stm32/usb-stream.c | 5 | ||||
-rw-r--r-- | chip/stm32/usb-stream.h | 7 |
8 files changed, 74 insertions, 13 deletions
diff --git a/board/servo_micro/board.c b/board/servo_micro/board.c index a665b3dfe8..a06978b84d 100644 --- a/board/servo_micro/board.c +++ b/board/servo_micro/board.c @@ -101,7 +101,7 @@ USB_STREAM_CONFIG_USART_IFACE(usart2_usb, static struct usart_config const usart3; struct usb_stream_config const usart3_usb; -static struct queue const usart3_to_usb = QUEUE_DIRECT(128, uint8_t, +static struct queue const usart3_to_usb = QUEUE_DIRECT(1024, uint8_t, usart3.producer, usart3_usb.consumer); static struct queue const usb_to_usart3 = QUEUE_DIRECT(64, uint8_t, usart3_usb.producer, usart3.consumer); @@ -203,6 +203,39 @@ DECLARE_CONSOLE_COMMAND(parity, command_uart_parity, "Set parity on uart"); /****************************************************************************** + * Set baud rate setting on usarts. + */ +static int command_uart_baud(int argc, char **argv) +{ + int baud = 0; + struct usart_config const *usart; + char *e; + + if ((argc < 2) || (argc > 3)) + return EC_ERROR_PARAM_COUNT; + + if (!strcasecmp(argv[1], "usart2")) + usart = &usart2; + else if (!strcasecmp(argv[1], "usart3")) + usart = &usart3; + else if (!strcasecmp(argv[1], "usart4")) + usart = &usart4; + else + return EC_ERROR_PARAM1; + + baud = strtoi(argv[2], &e, 0); + if (*e || baud < 0) + return EC_ERROR_PARAM2; + + usart_set_baud(usart, baud); + + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(baud, command_uart_baud, + "usart[2|3|4] rate", + "Set baud rate on uart"); + +/****************************************************************************** * Commands for sending the magic non-I2C handshake over I2C bus wires to an * ITE IT8320 EC chip to enable direct firmware update (DFU) over I2C mode. */ diff --git a/chip/stm32/usart-stm32f0.c b/chip/stm32/usart-stm32f0.c index 8ae2085498..54d68977ef 100644 --- a/chip/stm32/usart-stm32f0.c +++ b/chip/stm32/usart-stm32f0.c @@ -36,11 +36,16 @@ static void usart_variant_enable(struct usart_config const *config) */ configs[config->hw->index] = config; - usart_set_baud_f0_l(config, clock_get_freq()); + usart_set_baud(config, config->baud); task_enable_irq(config->hw->irq); } +void usart_set_baud(struct usart_config const *config, int baud) +{ + usart_set_baud_f0_l(config, baud, clock_get_freq()); +} + static void usart_variant_disable(struct usart_config const *config) { int index = config->hw->index; @@ -69,7 +74,8 @@ static void freq_change(void) for (i = 0; i < ARRAY_SIZE(configs); ++i) if (configs[i]) - usart_set_baud_f0_l(configs[i], clock_get_freq()); + usart_set_baud_f0_l(configs[i], configs[i]->baud, + clock_get_freq()); } DECLARE_HOOK(HOOK_FREQ_CHANGE, freq_change, HOOK_PRIO_DEFAULT); diff --git a/chip/stm32/usart-stm32f3.c b/chip/stm32/usart-stm32f3.c index a6c7fc8991..42a0cf310e 100644 --- a/chip/stm32/usart-stm32f3.c +++ b/chip/stm32/usart-stm32f3.c @@ -37,7 +37,7 @@ static void usart_variant_enable(struct usart_config const *config) */ STM32_RCC_CFGR3 |= 0x000f0003; - usart_set_baud_f0_l(config, 8000000); + usart_set_baud_f0_l(config, config->baud, 8000000); task_enable_irq(config->hw->irq); } diff --git a/chip/stm32/usart-stm32l.c b/chip/stm32/usart-stm32l.c index a42eab41ff..f57443cc96 100644 --- a/chip/stm32/usart-stm32l.c +++ b/chip/stm32/usart-stm32l.c @@ -39,7 +39,7 @@ static void usart_variant_enable(struct usart_config const *config) */ configs[config->hw->index] = config; - usart_set_baud_f0_l(config, clock_get_freq()); + usart_set_baud_f0_l(config, config->baud, clock_get_freq()); task_enable_irq(config->hw->irq); } @@ -62,7 +62,8 @@ static void freq_change(void) for (i = 0; i < ARRAY_SIZE(configs); ++i) if (configs[i]) - usart_set_baud_f0_l(configs[i], clock_get_freq()); + usart_set_baud_f0_l(configs[i], configs[i]->baud, + clock_get_freq()); } DECLARE_HOOK(HOOK_FREQ_CHANGE, freq_change, HOOK_PRIO_DEFAULT); diff --git a/chip/stm32/usart.c b/chip/stm32/usart.c index 90be4f6194..0ef357466c 100644 --- a/chip/stm32/usart.c +++ b/chip/stm32/usart.c @@ -86,9 +86,10 @@ void usart_shutdown(struct usart_config const *config) config->hw->ops->disable(config); } -void usart_set_baud_f0_l(struct usart_config const *config, int frequency_hz) +void usart_set_baud_f0_l(struct usart_config const *config, int baud, + int frequency_hz) { - int div = DIV_ROUND_NEAREST(frequency_hz, config->baud); + int div = DIV_ROUND_NEAREST(frequency_hz, baud); intptr_t base = config->hw->base; if (div / 16 > 0) { @@ -108,9 +109,10 @@ void usart_set_baud_f0_l(struct usart_config const *config, int frequency_hz) } } -void usart_set_baud_f(struct usart_config const *config, int frequency_hz) +void usart_set_baud_f(struct usart_config const *config, int baud, + int frequency_hz) { - int div = DIV_ROUND_NEAREST(frequency_hz, config->baud); + int div = DIV_ROUND_NEAREST(frequency_hz, baud); /* STM32F only supports x16 oversampling */ STM32_USART_BRR(config->hw->base) = div; diff --git a/chip/stm32/usart.h b/chip/stm32/usart.h index d218f64fd5..53b13762e9 100644 --- a/chip/stm32/usart.h +++ b/chip/stm32/usart.h @@ -201,8 +201,10 @@ void usart_interrupt(struct usart_config const *config); * peripheral variant code uses during initialization and clock frequency * change. The baud rate divisor input frequency is passed in Hertz. */ -void usart_set_baud_f0_l(struct usart_config const *config, int frequency_hz); -void usart_set_baud_f(struct usart_config const *config, int frequency_hz); +void usart_set_baud_f0_l(struct usart_config const *config, int baud, + int frequency_hz); +void usart_set_baud_f(struct usart_config const *config, int baud, + int frequency_hz); /* * Allow specification of parity for this usart. @@ -217,6 +219,13 @@ void usart_set_parity(struct usart_config const *config, int parity); int usart_get_parity(struct usart_config const *config); /* + * Set baud rate for this usart. Note that baud rate will get reset on + * core frequency change, so this only makes sense if the board never + * goes to deep idle. + */ +void usart_set_baud(struct usart_config const *config, int baud); + +/* * Different families provide different ways of clearing the transmit complete * flag. This function will be provided by the family specific implementation. */ diff --git a/chip/stm32/usb-stream.c b/chip/stm32/usb-stream.c index d66a5ae2a0..79e9e1ace5 100644 --- a/chip/stm32/usb-stream.c +++ b/chip/stm32/usb-stream.c @@ -164,9 +164,12 @@ int usb_usart_interface(struct usb_stream_config const *config, case USB_USART_SET_PARITY: usart_set_parity(usart, req.wValue); break; + case USB_USART_SET_BAUD: + usart_set_baud(usart, req.wValue * 100); + break; /* TODO(nsanders): support reading parity. */ - /* TODO(nsanders): support baud. */ + /* TODO(nsanders): support reading baud. */ default: return -1; } diff --git a/chip/stm32/usb-stream.h b/chip/stm32/usb-stream.h index f89d62a65c..af96db551d 100644 --- a/chip/stm32/usb-stream.h +++ b/chip/stm32/usb-stream.h @@ -277,6 +277,13 @@ enum usb_usart { USB_USART_REQ_BAUD = 2, USB_USART_SET_BAUD = 3, }; + +/* + * baud rate is req/set in multiples of 100, to avoid overflowing + * 16-bit integer. + */ +#define USB_USART_BAUD_MULTIPLIER 100 + int usb_usart_interface(struct usb_stream_config const *config, struct usart_config const *usart, int interface, usb_uint *rx_buf, usb_uint *tx_buf); |