diff options
author | Daisuke Nojiri <dnojiri@chromium.org> | 2016-04-20 14:49:56 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-04-25 16:49:02 -0700 |
commit | 40c02e3ff2477df1aca7657a92905816e5a13d0c (patch) | |
tree | 57f05231828259506bf8bfdd2c494e533715e01f /chip | |
parent | cb0d8108e5a5b630ec05a8d21a824cb601246bf5 (diff) | |
download | chrome-ec-40c02e3ff2477df1aca7657a92905816e5a13d0c.tar.gz |
Bring up STM32L476G-Eval
This patch adds initial set of files to bring up STM32L476G-Eval board.
BUG=none
BRANCH=tot
TEST=Tested console. make buildall && make tests
Change-Id: I0c0f73f31e84099746fced4214c5ed7f45468cef
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/340100
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r-- | chip/stm32/build.mk | 4 | ||||
-rw-r--r-- | chip/stm32/clock-stm32l4.c | 204 | ||||
-rw-r--r-- | chip/stm32/config-stm32l476.h | 20 | ||||
-rw-r--r-- | chip/stm32/config_chip.h | 4 | ||||
-rw-r--r-- | chip/stm32/dma.c | 4 | ||||
-rw-r--r-- | chip/stm32/gpio-stm32l4.c | 26 | ||||
-rw-r--r-- | chip/stm32/jtag-stm32l4.c | 21 | ||||
-rw-r--r-- | chip/stm32/registers.h | 87 | ||||
-rw-r--r-- | chip/stm32/system.c | 6 | ||||
-rw-r--r-- | chip/stm32/uart.c | 11 |
10 files changed, 371 insertions, 16 deletions
diff --git a/chip/stm32/build.mk b/chip/stm32/build.mk index f7af790555..9d76c03885 100644 --- a/chip/stm32/build.mk +++ b/chip/stm32/build.mk @@ -11,8 +11,8 @@ ifeq ($(CHIP_FAMILY),stm32f0) CORE:=cortex-m0 # Force ARMv6-M ISA used by the Cortex-M0 CFLAGS_CPU+=-march=armv6-m -mcpu=cortex-m0 -else ifeq ($(CHIP_FAMILY),stm32f3) -# STM32F3xx sub-family has a Cortex-M4 ARM core +else ifeq ($(CHIP_FAMILY),$(filter $(CHIP_FAMILY),stm32f3 stm32l4)) +# STM32F3xx and STM32L4xx sub-family has a Cortex-M4 ARM core CORE:=cortex-m # Allow the full Cortex-M4 instruction set CFLAGS_CPU+=-march=armv7e-m -mcpu=cortex-m4 diff --git a/chip/stm32/clock-stm32l4.c b/chip/stm32/clock-stm32l4.c new file mode 100644 index 0000000000..7cbd098a4d --- /dev/null +++ b/chip/stm32/clock-stm32l4.c @@ -0,0 +1,204 @@ +/* Copyright 2016 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. + */ + +/* Clocks and power management settings */ + +#include "chipset.h" +#include "clock.h" +#include "common.h" +#include "console.h" +#include "cpu.h" +#include "hooks.h" +#include "registers.h" +#include "util.h" + +/* High-speed oscillator is 16 MHz */ +#define HSI_CLOCK 16000000 +/* + * MSI is 2 MHz (default) 1 MHz, depending on ICSCR setting. We use 1 MHz + * because it's the lowest clock rate we can still run 115200 baud serial + * for the debug console. + */ +#define MSI_2MHZ_CLOCK (1 << 21) +#define MSI_1MHZ_CLOCK (1 << 20) + +enum clock_osc { + OSC_INIT = 0, /* Uninitialized */ + OSC_HSI, /* High-speed oscillator */ + OSC_MSI, /* Med-speed oscillator @ 1 MHz */ +}; + +static int freq; +static int current_osc; + +int clock_get_freq(void) +{ + return freq; +} + +void clock_wait_bus_cycles(enum bus_type bus, uint32_t cycles) +{ + volatile uint32_t dummy __attribute__((unused)); + + if (bus == BUS_AHB) { + while (cycles--) + dummy = STM32_DMA1_REGS->isr; + } else { /* APB */ + while (cycles--) + dummy = STM32_USART_BRR(STM32_USART1_BASE); + } +} + +/** + * Set which oscillator is used for the clock + * + * @param osc Oscillator to use + */ +static void clock_set_osc(enum clock_osc osc) +{ + if (osc == current_osc) + return; + + if (current_osc != OSC_INIT) + hook_notify(HOOK_PRE_FREQ_CHANGE); + + switch (osc) { + case OSC_HSI: + /* Ensure that HSI is ON */ + if (!(STM32_RCC_CR & STM32_RCC_CR_HSIRDY)) { + /* Enable HSI */ + STM32_RCC_CR |= STM32_RCC_CR_HSION; + /* Wait for HSI to be ready */ + while (!(STM32_RCC_CR & STM32_RCC_CR_HSIRDY)) + ; + } + + /* Disable LPSDSR */ + STM32_PWR_CR &= ~STM32_PWR_CR_LPSDSR; + + /* Switch to HSI */ + STM32_RCC_CFGR = STM32_RCC_CFGR_SW_HSI; + /* RM says to check SWS bits to make sure HSI is the sysclock */ + while ((STM32_RCC_CFGR & STM32_RCC_CFGR_SWS_MASK) != + STM32_RCC_CFGR_SWS_HSI) + ; + + /* Disable MSI */ + STM32_RCC_CR &= ~STM32_RCC_CR_MSION; + + freq = HSI_CLOCK; + break; + + case OSC_MSI: + /* Switch to MSI @ 1MHz */ + STM32_RCC_ICSCR = + (STM32_RCC_ICSCR & ~STM32_RCC_ICSCR_MSIRANGE_MASK) | + STM32_RCC_ICSCR_MSIRANGE_1MHZ; + /* Ensure that MSI is ON */ + if (!(STM32_RCC_CR & STM32_RCC_CR_MSIRDY)) { + /* Enable MSI */ + STM32_RCC_CR |= STM32_RCC_CR_MSION; + /* Wait for MSI to be ready */ + while (!(STM32_RCC_CR & STM32_RCC_CR_MSIRDY)) + ; + } + + /* Switch to MSI */ + STM32_RCC_CFGR = STM32_RCC_CFGR_SW_MSI; + /* RM says to check SWS bits to make sure MSI is the sysclock */ + while ((STM32_RCC_CFGR & STM32_RCC_CFGR_SWS_MASK) != + STM32_RCC_CFGR_SWS_MSI) + ; + + /* Disable HSI */ + STM32_RCC_CR &= ~STM32_RCC_CR_HSION; + + /* Enable LPSDSR */ + STM32_PWR_CR |= STM32_PWR_CR_LPSDSR; + + freq = MSI_1MHZ_CLOCK; + break; + + default: + break; + } + + /* Notify modules of frequency change unless we're initializing */ + if (current_osc != OSC_INIT) { + current_osc = osc; + hook_notify(HOOK_FREQ_CHANGE); + } else { + current_osc = osc; + } +} + +void clock_enable_module(enum module_id module, int enable) +{ + static uint32_t clock_mask; + int new_mask; + + if (enable) + new_mask = clock_mask | (1 << module); + else + new_mask = clock_mask & ~(1 << module); + + /* Only change clock if needed */ + if ((!!new_mask) != (!!clock_mask)) { + + /* Flush UART before switching clock speed */ + cflush(); + + clock_set_osc(new_mask ? OSC_HSI : OSC_MSI); + } + + clock_mask = new_mask; +} + +void clock_init(void) +{ + /* + * The initial state : + * SYSCLK from MSI (=2MHz), no divider on AHB, APB1, APB2 + * PLL unlocked, RTC enabled on LSE + */ + + /* Switch to high-speed oscillator */ + clock_set_osc(OSC_HSI); +} + +static void clock_chipset_startup(void) +{ + /* Return to full speed */ + clock_enable_module(MODULE_CHIPSET, 1); +} +DECLARE_HOOK(HOOK_CHIPSET_STARTUP, clock_chipset_startup, HOOK_PRIO_DEFAULT); +DECLARE_HOOK(HOOK_CHIPSET_RESUME, clock_chipset_startup, HOOK_PRIO_DEFAULT); + +static void clock_chipset_shutdown(void) +{ + /* Drop to lower clock speed if no other module requires full speed */ + clock_enable_module(MODULE_CHIPSET, 0); +} +DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, clock_chipset_shutdown, HOOK_PRIO_DEFAULT); +DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, clock_chipset_shutdown, HOOK_PRIO_DEFAULT); + +static int command_clock(int argc, char **argv) +{ + if (argc >= 2) { + if (!strcasecmp(argv[1], "hsi")) + clock_set_osc(OSC_HSI); + else if (!strcasecmp(argv[1], "msi")) + clock_set_osc(OSC_MSI); + else + return EC_ERROR_PARAM1; + } + + ccprintf("Clock frequency is now %d Hz\n", freq); + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(clock, command_clock, + "hsi | msi", + "Set clock frequency", + NULL); diff --git a/chip/stm32/config-stm32l476.h b/chip/stm32/config-stm32l476.h new file mode 100644 index 0000000000..9f6b35b8b1 --- /dev/null +++ b/chip/stm32/config-stm32l476.h @@ -0,0 +1,20 @@ +/* Copyright 2016 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. + */ + +/* Memory mapping */ +#define CONFIG_FLASH_SIZE 0x00100000 /* 1 MB */ +#define CONFIG_FLASH_BANK_SIZE 0x800 /* 2 kB */ +#define CONFIG_FLASH_ERASE_SIZE 0x800 /* 2 KB */ +#define CONFIG_FLASH_WRITE_SIZE 0x8 /* 64 bits (without 8 bits ECC) */ + +/* Ideal write size in page-mode */ +#define CONFIG_FLASH_WRITE_IDEAL_SIZE 0x100 /* 256 (32 double words) */ + +#define CONFIG_RAM_BASE 0x20000000 +/* Only using SRAM1. SRAM2 (32 KB) is ignored. */ +#define CONFIG_RAM_SIZE 0x00018000 /* 96 kB */ + +/* Number of IRQ vectors on the NVIC */ +#define CONFIG_IRQ_COUNT 82 diff --git a/chip/stm32/config_chip.h b/chip/stm32/config_chip.h index 87ebd21c09..80415e413a 100644 --- a/chip/stm32/config_chip.h +++ b/chip/stm32/config_chip.h @@ -23,7 +23,9 @@ #define CHIP_VARIANT_STM32F03X #endif -#if defined(CHIP_VARIANT_STM32L15X) +#if defined(CHIP_VARIANT_STM32L476) +#include "config-stm32l476.h" +#elif defined(CHIP_VARIANT_STM32L15X) #include "config-stm32l15x.h" #elif defined(CHIP_VARIANT_STM32L100) #include "config-stm32l100.h" diff --git a/chip/stm32/dma.c b/chip/stm32/dma.c index d169cf7f45..3b45544190 100644 --- a/chip/stm32/dma.c +++ b/chip/stm32/dma.c @@ -230,7 +230,11 @@ void dma_test(enum dma_channel channel) void dma_init(void) { +#ifdef CHIP_FAMILY_STM32L4 + STM32_RCC_AHB1ENR |= STM32_RCC_AHB1ENR_DMA1EN; +#else STM32_RCC_AHBENR |= STM32_RCC_HB_DMA1; +#endif #ifdef CHIP_FAMILY_STM32F3 STM32_RCC_AHBENR |= STM32_RCC_HB_DMA2; #endif diff --git a/chip/stm32/gpio-stm32l4.c b/chip/stm32/gpio-stm32l4.c new file mode 100644 index 0000000000..67df8ba157 --- /dev/null +++ b/chip/stm32/gpio-stm32l4.c @@ -0,0 +1,26 @@ +/* Copyright 2016 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. + */ + +/* GPIO module for Chrome EC */ + +#include "clock.h" +#include "common.h" +#include "registers.h" + +void gpio_enable_clocks(void) +{ + /* + * Enable all GPIOs clocks + * + * TODO(crosbug.com/p/23770): only enable the banks we need to, + * and support disabling some of them in low-power idle. + */ + STM32_RCC_AHB2ENR |= STM32_RCC_AHB2ENR_GPIOMASK; + + /* Delay 1 AHB clock cycle after the clock is enabled */ + clock_wait_bus_cycles(BUS_AHB, 1); +} + +#include "gpio-f0-l.c" diff --git a/chip/stm32/jtag-stm32l4.c b/chip/stm32/jtag-stm32l4.c new file mode 100644 index 0000000000..44fb9972e3 --- /dev/null +++ b/chip/stm32/jtag-stm32l4.c @@ -0,0 +1,21 @@ +/* Copyright 2016 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. + */ +/* Settings to enable JTAG debugging */ + +#include "jtag.h" +#include "registers.h" + +void jtag_pre_init(void) +{ + /* + * Stop all timers we might use (TIM1-8) and watchdogs when + * the JTAG stops the CPU. + */ + STM32_DBGMCU_APB1FZ |= + STM32_RCC_PB1_TIM2 | STM32_RCC_PB1_TIM3 | STM32_RCC_PB1_TIM4 | + STM32_RCC_PB1_TIM5 | STM32_RCC_PB1_TIM6 | STM32_RCC_PB1_TIM7 | + STM32_RCC_PB1_WWDG | STM32_RCC_PB1_IWDG; + STM32_DBGMCU_APB2FZ |= STM32_RCC_PB2_TIM1 | STM32_RCC_PB2_TIM8; +} diff --git a/chip/stm32/registers.h b/chip/stm32/registers.h index 74eee526cb..33b2d9faeb 100644 --- a/chip/stm32/registers.h +++ b/chip/stm32/registers.h @@ -156,7 +156,8 @@ #define STM32_USART_BASE(n) CONCAT3(STM32_USART, n, _BASE) #define STM32_USART_REG(base, offset) REG32((base) + (offset)) -#if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) +#if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) || \ + defined(CHIP_FAMILY_STM32L4) #define STM32_USART_CR1(base) STM32_USART_REG(base, 0x00) #define STM32_USART_CR1_UE (1 << 0) #define STM32_USART_CR1_UESM (1 << 1) @@ -352,13 +353,16 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define GPIO_ALT_RI 0xE #define GPIO_ALT_EVENTOUT 0xF -#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) +#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) || \ + defined(CHIP_FAMILY_STM32L4) #define STM32_GPIOA_BASE 0x48000000 #define STM32_GPIOB_BASE 0x48000400 #define STM32_GPIOC_BASE 0x48000800 #define STM32_GPIOD_BASE 0x48000C00 #define STM32_GPIOE_BASE 0x48001000 #define STM32_GPIOF_BASE 0x48001400 +#define STM32_GPIOG_BASE 0x48001800 /* only for stm32l4 */ +#define STM32_GPIOH_BASE 0x48001C00 /* only for stm32l4 */ #define STM32_GPIO_MODER(b) REG32((b) + 0x00) #define STM32_GPIO_OTYPER(b) REG16((b) + 0x04) @@ -371,6 +375,7 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define STM32_GPIO_AFRL(b) REG32((b) + 0x20) #define STM32_GPIO_AFRH(b) REG32((b) + 0x24) #define STM32_GPIO_BRR(b) REG32((b) + 0x28) +#define STM32_GPIO_ASCR(b) REG32((b) + 0x2C) /* only for stm32l4 */ #define GPIO_ALT_F0 0x0 #define GPIO_ALT_F1 0x1 @@ -378,14 +383,21 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define GPIO_ALT_F3 0x3 #define GPIO_ALT_F4 0x4 #define GPIO_ALT_F5 0x5 +#define GPIO_ALT_F6 0x6 +#define GPIO_ALT_F7 0x7 +#define GPIO_ALT_F8 0x8 +#define GPIO_ALT_F9 0x9 +#define GPIO_ALT_FA 0xA +#define GPIO_ALT_FB 0xB +#define GPIO_ALT_FC 0xC +#define GPIO_ALT_FD 0xD +#define GPIO_ALT_FE 0xE +#define GPIO_ALT_FF 0xF #else #error Unsupported chip variant #endif - - - /* --- I2C --- */ #define STM32_I2C1_BASE 0x40005400 #define STM32_I2C2_BASE 0x40005800 @@ -543,6 +555,60 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define STM32_SYSCFG_PMC REG32(STM32_SYSCFG_BASE + 0x04) #define STM32_SYSCFG_EXTICR(n) REG32(STM32_SYSCFG_BASE + 8 + 4 * (n)) +#elif defined(CHIP_FAMILY_STM32L4) +#define STM32_RCC_BASE 0x40021000 + +#define STM32_RCC_CR REG32(STM32_RCC_BASE + 0x00) +#define STM32_RCC_CR_MSION (1 << 0) +#define STM32_RCC_CR_MSIRDY (1 << 1) +#define STM32_RCC_CR_HSION (1 << 8) +#define STM32_RCC_CR_HSIRDY (1 << 10) + +#define STM32_RCC_ICSCR REG32(STM32_RCC_BASE + 0x04) +#define STM32_RCC_ICSCR_MSIRANGE(n) ((n) << 13) +#define STM32_RCC_ICSCR_MSIRANGE_1MHZ STM32_RCC_ICSCR_MSIRANGE(4) +#define STM32_RCC_ICSCR_MSIRANGE_2MHZ STM32_RCC_ICSCR_MSIRANGE(5) +#define STM32_RCC_ICSCR_MSIRANGE_MASK STM32_RCC_ICSCR_MSIRANGE(7) + +#define STM32_RCC_CFGR REG32(STM32_RCC_BASE + 0x08) +#define STM32_RCC_CFGR_SW_MSI (0 << 0) +#define STM32_RCC_CFGR_SW_HSI (1 << 0) +#define STM32_RCC_CFGR_SW_HSE (2 << 0) +#define STM32_RCC_CFGR_SW_PLL (3 << 0) +#define STM32_RCC_CFGR_SW_MASK (3 << 0) +#define STM32_RCC_CFGR_SWS_MSI (0 << 2) +#define STM32_RCC_CFGR_SWS_HSI (1 << 2) +#define STM32_RCC_CFGR_SWS_HSE (2 << 2) +#define STM32_RCC_CFGR_SWS_PLL (3 << 2) +#define STM32_RCC_CFGR_SWS_MASK (3 << 2) + +#define STM32_RCC_AHB1ENR REG32(STM32_RCC_BASE + 0x48) +#define STM32_RCC_AHB1ENR_DMA1EN (1 << 0) +#define STM32_RCC_AHB1ENR_DMA2EN (1 << 1) + +#define STM32_RCC_AHB2ENR REG32(STM32_RCC_BASE + 0x4C) +#define STM32_RCC_AHB2ENR_GPIOMASK (0xff << 0) + +#define STM32_RCC_APB1ENR REG32(STM32_RCC_BASE + 0x58) +#define STM32_RCC_APB1ENR2 REG32(STM32_RCC_BASE + 0x5C) +#define STM32_RCC_APB1ENR2_LPUART1EN (1 << 0) + +#define STM32_RCC_APB2ENR REG32(STM32_RCC_BASE + 0x60) + +#define STM32_RCC_CCIPR REG32(STM32_RCC_BASE + 0x88) +#define STM32_RCC_CCIPR_LPUART1SEL_SHIFT (10) +#define STM32_RCC_CCIPR_USART1SEL_SHIFT (0) + +#define STM32_RCC_BDCR REG32(STM32_RCC_BASE + 0x90) + +#define STM32_RCC_CSR REG32(STM32_RCC_BASE + 0x94) + +#define STM32_RCC_PB2_TIM1 (1 << 11) +#define STM32_RCC_PB2_TIM8 (1 << 13) + +#define STM32_SYSCFG_BASE 0x40010000 +#define STM32_SYSCFG_EXTICR(n) REG32(STM32_SYSCFG_BASE + 8 + 4 * (n)) + #elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) #define STM32_RCC_BASE 0x40021000 @@ -634,7 +700,7 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define STM32_RTC_BASE 0x40002800 #if defined(CHIP_FAMILY_STM32L) || defined(CHIP_FAMILY_STM32F0) || \ - defined(CHIP_FAMILY_STM32F3) + defined(CHIP_FAMILY_STM32F3) || defined(CHIP_FAMILY_STM32L4) #define STM32_RTC_TR REG32(STM32_RTC_BASE + 0x00) #define STM32_RTC_DR REG32(STM32_RTC_BASE + 0x04) #define STM32_RTC_CR REG32(STM32_RTC_BASE + 0x08) @@ -780,7 +846,8 @@ typedef volatile struct stm32_spi_regs stm32_spi_regs_t; #define STM32_OPTB_WRP3L 0x18 #define STM32_OPTB_WRP3H 0x1c -#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) +#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) || \ + defined(CHIP_FAMILY_STM32L4) #define STM32_FLASH_REGS_BASE 0x40022000 #define STM32_FLASH_ACR REG32(STM32_FLASH_REGS_BASE + 0x00) @@ -1128,7 +1195,8 @@ typedef volatile struct stm32_spi_regs stm32_spi_regs_t; #if defined(CHIP_FAMILY_STM32L) #define STM32_DMA1_BASE 0x40026000 -#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) +#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) || \ + defined(CHIP_FAMILY_STM32L4) #define STM32_DMA1_BASE 0x40020000 #define STM32_DMA2_BASE 0x40020400 #else @@ -1228,9 +1296,8 @@ typedef volatile struct stm32_dma_regs stm32_dma_regs_t; #define STM32_DMA1_REGS ((stm32_dma_regs_t *)STM32_DMA1_BASE) -#ifdef CHIP_FAMILY_STM32F3 +#if defined(CHIP_FAMILY_STM32F3) || defined(CHIP_FAMILY_STM32L4) #define STM32_DMA2_REGS ((stm32_dma_regs_t *)STM32_DMA2_BASE) - #define STM32_DMA_REGS(channel) \ ((channel) < STM32_DMAC_PER_CTLR ? STM32_DMA1_REGS : STM32_DMA2_REGS) #define STM32_DMA_CSELR(channel) \ diff --git a/chip/stm32/system.c b/chip/stm32/system.c index 682020b344..90a248eafa 100644 --- a/chip/stm32/system.c +++ b/chip/stm32/system.c @@ -207,7 +207,8 @@ void system_pre_init(void) /* Enable RTC and use LSI as clock source */ STM32_RCC_CSR = (STM32_RCC_CSR & ~0x00C30000) | 0x00420000; } -#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) +#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) || \ + defined(CHIP_FAMILY_STM32L4) if ((STM32_RCC_BDCR & 0x00018300) != 0x00008200) { /* the RTC settings are bad, we need to reset it */ STM32_RCC_BDCR |= 0x00010000; @@ -396,5 +397,8 @@ int system_is_reboot_warm(void) return ((STM32_RCC_AHBENR & 0x7e0000) == 0x7e0000); #elif defined(CHIP_FAMILY_STM32L) return ((STM32_RCC_AHBENR & 0x3f) == 0x3f); +#elif defined(CHIP_FAMILY_STM32L4) + return ((STM32_RCC_AHB2ENR & STM32_RCC_AHB2ENR_GPIOMASK) + == STM32_RCC_AHB2ENR_GPIOMASK); #endif } diff --git a/chip/stm32/uart.c b/chip/stm32/uart.c index 33ef1064f0..69dc7d26d2 100644 --- a/chip/stm32/uart.c +++ b/chip/stm32/uart.c @@ -15,6 +15,7 @@ #include "task.h" #include "uart.h" #include "util.h" +#include "stm32-dma.h" /* Console USART index */ #define UARTN CONFIG_UART_CONSOLE @@ -238,7 +239,7 @@ static void uart_freq_change(void) div = DIV_ROUND_NEAREST(freq, CONFIG_UART_BAUD_RATE); #if defined(CHIP_FAMILY_STM32L) || defined(CHIP_FAMILY_STM32F0) || \ - defined(CHIP_FAMILY_STM32F3) + defined(CHIP_FAMILY_STM32F3) || defined(CHIP_FAMILY_STM32L4) if (div / 16 > 0) { /* * CPU clock is high enough to support x16 oversampling. @@ -264,15 +265,18 @@ DECLARE_HOOK(HOOK_FREQ_CHANGE, uart_freq_change, HOOK_PRIO_DEFAULT); void uart_init(void) { - /* Enable USART clock */ + /* Select clock source */ #if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) #if (UARTN == 1) STM32_RCC_CFGR3 |= 0x0003; /* USART1 clock source from HSI(8MHz) */ #elif (UARTN == 2) STM32_RCC_CFGR3 |= 0x030000; /* USART2 clock source from HSI(8MHz) */ #endif /* UARTN */ +#elif defined(CHIP_FAMILY_STM32L4) + STM32_RCC_CCIPR |= (0x2 << STM32_RCC_CCIPR_USART1SEL_SHIFT); #endif /* CHIP_FAMILY_STM32F0 || CHIP_FAMILY_STM32F3 */ + /* Enable USART clock */ #if (UARTN == 1) STM32_RCC_APB2ENR |= STM32_RCC_PB2_USART1; #else @@ -316,6 +320,9 @@ void uart_init(void) #ifdef CONFIG_UART_TX_DMA /* Enable DMA transmitter */ STM32_USART_CR3(UARTN_BASE) |= STM32_USART_CR3_DMAT; +#ifdef CONFIG_UART_TX_DMA_PH + dma_select_channel(CONFIG_UART_TX_DMA_CH, CONFIG_UART_TX_DMA_PH); +#endif #else /* DMA disabled, special modes disabled, error interrupt disabled */ STM32_USART_CR3(UARTN_BASE) &= ~STM32_USART_CR3_DMAR & |