summaryrefslogtreecommitdiff
path: root/chip/stm32
diff options
context:
space:
mode:
Diffstat (limited to 'chip/stm32')
-rw-r--r--chip/stm32/build.mk7
-rw-r--r--chip/stm32/clock-stm32h7.c213
-rw-r--r--chip/stm32/config-stm32h7x3.h48
-rw-r--r--chip/stm32/config_chip.h6
-rw-r--r--chip/stm32/dma-stm32f4.c7
-rw-r--r--chip/stm32/gpio-stm32h7.c47
-rw-r--r--chip/stm32/gpio.c4
-rw-r--r--chip/stm32/hwtimer32.c11
-rw-r--r--chip/stm32/registers.h491
-rw-r--r--chip/stm32/system.c35
-rw-r--r--chip/stm32/uart.c8
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;