Last active
February 9, 2024 08:59
-
-
Save diorcety/6f9e5d7e1a13c1c123d531d90e3d4716 to your computer and use it in GitHub Desktop.
STM32 RDP without POR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* From https://www.youtube.com/watch?v=f7vs0NwZPFo */ | |
| /* | |
| * Warning -> if you use IWDG ! | |
| * EraseChip + POR + Flash -> will hang | |
| * BlankChip + Flash -> will hang | |
| * EraseChip + Flash -> may work | |
| * | |
| * In order to make it works you should do: | |
| * (EraseChip + POR)/BlankChip + Flash + reload option bytes (stm32l4x option_load 0 with openocd) | |
| * This will allow to use IWDG in any case after a Flash without another POR, and in this case, to change RDP without POR | |
| */ | |
| /** | |
| * @brief Same as _HAL_PWR_EnterSTANDBYMode but in RAM | |
| * @return void | |
| */ | |
| __RAM_FUNC void _HAL_PWR_EnterSTANDBYMode(void) | |
| { | |
| /* Set Stand-by mode */ | |
| MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_CR1_LPMS_STANDBY); | |
| /* Set SLEEPDEEP bit of Cortex System Control Register */ | |
| SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); | |
| /* This option is used to ensure that store operations are completed */ | |
| #if defined(__CC_ARM) | |
| __force_stores(); | |
| #endif | |
| /* Request Wait For Interrupt */ | |
| __WFI(); | |
| } | |
| /** | |
| * @brief Same behaviour that HAL_FLASH_OB_Launch but allow debugger attached | |
| * @return void | |
| */ | |
| __RAM_FUNC void _flash_ob_launch(void) | |
| { | |
| __disable_irq(); | |
| /* Disable all DBG features */ | |
| CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY); | |
| CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP); | |
| CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP); | |
| __HAL_DBGMCU_UNFREEZE_WWDG(); | |
| __HAL_DBGMCU_UNFREEZE_IWDG(); | |
| /* HAL_FLASH_OB_Launch is replaced by a standby */ | |
| /* To load new options into FLASH->OPTR from OB->RDP we need to wake from standby mode. | |
| * Execution after exit from standby mode is same as a reset. | |
| * For simplicity, use the IWDG to exit from standby. | |
| */ | |
| IWDG->KR = 0xCCCC; /* start */ | |
| IWDG->KR = 0x5555; /* enable access to PR and RLR regs */ | |
| IWDG->PR = IWDG_PR_PR_2; /* /64 prescaler for the dedicated 32kHz LSI clock = 512Hz */ | |
| IWDG->RLR = 256; /* count down from this value (256 is about 0.5secs at 512Hz) */ | |
| while (IWDG->SR) /* wait for setup to complete (slow clock domain) */ | |
| (void)0; | |
| IWDG->KR = 0xAAAA; /* refresh (feed) the watchdog */ | |
| /* Clear all related wakeup flags */ | |
| __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); | |
| #if 0 | |
| HAL_PWR_EnterSTANDBYMode(); | |
| #else | |
| _HAL_PWR_EnterSTANDBYMode(); | |
| #endif | |
| // Should not reach here, rollback changes in case of... | |
| /* Clear SLEEPDEEP bit of Cortex System Control Register */ | |
| CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); | |
| /* Deselect Standby mode */ | |
| MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_CR1_LPMS_STOP0); | |
| __enable_irq(); | |
| } | |
| int main(void) | |
| { | |
| ... | |
| /* Program Option Bytes */ | |
| status |= HAL_FLASHEx_OBProgram(&OBStruct); | |
| HAL_SuspendTick(); | |
| /* Launch Option Bytes Loading */ | |
| _flash_ob_launch(); | |
| ... | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment