cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L051: Setting FLASH_PECR_OBL_LAUNCH hangs CPU until POR (even a hard reset will not exit this condition). Is this broken in silicon (in which case it belongs in the errata)?

DAlbe.3
Senior
 
2 REPLIES 2

How exactly do you do that?

What are the option byte settings, and what are the steps you do before setting OBL_LAUNCH?

JW

DAlbe.3
Senior

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();
   }
}