diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2017-11-09 13:43:58 +0100 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-01-08 05:41:23 -0800 |
commit | e24a3953c2c23df219fc0c735e0c188fd8edbded (patch) | |
tree | d1b36505f04da9767ba75513287364f86f9b5eeb /chip/stm32 | |
parent | 57bb4ddf4163dbe3da48ba56464adbabfa596344 (diff) | |
download | chrome-ec-e24a3953c2c23df219fc0c735e0c188fd8edbded.tar.gz |
stm32: Add STM32H7 family
Start adding support for the STM32H7 family of device and the first
available one the STM32H743.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BRANCH=none
BUG=b:67081508
TEST=manual, run on stm32h743i-eval and zerblebarn boards
get a stable serial console.
Change-Id: I9ae10f0d843e5318451713c21ed22d455a23758c
Reviewed-on: https://chromium-review.googlesource.com/806168
Commit-Ready: Vincent Palatin <vpalatin@chromium.org>
Tested-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-by: Shawn N <shawnn@chromium.org>
Diffstat (limited to 'chip/stm32')
-rw-r--r-- | chip/stm32/build.mk | 7 | ||||
-rw-r--r-- | chip/stm32/clock-stm32h7.c | 213 | ||||
-rw-r--r-- | chip/stm32/config-stm32h7x3.h | 48 | ||||
-rw-r--r-- | chip/stm32/config_chip.h | 6 | ||||
-rw-r--r-- | chip/stm32/dma-stm32f4.c | 7 | ||||
-rw-r--r-- | chip/stm32/gpio-stm32h7.c | 47 | ||||
-rw-r--r-- | chip/stm32/gpio.c | 4 | ||||
-rw-r--r-- | chip/stm32/hwtimer32.c | 11 | ||||
-rw-r--r-- | chip/stm32/registers.h | 491 | ||||
-rw-r--r-- | chip/stm32/system.c | 35 | ||||
-rw-r--r-- | chip/stm32/uart.c | 8 |
11 files changed, 851 insertions, 26 deletions
diff --git a/chip/stm32/build.mk b/chip/stm32/build.mk index da16ea3a19..a5249b4b4a 100644 --- a/chip/stm32/build.mk +++ b/chip/stm32/build.mk @@ -16,6 +16,11 @@ else ifeq ($(CHIP_FAMILY),$(filter $(CHIP_FAMILY),stm32f3 stm32l4 stm32f4)) CORE:=cortex-m # Allow the full Cortex-M4 instruction set CFLAGS_CPU+=-march=armv7e-m -mcpu=cortex-m4 +else ifeq ($(CHIP_FAMILY),$(filter $(CHIP_FAMILY),stm32h7)) +# STM32FH7xx family has a Cortex-M7 ARM core +CORE:=cortex-m +# Allow the full Cortex-M4 instruction set (identical to M7) +CFLAGS_CPU+=-march=armv7e-m -mcpu=cortex-m4 else # other STM32 SoCs have a Cortex-M3 ARM core CORE:=cortex-m @@ -25,7 +30,7 @@ endif # Select between 16-bit and 32-bit timer for clock source TIMER_TYPE=$(if $(CONFIG_STM_HWTIMER32),32,) -DMA_TYPE=$(if $(CHIP_FAMILY_STM32F4),-stm32f4,) +DMA_TYPE=$(if $(CHIP_FAMILY_STM32F4)$(CHIP_FAMILY_STM32H7),-stm32f4,) chip-$(CONFIG_DMA)+=dma$(DMA_TYPE).o chip-$(CONFIG_COMMON_RUNTIME)+=system.o diff --git a/chip/stm32/clock-stm32h7.c b/chip/stm32/clock-stm32h7.c new file mode 100644 index 0000000000..291579ed16 --- /dev/null +++ b/chip/stm32/clock-stm32h7.c @@ -0,0 +1,213 @@ +/* Copyright 2017 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 default is 64 MHz */ +#define STM32_HSI_CLOCK 64000000 +/* + * PLL1 configuration: + * CPU freq = VCO / (DIVP + 1) = HSI / DIVM * DIVN / (DIVP + 1) + * = 64 * 4 * 50 / (4 + 1) + * = 160 Mhz + */ +#if !defined(PLL1_DIVM) && !defined(PLL1_DIVN) && !defined(PLL1_DIVP) +#define PLL1_DIVM 4 +#define PLL1_DIVN 50 +#define PLL1_DIVP 4 +#endif +#define PLL1_FREQ (STM32_HSI_CLOCK / PLL1_DIVM * PLL1_DIVN / (PLL1_DIVP+1)) + +enum clock_osc { + OSC_INIT = 0, /* Uninitialized */ + OSC_HSI, /* High-speed internal oscillator */ + OSC_CSI, /* Multi-speed internal oscillator: NOT IMPLEMENTED */ + OSC_HSE, /* High-speed external oscillator: NOT IMPLEMENTED */ + OSC_PLL, /* PLL */ +}; + +static int freq = STM32_HSI_CLOCK; +static int current_osc; + +int clock_get_freq(void) +{ + return freq; +} + +int clock_get_timer_freq(void) +{ + return clock_get_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_GPIO_IDR(GPIO_A); + } else { /* APB */ + while (cycles--) + dummy = STM32_USART_BRR(STM32_USART1_BASE); + } +} + +static void clock_enable_osc(enum clock_osc osc) +{ + uint32_t ready; + uint32_t on; + + switch (osc) { + case OSC_HSI: + ready = STM32_RCC_CR_HSIRDY; + on = STM32_RCC_CR_HSION; + break; + case OSC_PLL: + ready = STM32_RCC_CR_PLL1RDY; + on = STM32_RCC_CR_PLL1ON; + break; + default: + return; + } + + if (!(STM32_RCC_CR & ready)) { + STM32_RCC_CR |= on; + while (!(STM32_RCC_CR & ready)) + ; + } +} + +static void clock_switch_osc(enum clock_osc osc) +{ + uint32_t sw; + uint32_t sws; + + switch (osc) { + case OSC_HSI: + sw = STM32_RCC_CFGR_SW_HSI; + sws = STM32_RCC_CFGR_SWS_HSI; + break; + case OSC_PLL: + sw = STM32_RCC_CFGR_SW_PLL1; + sws = STM32_RCC_CFGR_SWS_PLL1; + break; + default: + return; + } + + STM32_RCC_CFGR = sw; + while ((STM32_RCC_CFGR & STM32_RCC_CFGR_SWS_MASK) != sws) + ; +} + +static void clock_set_osc(enum clock_osc osc) +{ + uint32_t val; + + if (osc == current_osc) + return; + + if (current_osc != OSC_INIT) + hook_notify(HOOK_PRE_FREQ_CHANGE); + + switch (osc) { + case OSC_HSI: + /* Switch to HSI */ + clock_switch_osc(osc); + + freq = STM32_HSI_CLOCK; + break; + + case OSC_PLL: + /* Configure PLL1 using 64 Mhz HSI as input */ + STM32_RCC_PLLCKSELR = STM32_RCC_PLLCKSEL_PLLSRC_HSI | + STM32_RCC_PLLCKSEL_DIVM1(PLL1_DIVM); + /* in integer mode, wide range VCO with 16Mhz input, use divP */ + STM32_RCC_PLLCFGR = STM32_RCC_PLLCFG_PLL1VCOSEL_WIDE + | STM32_RCC_PLLCFG_PLL1RGE_8M_16M + | STM32_RCC_PLLCFG_DIVP1EN; + STM32_RCC_PLL1DIVR = STM32_RCC_PLLDIV_DIVP(PLL1_DIVP) + | STM32_RCC_PLLDIV_DIVN(PLL1_DIVN); + /* turn on PLL1 and wait that it's ready */ + clock_enable_osc(OSC_PLL); + freq = PLL1_FREQ; + + /* Adjust flash latency */ + val = STM32_FLASH_ACR_WRHIGHFREQ_185MHZ | + (2 << STM32_FLASH_ACR_LATENCY_SHIFT); + STM32_FLASH_ACR = val; + while (val != STM32_FLASH_ACR) + ; + + /* Switch to PLL */ + clock_switch_osc(OSC_PLL); + 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(); +#if 0 /* Power management policy: TODO(b/67081508) not implemented for now */ + clock_set_osc(new_mask ? OSC_PLL : OSC_CSI); +#endif + } + + clock_mask = new_mask; +} + +void clock_init(void) +{ +#if 0 /* Keep default for now: HSI at 64 Mhz */ + clock_set_osc(OSC_PLL); +#endif +} + +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], "pll")) + clock_set_osc(OSC_PLL); + else + return EC_ERROR_PARAM1; + } + ccprintf("Clock frequency is now %d Hz\n", freq); + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(clock, command_clock, + "hsi | pll", "Set clock frequency"); diff --git a/chip/stm32/config-stm32h7x3.h b/chip/stm32/config-stm32h7x3.h new file mode 100644 index 0000000000..9b4dde19c9 --- /dev/null +++ b/chip/stm32/config-stm32h7x3.h @@ -0,0 +1,48 @@ +/* Copyright 2017 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 (1048 * 1024) + +/* Erasing 128K can take up to 2s, need to defer erase. */ +#define CONFIG_FLASH_DEFERRED_ERASE + +/* ITCM-RAM: 64kB 0x00000000 - 0x0000FFFF (CPU and MDMA) */ +/* DTCM-RAM: 128kB 0x20000000 - 0x2001FFFF (CPU and MDMA) */ +/* (D1) AXI-SRAM : 512kB 0x24000000 - 0x2407FFFF (no BDMA) */ +/* (D2) AHB-SRAM1: 128kB 0x30000000 - 0x3001FFFF */ +/* (D2) AHB-SRAM2: 128kB 0x30020000 - 0x3003FFFF */ +/* (D2) AHB-SRAM3: 32kB 0x30040000 - 0x30047FFF */ +/* (D3) AHB-SRAM4: 64kB 0x38000000 - 0x3800FFFF */ +/* (D3) backup RAM: 4kB 0x38800000 - 0x38800FFF */ +#define CONFIG_RAM_BASE 0x24000000 +#define CONFIG_RAM_SIZE 0x00080000 + +#define CONFIG_RO_MEM_OFF 0 +#define CONFIG_RO_SIZE (128 * 1024) +#define CONFIG_RW_MEM_OFF (128 * 1024) +#define CONFIG_RW_SIZE (896 * 1024) + +#define CONFIG_RO_STORAGE_OFF 0 +#define CONFIG_RW_STORAGE_OFF 0 + +#define CONFIG_EC_PROTECTED_STORAGE_OFF 0 +#define CONFIG_EC_PROTECTED_STORAGE_SIZE CONFIG_RW_MEM_OFF +#define CONFIG_EC_WRITABLE_STORAGE_OFF CONFIG_RW_MEM_OFF +#define CONFIG_EC_WRITABLE_STORAGE_SIZE \ + (CONFIG_FLASH_SIZE - CONFIG_EC_WRITABLE_STORAGE_OFF) + +#define CONFIG_WP_STORAGE_OFF CONFIG_EC_PROTECTED_STORAGE_OFF +#define CONFIG_WP_STORAGE_SIZE CONFIG_EC_PROTECTED_STORAGE_SIZE + +#undef I2C_PORT_COUNT +#define I2C_PORT_COUNT 4 + +/* Use PSTATE embedded in the RO image, not in its own erase block */ +#define CONFIG_FLASH_PSTATE +#undef CONFIG_FLASH_PSTATE_BANK + +/* Number of IRQ vectors on the NVIC */ +#define CONFIG_IRQ_COUNT 150 diff --git a/chip/stm32/config_chip.h b/chip/stm32/config_chip.h index 43769cf2bf..f9dcc2fda7 100644 --- a/chip/stm32/config_chip.h +++ b/chip/stm32/config_chip.h @@ -57,6 +57,8 @@ #elif defined(CHIP_VARIANT_STM32F03X) /* STM32F03x */ #include "config-stm32f03x.h" +#elif defined(CHIP_VARIANT_STM32H7X3) +#include "config-stm32h7x3.h" #else #error "Unsupported chip variant" #endif @@ -70,7 +72,9 @@ /* Program is run directly from storage */ #define CONFIG_MAPPED_STORAGE_BASE CONFIG_PROGRAM_MEMORY_BASE -#if !defined(CHIP_FAMILY_STM32F4) && !defined(CHIP_VARIANT_STM32F09X) +#if !defined(CHIP_FAMILY_STM32F4) && \ + !defined(CHIP_FAMILY_STM32H7) && \ + !defined(CHIP_VARIANT_STM32F09X) /* Compute the rest of the flash params from these */ #include "config_std_internal_flash.h" #endif diff --git a/chip/stm32/dma-stm32f4.c b/chip/stm32/dma-stm32f4.c index 135df53b1a..cdd3f54dd9 100644 --- a/chip/stm32/dma-stm32f4.c +++ b/chip/stm32/dma-stm32f4.c @@ -54,6 +54,13 @@ stm32_dma_stream_t *dma_get_channel(enum dma_channel stream) return &dma->stream[stream % STM32_DMAS_COUNT]; } +#ifdef CHIP_FAMILY_STM32H7 +void dma_select_channel(enum dma_channel channel, uint8_t req) +{ + STM2_DMAMUX_CxCR(DMAMUX1, channel) = req; +} +#endif + void dma_disable(enum dma_channel ch) { stm32_dma_stream_t *stream = dma_get_channel(ch); diff --git a/chip/stm32/gpio-stm32h7.c b/chip/stm32/gpio-stm32h7.c new file mode 100644 index 0000000000..a2fb97225d --- /dev/null +++ b/chip/stm32/gpio-stm32h7.c @@ -0,0 +1,47 @@ +/* Copyright 2017 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 "gpio.h" +#include "hooks.h" +#include "registers.h" +#include "task.h" +#include "util.h" + +void gpio_enable_clocks(void) +{ + /* Enable all GPIOs clocks */ + STM32_RCC_AHB4ENR |= STM32_RCC_AHB4ENR_GPIOMASK; + + /* Delay 1 AHB clock cycle after the clock is enabled */ + clock_wait_bus_cycles(BUS_AHB, 1); +} + +static void gpio_init(void) +{ + /* Enable IRQs now that pins are set up */ + task_enable_irq(STM32_IRQ_EXTI0); + task_enable_irq(STM32_IRQ_EXTI1); + task_enable_irq(STM32_IRQ_EXTI2); + task_enable_irq(STM32_IRQ_EXTI3); + task_enable_irq(STM32_IRQ_EXTI4); + task_enable_irq(STM32_IRQ_EXTI9_5); + task_enable_irq(STM32_IRQ_EXTI15_10); + +} +DECLARE_HOOK(HOOK_INIT, gpio_init, HOOK_PRIO_DEFAULT); + +DECLARE_IRQ(STM32_IRQ_EXTI0, gpio_interrupt, 1); +DECLARE_IRQ(STM32_IRQ_EXTI1, gpio_interrupt, 1); +DECLARE_IRQ(STM32_IRQ_EXTI2, gpio_interrupt, 1); +DECLARE_IRQ(STM32_IRQ_EXTI3, gpio_interrupt, 1); +DECLARE_IRQ(STM32_IRQ_EXTI4, gpio_interrupt, 1); +DECLARE_IRQ(STM32_IRQ_EXTI9_5, gpio_interrupt, 1); +DECLARE_IRQ(STM32_IRQ_EXTI15_10, gpio_interrupt, 1); + +#include "gpio-f0-l.c" diff --git a/chip/stm32/gpio.c b/chip/stm32/gpio.c index a89f046a01..7108d4a10e 100644 --- a/chip/stm32/gpio.c +++ b/chip/stm32/gpio.c @@ -27,7 +27,11 @@ void gpio_pre_init(void) int i; /* Required to configure external IRQ lines (SYSCFG_EXTICRn) */ +#ifdef CHIP_FAMILY_STM32H7 + STM32_RCC_APB4ENR |= STM32_RCC_SYSCFGEN; +#else STM32_RCC_APB2ENR |= STM32_RCC_SYSCFGEN; +#endif /* Delay 1 APB clock cycle after the clock is enabled */ clock_wait_bus_cycles(BUS_APB, 1); diff --git a/chip/stm32/hwtimer32.c b/chip/stm32/hwtimer32.c index c3625955a5..c04f326770 100644 --- a/chip/stm32/hwtimer32.c +++ b/chip/stm32/hwtimer32.c @@ -73,7 +73,7 @@ void __hw_timer_enable_clock(int n, int enable) * Mapping of timers to reg/mask is split into a few different ranges, * some specific to individual chips. */ -#if defined(CHIP_FAMILY_STM32F0) +#if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32H7) if (n == 1) { reg = &STM32_RCC_APB2ENR; mask = STM32_RCC_PB2_TIM1; @@ -85,25 +85,28 @@ void __hw_timer_enable_clock(int n, int enable) } #endif -#if defined(CHIP_FAMILY_STM32F0) +#if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32H7) if (n >= 15 && n <= 17) { reg = &STM32_RCC_APB2ENR; mask = STM32_RCC_PB2_TIM15 << (n - 15); } #endif -#if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) +#if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) || \ +defined(CHIP_FAMILY_STM32H7) if (n == 14) { reg = &STM32_RCC_APB1ENR; mask = STM32_RCC_PB1_TIM14; } #endif -#if defined(CHIP_FAMILY_STM32F3) +#if defined(CHIP_FAMILY_STM32F3) || defined(CHIP_FAMILY_STM32H7) if (n == 12 || n == 13) { reg = &STM32_RCC_APB1ENR; mask = STM32_RCC_PB1_TIM12 << (n - 12); } +#endif +#if defined(CHIP_FAMILY_STM32F3) if (n == 18) { reg = &STM32_RCC_APB1ENR; mask = STM32_RCC_PB1_TIM18; diff --git a/chip/stm32/registers.h b/chip/stm32/registers.h index 5f787ce20f..e8a8f826aa 100644 --- a/chip/stm32/registers.h +++ b/chip/stm32/registers.h @@ -91,6 +91,7 @@ #define STM32_IRQ_CAN_SCE 22 /* STM32F373 only */ #define STM32_IRQ_EXTI9_5 23 +#ifndef CHIP_FAMILY_STM32H7 #define STM32_IRQ_LCD 24 /* STM32L15X only */ #define STM32_IRQ_TIM15 24 /* STM32F373 only */ #define STM32_IRQ_TIM9 25 /* STM32L15X only */ @@ -99,6 +100,7 @@ #define STM32_IRQ_TIM17 26 /* STM32F373 only */ #define STM32_IRQ_TIM11 27 /* STM32L15X only */ #define STM32_IRQ_TIM18_DAC2 27 /* STM32F373 only */ +#endif /* !CHIP_FAMILY_STM32H7 */ #define STM32_IRQ_TIM2 28 #define STM32_IRQ_TIM3 29 #define STM32_IRQ_TIM4 30 @@ -148,6 +150,12 @@ #define STM32_IRQ_RNG 80 /* STM32L4 only */ #define STM32_IRQ_FPU 81 /* STM32F373 only */ +#ifdef CHIP_FAMILY_STM32H7 +#define STM32_IRQ_TIM15 116 +#define STM32_IRQ_TIM16 117 +#define STM32_IRQ_TIM17 118 +#endif /* CHIP_FAMILY_STM32H7 */ + /* To simplify code generation, define DMA channel 9..10 */ #define STM32_IRQ_DMA_CHANNEL_9 STM32_IRQ_DMA2_CHANNEL1 #define STM32_IRQ_DMA_CHANNEL_10 STM32_IRQ_DMA2_CHANNEL2 @@ -160,7 +168,7 @@ #define STM32_IRQ_I2C3 STM32_IRQ_I2C3_EV #endif /* !CHIP_FAMILY_STM32F0 */ -#ifdef CHIP_FAMILY_STM32F4 +#if defined(CHIP_FAMILY_STM32F4) || defined(CHIP_FAMILY_STM32H7) /* * STM32F4 introduces a concept of DMA stream to allow * fine allocation of a stream to a channel. @@ -192,6 +200,8 @@ #endif /* Peripheral base addresses */ + +#ifndef CHIP_FAMILY_STM32H7 #if defined(CHIP_FAMILY_STM32F4) #define STM32_ADC1_BASE 0x40012000 #define STM32_ADC_BASE 0x40012300 @@ -356,6 +366,76 @@ #define STM32_WWDG_BASE 0x40002C00 +#else /* CHIP_FAMILY_STM32H7 */ + +#define STM32_DBGMCU_BASE 0x5C001000 + +#define STM32_BDMA_BASE 0x58025400 +#define STM32_DMA1_BASE 0x40020000 +#define STM32_DMA2_BASE 0x40020400 +#define STM32_DMA2D_BASE 0x52001000 +#define STM32_DMAMUX1_BASE 0x40020800 +#define STM32_DMAMUX2_BASE 0x58025800 +#define STM32_MDMA_BASE 0x52000000 + +#define STM32_EXTI_BASE 0x58000000 + +#define STM32_FLASH_REGS_BASE 0x52002000 + +#define STM32_GPIOA_BASE 0x58020000 +#define STM32_GPIOB_BASE 0x58020400 +#define STM32_GPIOC_BASE 0x58020800 +#define STM32_GPIOD_BASE 0x58020C00 +#define STM32_GPIOE_BASE 0x58021000 +#define STM32_GPIOF_BASE 0x58021400 +#define STM32_GPIOG_BASE 0x58021800 +#define STM32_GPIOH_BASE 0x58021C00 +#define STM32_GPIOI_BASE 0x58022000 +#define STM32_GPIOJ_BASE 0x58022400 +#define STM32_GPIOK_BASE 0x58022800 + +#define STM32_IWDG_BASE 0x58004800 + +#define STM32_PWR_BASE 0x58024800 +#define STM32_RCC_BASE 0x58024400 +#define STM32_RTC_BASE 0x58004000 + +#define STM32_SYSCFG_BASE 0x58000400 + +#define STM32_SPI1_BASE 0x40013000 +#define STM32_SPI2_BASE 0x40003800 +#define STM32_SPI3_BASE 0x40003c00 +#define STM32_SPI4_BASE 0x40013400 +#define STM32_SPI5_BASE 0x40015000 + +#define STM32_TIM1_BASE 0x40010000 +#define STM32_TIM2_BASE 0x40000000 +#define STM32_TIM3_BASE 0x40000400 +#define STM32_TIM4_BASE 0x40000800 +#define STM32_TIM5_BASE 0x40000c00 +#define STM32_TIM6_BASE 0x40001000 +#define STM32_TIM7_BASE 0x40001400 +#define STM32_TIM8_BASE 0x40010400 +#define STM32_TIM12_BASE 0x40001800 +#define STM32_TIM13_BASE 0x40001c00 +#define STM32_TIM14_BASE 0x40002000 +#define STM32_TIM15_BASE 0x40014000 +#define STM32_TIM16_BASE 0x40014400 +#define STM32_TIM17_BASE 0x40014800 + +#define STM32_UNIQUE_ID_BASE 0x1ff1e800 + +#define STM32_USART1_BASE 0x40011000 +#define STM32_USART2_BASE 0x40004400 +#define STM32_USART3_BASE 0x40004800 +#define STM32_USART4_BASE 0x40004c00 +#define STM32_USART5_BASE 0x40005000 +#define STM32_USART6_BASE 0x40011400 +#define STM32_USART7_BASE 0x40007800 +#define STM32_USART8_BASE 0x40007C00 + +#endif /* CHIP_FAMILY_STM32H7 */ + #ifndef __ASSEMBLER__ /* Register definitions */ @@ -365,7 +445,8 @@ #define STM32_USART_REG(base, offset) REG32((base) + (offset)) #if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) || \ - defined(CHIP_FAMILY_STM32L4) || defined(CHIP_VARIANT_STM32F76X) + defined(CHIP_FAMILY_STM32L4) || defined(CHIP_VARIANT_STM32F76X) || \ + defined(CHIP_FAMILY_STM32H7) #define STM32_USART_CR1(base) STM32_USART_REG(base, 0x00) #define STM32_USART_CR1_UE (1 << 0) #define STM32_USART_CR1_UESM (1 << 1) @@ -397,6 +478,7 @@ #define STM32_USART_ICR_TCCF (1 << 6) #define STM32_USART_RDR(base) STM32_USART_REG(base, 0x24) #define STM32_USART_TDR(base) STM32_USART_REG(base, 0x28) +#define STM32_USART_PRESC(base) STM32_USART_REG(base, 0x2C) /* register alias */ #define STM32_USART_SR(base) STM32_USART_ISR(base) #define STM32_USART_SR_ORE (1 << 3) @@ -514,10 +596,13 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define GPIO_G STM32_GPIOG_BASE #define GPIO_H STM32_GPIOH_BASE #define GPIO_I STM32_GPIOI_BASE +#define GPIO_J STM32_GPIOJ_BASE +#define GPIO_K STM32_GPIOK_BASE #define DUMMY_GPIO_BANK GPIO_A -#if defined(CHIP_FAMILY_STM32L) || defined(CHIP_FAMILY_STM32F4) +#if defined(CHIP_FAMILY_STM32L) || defined(CHIP_FAMILY_STM32F4) || \ + defined(CHIP_FAMILY_STM32H7) #define STM32_GPIO_MODER(b) REG32((b) + 0x00) #define STM32_GPIO_OTYPER(b) REG16((b) + 0x04) @@ -739,6 +824,15 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define STM32_PWR_CSR REG32(STM32_PWR_BASE + 0x10) #else #define STM32_PWR_CSR REG32(STM32_PWR_BASE + 0x04) +#ifdef CHIP_FAMILY_STM32H7 +#define STM32_PWR_CR2 REG32(STM32_PWR_BASE + 0x08) +#define STM32_PWR_CR3 REG32(STM32_PWR_BASE + 0x0C) +#define STM32_PWR_CPUCR REG32(STM32_PWR_BASE + 0x10) +#define STM32_PWR_D3CR REG32(STM32_PWR_BASE + 0x18) +#define STM32_PWR_WKUPCR REG32(STM32_PWR_BASE + 0x20) +#define STM32_PWR_WKUPFR REG32(STM32_PWR_BASE + 0x24) +#define STM32_PWR_WKUPEPR REG32(STM32_PWR_BASE + 0x28) +#endif /* CHIP_FAMILY_STM32H7 */ #endif #if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) #define STM32_PWR_CSR_EWUP1 (1 << 8) @@ -1220,6 +1314,135 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define STM32_SYSCFG_CMPCR REG32(STM32_SYSCFG_BASE + 0x20) #define STM32_SYSCFG_CFGR REG32(STM32_SYSCFG_BASE + 0x2C) +#elif defined(CHIP_FAMILY_STM32H7) +#define STM32_RCC_CR REG32(STM32_RCC_BASE + 0x000) +#define STM32_RCC_ICSCR REG32(STM32_RCC_BASE + 0x004) +#define STM32_RCC_CRRCR REG32(STM32_RCC_BASE + 0x008) +#define STM32_RCC_CFGR REG32(STM32_RCC_BASE + 0x010) +#define STM32_RCC_D1CFGR REG32(STM32_RCC_BASE + 0x018) +#define STM32_RCC_D2CFGR REG32(STM32_RCC_BASE + 0x01C) +#define STM32_RCC_D3CFGR REG32(STM32_RCC_BASE + 0x020) +#define STM32_RCC_PLLCKSELR REG32(STM32_RCC_BASE + 0x028) +#define STM32_RCC_PLLCFGR REG32(STM32_RCC_BASE + 0x02C) +#define STM32_RCC_PLL1DIVR REG32(STM32_RCC_BASE + 0x030) +#define STM32_RCC_PLL1FRACR REG32(STM32_RCC_BASE + 0x034) +#define STM32_RCC_PLL2DIVR REG32(STM32_RCC_BASE + 0x038) +#define STM32_RCC_PLL2FRACR REG32(STM32_RCC_BASE + 0x03C) +#define STM32_RCC_PLL3DIVR REG32(STM32_RCC_BASE + 0x040) +#define STM32_RCC_PLL3FRACR REG32(STM32_RCC_BASE + 0x044) +#define STM32_RCC_D1CCIPR REG32(STM32_RCC_BASE + 0x04C) +#define STM32_RCC_D2CCIP1R REG32(STM32_RCC_BASE + 0x050) +#define STM32_RCC_D2CCIP2R REG32(STM32_RCC_BASE + 0x054) +#define STM32_RCC_D3CCIPR REG32(STM32_RCC_BASE + 0x058) +#define STM32_RCC_CIER REG32(STM32_RCC_BASE + 0x060) +#define STM32_RCC_CIFR REG32(STM32_RCC_BASE + 0x064) +#define STM32_RCC_CICR REG32(STM32_RCC_BASE + 0x068) +#define STM32_RCC_BDCR REG32(STM32_RCC_BASE + 0x070) +#define STM32_RCC_CSR REG32(STM32_RCC_BASE + 0x074) + +#define STM32_RCC_APB2RSTR REG32(STM32_RCC_BASE + 0x098) + +#define STM32_RCC_RSR REG32(STM32_RCC_BASE + 0x0D0) +#define STM32_RCC_AHB3ENR REG32(STM32_RCC_BASE + 0x0D4) +#define STM32_RCC_AHB1ENR REG32(STM32_RCC_BASE + 0x0D8) +#define STM32_RCC_AHB2ENR REG32(STM32_RCC_BASE + 0x0DC) +#define STM32_RCC_AHB4ENR REG32(STM32_RCC_BASE + 0x0E0) +#define STM32_RCC_AHB4ENR_GPIOMASK 0x3ff +#define STM32_RCC_APB3ENR REG32(STM32_RCC_BASE + 0x0E4) +#define STM32_RCC_APB1LENR REG32(STM32_RCC_BASE + 0x0E8) +#define STM32_RCC_APB1HENR REG32(STM32_RCC_BASE + 0x0EC) +#define STM32_RCC_APB2ENR REG32(STM32_RCC_BASE + 0x0F0) +#define STM32_RCC_APB4ENR REG32(STM32_RCC_BASE + 0x0F4) +#define STM32_RCC_SYSCFGEN (1 << 1) +#define STM32_RCC_AHB3LPENR REG32(STM32_RCC_BASE + 0x0FC) +#define STM32_RCC_AHB1LPENR REG32(STM32_RCC_BASE + 0x100) +#define STM32_RCC_AHB2LPENR REG32(STM32_RCC_BASE + 0x104) +#define STM32_RCC_AHB4LPENR REG32(STM32_RCC_BASE + 0x108) +#define STM32_RCC_APB3LPENR REG32(STM32_RCC_BASE + 0x10C) +#define STM32_RCC_APB1LLPENR REG32(STM32_RCC_BASE + 0x110) +#define STM32_RCC_APB1HLPENR REG32(STM32_RCC_BASE + 0x114) +#define STM32_RCC_APB2LPENR REG32(STM32_RCC_BASE + 0x118) +#define STM32_RCC_APB4LPENR REG32(STM32_RCC_BASE + 0x11C) +/* Aliases */ +#define STM32_RCC_APB1ENR STM32_RCC_APB1LENR + +#define STM32_RCC_CR_HSION (1 << 0) +#define STM32_RCC_CR_HSIRDY (1 << 2) +#define STM32_RCC_CR_CSION (1 << 7) +#define STM32_RCC_CR_CSIRDY (1 << 8) +#define STM32_RCC_CR_PLL1ON (1 << 24) +#define STM32_RCC_CR_PLL1RDY (1 << 25) +#define STM32_RCC_CR_PLL2ON (1 << 26) +#define STM32_RCC_CR_PLL2RDY (1 << 27) +#define STM32_RCC_CR_PLL3ON (1 << 28) +#define STM32_RCC_CR_PLL3RDY (1 << 29) +#define STM32_RCC_CFGR_SW_HSI (0 << 0) +#define STM32_RCC_CFGR_SW_CSI (1 << 0) +#define STM32_RCC_CFGR_SW_HSE (2 << 0) +#define STM32_RCC_CFGR_SW_PLL1 (3 << 0) +#define STM32_RCC_CFGR_SW_MASK (3 << 0) +#define STM32_RCC_CFGR_SWS_HSI (0 << 3) +#define STM32_RCC_CFGR_SWS_CSI (1 << 3) +#define STM32_RCC_CFGR_SWS_HSE (2 << 3) +#define STM32_RCC_CFGR_SWS_PLL1 (3 << 3) +#define STM32_RCC_CFGR_SWS_MASK (3 << 3) +#define STM32_RCC_PLLCKSEL_PLLSRC_HSI (0 << 0) +#define STM32_RCC_PLLCKSEL_PLLSRC_CSI (1 << 0) +#define STM32_RCC_PLLCKSEL_PLLSRC_HSE (2 << 0) +#define STM32_RCC_PLLCKSEL_PLLSRC_NONE (3 << 0) +#define STM32_RCC_PLLCKSEL_PLLSRC_MASK (3 << 0) +#define STM32_RCC_PLLCKSEL_DIVM1(m) ((m) << 4) +#define STM32_RCC_PLLCKSEL_DIVM2(m) ((m) << 12) +#define STM32_RCC_PLLCKSEL_DIVM3(m) ((m) << 20) +#define STM32_RCC_PLLCFG_PLL1VCOSEL_FRACEN (1 << 0) +#define STM32_RCC_PLLCFG_PLL1VCOSEL_WIDE (0 << 1) +#define STM32_RCC_PLLCFG_PLL1VCOSEL_MEDIUM (1 << 1) +#define STM32_RCC_PLLCFG_PLL1RGE_1M_2M (0 << 2) +#define STM32_RCC_PLLCFG_PLL1RGE_2M_4M (1 << 2) +#define STM32_RCC_PLLCFG_PLL1RGE_4M_8M (2 << 2) +#define STM32_RCC_PLLCFG_PLL1RGE_8M_16M (3 << 2) +#define STM32_RCC_PLLCFG_DIVP1EN (1 << 16) +#define STM32_RCC_PLLCFG_DIVQ1EN (1 << 17) +#define STM32_RCC_PLLCFG_DIVR1EN (1 << 18) +#define STM32_RCC_PLLDIV_DIVN(n) (((n) - 1) << 0) +#define STM32_RCC_PLLDIV_DIVP(p) (((p) - 1) << 9) +#define STM32_RCC_PLLDIV_DIVQ(q) (((q) - 1) << 16) +#define STM32_RCC_PLLDIV_DIVR(r) (((r) - 1) << 24) +#define STM32_RCC_PLLFRAC(n) ((n) << 3) +#define STM32_RCC_D2CCIP2_USART234578SEL_PCLK (0 << 0) +#define STM32_RCC_D2CCIP2_USART234578SEL_PLL2Q (1 << 0) +#define STM32_RCC_D2CCIP2_USART234578SEL_PLL3Q (2 << 0) +#define STM32_RCC_D2CCIP2_USART234578SEL_HSI (3 << 0) +#define STM32_RCC_D2CCIP2_USART234578SEL_CSI (4 << 0) +#define STM32_RCC_D2CCIP2_USART234578SEL_LSE (5 << 0) +#define STM32_RCC_D2CCIP2_USART234578SEL_MASK (7 << 0) +#define STM32_RCC_D2CCIP2_USART16SEL_PCLK (0 << 3) +#define STM32_RCC_D2CCIP2_USART16SEL_PLL2Q (1 << 3) +#define STM32_RCC_D2CCIP2_USART16SEL_PLL3Q (2 << 3) +#define STM32_RCC_D2CCIP2_USART16SEL_HSI (3 << 3) +#define STM32_RCC_D2CCIP2_USART16SEL_CSI (4 << 3) +#define STM32_RCC_D2CCIP2_USART16SEL_LSE (5 << 3) +#define STM32_RCC_D2CCIP2_USART16SEL_MASK (7 << 3) + +#define STM32_SYSCFG_PMCR REG32(STM32_SYSCFG_BASE + 0x04) +#define STM32_SYSCFG_EXTICR(n) REG32(STM32_SYSCFG_BASE + 8 + 4 * (n)) + +/* Peripheral bits for APB2ENR regs */ +#define STM32_RCC_PB2_TIM1 (1 << 0) +#define STM32_RCC_PB2_TIM2 (1 << 1) +#define STM32_RCC_PB2_USART1 (1 << 4) +#define STM32_RCC_PB2_SPI1 (1 << 12) +#define STM32_RCC_PB2_SPI4 (1 << 13) +#define STM32_RCC_PB2_TIM15 (1 << 16) +#define STM32_RCC_PB2_TIM16 (1 << 17) +#define STM32_RCC_PB2_TIM17 (1 << 18) + +/* Peripheral bits for AHB1/2/3/4ENR regs */ +#define STM32_RCC_HB1_DMA1 (1 << 0) +#define STM32_RCC_HB1_DMA2 (1 << 1) +#define STM32_RCC_HB3_MDMA (1 << 0) +#define STM32_RCC_HB4_BDMA (1 << 21) + #else #error Unsupported chip variant #endif @@ -1242,6 +1465,9 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define STM32_RCC_PB1_TIM5 (1 << 3) #define STM32_RCC_PB1_TIM6 (1 << 4) #define STM32_RCC_PB1_TIM7 (1 << 5) +#define STM32_RCC_PB1_TIM12 (1 << 6) /* STM32H7 */ +#define STM32_RCC_PB1_TIM13 (1 << 7) /* STM32H7 */ +#define STM32_RCC_PB1_TIM14 (1 << 8) /* STM32H7 */ #define STM32_RCC_PB1_RTC (1 << 10) /* DBGMCU only */ #define STM32_RCC_PB1_WWDG (1 << 11) #define STM32_RCC_PB1_IWDG (1 << 12) /* DBGMCU only */ @@ -1252,12 +1478,43 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define STM32_RCC_PB1_USART4 (1 << 19) #define STM32_RCC_PB1_USART5 (1 << 20) #define STM32_RCC_PB2_SPI1 (1 << 12) -#if defined(CHIP_FAMILY_STM32F4) +#if defined(CHIP_FAMILY_STM32F4) || defined(CHIP_FAMILY_STM32H7) #define STM32_RCC_PB2_USART1 (1 << 4) #else #define STM32_RCC_PB2_USART1 (1 << 14) #endif +/* Reset causes definitions */ +#ifdef CHIP_FAMILY_STM32H7 +#define STM32_RCC_RESET_CAUSE STM32_RCC_RSR +#define RESET_CAUSE_WDG 0x14000000 +#define RESET_CAUSE_SFT 0x01000000 +#define RESET_CAUSE_POR 0x00800000 +#define RESET_CAUSE_PIN 0x00400000 +#define RESET_CAUSE_OTHER 0xfffe0000 +#define RESET_CAUSE_RMVF 0x00010000 +/* Power cause in PWR CPUCR register (Standby&Stop modes) */ +#define STM32_PWR_RESET_CAUSE STM32_PWR_CPUCR +#define STM32_PWR_RESET_CAUSE_CLR STM32_PWR_CPUCR +#define RESET_CAUSE_SBF 0x00000040 +#define RESET_CAUSE_SBF_CLR 0x00000200 + +#else /* !CHIP_FAMILY_STM32H7 */ +/* Reset causes in RCC CSR register */ +#define STM32_RCC_RESET_CAUSE STM32_RCC_CSR +#define RESET_CAUSE_WDG 0x60000000 +#define RESET_CAUSE_SFT 0x10000000 +#define RESET_CAUSE_POR 0x08000000 +#define RESET_CAUSE_PIN 0x04000000 +#define RESET_CAUSE_OTHER 0xfe000000 +#define RESET_CAUSE_RMVF 0x01000000 +/* Power cause in PWR CSR register */ +#define STM32_PWR_RESET_CAUSE STM32_PWR_CSR +#define STM32_PWR_RESET_CAUSE_CLR STM32_PWR_CR +#define RESET_CAUSE_SBF 0x00000002 +#define RESET_CAUSE_SBF_CLR 0x00000004 +#endif /* !CHIP_FAMILY_STM32H7 */ + /* --- Watchdogs --- */ #define STM32_WWDG_CR REG32(STM32_WWDG_BASE + 0x00) @@ -1275,12 +1532,13 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define STM32_IWDG_RLR REG32(STM32_IWDG_BASE + 0x08) #define STM32_IWDG_RLR_MAX 0x0fff #define STM32_IWDG_SR REG32(STM32_IWDG_BASE + 0x0C) +#define STM32_IWDG_WINR REG32(STM32_IWDG_BASE + 0x10) /* --- Real-Time Clock --- */ #if defined(CHIP_FAMILY_STM32L) || defined(CHIP_FAMILY_STM32F0) || \ defined(CHIP_FAMILY_STM32F3) || defined(CHIP_FAMILY_STM32L4) || \ - defined(CHIP_FAMILY_STM32F4) + defined(CHIP_FAMILY_STM32F4) || defined(CHIP_FAMILY_STM32H7) #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) @@ -1309,7 +1567,7 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define STM32_RTC_BACKUP(n) REG32(STM32_RTC_BASE + 0x50 + 4 * (n)) #define STM32_BKP_DATA(n) STM32_RTC_BACKUP(n) -#ifdef CHIP_FAMILY_STM32F3 +#if defined(CHIP_FAMILY_STM32F3) || defined(CHIP_FAMILY_STM32H7) #define STM32_BKP_ENTRIES 32 #else #define STM32_BKP_ENTRIES 20 @@ -1323,6 +1581,23 @@ typedef volatile struct timer_ctlr timer_ctlr_t; /* The SPI controller registers */ struct stm32_spi_regs { +#ifdef CHIP_FAMILY_STM32H7 + uint32_t cr1; + uint32_t cr2; + uint32_t cfg1; + uint32_t cfg2; + uint32_t ier; + uint32_t sr; + uint32_t ifcr; + uint32_t _pad0; + uint32_t txdr; + uint32_t _pad1[3]; + uint32_t rxdr; + uint32_t _pad2[3]; + uint32_t crcpoly; + uint32_t rxcrcr; + uint32_t txcrcr; +#else /* !CHIP_FAMILY_STM32H7 */ uint16_t cr1; uint16_t _pad0; uint16_t cr2; @@ -1336,6 +1611,7 @@ struct stm32_spi_regs { unsigned txcrcr; unsigned i2scfgr; /* STM32L only */ unsigned i2spr; /* STM32L only */ +#endif /* !CHIP_FAMILY_STM32H7 */ }; /* Must be volatile, or compiler optimizes out repeated accesses */ typedef volatile struct stm32_spi_regs stm32_spi_regs_t; @@ -1343,7 +1619,26 @@ typedef volatile struct stm32_spi_regs stm32_spi_regs_t; #define STM32_SPI1_REGS ((stm32_spi_regs_t *)STM32_SPI1_BASE) #define STM32_SPI2_REGS ((stm32_spi_regs_t *)STM32_SPI2_BASE) #define STM32_SPI3_REGS ((stm32_spi_regs_t *)STM32_SPI3_BASE) +#define STM32_SPI4_REGS ((stm32_spi_regs_t *)STM32_SPI4_BASE) + +#ifdef CHIP_FAMILY_STM32H7 +#define STM32_SPI_CR1_SPE (1 << 0) +#define STM32_SPI_CR1_CSTART (1 << 9) +#define STM32_SPI_CR1_SSI (1 << 12) +#define STM32_SPI_CR1_DIV(div) ((div) << 28) +#define STM32_SPI_CFG1_DATASIZE(n) (((n) - 1) << 0) +#define STM32_SPI_CFG1_FTHLV(n) (((n) - 1) << 5) +#define STM32_SPI_CFG1_RXDMAEN (1 << 14) +#define STM32_SPI_CFG1_TXDMAEN (1 << 15) +#define STM32_SPI_CFG1_CRCSIZE(n) (((n) - 1) << 16) +#define STM32_SPI_CFG2_MSTR (1 << 22) +#define STM32_SPI_CFG2_SSM (1 << 26) +#define STM32_SPI_CFG2_AFCNTR (1 << 31) +#define STM32_SPI_SR_RXNE (1 << 0) +#define STM32_SPI_SR_FRLVL (3 << 13) +#define STM32_SPI_SR_TXC (1 << 12) +#else /* !CHIP_FAMILY_STM32H7 */ #define STM32_SPI_CR1_BIDIMODE (1 << 15) #define STM32_SPI_CR1_BIDIOE (1 << 14) #define STM32_SPI_CR1_CRCEN (1 << 13) @@ -1370,13 +1665,24 @@ typedef volatile struct stm32_spi_regs stm32_spi_regs_t; #define STM32_SPI_SR_BSY (1 << 7) #define STM32_SPI_SR_FRLVL (3 << 9) #define STM32_SPI_SR_FTLVL (3 << 11) +#endif /* !CHIP_FAMILY_STM32H7 */ /* --- Debug --- */ #define STM32_DBGMCU_IDCODE REG32(STM32_DBGMCU_BASE + 0x00) #define STM32_DBGMCU_CR REG32(STM32_DBGMCU_BASE + 0x04) +#ifndef CHIP_FAMILY_STM32H7 #define STM32_DBGMCU_APB1FZ REG32(STM32_DBGMCU_BASE + 0x08) #define STM32_DBGMCU_APB2FZ REG32(STM32_DBGMCU_BASE + 0x0C) +#else /* CHIP_FAMILY_STM32H7 */ +#define STM32_DBGMCU_APB3FZ REG32(STM32_DBGMCU_BASE + 0x34) +#define STM32_DBGMCU_APB1LFZ REG32(STM32_DBGMCU_BASE + 0x3C) +#define STM32_DBGMCU_APB1HFZ REG32(STM32_DBGMCU_BASE + 0x44) +#define STM32_DBGMCU_APB2FZ REG32(STM32_DBGMCU_BASE + 0x4C) +#define STM32_DBGMCU_APB4FZ REG32(STM32_DBGMCU_BASE + 0x54) +/* Alias */ +#define STM32_DBGMCU_APB1FZ STM32_DBGMCU_APB1LFZ +#endif /* CHIP_FAMILY_STM32H7 */ /* --- Flash --- */ @@ -1577,17 +1883,63 @@ typedef volatile struct stm32_spi_regs stm32_spi_regs_t; (STM32_OTP_LOCK_BASE + ((_block) / 4) * 4) #define STM32_OPT_LOCK_MASK(_block) ((0xFF << ((_block) % 4) * 8)) +#elif defined(CHIP_FAMILY_STM32H7) +#define STM32_FLASH_ACR REG32(STM32_FLASH_REGS_BASE + 0x00) +#define STM32_FLASH_ACR_LATENCY_SHIFT (0) +#define STM32_FLASH_ACR_LATENCY_MASK (7 << STM32_FLASH_ACR_LATENCY_SHIFT) +#define STM32_FLASH_ACR_WRHIGHFREQ_85MHZ (0 << 4) +#define STM32_FLASH_ACR_WRHIGHFREQ_185MHZ (1 << 4) +#define STM32_FLASH_ACR_WRHIGHFREQ_285MHZ (2 << 4) +#define STM32_FLASH_ACR_WRHIGHFREQ_385MHZ (3 << 4) + #else #error Unsupported chip variant #endif /* --- External Interrupts --- */ +#ifndef CHIP_FAMILY_STM32H7 #define STM32_EXTI_IMR REG32(STM32_EXTI_BASE + 0x00) #define STM32_EXTI_EMR REG32(STM32_EXTI_BASE + 0x04) #define STM32_EXTI_RTSR REG32(STM32_EXTI_BASE + 0x08) #define STM32_EXTI_FTSR REG32(STM32_EXTI_BASE + 0x0c) #define STM32_EXTI_SWIER REG32(STM32_EXTI_BASE + 0x10) #define STM32_EXTI_PR REG32(STM32_EXTI_BASE + 0x14) +#else /* CHIP_FAMILY_STM32H7 */ +#define STM32_EXTI_RTSR1 REG32(STM32_EXTI_BASE + 0x00) +#define STM32_EXTI_FTSR1 REG32(STM32_EXTI_BASE + 0x04) +#define STM32_EXTI_SWIER1 REG32(STM32_EXTI_BASE + 0x08) +#define STM32_EXTI_D3PMR1 REG32(STM32_EXTI_BASE + 0x0C) +#define STM32_EXTI_D3PCR1L REG32(STM32_EXTI_BASE + 0x10) +#define STM32_EXTI_D3PCR1H REG32(STM32_EXTI_BASE + 0x14) +#define STM32_EXTI_RTSR2 REG32(STM32_EXTI_BASE + 0x20) +#define STM32_EXTI_FTSR2 REG32(STM32_EXTI_BASE + 0x24) +#define STM32_EXTI_SWIER2 REG32(STM32_EXTI_BASE + 0x28) +#define STM32_EXTI_D3PMR2 REG32(STM32_EXTI_BASE + 0x2C) +#define STM32_EXTI_D3PCR2L REG32(STM32_EXTI_BASE + 0x30) +#define STM32_EXTI_D3PCR2H REG32(STM32_EXTI_BASE + 0x34) +#define STM32_EXTI_RTSR3 REG32(STM32_EXTI_BASE + 0x40) +#define STM32_EXTI_FTSR3 REG32(STM32_EXTI_BASE + 0x44) +#define STM32_EXTI_SWIER3 REG32(STM32_EXTI_BASE + 0x48) +#define STM32_EXTI_D3PMR3 REG32(STM32_EXTI_BASE + 0x4C) +#define STM32_EXTI_D3PCR3L REG32(STM32_EXTI_BASE + 0x50) +#define STM32_EXTI_D3PCR3H REG32(STM32_EXTI_BASE + 0x54) +#define STM32_EXTI_CPUIMR1 REG32(STM32_EXTI_BASE + 0x80) +#define STM32_EXTI_CPUIER1 REG32(STM32_EXTI_BASE + 0x84) +#define STM32_EXTI_CPUPR1 REG32(STM32_EXTI_BASE + 0x88) +#define STM32_EXTI_CPUIMR2 REG32(STM32_EXTI_BASE + 0x90) +#define STM32_EXTI_CPUIER2 REG32(STM32_EXTI_BASE + 0x94) +#define STM32_EXTI_CPUPR2 REG32(STM32_EXTI_BASE + 0x98) +#define STM32_EXTI_CPUIMR3 REG32(STM32_EXTI_BASE + 0xA0) +#define STM32_EXTI_CPUIER3 REG32(STM32_EXTI_BASE + 0xA4) +#define STM32_EXTI_CPUPR3 REG32(STM32_EXTI_BASE + 0xA8) +/* Aliases */ +#define STM32_EXTI_IMR STM32_EXTI_CPUIMR1 +#define STM32_EXTI_EMR STM32_EXTI_CPUIMR1 +#define STM32_EXTI_RTSR STM32_EXTI_RTSR1 +#define STM32_EXTI_FTSR STM32_EXTI_FTSR1 +#define STM32_EXTI_SWIER STM32_EXTI_SWIER1 +#define STM32_EXTI_PR STM32_EXTI_CPUPR1 +#endif /* CHIP_FAMILY_STM32H7 */ #if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) || \ defined(CHIP_FAMILY_STM32F4) @@ -1886,7 +2238,7 @@ typedef volatile struct stm32_spi_regs stm32_spi_regs_t; /* --- DMA --- */ -#if defined(CHIP_FAMILY_STM32F4) +#if defined(CHIP_FAMILY_STM32F4) || defined(CHIP_FAMILY_STM32H7) /* * Available DMA streams, numbered from 0. @@ -1961,7 +2313,8 @@ enum dma_channel { STM32_DMAC_SPI2_RX = STM32_DMA1_STREAM3, /* REQ 0 */ STM32_DMAC_SPI3_TX = STM32_DMA1_STREAM7, /* REQ 0 */ STM32_DMAC_SPI3_RX = STM32_DMA1_STREAM0, /* REQ 0 */ - + STM32_DMAC_SPI4_TX = STM32_DMA2_STREAM1, /* STM32H7 */ + STM32_DMAC_SPI4_RX = STM32_DMA2_STREAM4, /* STM32H7 */ }; #define STM32_REQ_USART1_TX 4 @@ -2120,7 +2473,7 @@ typedef volatile struct stm32_dma_regs stm32_dma_regs_t; -#if defined(CHIP_FAMILY_STM32F4) +#if defined(CHIP_FAMILY_STM32F4) || defined(CHIP_FAMILY_STM32H7) #define STM32_DMA2_REGS ((stm32_dma_regs_t *)STM32_DMA2_BASE) #define STM32_DMA_REGS(channel) \ @@ -2153,8 +2506,13 @@ typedef volatile struct stm32_dma_regs stm32_dma_regs_t; #define STM32_DMA_CCR_CT (1 << 19) #define STM32_DMA_CCR_PBURST(b_len) ((((b_len) - 4) / 4) << 21) #define STM32_DMA_CCR_MBURST(b_len) ((((b_len) - 4) / 4) << 21) +#ifdef CHIP_FAMILY_STM32H7 +#define STM32_DMA_CCR_CHANNEL_MASK (0 << 25) +#define STM32_DMA_CCR_CHANNEL(channel) (0) +#else /* !CHIP_FAMILY_STM32H7 */ #define STM32_DMA_CCR_CHANNEL_MASK (0x7 << 25) #define STM32_DMA_CCR_CHANNEL(channel) ((channel) << 25) +#endif /* !CHIP_FAMILY_STM32H7 */ #define STM32_DMA_CCR_RSVD_MASK (0xF0100000) @@ -2266,6 +2624,121 @@ typedef volatile struct stm32_dma_regs stm32_dma_regs_t; #define STM32_DMA_CCR_MEM2MEM (1 << 14) #endif /* !CHIP_FAMILY_STM32F4 */ +#ifdef CHIP_FAMILY_STM32H7 +/* The requests for the DMA1/DMA2 controllers are routed through DMAMUX1. */ +/* DMAMUX1/2 registers */ +#define DMAMUX1 0 +#define DMAMUX2 1 +#define STM32_DMAMUX_BASE(n) ((n) ? STM32_DMAMUX2_BASE \ + : STM32_DMAMUX1_BASE) +#define STM32_DMAMUX_REG32(n, off) REG32(STM32_DMAMUX_BASE(n) + (off)) +#define STM2_DMAMUX_CxCR(n, x) STM32_DMAMUX_REG32(n, 4 * (x)) +#define STM2_DMAMUX_CSR(n) STM32_DMAMUX_REG32(n, 0x80) +#define STM2_DMAMUX_CFR(n) STM32_DMAMUX_REG32(n, 0x84) +#define STM2_DMAMUX_RGxCR(n, x) STM32_DMAMUX_REG32(n, 0x100 + 4 * (x)) +#define STM2_DMAMUX_RGSR(n) STM32_DMAMUX_REG32(n, 0x140) +#define STM2_DMAMUX_RGCFR(n) STM32_DMAMUX_REG32(n, 0x144) + +enum dmamux1_request { + DMAMUX1_REQ_ADC1 = 9, + DMAMUX1_REQ_ADC2 = 10, + DMAMUX1_REQ_TIM1_CH1 = 11, + DMAMUX1_REQ_TIM1_CH2 = 12, + DMAMUX1_REQ_TIM1_CH3 = 13, + DMAMUX1_REQ_TIM1_CH4 = 14, + DMAMUX1_REQ_TIM1_UP = 15, + DMAMUX1_REQ_TIM1_TRIG = 16, + DMAMUX1_REQ_TIM1_COM = 17, + DMAMUX1_REQ_TIM2_CH1 = 18, + DMAMUX1_REQ_TIM2_CH2 = 19, + DMAMUX1_REQ_TIM2_CH3 = 20, + DMAMUX1_REQ_TIM2_CH4 = 21, + DMAMUX1_REQ_TIM2_UP = 22, + DMAMUX1_REQ_TIM3_CH1 = 23, + DMAMUX1_REQ_TIM3_CH2 = 24, + DMAMUX1_REQ_TIM3_CH3 = 25, + DMAMUX1_REQ_TIM3_CH4 = 26, + DMAMUX1_REQ_TIM3_UP = 27, + DMAMUX1_REQ_TIM3_TRIG = 28, + DMAMUX1_REQ_TIM4_CH1 = 29, + DMAMUX1_REQ_TIM4_CH2 = 30, + DMAMUX1_REQ_TIM4_CH3 = 31, + DMAMUX1_REQ_TIM4_UP = 32, + DMAMUX1_REQ_I2C1_RX = 33, + DMAMUX1_REQ_I2C1_TX = 34, + DMAMUX1_REQ_I2C2_RX = 35, + DMAMUX1_REQ_I2C2_TX = 36, + DMAMUX1_REQ_SPI1_RX = 37, + DMAMUX1_REQ_SPI1_TX = 38, + DMAMUX1_REQ_SPI2_RX = 39, + DMAMUX1_REQ_SPI2_TX = 40, + DMAMUX1_REQ_USART1_RX = 41, + DMAMUX1_REQ_USART1_TX = 42, + DMAMUX1_REQ_USART2_RX = 43, + DMAMUX1_REQ_USART2_TX = 44, + DMAMUX1_REQ_USART3_RX = 45, + DMAMUX1_REQ_USART3_TX = 46, + DMAMUX1_REQ_TIM8_CH1 = 47, + DMAMUX1_REQ_TIM8_CH2 = 48, + DMAMUX1_REQ_TIM8_CH3 = 49, + DMAMUX1_REQ_TIM8_CH4 = 50, + DMAMUX1_REQ_TIM8_UP = 51, + DMAMUX1_REQ_TIM8_TRIG = 52, + DMAMUX1_REQ_TIM8_COM = 53, + DMAMUX1_REQ_TIM5_CH1 = 55, + DMAMUX1_REQ_TIM5_CH2 = 56, + DMAMUX1_REQ_TIM5_CH3 = 57, + DMAMUX1_REQ_TIM5_CH4 = 58, + DMAMUX1_REQ_TIM5_UP = 59, + DMAMUX1_REQ_TIM5_TRIG = 60, + DMAMUX1_REQ_SPI3_RX = 61, + DMAMUX1_REQ_SPI3_TX = 62, + DMAMUX1_REQ_UART4_RX = 63, + DMAMUX1_REQ_UART4_TX = 64, + DMAMUX1_REQ_USART5_RX = 65, + DMAMUX1_REQ_UART5_TX = 66, + DMAMUX1_REQ_DAC1 = 67, + DMAMUX1_REQ_DAC2 = 68, + DMAMUX1_REQ_TIM6_UP = 69, + DMAMUX1_REQ_TIM7_UP = 70, + DMAMUX1_REQ_USART6_RX = 71, + DMAMUX1_REQ_USART6_TX = 72, + DMAMUX1_REQ_I2C3_RX = 73, + DMAMUX1_REQ_I2C3_TX = 74, + DMAMUX1_REQ_DCMI = 75, + DMAMUX1_REQ_CRYP_IN = 76, + DMAMUX1_REQ_CRYP_OUT = 77, + DMAMUX1_REQ_HASH_IN = 78, + DMAMUX1_REQ_UART7_RX = 79, + DMAMUX1_REQ_UART7_TX = 80, + DMAMUX1_REQ_UART8_RX = 81, + DMAMUX1_REQ_UART8_TX = 82, + DMAMUX1_REQ_SPI4_RX = 83, + DMAMUX1_REQ_SPI4_TX = 84, + DMAMUX1_REQ_SPI5_RX = 85, + DMAMUX1_REQ_SPI5_TX = 86, + DMAMUX1_REQ_SAI1_A = 87, + DMAMUX1_REQ_SAI1_B = 88, + DMAMUX1_REQ_SAI2_A = 89, + DMAMUX1_REQ_SAI2_B = 90, + DMAMUX1_REQ_SWPMI_RX = 91, + DMAMUX1_REQ_SWPMI_TX = 92, + DMAMUX1_REQ_SPDIFRX_DT = 93, + DMAMUX1_REQ_SPDIFRX_CS = 94, + DMAMUX1_REQ_TIM15_CH1 = 105, + DMAMUX1_REQ_TIM15_UP = 106, + DMAMUX1_REQ_TIM15_TRIG = 107, + DMAMUX1_REQ_TIM15_COM = 108, + DMAMUX1_REQ_TIM16_CH1 = 109, + DMAMUX1_REQ_TIM16_UP = 110, + DMAMUX1_REQ_TIM17_CH1 = 111, + DMAMUX1_REQ_TIM17_UP = 112, + DMAMUX1_REQ_SAI3_A = 113, + DMAMUX1_REQ_SAI3_B = 114, + DMAMUX1_REQ_ADC3 = 115, +}; +#endif /* CHIP_FAMILY_STM32H7 */ + /* --- CRC --- */ #define STM32_CRC_DR REG32(STM32_CRC_BASE + 0x0) #define STM32_CRC_DR32 REG32(STM32_CRC_BASE + 0x0) diff --git a/chip/stm32/system.c b/chip/stm32/system.c index c9bc61a818..47052dfccf 100644 --- a/chip/stm32/system.c +++ b/chip/stm32/system.c @@ -137,17 +137,17 @@ void system_hibernate(uint32_t seconds, uint32_t microseconds) static void check_reset_cause(void) { uint32_t flags = bkpdata_read(BKPDATA_INDEX_SAVED_RESET_FLAGS); - uint32_t raw_cause = STM32_RCC_CSR; - uint32_t pwr_status = STM32_PWR_CSR; + uint32_t raw_cause = STM32_RCC_RESET_CAUSE; + uint32_t pwr_status = STM32_PWR_RESET_CAUSE; /* Clear the hardware reset cause by setting the RMVF bit */ - STM32_RCC_CSR |= 1 << 24; + STM32_RCC_RESET_CAUSE |= RESET_CAUSE_RMVF; /* Clear SBF in PWR_CSR */ - STM32_PWR_CR |= 1 << 3; + STM32_PWR_RESET_CAUSE_CLR |= RESET_CAUSE_SBF_CLR; /* Clear saved reset flags */ bkpdata_write(BKPDATA_INDEX_SAVED_RESET_FLAGS, 0); - if (raw_cause & 0x60000000) { + if (raw_cause & RESET_CAUSE_WDG) { /* * IWDG or WWDG, if the watchdog was not used as an hard reset * mechanism @@ -156,20 +156,20 @@ static void check_reset_cause(void) flags |= RESET_FLAG_WATCHDOG; } - if (raw_cause & 0x10000000) + if (raw_cause & RESET_CAUSE_SFT) flags |= RESET_FLAG_SOFT; - if (raw_cause & 0x08000000) + if (raw_cause & RESET_CAUSE_POR) flags |= RESET_FLAG_POWER_ON; - if (raw_cause & 0x04000000) + if (raw_cause & RESET_CAUSE_PIN) flags |= RESET_FLAG_RESET_PIN; - if (pwr_status & 0x00000002) + if (pwr_status & RESET_CAUSE_SBF) /* Hibernated and subsequently awakened */ flags |= RESET_FLAG_HIBERNATE; - if (!flags && (raw_cause & 0xfe000000)) + if (!flags && (raw_cause & RESET_CAUSE_OTHER)) flags |= RESET_FLAG_OTHER; /* @@ -223,6 +223,8 @@ void chip_pre_init(void) STM32_RCC_PB1_WWDG | STM32_RCC_PB1_IWDG; apb2fz_reg = STM32_RCC_PB2_TIM9 | STM32_RCC_PB2_TIM10 | STM32_RCC_PB2_TIM11; +#elif defined(CHIP_FAMILY_STM32H7) + /* TODO(b/67081508) */ #endif if (apb1fz_reg) @@ -239,22 +241,29 @@ void system_pre_init(void) #endif /* enable clock on Power module */ +#ifndef CHIP_FAMILY_STM32H7 STM32_RCC_APB1ENR |= STM32_RCC_PWREN; +#endif #if defined(CHIP_FAMILY_STM32F4) /* enable backup registers */ STM32_RCC_AHB1ENR |= STM32_RCC_AHB1ENR_BKPSRAMEN; +#elif defined(CHIP_FAMILY_STM32H7) + /* enable backup registers */ + STM32_RCC_AHB4ENR |= 1 << 28; #else /* enable backup registers */ STM32_RCC_APB1ENR |= 1 << 27; #endif /* Delay 1 APB clock cycle after the clock is enabled */ clock_wait_bus_cycles(BUS_APB, 1); +#ifndef CHIP_FAMILY_STM32H7 /* Enable access to RCC CSR register and RTC backup registers */ STM32_PWR_CR |= 1 << 8; #ifdef CHIP_VARIANT_STM32L476 /* Enable Vddio2 */ STM32_PWR_CR2 |= 1 << 9; #endif +#endif /* !CHIP_FAMILY_STM32H7 */ /* switch on LSI */ STM32_RCC_CSR |= 1 << 0; @@ -270,7 +279,8 @@ void system_pre_init(void) STM32_RCC_CSR = (STM32_RCC_CSR & ~0x00C30000) | 0x00420000; } #elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) || \ - defined(CHIP_FAMILY_STM32L4) || defined(CHIP_FAMILY_STM32F4) + defined(CHIP_FAMILY_STM32L4) || defined(CHIP_FAMILY_STM32F4) || \ + defined(CHIP_FAMILY_STM32H7) if ((STM32_RCC_BDCR & BDCR_ENABLE_MASK) != BDCR_ENABLE_VALUE) { /* The RTC settings are bad, we need to reset it */ STM32_RCC_BDCR |= STM32_RCC_BDCR_BDRST; @@ -476,5 +486,8 @@ int system_is_reboot_warm(void) #elif defined(CHIP_FAMILY_STM32F4) return ((STM32_RCC_AHB1ENR & STM32_RCC_AHB1ENR_GPIOMASK) == STM32_RCC_AHB1ENR_GPIOMASK); +#elif defined(CHIP_FAMILY_STM32H7) + return ((STM32_RCC_AHB4ENR & STM32_RCC_AHB4ENR_GPIOMASK) + == STM32_RCC_AHB4ENR_GPIOMASK); #endif } diff --git a/chip/stm32/uart.c b/chip/stm32/uart.c index de92454369..8410497d72 100644 --- a/chip/stm32/uart.c +++ b/chip/stm32/uart.c @@ -232,6 +232,8 @@ static void uart_freq_change(void) * up from sleep */ freq = 8000000; +#elif defined(CHIP_FAMILY_STM32H7) + freq = 64000000; /* from 64 Mhz HSI */ #else /* UART clocked from the main clock */ freq = clock_get_freq(); @@ -278,6 +280,12 @@ void uart_init(void) #elif (UARTN == 2) STM32_RCC_CFGR3 |= 0x030000; /* USART2 clock source from HSI(8MHz) */ #endif /* UARTN */ +#elif defined(CHIP_FAMILY_STM32H7) /* Clocked from 64 Mhz HSI */ +#if ((UARTN == 1) || (UARTN == 6)) + STM32_RCC_D2CCIP2R |= STM32_RCC_D2CCIP2_USART16SEL_HSI; +#else + STM32_RCC_D2CCIP2R |= STM32_RCC_D2CCIP2_USART234578SEL_HSI; +#endif /* UARTN */ #elif defined(CHIP_FAMILY_STM32L4) /* USART1 clock source from SYSCLK */ STM32_RCC_CCIPR &= ~STM32_RCC_CCIPR_USART1SEL_MASK; |