diff --git a/arch/arm/src/common/stm32/stm32_flash.h b/arch/arm/src/common/stm32/stm32_flash.h index 9050b255d6bc1..716323b4c1649 100644 --- a/arch/arm/src/common/stm32/stm32_flash.h +++ b/arch/arm/src/common/stm32/stm32_flash.h @@ -46,6 +46,8 @@ void stm32_flash_getopt(uint32_t *opt); int stm32_flash_optmodify(uint32_t clear, uint32_t set); +int stm32_flash_optload(void); +int stm32_flash_swapbanks(void); void stm32_flash_lock(void); void stm32_flash_unlock(void); diff --git a/arch/arm/src/common/stm32/stm32_flash_m0_g0c0.c b/arch/arm/src/common/stm32/stm32_flash_m0_g0c0.c index 7b4d5e1e5e9a1..a44a6b06bfad2 100644 --- a/arch/arm/src/common/stm32/stm32_flash_m0_g0c0.c +++ b/arch/arm/src/common/stm32/stm32_flash_m0_g0c0.c @@ -588,6 +588,97 @@ int stm32_flash_optmodify(uint32_t clear, uint32_t set) return 0; } +/**************************************************************************** + * Name: stm32_flash_optload + * + * Description: + * Reload the flash option bytes. If an option-byte change affects the + * flash-bank mapping, the reload immediately resets the system. + * + * Returned Value: + * Zero or a negated errno value. + * + * -EBUSY: Timeout waiting for a previous flash operation to finish. + * + ****************************************************************************/ + +int stm32_flash_optload(void) +{ + int ret; + bool was_locked; + + ret = flash_wait_for_operation(); + if (ret != 0) + { + return -EBUSY; + } + + was_locked = flash_unlock_opt(); + modifyreg32(STM32_FLASH_SR, 0, FLASH_SR_CLEAR_ERROR_FLAGS); + + ret = flash_wait_for_operation(); + if (ret != 0) + { + ret = -EBUSY; + goto exit; + } + + modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_OBL_LAUNCH); + + while (getreg32(STM32_FLASH_CR) & FLASH_CR_OBL_LAUNCH) + { + } + +exit: + if (was_locked) + { + flash_lock_opt(); + } + + return ret; +} + +/**************************************************************************** + * Name: stm32_flash_swapbanks + * + * Description: + * Toggle the flash-bank mapping in the option bytes. The new mapping takes + * effect after a power-on reset or a call to stm32_flash_optload(). + * + * Returned Value: + * Zero or a negated errno value. + * + * -EBUSY: Timeout waiting for a previous flash operation to finish. + * -EPERM: Bank swapping is prohibited by the boot lock. + * + ****************************************************************************/ + +int stm32_flash_swapbanks(void) +{ + int ret = 0; + +#ifdef FLASH_DUAL_BANK + uint32_t reg; + + if (getreg32(STM32_FLASH_SECR) & FLASH_SECR_BOOT_LOCK) + { + return -EPERM; + } + + reg = getreg32(STM32_FLASH_OPTR); + if (reg & FLASH_OPTR_NSWAP_BANK) + { + ret = stm32_flash_optmodify(FLASH_OPTR_NSWAP_BANK, 0); + } + else + { + ret = stm32_flash_optmodify(0, FLASH_OPTR_NSWAP_BANK); + } +#endif + + return ret; +} + #ifdef CONFIG_ARCH_HAVE_PROGMEM /* up_progmem_x functions defined in nuttx/include/nuttx/progmem.h