From 663bf4d9680b4768c6ecd44364d86987b7518171 Mon Sep 17 00:00:00 2001 From: Javier Casas Date: Thu, 8 Sep 2022 10:13:14 +0200 Subject: [PATCH] Add support for stm32h7b3xx MCU's flash --- arch/arm/include/stm32h7/chip.h | 57 +- arch/arm/include/stm32h7/irq.h | 2 + arch/arm/src/stm32h7/Kconfig | 42 + arch/arm/src/stm32h7/hardware/stm32_dmamux.h | 2 + .../arm/src/stm32h7/hardware/stm32_ethernet.h | 4 +- arch/arm/src/stm32h7/hardware/stm32_exti.h | 4 +- arch/arm/src/stm32h7/hardware/stm32_flash.h | 2 + arch/arm/src/stm32h7/hardware/stm32_gpio.h | 2 + arch/arm/src/stm32h7/hardware/stm32_i2c.h | 2 + .../src/stm32h7/hardware/stm32_memorymap.h | 2 + arch/arm/src/stm32h7/hardware/stm32_pinmap.h | 2 + arch/arm/src/stm32h7/hardware/stm32_pwr.h | 2 + arch/arm/src/stm32h7/hardware/stm32_rcc.h | 2 + arch/arm/src/stm32h7/hardware/stm32_sdmmc.h | 2 + arch/arm/src/stm32h7/hardware/stm32_spi.h | 2 + arch/arm/src/stm32h7/hardware/stm32_syscfg.h | 2 + arch/arm/src/stm32h7/hardware/stm32_uart.h | 2 + .../src/stm32h7/hardware/stm32h7b3xx_flash.h | 298 ++++++ .../src/stm32h7/hardware/stm32h7x3xx_gpio.h | 4 +- .../src/stm32h7/hardware/stm32h7x3xx_pinmap.h | 4 +- .../src/stm32h7/hardware/stm32h7x3xx_pwr.h | 35 +- .../src/stm32h7/hardware/stm32h7x3xx_spi.h | 4 +- .../src/stm32h7/hardware/stm32h7x3xx_uart.h | 4 +- arch/arm/src/stm32h7/stm32_exti_gpio.c | 4 +- arch/arm/src/stm32h7/stm32_flash.c | 976 +---------------- arch/arm/src/stm32h7/stm32_gpio.c | 4 +- arch/arm/src/stm32h7/stm32_rcc.c | 2 + arch/arm/src/stm32h7/stm32h743xx_flash.c | 978 ++++++++++++++++++ arch/arm/src/stm32h7/stm32h7b3xx_flash.c | 968 +++++++++++++++++ arch/arm/src/stm32h7/stm32h7x3xx_rcc.c | 8 + 30 files changed, 2438 insertions(+), 984 deletions(-) create mode 100644 arch/arm/src/stm32h7/hardware/stm32h7b3xx_flash.h create mode 100644 arch/arm/src/stm32h7/stm32h743xx_flash.c create mode 100644 arch/arm/src/stm32h7/stm32h7b3xx_flash.c diff --git a/arch/arm/include/stm32h7/chip.h b/arch/arm/include/stm32h7/chip.h index 3d0d0be491..4a317516f4 100644 --- a/arch/arm/include/stm32h7/chip.h +++ b/arch/arm/include/stm32h7/chip.h @@ -70,7 +70,8 @@ defined (CONFIG_ARCH_CHIP_STM32H753II) || \ defined (CONFIG_ARCH_CHIP_STM32H753VI) || \ defined (CONFIG_ARCH_CHIP_STM32H753XI) || \ - defined (CONFIG_ARCH_CHIP_STM32H753ZI) + defined (CONFIG_ARCH_CHIP_STM32H753ZI) || \ + defined (CONFIG_ARCH_CHIP_STM32H7B3LI) #elif defined(CONFIG_ARCH_CHIP_STM32H747XI) #else # error STM32 H7 chip not identified @@ -116,6 +117,60 @@ # error CONFIG_STM32H7_IO_CONFIG_x Not Set # endif +# define STM32H7_NDMA (4) /* (4) DMA1, DMA2, BDMA and MDMA */ +# define STM32H7_NADC (3) /* (3) ADC1-3*/ +# define STM32H7_NDAC (2) /* (2) DAC1-2*/ +# define STM32H7_NCMP (2) /* (2) ultra-low power comparators */ +# define STM32H7_NPGA (2) /* (2) Operational amplifiers: OPAMP */ +# define STM32H7_NDFSDM (1) /* (1) digital filters for sigma delta modulator */ +# define STM32H7_NUSART (4) /* (4) USART1-3, 6 */ +# define STM32H7_NSPI (6) /* (6) SPI1-6 */ +# define STM32H7_NI2S (3) /* (3) I2S1-3 */ +# define STM32H7_NUART (4) /* (4) UART4-5, 7-8 */ +# define STM32H7_NI2C (4) /* (4) I2C1-4 */ +# define STM32H7_NSAI (4) /* (4) SAI1-4*/ +# define STM32H7_NCAN (2) /* (2) CAN1-2 */ +# define STM32H7_NSDIO (2) /* (2) SDIO */ +#elif defined(CONFIG_STM32H7_STM32H7B3XX) +/* Memory */ + +# define STM32H7_SRAM_SIZE (1024*1024) /* 1024Kb SRAM on AXI bus Matrix (D1) */ +# define STM32H7_SRAM1_SIZE (64*1024) /* 64Kb SRAM1 on AHB bus Matrix (D2) */ +# define STM32H7_SRAM2_SIZE (64*1024) /* 64Kb SRAM2 on AHB bus Matrix (D2) */ +# define STM32H7_SRAM3_SIZE (0*1024) /* No SRAM3 on AHB bus Matrix (D2) */ +# define STM32H7_SRAM123_SIZE (128*1024) /* 128Kb SRAM123 on AHB bus Matrix (D2) */ +# define STM32H7_SRAM4_SIZE (32*1024) /* 32Kb SRAM2 on AHB bus Matrix (D3) */ +# if defined(CONFIG_ARMV7M_HAVE_DTCM) +# define STM32H7_DTCM_SRAM_SIZE (128*1024) /* 128Kb DTCM SRAM on TCM interface */ +# else +# define STM32H7_DTCM_SRAM_SIZE (0) /* No DTCM SRAM on TCM interface */ +# endif +# if defined(CONFIG_ARMV7M_HAVE_ITCM) +# define STM32H7_ITCM_SRAM_SIZE (64*1024) /* 64b ITCM SRAM on TCM interface */ +# else +# define STM32H7_ITCM_SRAM_SIZE (0) /* No ITCM SRAM on TCM interface */ +# endif + +/* Peripherals */ + +# if defined(CONFIG_STM32H7_IO_CONFIG_A) +# define STM32H7_NGPIO (10) /* GPIOA-GPIOJ */ +# elif defined(CONFIG_STM32H7_IO_CONFIG_B) +# define STM32H7_NGPIO (11) /* GPIOA-GPIOK */ +# elif defined(CONFIG_STM32H7_IO_CONFIG_I) +# define STM32H7_NGPIO (9) /* GPIOA-GPIOI */ +# elif defined(CONFIG_STM32H7_IO_CONFIG_L) +# define STM32H7_NGPIO (11) /* GPIOA-GPIOK */ +# elif defined(CONFIG_STM32H7_IO_CONFIG_V) +# define STM32H7_NGPIO (8) /* GPIOA-GPIOH, missing GPIOF-GPIOG */ +# elif defined(CONFIG_STM32H7_IO_CONFIG_X) +# define STM32H7_NGPIO (11) /* GPIOA-GPIOK */ +# elif defined(CONFIG_STM32H7_IO_CONFIG_Z) +# define STM32H7_NGPIO (8) /* GPIOA-GPIOH */ +# else +# error CONFIG_STM32H7_IO_CONFIG_x Not Set +# endif + # define STM32H7_NDMA (4) /* (4) DMA1, DMA2, BDMA and MDMA */ # define STM32H7_NADC (3) /* (3) ADC1-3*/ # define STM32H7_NDAC (2) /* (2) DAC1-2*/ diff --git a/arch/arm/include/stm32h7/irq.h b/arch/arm/include/stm32h7/irq.h index 54ec535af1..e35f97d6d0 100644 --- a/arch/arm/include/stm32h7/irq.h +++ b/arch/arm/include/stm32h7/irq.h @@ -69,6 +69,8 @@ #if defined(CONFIG_STM32H7_STM32H7X3XX) # include +#elif defined(CONFIG_STM32H7_STM32H7B3XX) +# include #elif defined(CONFIG_STM32H7_STM32H7X7XX) # include #else diff --git a/arch/arm/src/stm32h7/Kconfig b/arch/arm/src/stm32h7/Kconfig index 402ca98f6e..b34252ab01 100644 --- a/arch/arm/src/stm32h7/Kconfig +++ b/arch/arm/src/stm32h7/Kconfig @@ -215,8 +215,29 @@ config ARCH_CHIP_STM32H753ZI STM32 H7 Cortex M7, 2048 Kb FLASH, 1024K Kb SRAM, with cryptographic accelerator, LQFP144 +config ARCH_CHIP_STM32H7B3LI + bool "STM32H7B3LI" + select STM32H7_STM32H7B3XX + select STM32H7_FLASH_CONFIG_I + select STM32H7_IO_CONFIG_L + select STM32H7_HAVE_FDCAN1 + select STM32H7_HAVE_FDCAN2 + select STM32H7_HAVE_SMPS + ---help--- + STM32 H7 Cortex M7, 2048 Kb FLASH, 1376 Kb SRAM, + with cryptographic accelerator, TFBGA225 + endchoice # STM32 H7 Chip Selection +config STM32H7_HAVE_SMPS + bool + default n + +config STM32H7_PWR_DIRECT_SMPS_SUPPLY + bool "Use direct SMPS supply mode" + depends on STM32H7_HAVE_SMPS + default n + config STM32H7_IO_CONFIG_A bool default n @@ -229,6 +250,10 @@ config STM32H7_IO_CONFIG_I bool default n +config STM32H7_IO_CONFIG_L + bool + default n + config STM32H7_IO_CONFIG_V bool default n @@ -258,6 +283,23 @@ config STM32H7_STM32H7X3XX select STM32H7_HAVE_SPI5 if !STM32H7_IO_CONFIG_V select STM32H7_HAVE_SPI6 +config STM32H7_STM32H7B3XX + bool + default n + select ARCH_HAVE_FPU + select ARCH_HAVE_DPFPU + select ARMV7M_HAVE_ICACHE + select ARMV7M_HAVE_DCACHE + select ARMV7M_HAVE_ITCM + select ARMV7M_HAVE_DTCM + select STM32H7_HAVE_ETHERNET + select STM32H7_HAVE_FMC + select STM32H7_HAVE_GPIOF if !STM32H7_IO_CONFIG_V + select STM32H7_HAVE_GPIOG if !STM32H7_IO_CONFIG_V + select STM32H7_HAVE_SPI4 + select STM32H7_HAVE_SPI5 if !STM32H7_IO_CONFIG_V + select STM32H7_HAVE_SPI6 + config STM32H7_STM32H7X7XX bool default n diff --git a/arch/arm/src/stm32h7/hardware/stm32_dmamux.h b/arch/arm/src/stm32h7/hardware/stm32_dmamux.h index fcfb1c297c..74d35c5799 100644 --- a/arch/arm/src/stm32h7/hardware/stm32_dmamux.h +++ b/arch/arm/src/stm32h7/hardware/stm32_dmamux.h @@ -203,6 +203,8 @@ #if defined(CONFIG_STM32H7_STM32H7X3XX) # include "hardware/stm32h7x3xx_dmamux.h" +#elif defined(CONFIG_STM32H7_STM32H7B3XX) +# include "hardware/stm32h7x3xx_dmamux.h" #elif defined(CONFIG_STM32H7_STM32H7X7XX) # include "hardware/stm32h7x3xx_dmamux.h" #else diff --git a/arch/arm/src/stm32h7/hardware/stm32_ethernet.h b/arch/arm/src/stm32h7/hardware/stm32_ethernet.h index 4abdd0f4c9..5ed1e6c008 100644 --- a/arch/arm/src/stm32h7/hardware/stm32_ethernet.h +++ b/arch/arm/src/stm32h7/hardware/stm32_ethernet.h @@ -31,7 +31,7 @@ * families */ -#if defined(CONFIG_STM32H7_STM32H7X3XX) +#if defined(CONFIG_STM32H7_STM32H7X3XX) || defined(CONFIG_STM32H7_STM32H7B3XX) /**************************************************************************** * Pre-processor Definitions @@ -674,5 +674,5 @@ struct eth_desc_s ****************************************************************************/ #endif /* __ASSEMBLY__ */ -#endif /* CONFIG_STM32H7_STM32H7X3XX */ +#endif /* CONFIG_STM32H7_STM32H7X3XX || CONFIG_STM32H7_STM32H7B3XX */ #endif /* __ARCH_ARM_SRC_STM32H7_HARDWARE_STM32_ETHERNET_H */ diff --git a/arch/arm/src/stm32h7/hardware/stm32_exti.h b/arch/arm/src/stm32h7/hardware/stm32_exti.h index b272283532..7c6f2bd6f5 100644 --- a/arch/arm/src/stm32h7/hardware/stm32_exti.h +++ b/arch/arm/src/stm32h7/hardware/stm32_exti.h @@ -33,7 +33,7 @@ * families */ -#if defined(CONFIG_STM32H7_STM32H7X3XX) || defined(CONFIG_STM32H7_STM32H7X7XX) +#if defined(CONFIG_STM32H7_STM32H7X3XX) || defined(CONFIG_STM32H7_STM32H7X7XX) || defined(CONFIG_STM32H7_STM32H7B3XX) /**************************************************************************** * Pre-processor Definitions @@ -237,5 +237,5 @@ #define EXTI_EVENT_ETHWKUP 86 /* Ethernet wakeup */ #define EXTI_EVENT_HSECSS 87 /* HSECSS interrupt */ -#endif /* CONFIG_STM32H7_STM32H7X3XX || CONFIG_STM32H7_STM32H7X7XX */ +#endif /* CONFIG_STM32H7_STM32H7X3XX || CONFIG_STM32H7_STM32H7X7XX || CONFIG_STM32H7_STM32H7B3XX */ #endif /* __ARCH_ARM_SRC_STM32H7_HARDWARE_STM32_EXTI_H */ diff --git a/arch/arm/src/stm32h7/hardware/stm32_flash.h b/arch/arm/src/stm32h7/hardware/stm32_flash.h index 9e49579188..ff722521ec 100644 --- a/arch/arm/src/stm32h7/hardware/stm32_flash.h +++ b/arch/arm/src/stm32h7/hardware/stm32_flash.h @@ -30,6 +30,8 @@ #if defined(CONFIG_STM32H7_STM32H7X3XX) # include "hardware/stm32h7x3xx_flash.h" +#elif defined(CONFIG_STM32H7_STM32H7B3XX) +# include "hardware/stm32h7b3xx_flash.h" #elif defined(CONFIG_STM32H7_STM32H7X7XX) # include "hardware/stm32h7x3xx_flash.h" #else diff --git a/arch/arm/src/stm32h7/hardware/stm32_gpio.h b/arch/arm/src/stm32h7/hardware/stm32_gpio.h index 3aa2bafd1c..d12816951d 100644 --- a/arch/arm/src/stm32h7/hardware/stm32_gpio.h +++ b/arch/arm/src/stm32h7/hardware/stm32_gpio.h @@ -30,6 +30,8 @@ #if defined(CONFIG_STM32H7_STM32H7X3XX) # include "hardware/stm32h7x3xx_gpio.h" +#elif defined(CONFIG_STM32H7_STM32H7B3XX) +# include "hardware/stm32h7x3xx_gpio.h" #elif defined(CONFIG_STM32H7_STM32H7X7XX) # include "hardware/stm32h7x3xx_gpio.h" #else diff --git a/arch/arm/src/stm32h7/hardware/stm32_i2c.h b/arch/arm/src/stm32h7/hardware/stm32_i2c.h index bc8fba81c7..77d5602102 100644 --- a/arch/arm/src/stm32h7/hardware/stm32_i2c.h +++ b/arch/arm/src/stm32h7/hardware/stm32_i2c.h @@ -30,6 +30,8 @@ #if defined(CONFIG_STM32H7_STM32H7X3XX) # include "hardware/stm32h7x3xx_i2c.h" +#elif defined(CONFIG_STM32H7_STM32H7B3XX) +# include "hardware/stm32h7x3xx_i2c.h" #elif defined(CONFIG_STM32H7_STM32H7X7XX) # include "hardware/stm32h7x3xx_i2c.h" #else diff --git a/arch/arm/src/stm32h7/hardware/stm32_memorymap.h b/arch/arm/src/stm32h7/hardware/stm32_memorymap.h index c758012431..faeeecca57 100644 --- a/arch/arm/src/stm32h7/hardware/stm32_memorymap.h +++ b/arch/arm/src/stm32h7/hardware/stm32_memorymap.h @@ -30,6 +30,8 @@ #if defined(CONFIG_STM32H7_STM32H7X3XX) # include "hardware/stm32h7x3xx_memorymap.h" +#elif defined(CONFIG_STM32H7_STM32H7B3XX) +# include "hardware/stm32h7x3xx_memorymap.h" #elif defined(CONFIG_STM32H7_STM32H7X7XX) # include "hardware/stm32h7x3xx_memorymap.h" #else diff --git a/arch/arm/src/stm32h7/hardware/stm32_pinmap.h b/arch/arm/src/stm32h7/hardware/stm32_pinmap.h index 4e50be9502..73ac5d02cf 100644 --- a/arch/arm/src/stm32h7/hardware/stm32_pinmap.h +++ b/arch/arm/src/stm32h7/hardware/stm32_pinmap.h @@ -30,6 +30,8 @@ #if defined(CONFIG_STM32H7_STM32H7X3XX) # include "hardware/stm32h7x3xx_pinmap.h" +#elif defined(CONFIG_STM32H7_STM32H7B3XX) +# include "hardware/stm32h7x3xx_pinmap.h" #elif defined(CONFIG_STM32H7_STM32H7X7XX) # include "hardware/stm32h7x3xx_pinmap.h" #else diff --git a/arch/arm/src/stm32h7/hardware/stm32_pwr.h b/arch/arm/src/stm32h7/hardware/stm32_pwr.h index a51de60264..b603780a4e 100644 --- a/arch/arm/src/stm32h7/hardware/stm32_pwr.h +++ b/arch/arm/src/stm32h7/hardware/stm32_pwr.h @@ -30,6 +30,8 @@ #if defined(CONFIG_STM32H7_STM32H7X3XX) # include "hardware/stm32h7x3xx_pwr.h" +#elif defined(CONFIG_STM32H7_STM32H7B3XX) +# include "hardware/stm32h7x3xx_pwr.h" #elif defined(CONFIG_STM32H7_STM32H7X7XX) # include "hardware/stm32h7x3xx_pwr.h" #else diff --git a/arch/arm/src/stm32h7/hardware/stm32_rcc.h b/arch/arm/src/stm32h7/hardware/stm32_rcc.h index 25e9f77b85..9c33b46002 100644 --- a/arch/arm/src/stm32h7/hardware/stm32_rcc.h +++ b/arch/arm/src/stm32h7/hardware/stm32_rcc.h @@ -30,6 +30,8 @@ #if defined(CONFIG_STM32H7_STM32H7X3XX) # include "hardware/stm32h7x3xx_rcc.h" +#elif defined(CONFIG_STM32H7_STM32H7B3XX) +# include "hardware/stm32h7x3xx_rcc.h" #elif defined(CONFIG_STM32H7_STM32H7X7XX) # include "hardware/stm32h7x3xx_rcc.h" #else diff --git a/arch/arm/src/stm32h7/hardware/stm32_sdmmc.h b/arch/arm/src/stm32h7/hardware/stm32_sdmmc.h index 03be53d38d..40649e49cc 100644 --- a/arch/arm/src/stm32h7/hardware/stm32_sdmmc.h +++ b/arch/arm/src/stm32h7/hardware/stm32_sdmmc.h @@ -30,6 +30,8 @@ #if defined(CONFIG_STM32H7_STM32H7X3XX) # include "stm32h7x3xx_sdmmc.h" +#elif defined(CONFIG_STM32H7_STM32H7B3XX) +# include "stm32h7x3xx_sdmmc.h" #elif defined(CONFIG_STM32H7_STM32H7X7XX) # include "stm32h7x3xx_sdmmc.h" #else diff --git a/arch/arm/src/stm32h7/hardware/stm32_spi.h b/arch/arm/src/stm32h7/hardware/stm32_spi.h index a132f09d7e..d8adb5b0ee 100644 --- a/arch/arm/src/stm32h7/hardware/stm32_spi.h +++ b/arch/arm/src/stm32h7/hardware/stm32_spi.h @@ -30,6 +30,8 @@ #if defined(CONFIG_STM32H7_STM32H7X3XX) # include "hardware/stm32h7x3xx_spi.h" +#elif defined(CONFIG_STM32H7_STM32H7B3XX) +# include "hardware/stm32h7x3xx_spi.h" #elif defined(CONFIG_STM32H7_STM32H7X7XX) # include "hardware/stm32h7x3xx_spi.h" #else diff --git a/arch/arm/src/stm32h7/hardware/stm32_syscfg.h b/arch/arm/src/stm32h7/hardware/stm32_syscfg.h index 702aff2ad8..a047afa39b 100644 --- a/arch/arm/src/stm32h7/hardware/stm32_syscfg.h +++ b/arch/arm/src/stm32h7/hardware/stm32_syscfg.h @@ -30,6 +30,8 @@ #if defined(CONFIG_STM32H7_STM32H7X3XX) # include "hardware/stm32h7x3xx_syscfg.h" +#elif defined(CONFIG_STM32H7_STM32H7B3XX) +# include "hardware/stm32h7x3xx_syscfg.h" #elif defined(CONFIG_STM32H7_STM32H7X7XX) # include "hardware/stm32h7x3xx_syscfg.h" #else diff --git a/arch/arm/src/stm32h7/hardware/stm32_uart.h b/arch/arm/src/stm32h7/hardware/stm32_uart.h index d581a43367..7323a412f7 100644 --- a/arch/arm/src/stm32h7/hardware/stm32_uart.h +++ b/arch/arm/src/stm32h7/hardware/stm32_uart.h @@ -30,6 +30,8 @@ #if defined(CONFIG_STM32H7_STM32H7X3XX) # include "hardware/stm32h7x3xx_uart.h" +#elif defined(CONFIG_STM32H7_STM32H7B3XX) +# include "hardware/stm32h7x3xx_uart.h" #elif defined(CONFIG_STM32H7_STM32H7X7XX) # include "hardware/stm32h7x3xx_uart.h" #else diff --git a/arch/arm/src/stm32h7/hardware/stm32h7b3xx_flash.h b/arch/arm/src/stm32h7/hardware/stm32h7b3xx_flash.h new file mode 100644 index 0000000000..6a53a97925 --- /dev/null +++ b/arch/arm/src/stm32h7/hardware/stm32h7b3xx_flash.h @@ -0,0 +1,298 @@ +/**************************************************************************** + * arch/arm/src/stm32h7/hardware/stm32h7b3xx_flash.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32H7_HARDWARE_STM32H7B3XX_FLASH_H +#define __ARCH_ARM_SRC_STM32H7_HARDWARE_STM32H7B3XX_FLASH_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define STM32_FLASH_ACR_OFFSET 0x0000 /* Access control register */ +#define STM32_FLASH_KEYR_OFFSET 0x0004 /* Key register for bank 1 */ +#define STM32_FLASH_OPTKEYR_OFFSET 0x0008 /* Option key register */ +#define STM32_FLASH_CR_OFFSET 0x000c /* Control register for bank 1 */ +#define STM32_FLASH_SR_OFFSET 0x0010 /* Status register for bank 1 */ +#define STM32_FLASH_CCR_OFFSET 0x0014 /* Clear control register for bank 1 */ +#define STM32_FLASH_OPTCR_OFFSET 0x0018 /* Option control register */ +#define STM32_FLASH_OPTSR_CUR_OFFSET 0x001c /* Option status register (CUR) */ +#define STM32_FLASH_OPTSR_PRG_OFFSET 0x0020 /* Option status register (PRG) */ +#define STM32_FLASH_OPTCCR_OFFSET 0x0024 /* Option clear control register */ +#define STM32_FLASH_PRAR_CUR_OFFSET 0x0028 /* Protection address for bank 1 */ +#define STM32_FLASH_PRAR_PRG_OFFSET 0x002C /* Protection address for bank 1 */ +#define STM32_FLASH_SCAR_CUR_OFFSET 0x0030 /* Secure address for bank 1 (CUR) */ +#define STM32_FLASH_SCAR_PRG_OFFSET 0x0034 /* Secure address for bank 1 (PRG) */ +#define STM32_FLASH_WPSN_CURR_OFFSET 0x0038 /* Write sector protection for bank 1 (CUR) */ +#define STM32_FLASH_WPSN_PRGR_OFFSET 0x003C /* Write sector protection for bank 1 (PRG) */ +#define STM32_FLASH_BOOT_CUR_OFFSET 0x0040 /* Boot address (CUR) */ +#define STM32_FLASH_BOOT_PRGR_OFFSET 0x0044 /* Boot address (PRG) */ +#define STM32_FLASH_CRCCR_OFFSET 0x0050 /* CRC control register for bank 1 */ +#define STM32_FLASH_CRCSADDR_OFFSET 0x0054 /* CRC start address register for bank 1 */ +#define STM32_FLASH_CRCEADDR_OFFSET 0x0058 /* CRC end address register for bank 1 */ +#define STM32_FLASH_CRCDATAR_OFFSET 0x005C /* CRC data register */ +#define STM32_FLASH_ECC_FAR_OFFSET 0x0060 /* ECC fail address register for bank 1 */ +#define STM32_FLASH_OTPBL_CUR_OFFSET 0x0068 /* current values of option bits */ +#define STM32_FLASH_OTPBL_PRG_OFFSET 0x006C /* program values in option bits */ + +#define STM32_FLASH_BANK1_OFFSET 0x0000 /* Bank 1 registers offset */ +#define STM32_FLASH_BANK2_OFFSET 0x0100 /* Bank 2 registers offset */ + +/* Register Addresses *******************************************************/ + +#define STM32_FLASH_ACR (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_ACR_OFFSET) +#define STM32_FLASH_KEYR1 (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_KEYR1_OFFSET) +#define STM32_FLASH_OPTKEYR (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_OPTKEYR_OFFSET) +#define STM32_FLASH_CR1 (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_CR1_OFFSET) +#define STM32_FLASH_SR1 (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_SR1_OFFSET) +#define STM32_FLASH_CCR1 (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_CCR1_OFFSET) +#define STM32_FLASH_OPTCR (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_OPTCR_OFFSET) +#define STM32_FLASH_OPTSR_CUR (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_OPTSR_CUR_OFFSET) +#define STM32_FLASH_OPTSR_PRG (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_OPTSR_PRG_OFFSET) +#define STM32_FLASH_OPTCCR (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_OPTCCR_OFFSET) +#define STM32_FLASH_PRAR_CUR1 (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_PRAR_CUR1_OFFSET) +#define STM32_FLASH_PRAR_PRG1 (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_PRAR_PRG1_OFFSET) +#define STM32_FLASH_SCAR_CUR1 (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_SCAR_CUR1_OFFSET) +#define STM32_FLASH_SCAR_PRG1 (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_SCAR_PRG1_OFFSET) +#define STM32_FLASH_WPSN_CUR1R (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_WPSN_CUR1R_OFFSET) +#define STM32_FLASH_WPSN_PRG1R (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_WPSN_PRG1R_OFFSET) +#define STM32_FLASH_BOOT_CUR (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_BOOT_CUR_OFFSET) +#define STM32_FLASH_BOOT_PRGR (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_BOOT_PRGR_OFFSET) +#define STM32_FLASH_CRCCR1 (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_CRCCR1_OFFSET) +#define STM32_FLASH_CRCSADD1R (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_CRCSADD1R_OFFSET) +#define STM32_FLASH_CRCEADD1R (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_CRCEADD1R_OFFSET) +#define STM32_FLASH_CRCDATAR (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_CRCDATAR_OFFSET) +#define STM32_FLASH_ECC_FA1R (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_ECC_FA1R_OFFSET) +#define STM32_FLASH_OTPBL_CUR (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_OTPBL_CUR_OFFSET) +#define STM32_FLASH_OTPBL_PRG (STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET + STM32_FLASH_OTPBL_PRG_OFFSET) + +#define STM32_FLASH_KEYR2 (STM32_FLASHIF_BASE + STM32_FLASH_BANK2_OFFSET + STM32_FLASH_KEYR2_OFFSET) +#define STM32_FLASH_CR2 (STM32_FLASHIF_BASE + STM32_FLASH_BANK2_OFFSET + STM32_FLASH_CR2_OFFSET) +#define STM32_FLASH_SR2 (STM32_FLASHIF_BASE + STM32_FLASH_BANK2_OFFSET + STM32_FLASH_SR2_OFFSET) +#define STM32_FLASH_CCR2 (STM32_FLASHIF_BASE + STM32_FLASH_BANK2_OFFSET + STM32_FLASH_CCR2_OFFSET) +#define STM32_FLASH_PRAR_CUR2 (STM32_FLASHIF_BASE + STM32_FLASH_BANK2_OFFSET + STM32_FLASH_PRAR_CUR2_OFFSET) +#define STM32_FLASH_PRAR_PRG2 (STM32_FLASHIF_BASE + STM32_FLASH_BANK2_OFFSET + STM32_FLASH_PRAR_PRG2_OFFSET) +#define STM32_FLASH_SCAR_CUR2 (STM32_FLASHIF_BASE + STM32_FLASH_BANK2_OFFSET + STM32_FLASH_SCAR_CUR2_OFFSET) +#define STM32_FLASH_SCAR_PRG2 (STM32_FLASHIF_BASE + STM32_FLASH_BANK2_OFFSET + STM32_FLASH_SCAR_PRG2_OFFSET) +#define STM32_FLASH_WPSN_CUR2R (STM32_FLASHIF_BASE + STM32_FLASH_BANK2_OFFSET + STM32_FLASH_WPSN_CUR2R_OFFSET) +#define STM32_FLASH_WPSN_PRG2R (STM32_FLASHIF_BASE + STM32_FLASH_BANK2_OFFSET + STM32_FLASH_WPSN_PRG2R_OFFSET) +#define STM32_FLASH_CRCCR2 (STM32_FLASHIF_BASE + STM32_FLASH_BANK2_OFFSET + STM32_FLASH_CRCCR2_OFFSET) +#define STM32_FLASH_CRCSADD2R (STM32_FLASHIF_BASE + STM32_FLASH_BANK2_OFFSET + STM32_FLASH_CRCSADD2R_OFFSET) +#define STM32_FLASH_CRCEADD2R (STM32_FLASHIF_BASE + STM32_FLASH_BANK2_OFFSET + STM32_FLASH_CRCEADD2R_OFFSET) +#define STM32_FLASH_ECC_FA2R (STM32_FLASHIF_BASE + STM32_FLASH_BANK2_OFFSET + STM32_FLASH_ECC_FA2R_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +/* Flash Access Control Register (ACR) Bank 1 or 2 */ + +#define FLASH_ACR_LATENCY_SHIFT (0) /* Bits 0-3: Latency */ +#define FLASH_ACR_LATENCY_MASK (15 << FLASH_ACR_LATENCY_SHIFT) +# define FLASH_ACR_LATENCY(n) ((n) << FLASH_ACR_LATENCY_SHIFT) /* n wait states */ +# define FLASH_ACR_LATENCY_0 (0 << FLASH_ACR_LATENCY_SHIFT) /* 0000: Zero wait states */ +# define FLASH_ACR_LATENCY_1 (1 << FLASH_ACR_LATENCY_SHIFT) /* 0001: One wait state */ +# define FLASH_ACR_LATENCY_2 (2 << FLASH_ACR_LATENCY_SHIFT) /* 0010: Two wait states */ +# define FLASH_ACR_LATENCY_3 (3 << FLASH_ACR_LATENCY_SHIFT) /* 0011: Three wait states */ +# define FLASH_ACR_LATENCY_4 (4 << FLASH_ACR_LATENCY_SHIFT) /* 0100: Four wait states */ +# define FLASH_ACR_LATENCY_5 (5 << FLASH_ACR_LATENCY_SHIFT) /* 0101: Five wait states */ +# define FLASH_ACR_LATENCY_6 (6 << FLASH_ACR_LATENCY_SHIFT) /* 0110: Six wait states */ +#define FLASH_ACR_WRHIGHFREQ_SHIFT (4) /* Bitd 4-5: Flash signal delay */ +#define FLASH_ACR_WRHIGHFREQ_MASK (3 << FLASH_ACR_WRHIGHFREQ_SHIFT) +# define FLASH_ACR_WRHIGHFREQ(n) ((n) << FLASH_ACR_WRHIGHFREQ_SHIFT) + +/* Flash Control Register (CR) Bank 1 or 2 */ + +#define FLASH_CR_LOCK (1 << 0) /* Bit 0: Lock */ +#define FLASH_CR_PG (1 << 1) /* Bit 1: Programming */ +#define FLASH_CR_SER (1 << 2) /* Bit 2: Sector erase */ +#define FLASH_CR_BER (1 << 3) /* Bit 3: Bank erase */ +#define FLASH_CR_FW (1 << 4) /* Bit 4: Force write */ +#define FLASH_CR_START (1 << 5) /* Bit 5: Erase start */ +#define FLASH_CR_SSN_SHIFT (6) /* Bits 6-12: Sector number */ +#define FLASH_CR_SSN_MASK (0x7f << FLASH_CR_SSN_SHIFT) /* Used to clear FLASH_CR_SSN bits */ + +# define FLASH_CR_SSN(n) ((uint32_t)((n) & 0x7f) << FLASH_CR_SSN_SHIFT) /* Sector n, n=0..127 */ + +#define FLASH_CR_CRCEN (1 << 15) /* Bit 15: CRC control enable */ +#define FLASH_CR_EOPIE (1 << 16) /* Bit 16: End-of-program interrupt enable */ +#define FLASH_CR_WRPERRIE (1 << 17) /* Bit 17: Write protection error interrupt enable */ +#define FLASH_CR_PGSERRIE (1 << 18) /* Bit 18: Programming sequence error interrupt enable */ +#define FLASH_CR_STRBERRIE (1 << 19) /* Bit 19: Strobe error interrupt enable */ +#define FLASH_CR_INCERRIE (1 << 21) /* Bit 21: Inconsistency error interrupt enable */ +#define FLASH_CR_RDPERRIE (1 << 23) /* Bit 23: Read protection error interrupt enable */ +#define FLASH_CR_RDSERRIE (1 << 24) /* Bit 24: Secure error interrupt enable */ +#define FLASH_CR_SNECCERRIE (1 << 25) /* Bit 25: ECC single correction error interrupt enable */ +#define FLASH_CR_DBECCERRIE (1 << 26) /* Bit 26: ECC double detection error interrupt enable */ +#define FLASH_CR_CRCENDIE (1 << 27) /* Bit 27: CRC end of calculation interrupt enable */ +#define FLASH_CR_CRCRDERRIE (1 << 28) /* Bit 28: CRC read error interrupt enable bit */ + +/* Flash Status Register (SR) Bank 1 or 2 */ + +#define FLASH_SR_BSY (1 << 0) /* Bit 0: Busy */ +#define FLASH_SR_WBNE (1 << 1) /* Bit 1: write buffer not empty */ +#define FLASH_SR_QW (1 << 2) /* Bit 2: wait queue flag */ +#define FLASH_SR_CRCBUSY (1 << 3) /* Bit 3: CRC busy flag */ + /* Bits 4-15: Reserved */ +#define FLASH_SR_EOP (1 << 16) /* Bit 16: End of program */ +#define FLASH_SR_WRPERR (1 << 17) /* Bit 17: Write protection error */ +#define FLASH_SR_PGSERR (1 << 18) /* Bit 18: Programming sequence error */ +#define FLASH_SR_STRBERR (1 << 19) /* Bit 19: Strobe error */ + /* Bit 20: Reserved */ +#define FLASH_SR_INCERR (1 << 21) /* Bit 21: Inconsistency error */ +#define FLASH_SR_RDPERR (1 << 23) /* Bit 23: Read protection error */ +#define FLASH_SR_RDSERR (1 << 24) /* Bit 24: Secure error */ +#define FLASH_SR_SNECCERR (1 << 25) /* Bit 25: ECC single error */ +#define FLASH_SR_DBECCERR (1 << 26) /* Bit 26: ECC double detection error */ +#define FLASH_SR_CRCEND (1 << 27) /* Bit 27: CRC end of calculation */ +#define FLASH_SR_CRCRDERR (1 << 28) /* Bit 28: CRC read error flag */ + +/* Flash Clear control register Bank 1 or 2 */ + +#define FLASH_CLR_EOP (1 << 16) /* Bit 16: Clear end of program */ +#define FLASH_CLR_WRPERR (1 << 17) /* Bit 17: Clear write protection error */ +#define FLASH_CLR_PGSERR (1 << 18) /* Bit 18: Clear programming sequence error */ +#define FLASH_CLR_STRBERR (1 << 19) /* Bit 19: Clear strobe error */ + /* Bit 20: Reserved */ +#define FLASH_CLR_INCERR (1 << 21) /* Bit 21: Clear inconsistency error */ +#define FLASH_CLR_RDPERR (1 << 23) /* Bit 23: Clear read protection error */ +#define FLASH_CLR_RDSERR (1 << 24) /* Bit 24: Clear secure error */ +#define FLASH_CLR_SNECCERR (1 << 25) /* Bit 25: Clear ECC single error */ +#define FLASH_CLR_DBECCERR (1 << 26) /* Bit 26: Clear ECC double detection error */ +#define FLASH_CLR_CRCEND (1 << 27) /* Bit 27: Clear CRC end of calculation */ +#define FLASH_CLR_CRCRDERR (1 << 28) /* Bit 28: Clear CRC read error flag */ + +/* Flash Option Control Register (OPTCR) Bank 1 or 2 */ + +#define FLASH_OPTCR_OPTLOCK (1 << 0) /* Bit 0: Option lock */ +#define FLASH_OPTCR_OPTSTRT (1 << 1) /* Bit 1: Option start */ + /* Bits 2-3: Reserved */ +#define FLASH_OPTCR_MER (1 << 4) /* Bit 4: Mass erase */ +#define FLASH_OPTCR_PGOTP (1 << 5) /* Bit 5: Enable OTP write */ + /* Bits 6-29: Reserved */ +#define FLASH_OPTCR_CHANGEERRIE (1 << 30) /* Bit 30: Option byte change error interrupt enable */ +#define FLASH_OPTCR_SWAPBANK (1 << 31) /* Bit 31: Bank swapping */ + +/* Flash Option Status Register (OPTSR) */ + +#define FLASH_OPTSR_BUSYV (1 << 0) /* Bit 0: Option byte change busy */ + /* Bit 1: Reserved */ +#define FLASH_OPTSR_BORLEV_SHIFT (2) /* Bits 2-3: Brownout level option */ +#define FLASH_OPTSR_BORLEV_MASK (3 << FLASH_OPTSR_BORLEV_SHIFT) +# define FLASH_OPTSR_BORLEV_0 (0 << FLASH_OPTSR_BORLEV_SHIFT) +# define FLASH_OPTSR_BORLEV_1 (1 << FLASH_OPTSR_BORLEV_SHIFT) +# define FLASH_OPTSR_BORLEV_2 (2 << FLASH_OPTSR_BORLEV_SHIFT) +# define FLASH_OPTSR_BORLEV_3 (3 << FLASH_OPTSR_BORLEV_SHIFT) +#define FLASH_OPTSR_IWDGSW (1 << 4) /* Bit 4: IWDG control mode */ + /* Bit 5: Reserved */ +#define FLASH_OPTSR_NRSTSTOP (1 << 6) /* Bit 6: DStop entry reset */ +#define FLASH_OPTSR_NRSTSTDY (1 << 7) /* Bit 7: DStandby entry reset */ +#define FLASH_OPTSR_RDP_SHIFT (8) /* Bits 8-15: Readout protection level */ +#define FLASH_OPTSR_RDP_MASK (0xff << FLASH_OPTSR_RDP_SHIFT) +# define FLASH_OPTSR_RDP(n) ((uint32_t)(n) << FLASH_OPTSR_RDP_SHIFT) +#define FLASH_OPTSR_VDDMMCHSLV (1 << 16) /* Bit 16: high-speed at low-voltage status bit */ +#define FLASH_OPTSR_IWDGFZSTOP (1 << 17) /* Bit 17: IWDG Stop mode freeze */ +#define FLASH_OPTSR_IWDGFZSTBY (1 << 18) /* Bit 18: IWDG Standby mode freeze */ +#define FLASH_OPTSR_STRAMSIZE_SHIFT (19) /* Bits 19-20: ST RAM size */ +#define FLASH_OPTSR_STRAMSIZE_MASK (3 << FLASH_OPTSR_STRAMSIZE_SHIFT) +# define FLASH_OPTSR_STRAMSIZE_2 (0 << FLASH_OPTSR_STRAMSIZE_SHIFT) +# define FLASH_OPTSR_STRAMSIZE_4 (1 << FLASH_OPTSR_STRAMSIZE_SHIFT) +# define FLASH_OPTSR_STRAMSIZE_8 (2 << FLASH_OPTSR_STRAMSIZE_SHIFT) +# define FLASH_OPTSR_STRAMSIZE_16 (3 << FLASH_OPTSR_STRAMSIZE_SHIFT) +#define FLASH_OPTSR_SECURITY (1 << 21) /* Bit 21: Security enable*/ + /* Bits 22-28: Reserved */ +#define FLASH_OPTSR_IOHSLV (1 << 29) /* Bit 29: IO high-speed at low-volateg */ +#define FLASH_OPTSR_CHANGEERR (1 << 30) /* Bit 30: Option byte change error */ +#define FLASH_OPTSR_SWAPBANK (1 << 31) /* Bit 31: Bank swapping status */ + +/* Flash Option Clear Control Register (OPTCCR) */ + + /* Bits 0-29: Reserved */ +#define FLASH_OPTCCR_OPTCHANGEERR (1 << 30) /* Bit 30: OPTCHANGEERR reset */ + /* Bit 31: Reserved */ + +/* Flash Protection Address (PRAR) Bank 1 or 2 */ + +#define FLASH_PRAR_START_SHIFT (0) /* Bits 0-11 Bank PCROP area start status bits */ +#define FLASH_PRAR_START_MASK (0xfff << FLASH_PRAR_START_SHIFT) + /* Bits 12-15: Reserved */ +#define FLASH_PRAR_END_SHIFT (16) /* Bits 16-27 Bank PCROP area end configuration bits */ +#define FLASH_PRAR_END_MASK (0xfff << FLASH_PRAR_END_SHIFT) + /* Bits 28-30: Reserved */ +#define FLASH_PRAR_DMEP (1 << 31) /* Bit 31: Bank PCROP protected erase enable option configuration bit */ + +/* Flash Secure Address (SCAR) Bank 1 or 2 */ + +#define FLASH_SCAR_START_SHIFT (0) /* Bits 0-11 Bank secure-only area start status bits */ +#define FLASH_SCAR_START_MASK (0xfff << FLASH_SCAR_START_SHIFT) + /* Bits 12-15: Reserved */ +#define FLASH_SCAR_END_SHIFT (16) /* Bits 16-27 Bank secure-only area end configuration bits */ +#define FLASH_SCAR_END_MASK (0xfff << FLASH_SCAR_END_SHIFT) + /* Bits 28-30: Reserved */ +#define FLASH_SCAR_DMES (1 << 31) /* Bit 31: Bank secure access protected erase enable option status bit */ + +/* Flash Write Sector Group Protection (WPSGN) Bank 1 or 2 */ + +#define FLASH_WPSGN_SHIFT (0) /* Bits 0-31: Sector group write protection option */ +#define FLASH_WPSGN_MASK (0xffffffff << FLASH_WPSGN_SHIFT) + +/* Flash Register Boot Address (BOOT) */ + +#define FLASH_BOOT_ADD0_SHIFT (0) /* Bits 0-15: Boot address 0 */ +#define FLASH_BOOT_ADD0_MASK (0xffff << FLASH_BOOT_ADD0_SHIFT) +#define FLASH_BOOT_ADD1_SHIFT (16) /* Bits 16-31: Boot address 1 */ +#define FLASH_BOOT_ADD1_MASK (0xffff << FLASH_BOOT_ADD1_SHIFT) + +/* Flash CRC Control Register (CRCCR) Bank 1 or 2 */ + +#define FLASH_CRCCR_CRC_SEC_SHIFT (0) /* Bits 0-6: CRC sector number */ +#define FLASH_CRCCR_CRC_SEC_MASK (0x7f << FLASH_CRCCR_CRC_SEC_SHIFT) +#define FLASH_CRCCR_CRC_BY_SECT (1 << 8) /* Bit 9: Bank CRC sector mode select bit */ +#define FLASH_CRCCR_ADD_SECT (1 << 9) /* Bit 9: Bank CRC sector select bit */ +#define FLASH_CRCCR_CLEAN_SECT (1 << 10) /* Bit 10: Bank CRC sector list clear bit */ +#define FLASH_CRCCR_START_CRC (1 << 16) /* Bit 16: Bank CRC start bit */ +#define FLASH_CRCCR_CLEAN_CRC (1 << 17) /* Bit 16: Bank CRC clean bit */ +#define FLASH_CRCCR_BURST_SHIFT (20) /* Bits 20-21: Bank CRC burst size */ +#define FLASH_CRCCR_BURST_MASK (3 << FLASH_CRCCR_BURST_SHIFT) +# define FLASH_CRCCR_BURST_4 (0 << FLASH_CRCCR_BURST_SHIFT) +# define FLASH_CRCCR_BURST_16 (1 << FLASH_CRCCR_BURST_SHIFT) +# define FLASH_CRCCR_BURST_64 (2 << FLASH_CRCCR_BURST_SHIFT) +# define FLASH_CRCCR_BURST_256 (3 << FLASH_CRCCR_BURST_SHIFT) +#define FLASH_CRCCR_ALL_BANK (1 << 22) /* Bit 22: Bank CRC select bit */ + +/* Flash CRC Start Address Register (CRCSADDR) Bank 1 or 2 */ + + /* Bits 0-1: Reserved */ +#define FLASH_CRCSADDR_START_SHIFT (2) /* Bits 2-19 CRC start address on bank */ +#define FLASH_CRCSADDR_START_MASK (0x3ffff << FLASH_CRCSADDR_START_SHIFT) + /* Bits 20-31: Reserved */ + +/* Flash CRC End Address Register (CRCSEDDR) Bank 1 or 2 */ + + /* Bits 0-1: Reserved */ +#define FLASH_CRCSEDDR_START_SHIFT (2) /* Bits 2-19 CRC end address on bank */ +#define FLASH_CRCSEDDR_START_MASK (0x3ffff << FLASH_CRCSEDDR_START_SHIFT) + /* Bits 20-31: Reserved */ + +/* Flash ECC fail Address(FAnR) Bank 1 or 2 */ + +#define FLASH_ECC_FAR_SHIFT (0) /* Bits 0-15 Bank 1 ECC error add */ +#define FLASH_ECC_FAR_MASK (0xffff << FLASH_CRCSEDDR_START_SHIFT) + +#endif /* __ARCH_ARM_SRC_STM32H7_HARDWARE_STM32H7B3XX_FLASH_H */ diff --git a/arch/arm/src/stm32h7/hardware/stm32h7x3xx_gpio.h b/arch/arm/src/stm32h7/hardware/stm32h7x3xx_gpio.h index 499c840554..4591235978 100644 --- a/arch/arm/src/stm32h7/hardware/stm32h7x3xx_gpio.h +++ b/arch/arm/src/stm32h7/hardware/stm32h7x3xx_gpio.h @@ -28,7 +28,7 @@ #include #include -#if defined(CONFIG_STM32H7_STM32H7X3XX) || defined(CONFIG_STM32H7_STM32H7X7XX) +#if defined(CONFIG_STM32H7_STM32H7X3XX) || defined(CONFIG_STM32H7_STM32H7X7XX) || defined(CONFIG_STM32H7_STM32H7B3XX) /**************************************************************************** * Pre-processor Definitions @@ -384,5 +384,5 @@ #define GPIO_AFRH15_SHIFT (28) #define GPIO_AFRH15_MASK (15 << GPIO_AFRH15_SHIFT) -#endif /* CONFIG_STM32H7_STM32H7X3XX || CONFIG_STM32H7_STM32H7X7XX */ +#endif /* CONFIG_STM32H7_STM32H7X3XX || CONFIG_STM32H7_STM32H7X7XX || CONFIG_STM32H7_STM32H7B3XX */ #endif /* __ARCH_ARM_SRC_STM32H7_HARDWARE_STM32H7X3XX_GPIO_H */ diff --git a/arch/arm/src/stm32h7/hardware/stm32h7x3xx_pinmap.h b/arch/arm/src/stm32h7/hardware/stm32h7x3xx_pinmap.h index 54a59e71a4..bec78e20e3 100644 --- a/arch/arm/src/stm32h7/hardware/stm32h7x3xx_pinmap.h +++ b/arch/arm/src/stm32h7/hardware/stm32h7x3xx_pinmap.h @@ -29,7 +29,7 @@ #include "stm32_gpio.h" -#if defined(CONFIG_STM32H7_STM32H7X3XX) || defined(CONFIG_STM32H7_STM32H7X7XX) +#if defined(CONFIG_STM32H7_STM32H7X3XX) || defined(CONFIG_STM32H7_STM32H7X7XX) || defined(CONFIG_STM32H7_STM32H7B3XX) /**************************************************************************** * Pre-processor Definitions @@ -1532,5 +1532,5 @@ #define GPIO_UART8_TX_1 (GPIO_ALT|GPIO_AF8|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN1) #define GPIO_UART8_TX_2 (GPIO_ALT|GPIO_AF8|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTJ|GPIO_PIN8) -#endif /* CONFIG_STM32H7_STM32H7X3XX || CONFIG_STM32H7_STM32H7X7XX */ +#endif /* CONFIG_STM32H7_STM32H7X3XX || CONFIG_STM32H7_STM32H7X7XX || CONFIG_STM32H7_STM32H7B3XX */ #endif /* __ARCH_ARM_SRC_STM32H7_HARDWARE_STM32H7X3XX_PINMAP_H */ diff --git a/arch/arm/src/stm32h7/hardware/stm32h7x3xx_pwr.h b/arch/arm/src/stm32h7/hardware/stm32h7x3xx_pwr.h index c654214d88..44aa1e21c4 100644 --- a/arch/arm/src/stm32h7/hardware/stm32h7x3xx_pwr.h +++ b/arch/arm/src/stm32h7/hardware/stm32h7x3xx_pwr.h @@ -21,6 +21,12 @@ #ifndef __ARCH_ARM_SRC_STM32H7_HARDWARE_STM32H7X3XX_PWR_H #define __ARCH_ARM_SRC_STM32H7_HARDWARE_STM32H7X3XX_PWR_H +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -121,16 +127,25 @@ /* Power control register 3 (CR3) */ -#define STM32_PWR_CR3_BYPASS (1 << 0) /* Bit 0: Power management unit bypass */ -#define STM32_PWR_CR3_LDOEN (1 << 1) /* Bit 1: Low drop-out regulator enable */ -#define STM32_PWR_CR3_LDOESCUEN (1 << 2) /* Bit 2: Supply configuration update enable */ - /* Bits 3-7: Reserved */ -#define STM32_PWR_CR3_VBE (1 << 8) /* Bit 8: VBAT charging enable */ -#define STM32_PWR_CR3_VBRS (1 << 9) /* Bit 9: VBAT charging resistor selection */ - /* Bits 10-23: Reserved */ -#define STM32_PWR_CR3_USB33DEN (1 << 24) /* Bit 24: VDD33USB voltage level detector enable */ -#define STM32_PWR_CR3_USBREGEN (1 << 25) /* Bit 25: USB regulator enable */ -#define STM32_PWR_CR3_USB33RDY (1 << 26) /* Bit 26: USB supply ready */ +#define STM32_PWR_CR3_BYPASS (1 << 0) /* Bit 0: Power management unit bypass */ +#define STM32_PWR_CR3_LDOEN (1 << 1) /* Bit 1: Low drop-out regulator enable */ +#define STM32_PWR_CR3_LDOESCUEN (1 << 2) /* Bit 2: Supply configuration update enable */ +#ifdef CONFIG_STM32H7_HAVE_SMPS +#define STM32_PWR_CR3_SMPSEXTHP (1 << 3) /* Bit 3: SMPS step-down converter external power delivery selection */ +#define STM32_PWR_CR3_SMPSLEVEL_SHIFT (4) /* BitS 4-5: SMPS step-down converter voltage output level selection */ +# define STM32_PWR_CR3_SMPSLEVEL_MASK (3 << STM32_PWR_CR3_SMPSLEVEL_SHIFT) +# define STM32_PWR_CR3_SMPSLEVEL_R (0 << STM32_PWR_CR3_SMPSLEVEL_SHIFT) /* 00: */ +# define STM32_PWR_CR3_SMPSLEVEL_1V8 (1 << STM32_PWR_CR3_SMPSLEVEL_SHIFT) /* 01 */ +# define STM32_PWR_CR3_SMPSLEVEL_2V5 (2 << STM32_PWR_CR3_SMPSLEVEL_SHIFT) /* 10: */ +# define STM32_PWR_CR3_SMPSLEVEL_2V5B (3 << STM32_PWR_CR3_SMPSLEVEL_SHIFT) /* 11: */ +#endif + /* Bits 6-7: Reserved */ +#define STM32_PWR_CR3_VBE (1 << 8) /* Bit 8: VBAT charging enable */ +#define STM32_PWR_CR3_VBRS (1 << 9) /* Bit 9: VBAT charging resistor selection */ + /* Bits 10-23: Reserved */ +#define STM32_PWR_CR3_USB33DEN (1 << 24) /* Bit 24: VDD33USB voltage level detector enable */ +#define STM32_PWR_CR3_USBREGEN (1 << 25) /* Bit 25: USB regulator enable */ +#define STM32_PWR_CR3_USB33RDY (1 << 26) /* Bit 26: USB supply ready */ /* Power CPU control register (CPUCR) */ diff --git a/arch/arm/src/stm32h7/hardware/stm32h7x3xx_spi.h b/arch/arm/src/stm32h7/hardware/stm32h7x3xx_spi.h index cc2f8f98cc..2a55696007 100644 --- a/arch/arm/src/stm32h7/hardware/stm32h7x3xx_spi.h +++ b/arch/arm/src/stm32h7/hardware/stm32h7x3xx_spi.h @@ -27,7 +27,7 @@ #include -#if defined(CONFIG_STM32H7_STM32H7X3XX) +#if defined(CONFIG_STM32H7_STM32H7X3XX) || defined(CONFIG_STM32H7_STM32H7B3XX) /**************************************************************************** * Pre-processor Definitions @@ -460,5 +460,5 @@ /* TODO: SPI/I2S configuration register */ -#endif /* CONFIG_STM32H7_STM32H7X3XX */ +#endif /* CONFIG_STM32H7_STM32H7X3XX || CONFIG_STM32H7_STM32H7B3XX */ #endif /* __ARCH_ARM_SRC_STM32H7_HARDWARE_STM32H7X3XX_SPI_H */ diff --git a/arch/arm/src/stm32h7/hardware/stm32h7x3xx_uart.h b/arch/arm/src/stm32h7/hardware/stm32h7x3xx_uart.h index bcdf6603a2..544d4c2e2c 100644 --- a/arch/arm/src/stm32h7/hardware/stm32h7x3xx_uart.h +++ b/arch/arm/src/stm32h7/hardware/stm32h7x3xx_uart.h @@ -29,7 +29,7 @@ #include "chip.h" #include "hardware/stm32_memorymap.h" -#if defined(CONFIG_STM32H7_STM32H7X3XX) || defined(CONFIG_STM32H7_STM32H7X7XX) +#if defined(CONFIG_STM32H7_STM32H7X3XX) || defined(CONFIG_STM32H7_STM32H7X7XX) || defined(CONFIG_STM32H7_STM32H7B3XX) /**************************************************************************** * Pre-processor Definitions @@ -410,5 +410,5 @@ # define USART_PRESC_DIV128 (10 << USART_PRESC_SHIFT) /* Input clock divided by 128 */ # define USART_PRESC_DIV256 (11 << USART_PRESC_SHIFT) /* Input clock divided by 256 */ -#endif /* CONFIG_STM32H7_STM32H7X3XX || CONFIG_STM32H7_STM32H7X7XX */ +#endif /* CONFIG_STM32H7_STM32H7X3XX || CONFIG_STM32H7_STM32H7X7XX || CONFIG_STM32H7_STM32H7B3XX */ #endif /* __ARCH_ARM_SRC_STM32H7_HARDWARE_STM32H7X3XX_UART_H */ diff --git a/arch/arm/src/stm32h7/stm32_exti_gpio.c b/arch/arm/src/stm32h7/stm32_exti_gpio.c index 6e0ccc79b0..2fbcc9f55e 100644 --- a/arch/arm/src/stm32h7/stm32_exti_gpio.c +++ b/arch/arm/src/stm32h7/stm32_exti_gpio.c @@ -42,7 +42,7 @@ * families */ -#if defined(CONFIG_STM32H7_STM32H7X3XX) || defined(CONFIG_STM32H7_STM32H7X7XX) +#if defined(CONFIG_STM32H7_STM32H7X3XX) || defined(CONFIG_STM32H7_STM32H7X7XX) || defined(CONFIG_STM32H7_STM32H7B3XX) /**************************************************************************** * Private Types @@ -372,4 +372,4 @@ int stm32_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, return OK; } -#endif /* CONFIG_STM32H7_STM32H7X3XX || CONFIG_STM32H7_STM32H7X7XX */ +#endif /* CONFIG_STM32H7_STM32H7X3XX || CONFIG_STM32H7_STM32H7X7XX || CONFIG_STM32H7_STM32H7B3XX */ diff --git a/arch/arm/src/stm32h7/stm32_flash.c b/arch/arm/src/stm32h7/stm32_flash.c index 2456e3f576..582625efc8 100644 --- a/arch/arm/src/stm32h7/stm32_flash.c +++ b/arch/arm/src/stm32h7/stm32_flash.c @@ -1,977 +1,39 @@ /**************************************************************************** * arch/arm/src/stm32h7/stm32_flash.c * - * Copyright (C) 2019 Gregory Nutt. All rights reserved. - * Authors: Gregory Nutt - * David Sidrane + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at * - * Ported from stm32f7_flash.c, this is the original license: + * http://www.apache.org/licenses/LICENSE-2.0 * - * Copyright (C) 2018 Wolpike LLC. All rights reserved. - * Author: Evgeniy Bobkov - * - * Ported from stm32f20xxf40xx_flash.c, this is the original license: - * - * Copyright (C) 2011 Uros Platise. All rights reserved. - * Author: Uros Platise - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. * ****************************************************************************/ -/* Provides standard flash access functions, to be used by the flash mtd - * driver. The interface is defined in the include/nuttx/progmem.h - * - * Requirements during write/erase operations on FLASH: - * - HSI must be ON. - * - Low Power Modes are not permitted during write/erase - */ - /**************************************************************************** * Included Files ****************************************************************************/ #include -#include -#include -#include -#include -#include - -#include "barriers.h" - -#include "hardware/stm32_flash.h" -#include "arm_internal.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* Flash size is known from the chip selection: - * - * When CONFIG_STM32H7_FLASH_OVERRIDE_DEFAULT is set the - * CONFIG_STM32H7_FLASH_CONFIG_x selects the default FLASH size based on - * the chip part number. This value can be overridden with - * CONFIG_STM32H7_FLASH_OVERRIDE_x - * - * Parts STM32H74xxE have 512Kb of FLASH - * Parts STM32H74xxG have 1024Kb of FLASH - * Parts STM32H74xxI have 2048Kb of FLASH - * - * N.B. Only Single bank mode is supported - */ - -#define _K(x) ((x)*1024) -#define FLASH_SECTOR_SIZE _K(128) -#define FLASH_PAGE_SIZE 32 - -#if !defined(CONFIG_STM32H7_FLASH_OVERRIDE_DEFAULT) && \ - !defined(CONFIG_STM32H7_FLASH_OVERRIDE_B) && \ - !defined(CONFIG_STM32H7_FLASH_OVERRIDE_G) && \ - !defined(CONFIG_STM32H7_FLASH_OVERRIDE_I) && \ - !defined(CONFIG_STM32H7_FLASH_CONFIG_B) && \ - !defined(CONFIG_STM32H7_FLASH_CONFIG_G) && \ - !defined(CONFIG_STM32H7_FLASH_CONFIG_I) -# define CONFIG_STM32H7_FLASH_OVERRIDE_B -# warning "Flash size not defined defaulting to 128KiB (B)" -#endif - -#if !defined(CONFIG_STM32H7_FLASH_OVERRIDE_DEFAULT) - -# undef CONFIG_STM32H7_FLASH_CONFIG_B -# undef CONFIG_STM32H7_FLASH_CONFIG_G -# undef CONFIG_STM32H7_FLASH_CONFIG_I - -# if defined(CONFIG_STM32H7_FLASH_OVERRIDE_B) - -# define CONFIG_STM32H7_FLASH_CONFIG_B - -# elif defined(CONFIG_STM32H7_FLASH_OVERRIDE_G) - -# define CONFIG_STM32H7_FLASH_CONFIG_G - -# elif defined(CONFIG_STM32H7_FLASH_OVERRIDE_I) - -# define CONFIG_STM32H7_FLASH_CONFIG_I - -# endif -#endif - -#if defined(CONFIG_STM32H7_FLASH_CONFIG_B) - -# define STM32_FLASH_NBLOCKS 1 -# define STM32_FLASH_SIZE _K(1 * 128) - -#elif defined(CONFIG_STM32H7_FLASH_CONFIG_G) - -# define STM32_FLASH_NBLOCKS 8 -# define STM32_FLASH_SIZE _K(8 * 128) - -#elif defined(CONFIG_STM32H7_FLASH_CONFIG_I) - -# define STM32_FLASH_NBLOCKS 16 -# define STM32_FLASH_SIZE _K(16 * 128) -# define STM32_DUAL_BANK 1 - -#endif - -#ifndef CONFIG_STM32H7_FLASH_CR_PSIZE -#define FLASH_CR_PSIZE FLASH_CR_PSIZE_X64 +#if defined(CONFIG_STM32H7_STM32H7X3XX) +# include "stm32h743xx_flash.c" +#elif defined(CONFIG_STM32H7_STM32H7B3XX) +# include "stm32h7b3xx_flash.c" +#elif defined(CONFIG_STM32H7_STM32H7X7XX) +# include "stm32h743xx_flash.c" #else -#define FLASH_CR_PSIZE (CONFIG_STM32H7_FLASH_CR_PSIZE << FLASH_CR_PSIZE_SHIFT) -#endif - -#define FLASH_KEY1 0x45670123 -#define FLASH_KEY2 0xcdef89ab -#define FLASH_OPTKEY1 0x08192a3b -#define FLASH_OPTKEY2 0x4c5d6e7f -#define FLASH_ERASEDVALUE 0xffu -#define FLASH_ERASEDVALUE_DW 0xffffffff -#define PROGMEM_NBLOCKS STM32_FLASH_NBLOCKS -#define FLASH_NPAGES (STM32_FLASH_SIZE / FLASH_PAGE_SIZE) - -#define FLASH_TIMEOUT_VALUE 5000000 /* 5s */ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -struct stm32h7_flash_priv_s -{ - mutex_t lock; /* Bank exclusive */ - uint32_t ifbase; /* FLASHIF interface base address */ - uint32_t base; /* FLASH base address */ - uint32_t stblock; /* The first Block Number */ - uint32_t stpage; /* The first Page Number */ -}; - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static struct stm32h7_flash_priv_s stm32h7_flash_bank1_priv = -{ - .lock = NXMUTEX_INITIALIZER, - .ifbase = STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET, - .base = STM32_FLASH_BANK1, - .stblock = 0, - .stpage = 0, -}; -#if STM32_DUAL_BANK -static struct stm32h7_flash_priv_s stm32h7_flash_bank2_priv = -{ - .lock = NXMUTEX_INITIALIZER, - .ifbase = STM32_FLASHIF_BASE + STM32_FLASH_BANK2_OFFSET, - .base = STM32_FLASH_BANK2, - .stblock = PROGMEM_NBLOCKS / 2, - .stpage = FLASH_NPAGES / 2, -}; +# error "Unsupported STM32 H7 chip" #endif /**************************************************************************** * Private Functions ****************************************************************************/ - -/**************************************************************************** - * Name: stm32h7_flash_getreg32 - * - * Description: - * Get a 32-bit register value by offset - * - ****************************************************************************/ - -static inline uint32_t stm32h7_flash_getreg32(struct stm32h7_flash_priv_s - *priv, uint32_t offset) -{ - return getreg32(priv->ifbase + offset); -} - -/**************************************************************************** - * Name: stm32h7_flash_putreg32 - * - * Description: - * Put a 32-bit register value by offset - * - ****************************************************************************/ - -static inline void stm32h7_flash_putreg32(struct stm32h7_flash_priv_s - *priv, uint32_t offset, - uint32_t value) -{ - putreg32(value, priv->ifbase + offset); -} - -/**************************************************************************** - * Name: stm32h7_flash_modifyreg32 - * - * Description: - * Modify a 32-bit register value by offset - * - ****************************************************************************/ - -static inline void stm32h7_flash_modifyreg32(struct stm32h7_flash_priv_s - *priv, uint32_t offset, - uint32_t clearbits, - uint32_t setbits) -{ - modifyreg32(priv->ifbase + offset, clearbits, setbits); -} - -/**************************************************************************** - * Name: stm32h7_unlock_flash - * - * Description: - * Unlock the Bank - * - ****************************************************************************/ - -static void stm32h7_unlock_flash(struct stm32h7_flash_priv_s *priv) -{ - while (stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET) & FLASH_SR_BSY) - { - } - - if (stm32h7_flash_getreg32(priv, STM32_FLASH_CR1_OFFSET) & FLASH_CR_LOCK) - { - /* Unlock sequence */ - - stm32h7_flash_putreg32(priv, STM32_FLASH_KEYR1_OFFSET, FLASH_KEY1); - stm32h7_flash_putreg32(priv, STM32_FLASH_KEYR1_OFFSET, FLASH_KEY2); - } -} - -/**************************************************************************** - * Name: stm32h7_lock_flash - * - * Description: - * Lock the Bank - * - ****************************************************************************/ - -static void stm32h7_lock_flash(struct stm32h7_flash_priv_s *priv) -{ - stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, 0, FLASH_CR_LOCK); -} - -/**************************************************************************** - * Name: stm32h7_flash_size - * - * Description: - * Returns the size in bytes of FLASH - * - ****************************************************************************/ - -static inline uint32_t stm32h7_flash_size( - struct stm32h7_flash_priv_s *priv) -{ - return FLASH_SECTOR_SIZE * PROGMEM_NBLOCKS; -} - -/**************************************************************************** - * Name: stm32h7_flash_bank - * - * Description: - * Returns the priv pointer to the correct bank - * - ****************************************************************************/ - -static inline -struct stm32h7_flash_priv_s * stm32h7_flash_bank(size_t address) -{ - struct stm32h7_flash_priv_s *priv = NULL; - - uint32_t bank_size; -#ifdef STM32_DUAL_BANK - bank_size = stm32h7_flash_size(priv) / 2; -#else - bank_size = stm32h7_flash_size(priv); -#endif - - if (address >= stm32h7_flash_bank1_priv.base && - address < stm32h7_flash_bank1_priv.base + bank_size) - { - priv = &stm32h7_flash_bank1_priv; - } - -#ifdef STM32_DUAL_BANK - else if (address >= stm32h7_flash_bank2_priv.base && - address < stm32h7_flash_bank2_priv.base + bank_size) - { - priv = &stm32h7_flash_bank2_priv; - } -#endif - - return priv; -} - -/**************************************************************************** - * Name: stm32h7_israngeerased - * - * Description: - * Returns count of non-erased words - * - ****************************************************************************/ - -static int stm32h7_israngeerased(size_t startaddress, size_t size) -{ - uint32_t *addr; - uint8_t *baddr; - size_t count = 0; - size_t bwritten = 0; - - if (!stm32h7_flash_bank(startaddress) || - !stm32h7_flash_bank(startaddress + size - 1)) - { - return -EIO; - } - - addr = (uint32_t *)startaddress; - while (count + 4 <= size) - { - if (getreg32(addr) != FLASH_ERASEDVALUE_DW) - { - bwritten++; - } - - addr++; - count += 4; - } - - baddr = (uint8_t *)startaddress; - while (count < size) - { - if (getreg8(baddr) != FLASH_ERASEDVALUE) - { - bwritten++; - } - - baddr++; - count++; - } - - return bwritten; -} - -/**************************************************************************** - * Name: stm32h7_wait_for_last_operation() - * - * Description: - * Wait for last write/erase operation to finish - * Return error in case of timeout - * - * Input Parameters: - * priv - Flash bank based config - * - * Returned Value: - * Zero or error value - * - * ETIME: Timeout while waiting for previous write/erase operation to - * complete - * - ****************************************************************************/ - -static int stm32h7_wait_for_last_operation(struct stm32h7_flash_priv_s - *priv) -{ - int i; - bool timeout = true; - - ARM_DSB(); - - for (i = 0; i < FLASH_TIMEOUT_VALUE; i++) - { - if (!(stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET) & - (FLASH_SR_QW | FLASH_SR_BSY | FLASH_SR_WBNE))) - { - timeout = false; - break; - } - - up_udelay(1); - } - - if (timeout) - { - return -EBUSY; - } - - return 0; -} - -/**************************************************************************** - * Name: stm32h7_unlock_flashopt - * - * Description: - * Unlock the flash option bytes - * Returns true if the flash was locked before, false otherwise - * - ****************************************************************************/ - -static bool stm32h7_unlock_flashopt(struct stm32h7_flash_priv_s *priv) -{ - bool ret = false; - - while (stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET) & FLASH_SR_BSY) - { - } - - if (stm32h7_flash_getreg32(priv, STM32_FLASH_OPTCR_OFFSET) & - FLASH_OPTCR_OPTLOCK) - { - /* Unlock sequence */ - - stm32h7_flash_putreg32(priv, STM32_FLASH_OPTKEYR_OFFSET, - FLASH_OPTKEY1); - stm32h7_flash_putreg32(priv, STM32_FLASH_OPTKEYR_OFFSET, - FLASH_OPTKEY2); - - /* Was locked before and now unlocked */ - - ret = true; - } - - return ret; -} - -/**************************************************************************** - * Name: stm32h7_lock_flashopt - * - * Description: - * Lock the flash option bytes - * - ****************************************************************************/ - -static void stm32h7_lock_flashopt(struct stm32h7_flash_priv_s *priv) -{ - stm32h7_flash_modifyreg32(priv, STM32_FLASH_OPTCR_OFFSET, 0, - FLASH_OPTCR_OPTLOCK); -} - -/**************************************************************************** - * Name: stm32h7_save_flashopt - * - * Description: - * Save the flash option bytes to non-volatile storage. - * - ****************************************************************************/ - -static void stm32h7_save_flashopt(struct stm32h7_flash_priv_s *priv) -{ - while (stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET) & - (FLASH_SR_BSY | FLASH_SR_CRCBUSY)) - { - } - while (stm32h7_flash_getreg32(priv, STM32_FLASH_SR2_OFFSET) & - (FLASH_SR_BSY | FLASH_SR_CRCBUSY)) - { - } - - /* Can only write flash options if the option control reg is unlocked */ - - if (!(stm32h7_flash_getreg32(priv, STM32_FLASH_OPTCR_OFFSET) & - FLASH_OPTCR_OPTLOCK)) - { - stm32h7_flash_modifyreg32(priv, STM32_FLASH_OPTCR_OFFSET, 0, - FLASH_OPTCR_OPTSTRT); - } - - /* Wait for the update to complete */ - - while (stm32h7_flash_getreg32(priv, STM32_FLASH_OPTSR_CUR_OFFSET) & - FLASH_OPTSR_BUSYV) - { - } -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: stm32h7_flash_unlock - * - * Description: - * Unlocks a bank - * - ****************************************************************************/ - -int stm32h7_flash_unlock(size_t addr) -{ - int ret = -ENODEV; - struct stm32h7_flash_priv_s *priv = stm32h7_flash_bank(addr); - - if (priv) - { - ret = nxmutex_lock(&priv->lock); - if (ret < 0) - { - return ret; - } - - stm32h7_unlock_flash(priv); - nxmutex_unlock(&priv->lock); - } - - return ret; -} - -/**************************************************************************** - * Name: stm32h7_flash_lock - * - * Description: - * Locks a bank - * - ****************************************************************************/ - -int stm32h7_flash_lock(size_t addr) -{ - int ret = -ENODEV; - struct stm32h7_flash_priv_s *priv = stm32h7_flash_bank(addr); - - if (priv) - { - ret = nxmutex_lock(&priv->lock); - if (ret < 0) - { - return ret; - } - - stm32h7_lock_flash(priv); - nxmutex_unlock(&priv->lock); - } - - return ret; -} - -/**************************************************************************** - * Name: stm32h7_flash_writeprotect - * - * Description: - * Enable or disable the write protection of a flash sector. - * - ****************************************************************************/ - -int stm32h7_flash_writeprotect(size_t block, bool enabled) -{ - struct stm32h7_flash_priv_s *priv; - uint32_t setbits = 0; - uint32_t clearbits = 0; - int rv = -ENODEV; - - if (block >= PROGMEM_NBLOCKS) - { - return -EFAULT; - } - - priv = stm32h7_flash_bank(STM32_FLASH_BANK1 + (block * FLASH_SECTOR_SIZE)); - - if (priv) - { - if (enabled) - { - clearbits = 1 << block % (STM32_FLASH_NBLOCKS / 2); - } - else - { - setbits = 1 << block % (STM32_FLASH_NBLOCKS / 2); - } - - stm32h7_flash_modifyreg32(priv, STM32_FLASH_WPSN_PRG1R_OFFSET, - clearbits, setbits); - rv = OK; - } - - return rv; -} - -/**************************************************************************** - * Name: stm32h7_flash_getopt - * - * Description: - * Returns the current flash option bytes from the FLASH_OPTSR_CR register. - * - ****************************************************************************/ - -uint32_t stm32h7_flash_getopt(void) -{ - struct stm32h7_flash_priv_s *priv; - priv = stm32h7_flash_bank(STM32_FLASH_BANK1); - if (priv) - { - return stm32h7_flash_getreg32(priv, STM32_FLASH_OPTSR_CUR_OFFSET); - } - - return 0; -} - -/**************************************************************************** - * Name: stm32h7_flash_optmodify - * - * Description: - * Modifies the current flash option bytes, given bits to set and clear. - * - ****************************************************************************/ - -void stm32h7_flash_optmodify(uint32_t clear, uint32_t set) -{ - struct stm32h7_flash_priv_s *priv; - bool was_locked; - - priv = stm32h7_flash_bank(STM32_FLASH_BANK1); - if (priv) - { - was_locked = stm32h7_unlock_flashopt(priv); - stm32h7_flash_modifyreg32(priv, STM32_FLASH_OPTSR_PRG_OFFSET, - clear, set); - stm32h7_save_flashopt(priv); - if (was_locked) - { - stm32h7_lock_flashopt(priv); - } - } -} - -/**************************************************************************** - * Name: stm32h7_flash_swapbanks - * - * Description: - * Swaps banks 1 and 2 in the processor's memory map. Takes effect - * the next time the system is reset. - * - ****************************************************************************/ - -void stm32h7_flash_swapbanks(void) -{ - uint32_t opts = stm32h7_flash_getopt(); - if (opts & FLASH_OPTCR_SWAPBANK) - { - stm32h7_flash_optmodify(FLASH_OPTCR_SWAPBANK, 0); - } - else - { - stm32h7_flash_optmodify(0, FLASH_OPTCR_SWAPBANK); - } -} - -size_t up_progmem_pagesize(size_t page) -{ - return FLASH_PAGE_SIZE; -} - -ssize_t up_progmem_getpage(size_t addr) -{ - struct stm32h7_flash_priv_s *priv; - - priv = stm32h7_flash_bank(addr); - - if (priv == NULL) - { - return -EFAULT; - } - - return priv->stpage + ((addr - priv->base) / FLASH_PAGE_SIZE); -} - -size_t up_progmem_getaddress(size_t page) -{ - struct stm32h7_flash_priv_s *priv; - if (page >= FLASH_NPAGES) - { - return SIZE_MAX; - } - - priv = stm32h7_flash_bank(STM32_FLASH_BANK1 + (page * FLASH_PAGE_SIZE)); - return priv->base + (page - priv->stpage) * FLASH_PAGE_SIZE; -} - -size_t up_progmem_neraseblocks(void) -{ - return PROGMEM_NBLOCKS; -} - -bool up_progmem_isuniform(void) -{ - return true; -} - -ssize_t up_progmem_ispageerased(size_t page) -{ - size_t addr; - size_t count; - size_t bwritten = 0; - - if (page >= FLASH_NPAGES) - { - return -EFAULT; - } - - /* Verify */ - - for (addr = up_progmem_getaddress(page), count = up_progmem_pagesize(page); - count; count--, addr++) - { - if (getreg8(addr) != FLASH_ERASEDVALUE) - { - bwritten++; - } - } - - return bwritten; -} - -size_t up_progmem_erasesize(size_t block) -{ - return FLASH_SECTOR_SIZE; -} - -ssize_t up_progmem_eraseblock(size_t block) -{ - struct stm32h7_flash_priv_s *priv; - int ret; - size_t block_address = STM32_FLASH_BANK1 + (block * FLASH_SECTOR_SIZE); - - if (block >= PROGMEM_NBLOCKS) - { - return -EFAULT; - } - - priv = stm32h7_flash_bank(block_address); - - ret = nxmutex_lock(&priv->lock); - if (ret < 0) - { - return (ssize_t)ret; - } - - if (stm32h7_wait_for_last_operation(priv)) - { - ret = -EIO; - goto exit_with_lock; - } - - /* Get flash ready and begin erasing single block */ - - stm32h7_unlock_flash(priv); - - stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, 0, FLASH_CR_SER); - stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, FLASH_CR_SNB_MASK, - FLASH_CR_SNB(block - priv->stblock)); - - stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, 0, FLASH_CR_START); - - /* Wait for erase operation to complete */ - - if (stm32h7_wait_for_last_operation(priv)) - { - ret = -EIO; - goto exit_with_unlock; - } - - stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, FLASH_CR_SER, 0); - stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, FLASH_CR_SNB_MASK, - 0); - ret = 0; - -exit_with_unlock: - stm32h7_lock_flash(priv); - -exit_with_lock: - nxmutex_unlock(&priv->lock); - - /* Verify */ - - if (ret == 0 && - stm32h7_israngeerased(block_address, up_progmem_erasesize(block)) == 0) - { - ret = up_progmem_erasesize(block); /* success */ - } - else - { - ret = -EIO; /* failure */ - } - - return ret; -} - -ssize_t up_progmem_write(size_t addr, const void *buf, size_t count) -{ - struct stm32h7_flash_priv_s *priv; - uint32_t *fp; - uint32_t *rp; - uint32_t *ll = (uint32_t *) buf; - size_t faddr; - size_t written = count; - int ret; - const size_t pagesize = up_progmem_pagesize(0); /* 256 bit, 32 bytes per page */ - const size_t llperpage = pagesize / sizeof(uint32_t); - size_t pcount = count / pagesize; - uint32_t sr; - - priv = stm32h7_flash_bank(addr); - - if (priv == NULL) - { - return -EFAULT; - } - - /* Check for valid address range */ - - if (addr < priv->base || - addr + count > priv->base + (STM32_FLASH_SIZE / 2)) - { - return -EFAULT; - } - - ret = nxmutex_lock(&priv->lock); - if (ret < 0) - { - return (ssize_t)ret; - } - - /* Check address and count alignment */ - - DEBUGASSERT(!(addr % pagesize)); - DEBUGASSERT(!(count % pagesize)); - - if (stm32h7_wait_for_last_operation(priv)) - { - written = -EIO; - goto exit_with_lock; - } - - /* Get flash ready and begin flashing */ - - stm32h7_unlock_flash(priv); - - stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, - FLASH_CR_PSIZE_MASK, FLASH_CR_PSIZE); - - stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, 0, FLASH_CR_PG); - - for (ll = (uint32_t *) buf, faddr = addr; pcount; - pcount -= 1, ll += llperpage, faddr += pagesize) - { - fp = (uint32_t *) faddr; - rp = ll; - - ARM_DSB(); - ARM_ISB(); - - /* Write 8 32 bit word and wait to complete */ - - *fp++ = *rp++; - *fp++ = *rp++; - *fp++ = *rp++; - *fp++ = *rp++; - *fp++ = *rp++; - *fp++ = *rp++; - *fp++ = *rp++; - *fp++ = *rp++; - - /* Data synchronous Barrier (DSB) just after the write operation. This - * will force the CPU to respect the sequence of instruction (no - * optimization). - */ - - ARM_DSB(); - ARM_ISB(); - - if (stm32h7_wait_for_last_operation(priv)) - { - written = -EIO; - goto exit_with_unlock; - } - - sr = stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET); - if (sr & (FLASH_SR_SNECCERR | FLASH_SR_DBECCERR)) - { - stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, - FLASH_CR_PG, - 0); - - stm32h7_flash_modifyreg32(priv, STM32_FLASH_CCR1_OFFSET, - 0, ~0); - ret = -EIO; - goto exit_with_unlock; - } - } - - stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, FLASH_CR_PG, 0); - - stm32h7_flash_modifyreg32(priv, STM32_FLASH_CCR1_OFFSET, - 0, ~0); -exit_with_unlock: - stm32h7_lock_flash(priv); - - /* Verify */ - - if (written > 0) - { - for (ll = (uint32_t *) buf, faddr = addr, pcount = count / pagesize; - pcount; pcount -= 1, ll += llperpage, faddr += pagesize) - { - fp = (uint32_t *) faddr; - rp = ll; - - stm32h7_flash_modifyreg32(priv, STM32_FLASH_CCR1_OFFSET, - 0, ~0); - if ((*fp++ != *rp++) || - (*fp++ != *rp++) || - (*fp++ != *rp++) || - (*fp++ != *rp++) || - (*fp++ != *rp++) || - (*fp++ != *rp++) || - (*fp++ != *rp++) || - (*fp++ != *rp++)) - { - written = -EIO; - break; - } - - sr = stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET); - if (sr & (FLASH_SR_SNECCERR | FLASH_SR_DBECCERR)) - { - written = -EIO; - break; - } - } - - stm32h7_flash_modifyreg32(priv, STM32_FLASH_CCR1_OFFSET, - 0, ~0); - } - -exit_with_lock: - nxmutex_unlock(&priv->lock); - return written; -} - -uint8_t up_progmem_erasestate(void) -{ - return FLASH_ERASEDVALUE; -} diff --git a/arch/arm/src/stm32h7/stm32_gpio.c b/arch/arm/src/stm32h7/stm32_gpio.c index 09c2a6e7f1..6838572b1e 100644 --- a/arch/arm/src/stm32h7/stm32_gpio.c +++ b/arch/arm/src/stm32h7/stm32_gpio.c @@ -41,7 +41,7 @@ * families */ -#if defined(CONFIG_STM32H7_STM32H7X3XX) || defined(CONFIG_STM32H7_STM32H7X7XX) +#if defined(CONFIG_STM32H7_STM32H7X3XX) || defined(CONFIG_STM32H7_STM32H7X7XX) || defined(CONFIG_STM32H7_STM32H7B3XX) /**************************************************************************** * Public Data @@ -530,4 +530,4 @@ void stm32_iocompensation(void) } #endif -#endif /* CONFIG_STM32H7_STM32H7X3XX || CONFIG_STM32H7_STM32H7X7XX */ +#endif /* CONFIG_STM32H7_STM32H7X3XX || CONFIG_STM32H7_STM32H7X7XX || CONFIG_STM32H7_STM32H7B3XX */ diff --git a/arch/arm/src/stm32h7/stm32_rcc.c b/arch/arm/src/stm32h7/stm32_rcc.c index cd6574246e..39d5ad0b02 100644 --- a/arch/arm/src/stm32h7/stm32_rcc.c +++ b/arch/arm/src/stm32h7/stm32_rcc.c @@ -56,6 +56,8 @@ #if defined(CONFIG_STM32H7_STM32H7X3XX) # include "stm32h7x3xx_rcc.c" +#elif defined(CONFIG_STM32H7_STM32H7B3XX) +# include "stm32h7x3xx_rcc.c" #elif defined(CONFIG_STM32H7_STM32H7X7XX) # include "stm32h7x7xx_rcc.c" #else diff --git a/arch/arm/src/stm32h7/stm32h743xx_flash.c b/arch/arm/src/stm32h7/stm32h743xx_flash.c new file mode 100644 index 0000000000..98034e237f --- /dev/null +++ b/arch/arm/src/stm32h7/stm32h743xx_flash.c @@ -0,0 +1,978 @@ +/**************************************************************************** + * arch/arm/src/stm32h7/stm32h743xx_flash.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * David Sidrane + * + * Ported from stm32f7_flash.c, this is the original license: + * + * Copyright (C) 2018 Wolpike LLC. All rights reserved. + * Author: Evgeniy Bobkov + * + * Ported from stm32f20xxf40xx_flash.c, this is the original license: + * + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Author: Uros Platise + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* Provides standard flash access functions, to be used by the flash mtd + * driver. The interface is defined in the include/nuttx/progmem.h + * + * Requirements during write/erase operations on FLASH: + * - HSI must be ON. + * - Low Power Modes are not permitted during write/erase + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include + +#include "barriers.h" + +#include "hardware/stm32_flash.h" +#include "arm_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Flash size is known from the chip selection: + * + * When CONFIG_STM32H7_FLASH_OVERRIDE_DEFAULT is set the + * CONFIG_STM32H7_FLASH_CONFIG_x selects the default FLASH size based on + * the chip part number. This value can be overridden with + * CONFIG_STM32H7_FLASH_OVERRIDE_x + * + * Parts STM32H74xxE have 512Kb of FLASH + * Parts STM32H74xxG have 1024Kb of FLASH + * Parts STM32H74xxI have 2048Kb of FLASH + * + * N.B. Only Single bank mode is supported + */ + +#define _K(x) ((x)*1024) +#define FLASH_SECTOR_SIZE _K(128) +#define FLASH_PAGE_SIZE 32 + +#if !defined(CONFIG_STM32H7_FLASH_OVERRIDE_DEFAULT) && \ + !defined(CONFIG_STM32H7_FLASH_OVERRIDE_B) && \ + !defined(CONFIG_STM32H7_FLASH_OVERRIDE_G) && \ + !defined(CONFIG_STM32H7_FLASH_OVERRIDE_I) && \ + !defined(CONFIG_STM32H7_FLASH_CONFIG_B) && \ + !defined(CONFIG_STM32H7_FLASH_CONFIG_G) && \ + !defined(CONFIG_STM32H7_FLASH_CONFIG_I) +# define CONFIG_STM32H7_FLASH_OVERRIDE_B +# warning "Flash size not defined defaulting to 128KiB (B)" +#endif + +#if !defined(CONFIG_STM32H7_FLASH_OVERRIDE_DEFAULT) + +# undef CONFIG_STM32H7_FLASH_CONFIG_B +# undef CONFIG_STM32H7_FLASH_CONFIG_G +# undef CONFIG_STM32H7_FLASH_CONFIG_I + +# if defined(CONFIG_STM32H7_FLASH_OVERRIDE_B) + +# define CONFIG_STM32H7_FLASH_CONFIG_B + +# elif defined(CONFIG_STM32H7_FLASH_OVERRIDE_G) + +# define CONFIG_STM32H7_FLASH_CONFIG_G + +# elif defined(CONFIG_STM32H7_FLASH_OVERRIDE_I) + +# define CONFIG_STM32H7_FLASH_CONFIG_I + +# endif +#endif + +#if defined(CONFIG_STM32H7_FLASH_CONFIG_B) + +# define STM32_FLASH_NBLOCKS 1 +# define STM32_FLASH_SIZE _K(1 * 128) + +#elif defined(CONFIG_STM32H7_FLASH_CONFIG_G) + +# define STM32_FLASH_NBLOCKS 8 +# define STM32_FLASH_SIZE _K(8 * 128) + +#elif defined(CONFIG_STM32H7_FLASH_CONFIG_I) + +# define STM32_FLASH_NBLOCKS 16 +# define STM32_FLASH_SIZE _K(16 * 128) +# define STM32_DUAL_BANK 1 + +#endif + +#ifndef CONFIG_STM32H7_FLASH_CR_PSIZE +#define FLASH_CR_PSIZE FLASH_CR_PSIZE_X64 +#else +#define FLASH_CR_PSIZE (CONFIG_STM32H7_FLASH_CR_PSIZE << FLASH_CR_PSIZE_SHIFT) +#endif + +#define FLASH_KEY1 0x45670123 +#define FLASH_KEY2 0xcdef89ab +#define FLASH_OPTKEY1 0x08192a3b +#define FLASH_OPTKEY2 0x4c5d6e7f +#define FLASH_ERASEDVALUE 0xffu +#define FLASH_ERASEDVALUE_DW 0xffffffff +#define PROGMEM_NBLOCKS STM32_FLASH_NBLOCKS +#define FLASH_NPAGES (STM32_FLASH_SIZE / FLASH_PAGE_SIZE) + +#define FLASH_TIMEOUT_VALUE 5000000 /* 5s */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct stm32h7_flash_priv_s +{ + mutex_t lock; /* Bank exclusive */ + uint32_t ifbase; /* FLASHIF interface base address */ + uint32_t base; /* FLASH base address */ + uint32_t stblock; /* The first Block Number */ + uint32_t stpage; /* The first Page Number */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct stm32h7_flash_priv_s stm32h7_flash_bank1_priv = +{ + .lock = NXMUTEX_INITIALIZER, + .ifbase = STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET, + .base = STM32_FLASH_BANK1, + .stblock = 0, + .stpage = 0, +}; +#if STM32_DUAL_BANK +static struct stm32h7_flash_priv_s stm32h7_flash_bank2_priv = +{ + .lock = NXMUTEX_INITIALIZER, + .ifbase = STM32_FLASHIF_BASE + STM32_FLASH_BANK2_OFFSET, + .base = STM32_FLASH_BANK2, + .stblock = PROGMEM_NBLOCKS / 2, + .stpage = FLASH_NPAGES / 2, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32h7_flash_getreg32 + * + * Description: + * Get a 32-bit register value by offset + * + ****************************************************************************/ + +static inline uint32_t stm32h7_flash_getreg32(struct stm32h7_flash_priv_s + *priv, uint32_t offset) +{ + return getreg32(priv->ifbase + offset); +} + +/**************************************************************************** + * Name: stm32h7_flash_putreg32 + * + * Description: + * Put a 32-bit register value by offset + * + ****************************************************************************/ + +static inline void stm32h7_flash_putreg32(struct stm32h7_flash_priv_s + *priv, uint32_t offset, + uint32_t value) +{ + putreg32(value, priv->ifbase + offset); +} + +/**************************************************************************** + * Name: stm32h7_flash_modifyreg32 + * + * Description: + * Modify a 32-bit register value by offset + * + ****************************************************************************/ + +static inline void stm32h7_flash_modifyreg32(struct stm32h7_flash_priv_s + *priv, uint32_t offset, + uint32_t clearbits, + uint32_t setbits) +{ + modifyreg32(priv->ifbase + offset, clearbits, setbits); +} + +/**************************************************************************** + * Name: stm32h7_unlock_flash + * + * Description: + * Unlock the Bank + * + ****************************************************************************/ + +static void stm32h7_unlock_flash(struct stm32h7_flash_priv_s *priv) +{ + while (stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET) & FLASH_SR_BSY) + { + } + + if (stm32h7_flash_getreg32(priv, STM32_FLASH_CR1_OFFSET) & FLASH_CR_LOCK) + { + /* Unlock sequence */ + + stm32h7_flash_putreg32(priv, STM32_FLASH_KEYR1_OFFSET, FLASH_KEY1); + stm32h7_flash_putreg32(priv, STM32_FLASH_KEYR1_OFFSET, FLASH_KEY2); + } +} + +/**************************************************************************** + * Name: stm32h7_lock_flash + * + * Description: + * Lock the Bank + * + ****************************************************************************/ + +static void stm32h7_lock_flash(struct stm32h7_flash_priv_s *priv) +{ + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, 0, FLASH_CR_LOCK); +} + +/**************************************************************************** + * Name: stm32h7_flash_size + * + * Description: + * Returns the size in bytes of FLASH + * + ****************************************************************************/ + +static inline uint32_t stm32h7_flash_size( + struct stm32h7_flash_priv_s *priv) +{ + return FLASH_SECTOR_SIZE * PROGMEM_NBLOCKS; +} + +/**************************************************************************** + * Name: stm32h7_flash_bank + * + * Description: + * Returns the priv pointer to the correct bank + * + ****************************************************************************/ + +static inline +struct stm32h7_flash_priv_s * stm32h7_flash_bank(size_t address) +{ + struct stm32h7_flash_priv_s *priv = NULL; + + uint32_t bank_size; +#ifdef STM32_DUAL_BANK + bank_size = stm32h7_flash_size(priv) / 2; +#else + bank_size = stm32h7_flash_size(priv); +#endif + + if (address >= stm32h7_flash_bank1_priv.base && + address < stm32h7_flash_bank1_priv.base + bank_size) + { + priv = &stm32h7_flash_bank1_priv; + } + +#ifdef STM32_DUAL_BANK + else if (address >= stm32h7_flash_bank2_priv.base && + address < stm32h7_flash_bank2_priv.base + bank_size) + { + priv = &stm32h7_flash_bank2_priv; + } +#endif + + return priv; +} + +/**************************************************************************** + * Name: stm32h7_israngeerased + * + * Description: + * Returns count of non-erased words + * + ****************************************************************************/ + +static int stm32h7_israngeerased(size_t startaddress, size_t size) +{ + uint32_t *addr; + uint8_t *baddr; + size_t count = 0; + size_t bwritten = 0; + + if (!stm32h7_flash_bank(startaddress) || + !stm32h7_flash_bank(startaddress + size - 1)) + { + return -EIO; + } + + addr = (uint32_t *)startaddress; + while (count + 4 <= size) + { + if (getreg32(addr) != FLASH_ERASEDVALUE_DW) + { + bwritten++; + } + + addr++; + count += 4; + } + + baddr = (uint8_t *)startaddress; + while (count < size) + { + if (getreg8(baddr) != FLASH_ERASEDVALUE) + { + bwritten++; + } + + baddr++; + count++; + } + + return bwritten; +} + +/**************************************************************************** + * Name: stm32h7_wait_for_last_operation() + * + * Description: + * Wait for last write/erase operation to finish + * Return error in case of timeout + * + * Input Parameters: + * priv - Flash bank based config + * + * Returned Value: + * Zero or error value + * + * ETIME: Timeout while waiting for previous write/erase operation to + * complete + * + ****************************************************************************/ + +static int stm32h7_wait_for_last_operation(struct stm32h7_flash_priv_s + *priv) +{ + int i; + bool timeout = true; + + ARM_DSB(); + + for (i = 0; i < FLASH_TIMEOUT_VALUE; i++) + { + if (!(stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET) & + (FLASH_SR_QW | FLASH_SR_BSY | FLASH_SR_WBNE))) + { + timeout = false; + break; + } + + up_udelay(1); + } + + if (timeout) + { + return -EBUSY; + } + + return 0; +} + +/**************************************************************************** + * Name: stm32h7_unlock_flashopt + * + * Description: + * Unlock the flash option bytes + * Returns true if the flash was locked before, false otherwise + * + ****************************************************************************/ + +static bool stm32h7_unlock_flashopt(struct stm32h7_flash_priv_s *priv) +{ + bool ret = false; + + while (stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET) & FLASH_SR_BSY) + { + } + + if (stm32h7_flash_getreg32(priv, STM32_FLASH_OPTCR_OFFSET) & + FLASH_OPTCR_OPTLOCK) + { + /* Unlock sequence */ + + stm32h7_flash_putreg32(priv, STM32_FLASH_OPTKEYR_OFFSET, + FLASH_OPTKEY1); + stm32h7_flash_putreg32(priv, STM32_FLASH_OPTKEYR_OFFSET, + FLASH_OPTKEY2); + + /* Was locked before and now unlocked */ + + ret = true; + } + + return ret; +} + +/**************************************************************************** + * Name: stm32h7_lock_flashopt + * + * Description: + * Lock the flash option bytes + * + ****************************************************************************/ + +static void stm32h7_lock_flashopt(struct stm32h7_flash_priv_s *priv) +{ + stm32h7_flash_modifyreg32(priv, STM32_FLASH_OPTCR_OFFSET, 0, + FLASH_OPTCR_OPTLOCK); +} + +/**************************************************************************** + * Name: stm32h7_save_flashopt + * + * Description: + * Save the flash option bytes to non-volatile storage. + * + ****************************************************************************/ + +static void stm32h7_save_flashopt(struct stm32h7_flash_priv_s *priv) +{ + while (stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET) & + (FLASH_SR_BSY | FLASH_SR_CRCBUSY)) + { + } + while (stm32h7_flash_getreg32(priv, STM32_FLASH_SR2_OFFSET) & + (FLASH_SR_BSY | FLASH_SR_CRCBUSY)) + { + } + + /* Can only write flash options if the option control reg is unlocked */ + + if (!(stm32h7_flash_getreg32(priv, STM32_FLASH_OPTCR_OFFSET) & + FLASH_OPTCR_OPTLOCK)) + { + stm32h7_flash_modifyreg32(priv, STM32_FLASH_OPTCR_OFFSET, 0, + FLASH_OPTCR_OPTSTRT); + } + + /* Wait for the update to complete */ + + while (stm32h7_flash_getreg32(priv, STM32_FLASH_OPTSR_CUR_OFFSET) & + FLASH_OPTSR_BUSYV) + { + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32h7_flash_unlock + * + * Description: + * Unlocks a bank + * + ****************************************************************************/ + +int stm32h7_flash_unlock(size_t addr) +{ + int ret = -ENODEV; + struct stm32h7_flash_priv_s *priv = stm32h7_flash_bank(addr); + + if (priv) + { + ret = nxmutex_lock(&priv->lock); + if (ret < 0) + { + return ret; + } + + stm32h7_unlock_flash(priv); + nxmutex_unlock(&priv->lock); + } + + return ret; +} + +/**************************************************************************** + * Name: stm32h7_flash_lock + * + * Description: + * Locks a bank + * + ****************************************************************************/ + +int stm32h7_flash_lock(size_t addr) +{ + int ret = -ENODEV; + struct stm32h7_flash_priv_s *priv = stm32h7_flash_bank(addr); + + if (priv) + { + ret = nxmutex_lock(&priv->lock); + if (ret < 0) + { + return ret; + } + + stm32h7_lock_flash(priv); + nxmutex_unlock(&priv->lock); + } + + return ret; +} + +/**************************************************************************** + * Name: stm32h7_flash_writeprotect + * + * Description: + * Enable or disable the write protection of a flash sector. + * + ****************************************************************************/ + +int stm32h7_flash_writeprotect(size_t block, bool enabled) +{ + struct stm32h7_flash_priv_s *priv; + uint32_t setbits = 0; + uint32_t clearbits = 0; + int rv = -ENODEV; + + if (block >= PROGMEM_NBLOCKS) + { + return -EFAULT; + } + + priv = stm32h7_flash_bank(STM32_FLASH_BANK1 + (block * FLASH_SECTOR_SIZE)); + + if (priv) + { + if (enabled) + { + clearbits = 1 << block % (STM32_FLASH_NBLOCKS / 2); + } + else + { + setbits = 1 << block % (STM32_FLASH_NBLOCKS / 2); + } + + stm32h7_flash_modifyreg32(priv, STM32_FLASH_WPSN_PRG1R_OFFSET, + clearbits, setbits); + rv = OK; + } + + return rv; +} + +/**************************************************************************** + * Name: stm32h7_flash_getopt + * + * Description: + * Returns the current flash option bytes from the FLASH_OPTSR_CR register. + * + ****************************************************************************/ + +uint32_t stm32h7_flash_getopt(void) +{ + struct stm32h7_flash_priv_s *priv; + priv = stm32h7_flash_bank(STM32_FLASH_BANK1); + if (priv) + { + return stm32h7_flash_getreg32(priv, STM32_FLASH_OPTSR_CUR_OFFSET); + } + + return 0; +} + +/**************************************************************************** + * Name: stm32h7_flash_optmodify + * + * Description: + * Modifies the current flash option bytes, given bits to set and clear. + * + ****************************************************************************/ + +void stm32h7_flash_optmodify(uint32_t clear, uint32_t set) +{ + struct stm32h7_flash_priv_s *priv; + bool was_locked; + + priv = stm32h7_flash_bank(STM32_FLASH_BANK1); + if (priv) + { + was_locked = stm32h7_unlock_flashopt(priv); + stm32h7_flash_modifyreg32(priv, STM32_FLASH_OPTSR_PRG_OFFSET, + clear, set); + stm32h7_save_flashopt(priv); + if (was_locked) + { + stm32h7_lock_flashopt(priv); + } + } +} + +/**************************************************************************** + * Name: stm32h7_flash_swapbanks + * + * Description: + * Swaps banks 1 and 2 in the processor's memory map. Takes effect + * the next time the system is reset. + * + ****************************************************************************/ + +void stm32h7_flash_swapbanks(void) +{ + uint32_t opts = stm32h7_flash_getopt(); + if (opts & FLASH_OPTCR_SWAPBANK) + { + stm32h7_flash_optmodify(FLASH_OPTCR_SWAPBANK, 0); + } + else + { + stm32h7_flash_optmodify(0, FLASH_OPTCR_SWAPBANK); + } +} + +size_t up_progmem_pagesize(size_t page) +{ + return FLASH_PAGE_SIZE; +} + +ssize_t up_progmem_getpage(size_t addr) +{ + struct stm32h7_flash_priv_s *priv; + + priv = stm32h7_flash_bank(addr); + + if (priv == NULL) + { + return -EFAULT; + } + + return priv->stpage + ((addr - priv->base) / FLASH_PAGE_SIZE); +} + +size_t up_progmem_getaddress(size_t page) +{ + struct stm32h7_flash_priv_s *priv; + if (page >= FLASH_NPAGES) + { + return SIZE_MAX; + } + + priv = stm32h7_flash_bank(STM32_FLASH_BANK1 + (page * FLASH_PAGE_SIZE)); + return priv->base + (page - priv->stpage) * FLASH_PAGE_SIZE; +} + +size_t up_progmem_neraseblocks(void) +{ + return PROGMEM_NBLOCKS; +} + +bool up_progmem_isuniform(void) +{ + return true; +} + +ssize_t up_progmem_ispageerased(size_t page) +{ + size_t addr; + size_t count; + size_t bwritten = 0; + + if (page >= FLASH_NPAGES) + { + return -EFAULT; + } + + /* Verify */ + + for (addr = up_progmem_getaddress(page), count = up_progmem_pagesize(page); + count; count--, addr++) + { + if (getreg8(addr) != FLASH_ERASEDVALUE) + { + bwritten++; + } + } + + return bwritten; +} + +size_t up_progmem_erasesize(size_t block) +{ + return FLASH_SECTOR_SIZE; +} + +ssize_t up_progmem_eraseblock(size_t block) +{ + struct stm32h7_flash_priv_s *priv; + int ret; + size_t block_address = STM32_FLASH_BANK1 + (block * FLASH_SECTOR_SIZE); + + if (block >= PROGMEM_NBLOCKS) + { + return -EFAULT; + } + + priv = stm32h7_flash_bank(block_address); + + ret = nxmutex_lock(&priv->lock); + if (ret < 0) + { + return (ssize_t)ret; + } + + if (stm32h7_wait_for_last_operation(priv)) + { + ret = -EIO; + goto exit_with_lock; + } + + /* Get flash ready and begin erasing single block */ + + stm32h7_unlock_flash(priv); + + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, 0, FLASH_CR_SER); + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, FLASH_CR_SNB_MASK, + FLASH_CR_SNB(block - priv->stblock)); + + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, 0, FLASH_CR_START); + + /* Wait for erase operation to complete */ + + if (stm32h7_wait_for_last_operation(priv)) + { + ret = -EIO; + goto exit_with_unlock; + } + + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, FLASH_CR_SER, 0); + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, FLASH_CR_SNB_MASK, + 0); + ret = 0; + +exit_with_unlock: + stm32h7_lock_flash(priv); + +exit_with_lock: + nxmutex_unlock(&priv->lock); + + /* Verify */ + + if (ret == 0 && + stm32h7_israngeerased(block_address, up_progmem_erasesize(block)) == 0) + { + ret = up_progmem_erasesize(block); /* success */ + } + else + { + ret = -EIO; /* failure */ + } + + return ret; +} + +ssize_t up_progmem_write(size_t addr, const void *buf, size_t count) +{ + struct stm32h7_flash_priv_s *priv; + uint32_t *fp; + uint32_t *rp; + uint32_t *ll = (uint32_t *) buf; + size_t faddr; + size_t written = count; + int ret; + const size_t pagesize = up_progmem_pagesize(0); /* 256 bit, 32 bytes per page */ + const size_t llperpage = pagesize / sizeof(uint32_t); + size_t pcount = count / pagesize; + uint32_t sr; + + priv = stm32h7_flash_bank(addr); + + if (priv == NULL) + { + return -EFAULT; + } + + /* Check for valid address range */ + + if (addr < priv->base || + addr + count > priv->base + (STM32_FLASH_SIZE / 2)) + { + return -EFAULT; + } + + ret = nxmutex_lock(&priv->lock); + if (ret < 0) + { + return (ssize_t)ret; + } + + /* Check address and count alignment */ + + DEBUGASSERT(!(addr % pagesize)); + DEBUGASSERT(!(count % pagesize)); + + if (stm32h7_wait_for_last_operation(priv)) + { + written = -EIO; + goto exit_with_lock; + } + + /* Get flash ready and begin flashing */ + + stm32h7_unlock_flash(priv); + + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, + FLASH_CR_PSIZE_MASK, FLASH_CR_PSIZE); + + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, 0, FLASH_CR_PG); + + for (ll = (uint32_t *) buf, faddr = addr; pcount; + pcount -= 1, ll += llperpage, faddr += pagesize) + { + fp = (uint32_t *) faddr; + rp = ll; + + ARM_DSB(); + ARM_ISB(); + + /* Write 8 32 bit word and wait to complete */ + + *fp++ = *rp++; + *fp++ = *rp++; + *fp++ = *rp++; + *fp++ = *rp++; + *fp++ = *rp++; + *fp++ = *rp++; + *fp++ = *rp++; + *fp++ = *rp++; + + /* Data synchronous Barrier (DSB) just after the write operation. This + * will force the CPU to respect the sequence of instruction (no + * optimization). + */ + + ARM_DSB(); + ARM_ISB(); + + if (stm32h7_wait_for_last_operation(priv)) + { + written = -EIO; + goto exit_with_unlock; + } + + sr = stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET); + if (sr & (FLASH_SR_SNECCERR | FLASH_SR_DBECCERR)) + { + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, + FLASH_CR_PG, + 0); + + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CCR1_OFFSET, + 0, ~0); + ret = -EIO; + goto exit_with_unlock; + } + } + + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, FLASH_CR_PG, 0); + + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CCR1_OFFSET, + 0, ~0); +exit_with_unlock: + stm32h7_lock_flash(priv); + + /* Verify */ + + if (written > 0) + { + for (ll = (uint32_t *) buf, faddr = addr, pcount = count / pagesize; + pcount; pcount -= 1, ll += llperpage, faddr += pagesize) + { + fp = (uint32_t *) faddr; + rp = ll; + + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CCR1_OFFSET, + 0, ~0); + if ((*fp++ != *rp++) || + (*fp++ != *rp++) || + (*fp++ != *rp++) || + (*fp++ != *rp++) || + (*fp++ != *rp++) || + (*fp++ != *rp++) || + (*fp++ != *rp++) || + (*fp++ != *rp++)) + { + written = -EIO; + break; + } + + sr = stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET); + if (sr & (FLASH_SR_SNECCERR | FLASH_SR_DBECCERR)) + { + written = -EIO; + break; + } + } + + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CCR1_OFFSET, + 0, ~0); + } + +exit_with_lock: + nxmutex_unlock(&priv->lock); + return written; +} + +uint8_t up_progmem_erasestate(void) +{ + return FLASH_ERASEDVALUE; +} + diff --git a/arch/arm/src/stm32h7/stm32h7b3xx_flash.c b/arch/arm/src/stm32h7/stm32h7b3xx_flash.c new file mode 100644 index 0000000000..c7f48def90 --- /dev/null +++ b/arch/arm/src/stm32h7/stm32h7b3xx_flash.c @@ -0,0 +1,968 @@ +/**************************************************************************** + * arch/arm/src/stm32h7/stm32h7b3xx_flash.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * David Sidrane + * + * Ported from stm32f7_flash.c, this is the original license: + * + * Copyright (C) 2018 Wolpike LLC. All rights reserved. + * Author: Evgeniy Bobkov + * + * Ported from stm32h743xx_flash.c, this is the original license: + * + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Author: Uros Platise + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* Provides standard flash access functions, to be used by the flash mtd + * driver. The interface is defined in the include/nuttx/progmem.h + * + * Requirements during write/erase operations on FLASH: + * - HSI must be ON. + * - Low Power Modes are not permitted during write/erase + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include + +#include "barriers.h" + +#include "hardware/stm32_flash.h" +#include "arm_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Flash size is known from the chip selection: + * + * When CONFIG_STM32H7_FLASH_OVERRIDE_DEFAULT is set the + * CONFIG_STM32H7_FLASH_CONFIG_x selects the default FLASH size based on + * the chip part number. This value can be overridden with + * CONFIG_STM32H7_FLASH_OVERRIDE_x + * + * Parts STM32H7x3xG have 1024Kb of FLASH + * Parts STM32H7x3xI have 2048Kb of FLASH + * + * N.B. Only Single bank mode is supported + */ + +#define _K(x) ((x)*1024) + +#define FLASH_SECTOR_SIZE _K(8) + +#define FLASH_PAGE_SIZE 16 + +#if !defined(CONFIG_STM32H7_FLASH_OVERRIDE_DEFAULT) && \ + !defined(CONFIG_STM32H7_FLASH_OVERRIDE_G) && \ + !defined(CONFIG_STM32H7_FLASH_OVERRIDE_I) && \ + !defined(CONFIG_STM32H7_FLASH_CONFIG_G) && \ + !defined(CONFIG_STM32H7_FLASH_CONFIG_I) +# define CONFIG_STM32H7_FLASH_OVERRIDE_G +# warning "Flash size not defined defaulting to 1024KiB (G)" +#endif + +#if !defined(CONFIG_STM32H7_FLASH_OVERRIDE_DEFAULT) + +# undef CONFIG_STM32H7_FLASH_CONFIG_B +# undef CONFIG_STM32H7_FLASH_CONFIG_G +# undef CONFIG_STM32H7_FLASH_CONFIG_I + +# if defined(CONFIG_STM32H7_FLASH_OVERRIDE_G) + +# define CONFIG_STM32H7_FLASH_CONFIG_G + +# elif defined(CONFIG_STM32H7_FLASH_OVERRIDE_I) + +# define CONFIG_STM32H7_FLASH_CONFIG_I + +# endif +#endif + +#if defined(CONFIG_STM32H7_FLASH_CONFIG_G) + +# define STM32_FLASH_NBLOCKS 128 +# define STM32_FLASH_SIZE _K(128 * 8) + +#elif defined(CONFIG_STM32H7_FLASH_CONFIG_I) + +# define STM32_FLASH_NBLOCKS 256 +# define STM32_FLASH_SIZE _K(256 * 8) + +#endif + +#define FLASH_KEY1 0x45670123 +#define FLASH_KEY2 0xcdef89ab +#define FLASH_OPTKEY1 0x08192a3b +#define FLASH_OPTKEY2 0x4c5d6e7f +#define FLASH_ERASEDVALUE 0xffu +#define FLASH_ERASEDVALUE_DW 0xffffffff +#define PROGMEM_NBLOCKS STM32_FLASH_NBLOCKS +#define FLASH_NPAGES (STM32_FLASH_SIZE / FLASH_PAGE_SIZE) + +#define FLASH_TIMEOUT_VALUE 5000000 /* 5s */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct stm32h7_flash_priv_s +{ + sem_t sem; /* Bank exclusive */ + uint32_t ifbase; /* FLASHIF interface base address */ + uint32_t base; /* FLASH base address */ + uint32_t stblock; /* The first Block Number */ + uint32_t stpage; /* The first Page Number */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct stm32h7_flash_priv_s stm32h7_flash_bank1_priv = +{ + .sem = SEM_INITIALIZER(1), + .ifbase = STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET, + .base = STM32_FLASH_BANK1, + .stblock = 0, + .stpage = 0, +}; +#if STM32_FLASH_NBLOCKS > 1 +static struct stm32h7_flash_priv_s stm32h7_flash_bank2_priv = +{ + .sem = SEM_INITIALIZER(1), + .ifbase = STM32_FLASHIF_BASE + STM32_FLASH_BANK2_OFFSET, + .base = STM32_FLASH_BANK2, + .stblock = PROGMEM_NBLOCKS / 2, + .stpage = FLASH_NPAGES / 2, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32h7_flash_getreg32 + * + * Description: + * Get a 32-bit register value by offset + * + ****************************************************************************/ + +static inline uint32_t stm32h7_flash_getreg32(struct stm32h7_flash_priv_s + *priv, uint32_t offset) +{ + return getreg32(priv->ifbase + offset); +} + +/**************************************************************************** + * Name: stm32h7_flash_putreg32 + * + * Description: + * Put a 32-bit register value by offset + * + ****************************************************************************/ + +static inline void stm32h7_flash_putreg32(struct stm32h7_flash_priv_s + *priv, uint32_t offset, + uint32_t value) +{ + putreg32(value, priv->ifbase + offset); +} + +/**************************************************************************** + * Name: stm32h7_flash_modifyreg32 + * + * Description: + * Modify a 32-bit register value by offset + * + ****************************************************************************/ + +static inline void stm32h7_flash_modifyreg32(struct stm32h7_flash_priv_s + *priv, uint32_t offset, + uint32_t clearbits, + uint32_t setbits) +{ + modifyreg32(priv->ifbase + offset, clearbits, setbits); +} + +/**************************************************************************** + * Name: stm32h7_flash_sem_lock + * + * Description: + * Take the Bank exclusive access semaphore + * + ****************************************************************************/ + +static int stm32h7_flash_sem_lock(struct stm32h7_flash_priv_s *priv) +{ + return nxsem_wait_uninterruptible(&priv->sem); +} + +/**************************************************************************** + * Name: stm32h7_flash_sem_unlock + * + * Description: + * Release the Bank exclusive access semaphore + * + ****************************************************************************/ + +static inline void stm32h7_flash_sem_unlock(struct stm32h7_flash_priv_s + *priv) +{ + nxsem_post(&priv->sem); +} + +/**************************************************************************** + * Name: stm32h7_unlock_flash + * + * Description: + * Unlock the Bank + * + ****************************************************************************/ + +static void stm32h7_unlock_flash(struct stm32h7_flash_priv_s *priv) +{ + while (stm32h7_flash_getreg32(priv, STM32_FLASH_SR_OFFSET) & FLASH_SR_BSY) + { + } + + if (stm32h7_flash_getreg32(priv, STM32_FLASH_CR_OFFSET) & FLASH_CR_LOCK) + { + /* Unlock sequence */ + + stm32h7_flash_putreg32(priv, STM32_FLASH_KEYR_OFFSET, FLASH_KEY1); + stm32h7_flash_putreg32(priv, STM32_FLASH_KEYR_OFFSET, FLASH_KEY2); + } +} + +/**************************************************************************** + * Name: stm32h7_lock_flash + * + * Description: + * Lock the Bank + * + ****************************************************************************/ + +static void stm32h7_lock_flash(struct stm32h7_flash_priv_s *priv) +{ + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR_OFFSET, 0, FLASH_CR_LOCK); +} + +/**************************************************************************** + * Name: stm32h7_flash_size + * + * Description: + * Returns the size in bytes of FLASH + * + ****************************************************************************/ + +static inline uint32_t stm32h7_flash_size( + struct stm32h7_flash_priv_s *priv) +{ + return FLASH_SECTOR_SIZE * PROGMEM_NBLOCKS; +} + +/**************************************************************************** + * Name: stm32h7_flash_bank + * + * Description: + * Returns the priv pointer to the correct bank + * + ****************************************************************************/ + +static inline +struct stm32h7_flash_priv_s * stm32h7_flash_bank(size_t address) +{ + struct stm32h7_flash_priv_s *priv = &stm32h7_flash_bank1_priv; + if (address < priv->base || address >= + priv->base + stm32h7_flash_size(priv)) + { + return NULL; + } + +#if STM32_FLASH_NBLOCKS > 1 + if (address >= stm32h7_flash_bank2_priv.base) + { + priv = &stm32h7_flash_bank2_priv; + } +#endif + + return priv; +} + +/**************************************************************************** + * Name: stm32h7_israngeerased + * + * Description: + * Returns count of non-erased words + * + ****************************************************************************/ + +static int stm32h7_israngeerased(size_t startaddress, size_t size) +{ + uint32_t *addr; + uint8_t *baddr; + size_t count = 0; + size_t bwritten = 0; + + if (!stm32h7_flash_bank(startaddress) || + !stm32h7_flash_bank(startaddress + size)) + { + return -EIO; + } + + addr = (uint32_t *)startaddress; + while (count + 4 <= size) + { + if (getreg32(addr) != FLASH_ERASEDVALUE_DW) + { + bwritten++; + } + + addr++; + count += 4; + } + + baddr = (uint8_t *)addr; + while (count < size) + { + if (getreg8(baddr) != FLASH_ERASEDVALUE) + { + bwritten++; + } + + count++; + } + + return bwritten; +} + +/**************************************************************************** + * Name: stm32h7_wait_for_last_operation() + * + * Description: + * Wait for last write/erase operation to finish + * Return error in case of timeout + * + * Input Parameters: + * priv - Flash bank based config + * + * Returned Value: + * Zero or error value + * + * ETIME: Timeout while waiting for previous write/erase operation to + * complete + * + ****************************************************************************/ + +static int stm32h7_wait_for_last_operation(struct stm32h7_flash_priv_s + *priv) +{ + int i; + bool timeout = true; + + ARM_DSB(); + + for (i = 0; i < FLASH_TIMEOUT_VALUE; i++) + { + if (!(stm32h7_flash_getreg32(priv, STM32_FLASH_SR_OFFSET) & + (FLASH_SR_QW | FLASH_SR_BSY | FLASH_SR_WBNE))) + { + timeout = false; + break; + } + + up_udelay(1); + } + + if (timeout) + { + return -EBUSY; + } + + return 0; +} + +/**************************************************************************** + * Name: stm32h7_unlock_flashopt + * + * Description: + * Unlock the flash option bytes + * Returns true if the flash was locked before, false otherwise + * + ****************************************************************************/ + +static bool stm32h7_unlock_flashopt(struct stm32h7_flash_priv_s *priv) +{ + bool ret = false; + + while (stm32h7_flash_getreg32(priv, STM32_FLASH_SR_OFFSET) & FLASH_SR_BSY) + { + } + + if (stm32h7_flash_getreg32(priv, STM32_FLASH_OPTCR_OFFSET) & + FLASH_OPTCR_OPTLOCK) + { + /* Unlock sequence */ + + stm32h7_flash_putreg32(priv, STM32_FLASH_OPTKEYR_OFFSET, + FLASH_OPTKEY1); + stm32h7_flash_putreg32(priv, STM32_FLASH_OPTKEYR_OFFSET, + FLASH_OPTKEY2); + + /* Was locked before and now unlocked */ + + ret = true; + } + + return ret; +} + +/**************************************************************************** + * Name: stm32h7_lock_flashopt + * + * Description: + * Lock the flash option bytes + * + ****************************************************************************/ + +static void stm32h7_lock_flashopt(struct stm32h7_flash_priv_s *priv) +{ + stm32h7_flash_modifyreg32(priv, STM32_FLASH_OPTCR_OFFSET, 0, + FLASH_OPTCR_OPTLOCK); +} + +/**************************************************************************** + * Name: stm32h7_save_flashopt + * + * Description: + * Save the flash option bytes to non-volatile storage. + * + ****************************************************************************/ + +static void stm32h7_save_flashopt(struct stm32h7_flash_priv_s *priv) +{ + while (stm32h7_flash_getreg32(priv, STM32_FLASH_SR_OFFSET) & + (FLASH_SR_BSY | FLASH_SR_CRCBUSY)) + { + } + + /* Can only write flash options if the option control reg is unlocked */ + + if (!(stm32h7_flash_getreg32(priv, STM32_FLASH_OPTCR_OFFSET) & + FLASH_OPTCR_OPTLOCK)) + { + stm32h7_flash_modifyreg32(priv, STM32_FLASH_OPTCR_OFFSET, 0, + FLASH_OPTCR_OPTSTRT); + } + + /* Wait for the update to complete */ + + while (stm32h7_flash_getreg32(priv, STM32_FLASH_OPTSR_CUR_OFFSET) & + FLASH_OPTSR_BUSYV) + { + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32h7_flash_unlock + * + * Description: + * Unlocks a bank + * + ****************************************************************************/ + +int stm32h7_flash_unlock(size_t addr) +{ + int ret = -ENODEV; + struct stm32h7_flash_priv_s *priv = stm32h7_flash_bank(addr); + + if (priv) + { + ret = stm32h7_flash_sem_lock(priv); + if (ret < 0) + { + return ret; + } + + stm32h7_unlock_flash(priv); + stm32h7_flash_sem_unlock(priv); + } + + return ret; +} + +/**************************************************************************** + * Name: stm32h7_flash_lock + * + * Description: + * Locks a bank + * + ****************************************************************************/ + +int stm32h7_flash_lock(size_t addr) +{ + int ret = -ENODEV; + struct stm32h7_flash_priv_s *priv = stm32h7_flash_bank(addr); + + if (priv) + { + ret = stm32h7_flash_sem_lock(priv); + if (ret < 0) + { + return ret; + } + + stm32h7_lock_flash(priv); + stm32h7_flash_sem_unlock(priv); + } + + return ret; +} + +/**************************************************************************** + * Name: stm32h7_flash_writeprotect + * + * Description: + * Enable or disable the write protection of a flash sector. + * + ****************************************************************************/ + +int stm32h7_flash_writeprotect(size_t block, bool enabled) +{ + struct stm32h7_flash_priv_s *priv; + uint32_t setbits = 0; + uint32_t clearbits = 0; + int rv = -ENODEV; + + if (block >= PROGMEM_NBLOCKS) + { + return -EFAULT; + } + + priv = stm32h7_flash_bank(STM32_FLASH_BANK1 + (block * FLASH_SECTOR_SIZE)); + + if (priv) + { + if (enabled) + { + clearbits = 1 << block % (STM32_FLASH_NBLOCKS / 2); + } + else + { + setbits = 1 << block % (STM32_FLASH_NBLOCKS / 2); + } + + stm32h7_flash_modifyreg32(priv, STM32_FLASH_WPSN_PRGR_OFFSET, + clearbits, setbits); + rv = OK; + } + + return rv; +} + +/**************************************************************************** + * Name: stm32h7_flash_getopt + * + * Description: + * Returns the current flash option bytes from the FLASH_OPTSR_CR register. + * + ****************************************************************************/ + +uint32_t stm32h7_flash_getopt(void) +{ + struct stm32h7_flash_priv_s *priv; + priv = stm32h7_flash_bank(STM32_FLASH_BANK1); + if (priv) + { + return stm32h7_flash_getreg32(priv, STM32_FLASH_OPTSR_CUR_OFFSET); + } + + return 0; +} + +/**************************************************************************** + * Name: stm32h7_flash_optmodify + * + * Description: + * Modifies the current flash option bytes, given bits to set and clear. + * + ****************************************************************************/ + +void stm32h7_flash_optmodify(uint32_t clear, uint32_t set) +{ + struct stm32h7_flash_priv_s *priv; + bool was_locked; + + priv = stm32h7_flash_bank(STM32_FLASH_BANK1); + if (priv) + { + was_locked = stm32h7_unlock_flashopt(priv); + stm32h7_flash_modifyreg32(priv, STM32_FLASH_OPTSR_PRG_OFFSET, + clear, set); + stm32h7_save_flashopt(priv); + if (was_locked) + { + stm32h7_lock_flashopt(priv); + } + } +} + +/**************************************************************************** + * Name: stm32h7_flash_swapbanks + * + * Description: + * Swaps banks 1 and 2 in the processor's memory map. Takes effect + * the next time the system is reset. + * + ****************************************************************************/ + +void stm32h7_flash_swapbanks(void) +{ + uint32_t opts = stm32h7_flash_getopt(); + if (opts & FLASH_OPTCR_SWAPBANK) + { + stm32h7_flash_optmodify(FLASH_OPTCR_SWAPBANK, 0); + } + else + { + stm32h7_flash_optmodify(0, FLASH_OPTCR_SWAPBANK); + } +} + +size_t up_progmem_pagesize(size_t page) +{ + return FLASH_SECTOR_SIZE; +} + +ssize_t up_progmem_getpage(size_t addr) +{ + struct stm32h7_flash_priv_s *priv; + + priv = stm32h7_flash_bank(addr); + + if (priv == NULL) + { + return -EFAULT; + } + + return priv->stpage + ((addr - priv->base) / FLASH_PAGE_SIZE); +} + +size_t up_progmem_getaddress(size_t block) +{ + struct stm32h7_flash_priv_s *priv; + if (block >= STM32_FLASH_NBLOCKS) + { + return SIZE_MAX; + } + + priv = stm32h7_flash_bank(STM32_FLASH_BANK1 + (block * FLASH_SECTOR_SIZE)); + return priv->base + (block - priv->stblock) * FLASH_SECTOR_SIZE; +} + +size_t up_progmem_neraseblocks(void) +{ + return PROGMEM_NBLOCKS; +} + +bool up_progmem_isuniform(void) +{ + return true; +} + +ssize_t up_progmem_ispageerased(size_t page) +{ + size_t addr; + size_t count; + size_t bwritten = 0; + + if (page >= FLASH_NPAGES) + { + return -EFAULT; + } + + /* Verify */ + + for (addr = up_progmem_getaddress(page), count = up_progmem_pagesize(page); + count; count--, addr++) + { + if (getreg8(addr) != FLASH_ERASEDVALUE) + { + bwritten++; + } + } + + return bwritten; +} + +size_t up_progmem_erasesize(size_t block) +{ + return FLASH_SECTOR_SIZE; +} + +ssize_t up_progmem_eraseblock(size_t block) +{ + struct stm32h7_flash_priv_s *priv; + int ret; + size_t block_address = STM32_FLASH_BANK1 + (block * FLASH_SECTOR_SIZE); + + if (block >= PROGMEM_NBLOCKS) + { + return -EFAULT; + } + + priv = stm32h7_flash_bank(block_address); + + ret = stm32h7_flash_sem_lock(priv); + if (ret < 0) + { + return (ssize_t)ret; + } + + up_invalidate_dcache((uintptr_t)block_address, + (uintptr_t)(block_address + FLASH_SECTOR_SIZE - 1)); + + if (stm32h7_wait_for_last_operation(priv)) + { + ret = -EIO; + goto exit_with_sem; + } + + /* Get flash ready and begin erasing single block */ + + stm32h7_unlock_flash(priv); + + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR_OFFSET, 0, FLASH_CR_SER); + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR_OFFSET, FLASH_CR_SSN_MASK, + FLASH_CR_SSN(block - priv->stblock)); + + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR_OFFSET, + 0, FLASH_CR_SER | FLASH_CR_START); + + /* Wait for erase operation to complete */ + + if (stm32h7_wait_for_last_operation(priv)) + { + ret = -EIO; + goto exit_with_lock_sem; + } + + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR_OFFSET, + FLASH_CR_SER, 0); + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR_OFFSET, + FLASH_CR_SSN_MASK, 0); + + ret = 0; + +exit_with_lock_sem: + stm32h7_lock_flash(priv); + +exit_with_sem: + stm32h7_flash_sem_unlock(priv); + + /* Verify */ + + if (ret == 0 && + stm32h7_israngeerased(block_address, up_progmem_erasesize(block)) == 0) + { + ret = up_progmem_erasesize(block); /* success */ + } + else + { + ret = -EIO; /* failure */ + } + + return ret; +} + +ssize_t up_progmem_write(size_t addr, const void *buf, size_t count) +{ + struct stm32h7_flash_priv_s *priv; + uint32_t *fp; + uint32_t *rp; + uint32_t *ll = (uint32_t *) buf; + size_t faddr; + size_t written = count; + int ret; + const size_t pagesize = 16; /* 128 bit, 16 bytes per page */ + const size_t llperpage = pagesize / sizeof(uint32_t); + size_t pcount = count / pagesize; + uint32_t sr; + + priv = stm32h7_flash_bank(addr); + + if (priv == NULL) + { + return -EFAULT; + } + + /* Check for valid address range */ + + if (addr < priv->base || + addr + count > priv->base + (STM32_FLASH_SIZE / 2)) + { + return -EFAULT; + } + + ret = stm32h7_flash_sem_lock(priv); + if (ret < 0) + { + return (ssize_t)ret; + } + + /* Check address and count alignment */ + + DEBUGASSERT(!(addr % pagesize)); + DEBUGASSERT(!(count % pagesize)); + + if (stm32h7_wait_for_last_operation(priv)) + { + written = -EIO; + goto exit_with_sem; + } + + /* Get flash ready and begin flashing */ + + stm32h7_unlock_flash(priv); + + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR_OFFSET, 0, FLASH_CR_PG); + + for (ll = (uint32_t *) buf, faddr = addr; pcount; + pcount -= 1, ll += llperpage, faddr += pagesize) + { + fp = (uint32_t *) faddr; + rp = ll; + + ARM_DSB(); + ARM_ISB(); + + /* Write 4 32 bit word and wait to complete */ + + *fp++ = *rp++; + *fp++ = *rp++; + *fp++ = *rp++; + *fp++ = *rp++; + + /* Data synchronous Barrier (DSB) just after the write operation. This + * will force the CPU to respect the sequence of instruction (no + * optimization). + */ + + ARM_DSB(); + ARM_ISB(); + + if (stm32h7_wait_for_last_operation(priv)) + { + written = -EIO; + goto exit_with_lock_sem; + } + + sr = stm32h7_flash_getreg32(priv, STM32_FLASH_SR_OFFSET); + if (sr & (FLASH_SR_SNECCERR | FLASH_SR_DBECCERR)) + { + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR_OFFSET, + FLASH_CR_PG, + 0); + + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CCR_OFFSET, + 0, ~0); + ret = -EIO; + goto exit_with_lock_sem; + } + } + + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR_OFFSET, FLASH_CR_PG, 0); + + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CCR_OFFSET, + 0, ~0); +exit_with_lock_sem: + stm32h7_lock_flash(priv); + + /* Verify */ + + if (written > 0) + { + for (ll = (uint32_t *) buf, faddr = addr, pcount = count / pagesize; + pcount; pcount -= 1, ll += llperpage, faddr += pagesize) + { + fp = (uint32_t *) faddr; + rp = ll; + + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CCR_OFFSET, + 0, ~0); + if ((*fp++ != *rp++) || + (*fp++ != *rp++) || + (*fp++ != *rp++) || + (*fp++ != *rp++)) + { + written = -EIO; + break; + } + + sr = stm32h7_flash_getreg32(priv, STM32_FLASH_SR_OFFSET); + if (sr & (FLASH_SR_SNECCERR | FLASH_SR_DBECCERR)) + { + written = -EIO; + break; + } + } + + stm32h7_flash_modifyreg32(priv, STM32_FLASH_CCR_OFFSET, + 0, ~0); + } + +exit_with_sem: + stm32h7_flash_sem_unlock(priv); + return written; +} + +uint8_t up_progmem_erasestate(void) +{ + return FLASH_ERASEDVALUE; +} diff --git a/arch/arm/src/stm32h7/stm32h7x3xx_rcc.c b/arch/arm/src/stm32h7/stm32h7x3xx_rcc.c index 9462ae2352..f5f4a2f26e 100644 --- a/arch/arm/src/stm32h7/stm32h7x3xx_rcc.c +++ b/arch/arm/src/stm32h7/stm32h7x3xx_rcc.c @@ -837,9 +837,17 @@ void stm32_stdclockconfig(void) * N.B. The system shall be power cycled before writing a new value. */ +#if defined(CONFIG_STM32H7_PWR_DIRECT_SMPS_SUPPLY) + regval = getreg32(STM32_PWR_CR3); + regval &= ~(STM32_PWR_CR3_BYPASS | STM32_PWR_CR3_LDOEN | + STM32_PWR_CR3_SMPSEXTHP | STM32_PWR_CR3_SMPSLEVEL_MASK); + regval |= STM32_PWR_CR3_LDOESCUEN; + putreg32(regval, STM32_PWR_CR3); +#else regval = getreg32(STM32_PWR_CR3); regval |= STM32_PWR_CR3_LDOEN | STM32_PWR_CR3_LDOESCUEN; putreg32(regval, STM32_PWR_CR3); +#endif /* Set the voltage output scale */