Add support for stm32h7b3xx MCU's flash

This commit is contained in:
Javier Casas 2022-09-08 10:13:14 +02:00 committed by Xiang Xiao
parent 81ff16c675
commit 663bf4d968
30 changed files with 2438 additions and 984 deletions

View File

@ -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*/

View File

@ -69,6 +69,8 @@
#if defined(CONFIG_STM32H7_STM32H7X3XX)
# include <arch/stm32h7/stm32h7x3xx_irq.h>
#elif defined(CONFIG_STM32H7_STM32H7B3XX)
# include <arch/stm32h7/stm32h7x3xx_irq.h>
#elif defined(CONFIG_STM32H7_STM32H7X7XX)
# include <arch/stm32h7/stm32h7x7xx_irq.h>
#else

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -28,7 +28,7 @@
#include <nuttx/config.h>
#include <arch/stm32h7/chip.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
@ -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 */

View File

@ -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 */

View File

@ -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 <nuttx/config.h>
/****************************************************************************
* 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) */

View File

@ -27,7 +27,7 @@
#include <nuttx/config.h>
#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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -1,977 +1,39 @@
/****************************************************************************
* arch/arm/src/stm32h7/stm32_flash.c
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Authors: Gregory Nutt <gnutt@nuttx.org>
* David Sidrane <david.sidrane@nscdg.com>
* 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 <evgen@wolpike.com>
*
* Ported from stm32f20xxf40xx_flash.c, this is the original license:
*
* Copyright (C) 2011 Uros Platise. All rights reserved.
* Author: Uros Platise <uros.platise@isotel.eu>
*
* 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 <nuttx/config.h>
#include <nuttx/arch.h>
#include <nuttx/mutex.h>
#include <stdbool.h>
#include <assert.h>
#include <errno.h>
#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;
}

View File

@ -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 */

View File

@ -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

View File

@ -0,0 +1,978 @@
/****************************************************************************
* arch/arm/src/stm32h7/stm32h743xx_flash.c
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Authors: Gregory Nutt <gnutt@nuttx.org>
* David Sidrane <david.sidrane@nscdg.com>
*
* Ported from stm32f7_flash.c, this is the original license:
*
* Copyright (C) 2018 Wolpike LLC. All rights reserved.
* Author: Evgeniy Bobkov <evgen@wolpike.com>
*
* Ported from stm32f20xxf40xx_flash.c, this is the original license:
*
* Copyright (C) 2011 Uros Platise. All rights reserved.
* Author: Uros Platise <uros.platise@isotel.eu>
*
* 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 <nuttx/config.h>
#include <nuttx/arch.h>
#include <nuttx/mutex.h>
#include <stdbool.h>
#include <assert.h>
#include <errno.h>
#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;
}

View File

@ -0,0 +1,968 @@
/****************************************************************************
* arch/arm/src/stm32h7/stm32h7b3xx_flash.c
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Authors: Gregory Nutt <gnutt@nuttx.org>
* David Sidrane <david.sidrane@nscdg.com>
*
* Ported from stm32f7_flash.c, this is the original license:
*
* Copyright (C) 2018 Wolpike LLC. All rights reserved.
* Author: Evgeniy Bobkov <evgen@wolpike.com>
*
* Ported from stm32h743xx_flash.c, this is the original license:
*
* Copyright (C) 2011 Uros Platise. All rights reserved.
* Author: Uros Platise <uros.platise@isotel.eu>
*
* 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 <nuttx/config.h>
#include <nuttx/arch.h>
#include <nuttx/semaphore.h>
#include <stdbool.h>
#include <assert.h>
#include <errno.h>
#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;
}

View File

@ -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 */