summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Staaf <robotboy@chromium.org>2015-02-18 10:25:45 -0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-02-24 03:08:07 +0000
commitd2964ba0cf936dc46da3b8f102a420483d0e69d2 (patch)
tree014f73cb92cb11f4de7242423b345474e041dc5b
parenta8628526a3a4790a1890ecffc6df1d42644697c8 (diff)
downloadchrome-ec-d2964ba0cf936dc46da3b8f102a420483d0e69d2.tar.gz
USART: Add STM32F3 support and fix STM32F baud rate bug
Previously the STM32F3 support was non-functional due to it being a cut and paste of the STM32F0, and the clocks are not set up the same way on the two platforms. Also, the STM32F initialization code was incorrectly calling the F0/L buad rate setup code. This change has the variant specific USART code pass the input frequency to the baud rate divisor clock to the baud rate setup code, instead of that code calling clock_get_freq() to determine the input clock frequency. This is required because the STM32F3 is not configured such that the clock_get_freq value and the input to the USART baud rate divisor match. Signed-off-by: Anton Staaf <robotboy@chromium.org> BRANCH=None BUG=None TEST=make buildall -j Verify USART works on discovery as well as Ryu Change-Id: I71248d83b53969d0e7020747a9bb9570803f30ac Reviewed-on: https://chromium-review.googlesource.com/250920 Reviewed-by: Vic Yang <victoryang@chromium.org> Trybot-Ready: Anton Staaf <robotboy@chromium.org> Tested-by: Anton Staaf <robotboy@chromium.org> Commit-Queue: Anton Staaf <robotboy@chromium.org>
-rw-r--r--chip/stm32/usart-stm32f.c5
-rw-r--r--chip/stm32/usart-stm32f0.c5
-rw-r--r--[l---------]chip/stm32/usart-stm32f3.c108
-rw-r--r--chip/stm32/usart-stm32f3.h20
-rw-r--r--chip/stm32/usart-stm32l.c5
-rw-r--r--chip/stm32/usart.c9
-rw-r--r--chip/stm32/usart.h6
7 files changed, 143 insertions, 15 deletions
diff --git a/chip/stm32/usart-stm32f.c b/chip/stm32/usart-stm32f.c
index 918b98b96e..276e1d7193 100644
--- a/chip/stm32/usart-stm32f.c
+++ b/chip/stm32/usart-stm32f.c
@@ -4,6 +4,7 @@
*/
#include "usart-stm32f.h"
+#include "clock.h"
#include "common.h"
#include "hooks.h"
#include "registers.h"
@@ -27,7 +28,7 @@ static void usart_variant_enable(struct usart_config const *config)
*/
configs[config->hw->index] = config;
- usart_set_baud_f0_l(config);
+ usart_set_baud_f(config, clock_get_freq());
task_enable_irq(config->hw->irq);
}
@@ -50,7 +51,7 @@ static void freq_change(void)
for (i = 0; i < ARRAY_SIZE(configs); ++i)
if (configs[i])
- usart_set_baud_f(configs[i]);
+ usart_set_baud_f(configs[i], clock_get_freq());
}
DECLARE_HOOK(HOOK_FREQ_CHANGE, freq_change, HOOK_PRIO_DEFAULT);
diff --git a/chip/stm32/usart-stm32f0.c b/chip/stm32/usart-stm32f0.c
index d0688d4d9e..4351966da6 100644
--- a/chip/stm32/usart-stm32f0.c
+++ b/chip/stm32/usart-stm32f0.c
@@ -4,6 +4,7 @@
*/
#include "usart-stm32f0.h"
+#include "clock.h"
#include "common.h"
#include "hooks.h"
#include "registers.h"
@@ -27,7 +28,7 @@ static void usart_variant_enable(struct usart_config const *config)
*/
configs[config->hw->index] = config;
- usart_set_baud_f0_l(config);
+ usart_set_baud_f0_l(config, clock_get_freq());
task_enable_irq(config->hw->irq);
}
@@ -60,7 +61,7 @@ static void freq_change(void)
for (i = 0; i < ARRAY_SIZE(configs); ++i)
if (configs[i])
- usart_set_baud_f0_l(configs[i]);
+ usart_set_baud_f0_l(configs[i], 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 a2f89b48b1..58eb500b1d 120000..100644
--- a/chip/stm32/usart-stm32f3.c
+++ b/chip/stm32/usart-stm32f3.c
@@ -1 +1,107 @@
-usart-stm32f0.c \ No newline at end of file
+/* Copyright 2015 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "usart-stm32f3.h"
+
+#include "common.h"
+#include "hooks.h"
+#include "registers.h"
+#include "task.h"
+#include "util.h"
+
+/*
+ * This configs array stores the currently active usart_config structure for
+ * each USART, an entry will be NULL if no USART driver is initialized for the
+ * corresponding hardware instance.
+ */
+static struct usart_config const *configs[STM32_USARTS_MAX];
+
+static void usart_variant_enable(struct usart_config const *config)
+{
+ configs[config->hw->index] = config;
+
+ /*
+ * All three USARTS are clocked from the HSI(8MHz) source. This is
+ * done because the clock sources elsewhere are setup so that the result
+ * of clock_get_freq() is not the input clock frequency to the USARTs
+ * baud rate divisors.
+ */
+ STM32_RCC_CFGR3 |= 0x000f0003;
+
+ usart_set_baud_f0_l(config, 8000000);
+
+ task_enable_irq(config->hw->irq);
+}
+
+static void usart_variant_disable(struct usart_config const *config)
+{
+ task_disable_irq(config->hw->irq);
+
+ configs[config->hw->index] = NULL;
+}
+
+static struct usart_hw_ops const usart_variant_hw_ops = {
+ .enable = usart_variant_enable,
+ .disable = usart_variant_disable,
+};
+
+/*
+ * USART interrupt bindings. These functions can not be defined as static or
+ * they will be removed by the linker because of the way that DECLARE_IRQ works.
+ */
+#if defined(CONFIG_STREAM_USART1)
+struct usart_hw_config const usart1_hw = {
+ .index = 0,
+ .base = STM32_USART1_BASE,
+ .irq = STM32_IRQ_USART1,
+ .clock_register = &STM32_RCC_APB2ENR,
+ .clock_enable = STM32_RCC_PB2_USART1,
+ .ops = &usart_variant_hw_ops,
+};
+
+void usart1_interrupt(void)
+{
+ usart_interrupt(configs[0]);
+}
+
+DECLARE_IRQ(STM32_IRQ_USART1, usart1_interrupt, 2);
+#endif
+
+#if defined(CONFIG_STREAM_USART2)
+struct usart_hw_config const usart2_hw = {
+ .index = 1,
+ .base = STM32_USART2_BASE,
+ .irq = STM32_IRQ_USART2,
+ .clock_register = &STM32_RCC_APB1ENR,
+ .clock_enable = STM32_RCC_PB1_USART2,
+ .ops = &usart_variant_hw_ops,
+};
+
+void usart2_interrupt(void)
+{
+ usart_interrupt(configs[1]);
+}
+
+DECLARE_IRQ(STM32_IRQ_USART2, usart2_interrupt, 2);
+#endif
+
+#if defined(CONFIG_STREAM_USART3)
+struct usart_hw_config const usart3_hw = {
+ .index = 2,
+ .base = STM32_USART3_BASE,
+ .irq = STM32_IRQ_USART3,
+ .clock_register = &STM32_RCC_APB1ENR,
+ .clock_enable = STM32_RCC_PB1_USART3,
+ .ops = &usart_variant_hw_ops,
+};
+#endif
+
+#if defined(CONFIG_STREAM_USART3)
+void usart3_interrupt(void)
+{
+ usart_interrupt(configs[2]);
+}
+
+DECLARE_IRQ(STM32_IRQ_USART3, usart3_interrupt, 2);
+#endif
diff --git a/chip/stm32/usart-stm32f3.h b/chip/stm32/usart-stm32f3.h
new file mode 100644
index 0000000000..ebf972aab9
--- /dev/null
+++ b/chip/stm32/usart-stm32f3.h
@@ -0,0 +1,20 @@
+/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef CHIP_STM32_USART_STM32F3_H
+#define CHIP_STM32_USART_STM32F3_H
+
+#include "usart.h"
+
+#define STM32_USARTS_MAX 3
+
+/*
+ * The STM32F3 series can have as many as three UARTS. These are the HW configs
+ * for those UARTS. They can be used to initialize STM32 generic UART configs.
+ */
+extern struct usart_hw_config const usart1_hw;
+extern struct usart_hw_config const usart2_hw;
+extern struct usart_hw_config const usart3_hw;
+
+#endif /* CHIP_STM32_USART_STM32F3_H */
diff --git a/chip/stm32/usart-stm32l.c b/chip/stm32/usart-stm32l.c
index 6725df3c14..0fd98df7c0 100644
--- a/chip/stm32/usart-stm32l.c
+++ b/chip/stm32/usart-stm32l.c
@@ -4,6 +4,7 @@
*/
#include "usart-stm32l.h"
+#include "clock.h"
#include "common.h"
#include "hooks.h"
#include "registers.h"
@@ -30,7 +31,7 @@ static void usart_variant_enable(struct usart_config const *config)
*/
configs[config->hw->index] = config;
- usart_set_baud_f0_l(config);
+ usart_set_baud_f0_l(config, clock_get_freq());
task_enable_irq(config->hw->irq);
}
@@ -53,7 +54,7 @@ static void freq_change(void)
for (i = 0; i < ARRAY_SIZE(configs); ++i)
if (configs[i])
- usart_set_baud_f0_l(configs[i]);
+ usart_set_baud_f0_l(configs[i], 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 29cb0b705f..d97eb45565 100644
--- a/chip/stm32/usart.c
+++ b/chip/stm32/usart.c
@@ -6,7 +6,6 @@
/* USART driver for Chrome EC */
#include "atomic.h"
-#include "clock.h"
#include "common.h"
#include "gpio.h"
#include "registers.h"
@@ -117,9 +116,9 @@ void usart_shutdown(struct usart_config const *config)
config->hw->ops->disable(config);
}
-void usart_set_baud_f0_l(struct usart_config const *config)
+void usart_set_baud_f0_l(struct usart_config const *config, int frequency_hz)
{
- int div = DIV_ROUND_NEAREST(clock_get_freq(), config->baud);
+ int div = DIV_ROUND_NEAREST(frequency_hz, config->baud);
intptr_t base = config->hw->base;
if (div / 16 > 0) {
@@ -139,9 +138,9 @@ void usart_set_baud_f0_l(struct usart_config const *config)
}
}
-void usart_set_baud_f(struct usart_config const *config)
+void usart_set_baud_f(struct usart_config const *config, int frequency_hz)
{
- int div = DIV_ROUND_NEAREST(clock_get_freq(), config->baud);
+ int div = DIV_ROUND_NEAREST(frequency_hz, config->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 8fff29288c..3293dd5722 100644
--- a/chip/stm32/usart.h
+++ b/chip/stm32/usart.h
@@ -177,9 +177,9 @@ void usart_interrupt(struct usart_config const *config);
/*
* These are HW specific baud rate calculation and setting functions that the
* peripheral variant code uses during initialization and clock frequency
- * change.
+ * change. The baud rate divisor input frequency is passed in Hertz.
*/
-void usart_set_baud_f0_l(struct usart_config const *config);
-void usart_set_baud_f(struct usart_config const *config);
+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);
#endif /* CHIP_STM32_USART_H */