summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@chromium.org>2018-08-27 16:05:09 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-08-29 11:15:45 -0700
commit7eb9ff3cfcf4b96356050da66bd957225bef6044 (patch)
tree62b5f35d135e99fa14e582d3487fabb6fa41aab2
parent63fd7e18588023b2940167b686611e609354b78a (diff)
downloadchrome-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.c35
-rw-r--r--chip/stm32/usart-stm32f0.c10
-rw-r--r--chip/stm32/usart-stm32f3.c2
-rw-r--r--chip/stm32/usart-stm32l.c5
-rw-r--r--chip/stm32/usart.c10
-rw-r--r--chip/stm32/usart.h13
-rw-r--r--chip/stm32/usb-stream.c5
-rw-r--r--chip/stm32/usb-stream.h7
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);