2023-05-19 05:17 PM
2023-05-20 12:35 AM
How exactly do you do that?
What are the option byte settings, and what are the steps you do before setting OBL_LAUNCH?
JW
2023-05-20 12:29 PM
I am setting option byte 0 to configure the RDPROT level to 1. There are many questions about exactly this topic on many forums; if you know the answer, please share it; otherwise, I'm hoping an ST employee will respond.
However, to help someone else finding this question, the following code works; note the commented out code on lines 27..29. That does *not* work and elicits the problem I described (CPU locks up and even a hard reset will not clear it...requires a power cycle).
Note too: I have tried placing this code in RAM and the same problem occurs.
/**
* Set Flash Readout Protection to level 1
* @note CPU will reset - this function does not exit
*/
void read_protect_flash(void) {
if ((FLASH->OPTR & FLASH_OPTR_RDPROT) == 0xAA) {
// flash read protection is currently disabled
__disable_irq();
// unlock NVM
FLASH->PEKEYR = FLASH_PEKEY1;
FLASH->PEKEYR = FLASH_PEKEY2;
// unlock option bytes
FLASH->OPTKEYR = FLASH_OPTKEY1;
FLASH->OPTKEYR = FLASH_OPTKEY2;
// Write/erase protocol: PELOCK=0, OPTLOCK=0, ERASE=0
CLEAR_BIT(FLASH->PECR, FLASH_PECR_ERASE);
// Set RDPROT to level 1
MODIFY_REG(OB->RDP, 0x00FF00FF, 0x004400BB);
// Wait for operation to finish
while ((FLASH->SR & FLASH_SR_BSY) != 0) { /* todo: timeout */ }
if (FLASH->SR & FLASH_SR_EOP) {
FLASH->SR = FLASH_SR_EOP; // clear the EOP flag
}
// Reload the option bytes and reset - this doesn't work
// CPU will hang until power cycled
//SET_BIT(FLASH->PECR, FLASH_PECR_OBL_LAUNCH);
// Lock flash and the option bytes
SET_BIT(FLASH->PECR, FLASH_PECR_OPTLOCK);
SET_BIT(FLASH->PECR, FLASH_PECR_PELOCK);
// Option bytes are re-read after exit from standby mode (which will reset)
// So configure IWDG to wake us from standby and then enter standby mode
watchdog_init(10); // reset in 10ms
SCB->SCR = SCB_SCR_SLEEPDEEP_Msk;
PWR->CR |= PWR_CR_PDDS | PWR_CR_CWUF | PWR_CR_CSBF; // clear wakeup and standby flags
while( (PWR->CSR & PWR_CSR_WUF) == PWR_CSR_WUF ); // wait for flags to clear
__SEV();
__WFE();
__WFE();
}
}