This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch pr402 in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit dad5d6865d88fc42648d762b861d3e5c783d430f Author: Joshua Lange <[email protected]> AuthorDate: Tue Feb 18 19:03:07 2020 -0600 Fixed some issues with internal flash driver on STM32H7 --- arch/arm/src/stm32h7/hardware/stm32h7x3xx_flash.h | 2 +- arch/arm/src/stm32h7/stm32_flash.c | 141 +++++++++++++++++++++- arch/arm/src/stm32h7/stm32_flash.h | 100 +++++++++++++++ 3 files changed, 236 insertions(+), 7 deletions(-) diff --git a/arch/arm/src/stm32h7/hardware/stm32h7x3xx_flash.h b/arch/arm/src/stm32h7/hardware/stm32h7x3xx_flash.h index 3de570d..976c67a 100644 --- a/arch/arm/src/stm32h7/hardware/stm32h7x3xx_flash.h +++ b/arch/arm/src/stm32h7/hardware/stm32h7x3xx_flash.h @@ -168,7 +168,7 @@ #define FLASH_CR_START (1 << 7) /* Bit 7: Erase start */ #define FLASH_CR_SNB_SHIFT (8) /* Bits 8-10: Sector number */ #define FLASH_CR_SNB_MASK (15 << FLASH_CR_SNB_SHIFT) /* Used to clear FLASH_CR_SNB bits */ -# define FLASH_CR_SNB(n) ((uint32_t)(n & 0x7) << FLASH_CR_SNB_SHIFT) /* Sector n, n=0..7 */ +# define FLASH_CR_SNB(n) ((uint32_t)((n) & 0x7) << FLASH_CR_SNB_SHIFT) /* Sector n, n=0..7 */ /* Bits 11-13: Reserved */ #define FLASH_CR_SPSS2 (1 << 14) /* Bit 14: Bank1 Reserved, Bank 2 special sector selection bit */ #define FLASH_CR_CRCEN (1 << 15) /* Bit 15: CRC control enable */ diff --git a/arch/arm/src/stm32h7/stm32_flash.c b/arch/arm/src/stm32h7/stm32_flash.c index e676697..0881eac 100644 --- a/arch/arm/src/stm32h7/stm32_flash.c +++ b/arch/arm/src/stm32h7/stm32_flash.c @@ -193,7 +193,7 @@ static struct stm32h7_flash_priv_s stm32h7_flash_bank2_priv = *****************************************************************************/ static inline uint32_t stm32h7_flash_getreg32(FAR struct stm32h7_flash_priv_s - *priv, uint8_t offset) + *priv, uint32_t offset) { return getreg32(priv->ifbase + offset); } @@ -207,7 +207,7 @@ static inline uint32_t stm32h7_flash_getreg32(FAR struct stm32h7_flash_priv_s ****************************************************************************/ static inline void stm32h7_flash_putreg32(FAR struct stm32h7_flash_priv_s - *priv, uint8_t offset, + *priv, uint32_t offset, uint32_t value) { putreg32(value, priv->ifbase + offset); @@ -222,7 +222,7 @@ static inline void stm32h7_flash_putreg32(FAR struct stm32h7_flash_priv_s *****************************************************************************/ static inline void stm32h7_flash_modifyreg32(FAR struct stm32h7_flash_priv_s - *priv, uint8_t offset, + *priv, uint32_t offset, uint32_t clearbits, uint32_t setbits) { @@ -330,6 +330,73 @@ FAR struct stm32h7_flash_priv_s * stm32h7_flash_bank(size_t address) return priv; } +/***************************************************************************** + * Name: stm32h7_unlock_flashopt + * + * Description: + * Unlock the flash option bytes + * + *****************************************************************************/ + +static void stm32h7_unlock_flashopt(FAR 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_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); + } +} + +/***************************************************************************** + * Name: stm32h7_lock_flashopt + * + * Description: + * Lock the flash option bytes + * + *****************************************************************************/ + +static void stm32h7_lock_flashopt(FAR 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(FAR 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 ****************************************************************************/ @@ -423,6 +490,67 @@ int stm32h7_flash_writeprotect(size_t block, bool enabled) 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; + priv = stm32h7_flash_bank(STM32_FLASH_BANK1); + if (priv) + { + stm32h7_unlock_flashopt(priv); + stm32h7_flash_modifyreg32(priv, STM32_FLASH_OPTSR_PRG_OFFSET, clear, set); + stm32h7_save_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; @@ -508,11 +636,12 @@ ssize_t up_progmem_eraseblock(size_t block) 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)); + FLASH_CR_SNB(block - priv->stblock)); stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, 0, FLASH_CR_START); - while (stm32h7_flash_getreg32(priv, STM32_FLASH_CR1_OFFSET) & FLASH_SR_BSY) + while (stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET) & + (FLASH_SR_BSY | FLASH_SR_QW)) { } @@ -600,7 +729,7 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count) ARM_ISB(); while (stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET) & - FLASH_SR_BSY) + (FLASH_SR_BSY | FLASH_SR_QW)) { } diff --git a/arch/arm/src/stm32h7/stm32_flash.h b/arch/arm/src/stm32h7/stm32_flash.h new file mode 100644 index 0000000..ca2696a --- /dev/null +++ b/arch/arm/src/stm32h7/stm32_flash.h @@ -0,0 +1,100 @@ +/**************************************************************************** + * arch/arm/src/stm32h7/stm32_fflash.h + * + * Copyright (C) 2020 Gregory Nutt. All rights reserved. + * Author: Joshua Lange <[email protected]> + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32H7_STM32_FLASH_H +#define __ARCH_ARM_SRC_STM32H7_STM32_FLASH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include "chip.h" +#include "hardware/stm32_flash.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: stm32h7_flash_getopt + * + * Description: + * Returns the current flash option bytes from the FLASH_OPTSR_CR register. + * + ****************************************************************************/ + +uint32_t stm32h7_flash_getopt(void); + +/**************************************************************************** + * 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); + +/**************************************************************************** + * 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); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32H7_STM32_FLASH_H */
