I have the following code for an STM32L051 which programs the option bytes to change RDP level from 0 to 1.
The change is implemented at the next power-on reset, when FLASH->OPTR is loaded from the option bytes.
/* Increase readout protection level from 0 to 1 */
void RDP_level0_to_level1(void) {
uint32_t primask_bit;
primask_bit = __get_PRIMASK();
__disable_irq();
FLASH->PEKEYR = FLASH_PEKEY1; /* Unlock eeprom data memory and FLASH->PECR register access */
FLASH->PEKEYR = FLASH_PEKEY2;
FLASH->OPTKEYR = FLASH_OPTKEY1; /* Unlock option bytes */
FLASH->OPTKEYR = FLASH_OPTKEY2;
__set_PRIMASK(primask_bit);
CLEAR_BIT(FLASH->PECR, FLASH_PECR_ERASE);
/* PELOCK = 0, OPTLOCK = 0, ERASE = 0 as per RM section 3.3.4 Writing/erasing the NVM > Write Option bytes */
/* 16-bit data is extended with its complemented value */
/* WPRMOD=0 */
OB->RDP = (~((uint32_t)OB_RDP_LEVEL_1) << 16) | (uint32_t)OB_RDP_LEVEL_1;
while ((FLASH->SR & FLASH_SR_BSY) != 0)
(void)0;
SET_BIT(FLASH->PECR, FLASH_PECR_OPTLOCK);
SET_BIT(FLASH->PECR, FLASH_PECR_PELOCK);
/* FLASH->OPTR will have the updated value (from OB->RDP) after next power on reset */
}
That works but rather than wait for a power on reset, I would like to force a reload of the option bytes immediately use the OBL_LAUNCH bit:
SET_BIT(FLASH->PECR, FLASH_PECR_OBL_LAUNCH); /* Reboot and Force Option Bytes Load, OPTLOCK must be 0 */
But adding that in causes the the device to hang:
void RDP_level0_to_level1_REBOOT(void) {
__disable_irq();
FLASH->PEKEYR = FLASH_PEKEY1; /* Unlock eeprom data memory and FLASH->PECR register access */
FLASH->PEKEYR = FLASH_PEKEY2;
FLASH->OPTKEYR = FLASH_OPTKEY1; /* Unlock option bytes */
FLASH->OPTKEYR = FLASH_OPTKEY2;
CLEAR_BIT(FLASH->PECR, FLASH_PECR_ERASE);
/* PELOCK = 0, OPTLOCK = 0, ERASE = 0 as per RM section 3.3.4 Writing/erasing the NVM > Write Option bytes */
/* 16-bit data is extended with its complemented value */
/* WPRMOD=0 */
OB->RDP = (~((uint32_t)OB_RDP_LEVEL_1) << 16) | (uint32_t)OB_RDP_LEVEL_1;
while ((FLASH->SR & FLASH_SR_BSY) != 0)
(void)0;
SET_BIT(FLASH->PECR, FLASH_PECR_OBL_LAUNCH); /* Reboot and Force Option Bytes Load, OPTLOCK must be 0 */
/* shouldn't get here */
}
I've tried various things, including running that function in RAM but am kinda stuck. The RM is somewhat lacking on OBL_LAUNCH information other than 'set this bit to load and reboot'.
The RESET pin just has 100nF to GND so device should be able to drive RESET without problem.
Has anyone successfully used OBL_LAUNCH ?