diff options
author | Jes B. Klinke <jbk@chromium.org> | 2021-08-31 10:43:04 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-09-08 18:57:37 +0000 |
commit | c8e071566ceb60190120dbc7c0c0a681364cc5d9 (patch) | |
tree | 3676cde58c8806b2e7245605ee8a980357e5706d | |
parent | f2af0a3a74192876fc1b72706813d756393da167 (diff) | |
download | chrome-ec-c8e071566ceb60190120dbc7c0c0a681364cc5d9.tar.gz |
chip/stm32: UART declarations for STM32L5 series
STM32L5 can have up to four UARTs, one more than previous Lx series.
These files were copied from usart-stm32l.{h,c}, modified only by
making one more copy of the appropriate declarations.
BUG=b:192262089
TEST=Compile with hyperdebug board (from later in the chain)
BRANCH=none
Signed-off-by: Jes Bodi Klinke <jbk@chromium.org>
Change-Id: I8bd2d13de67fc74b59c16a79a87fd4615912be09
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3133814
Reviewed-by: Scott Collyer <scollyer@chromium.org>
-rw-r--r-- | chip/stm32/usart-stm32l5.c | 146 | ||||
-rw-r--r-- | chip/stm32/usart-stm32l5.h | 19 |
2 files changed, 164 insertions, 1 deletions
diff --git a/chip/stm32/usart-stm32l5.c b/chip/stm32/usart-stm32l5.c index 289ff67e22..0245718e21 100644 --- a/chip/stm32/usart-stm32l5.c +++ b/chip/stm32/usart-stm32l5.c @@ -2,5 +2,149 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ +#include "usart-stm32l.h" -#include "usart-stm32l.c" +#include "clock.h" +#include "common.h" +#include "compile_time_macros.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. + */ +#define STM32_USARTS_MAX 4 + +static struct usart_config const *configs[STM32_USARTS_MAX]; + +struct usart_configs usart_get_configs(void) +{ + return (struct usart_configs) {configs, ARRAY_SIZE(configs)}; +} + +static void usart_variant_enable(struct usart_config const *config) +{ + /* Use single-bit sampling */ + STM32_USART_CR3(config->hw->base) |= STM32_USART_CR3_ONEBIT; + + /* + * Make sure we register this config before enabling the HW. + * If we did it the other way around the FREQ_CHANGE hook could be + * called before we update the configs array and we would miss the + * clock frequency change event, leaving our baud rate divisor wrong. + */ + configs[config->hw->index] = config; + + usart_set_baud_f0_l(config, config->baud, clock_get_freq()); + + 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, +}; + +static void freq_change(void) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(configs); ++i) + if (configs[i]) + usart_set_baud_f0_l(configs[i], configs[i]->baud, + clock_get_freq()); +} + +DECLARE_HOOK(HOOK_FREQ_CHANGE, freq_change, HOOK_PRIO_DEFAULT); + +void usart_clear_tc(struct usart_config const *config) +{ + STM32_USART_SR(config->hw->base) &= ~STM32_USART_SR_TC; +} + +/* + * 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, +}; + +void usart3_interrupt(void) +{ + usart_interrupt(configs[2]); +} + +DECLARE_IRQ(STM32_IRQ_USART4, usart4_interrupt, 2); +#endif + +#if defined(CONFIG_STREAM_USART4) +struct usart_hw_config const usart4_hw = { + .index = 2, + .base = STM32_USART4_BASE, + .irq = STM32_IRQ_USART4, + .clock_register = &STM32_RCC_APB1ENR, + .clock_enable = STM32_RCC_PB1_USART4, + .ops = &usart_variant_hw_ops, +}; + +void usart4_interrupt(void) +{ + usart_interrupt(configs[2]); +} + +DECLARE_IRQ(STM32_IRQ_USART4, usart4_interrupt, 2); +#endif diff --git a/chip/stm32/usart-stm32l5.h b/chip/stm32/usart-stm32l5.h new file mode 100644 index 0000000000..564ffbc580 --- /dev/null +++ b/chip/stm32/usart-stm32l5.h @@ -0,0 +1,19 @@ +/* Copyright 2021 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 __CROS_EC_USART_STM32L5_H +#define __CROS_EC_USART_STM32L5_H + +#include "usart.h" + +/* + * The STM32L5 series can have as many as four 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; +extern struct usart_hw_config const usart4_hw; + +#endif /* __CROS_EC_USART_STM32L5_H */ |