Skip to main content
CSeto.1
Associate
March 16, 2020
Question

Stm32 options bytes get randomly reprogrammed even when flash not unlocked

  • March 16, 2020
  • 0 replies
  • 665 views

I have a strange issue with my Stm32F767 project. We've seen with some boards randomly RDP will be enable to level 1, and BOOT0/1 are set to 0xffff. ESD seems like a potentially likely cause, but is there really enough energy in an ESD event to cause a flash erase to occur (given that the option byte bits are getting SET, not cleared, which implies a flash erase must have occurred). When this happens, the boards are recoverable with the removal of RDP back to level 0, and a reflash of the code.

We have two separate boards with this exact same chip and general layout, and we've only ever seen it with one of the two.

One other thing of note, when the board boots up, I check that the option byte word containing the RDP/brownout setting is correctly set. If it is not, I set the brownout protection to maximally restrictive with the following code. Is there any obvious issue with this code? The board is released from reset after programming and allowed to change its option bytes with this function. This function should never unlock the option bytes after that unless they change.

static void CheckProgramOptionBytes(void)
{
 uint32_t current_options_word;
 uint32_t desired_options;
 
 // Set desired options
 desired_options = 0;
 
 // Ref: RM0410, Page 113, 3.7.6, Flash option control register (FLASH_OPTCR)
 desired_options |= (0x01 << 31); // IWDG_STOP: IWDG counter active in STOP mode
 desired_options |= (0x01 << 30); // IWDG_STDBY: IWDG counter active in standby mode
 desired_options |= (0x01 << 29); // nDBANK: The Flash user area is seen as a single bank with 256 bits read access
 desired_options |= (0x01 << 28); // nDBOOT: Dual Boot disabled
 desired_options |= (0xfff << 16); // nWRP: No write protection for any banks
 desired_options |= (0xaa << 8); // No read out protection
 desired_options |= (0x01 << 7); // nRST_STDBY: No reset generated
 desired_options |= (0x01 << 6); // nRST_STOP: No reset generated
 desired_options |= (0x01 << 5); // IWDG_SW:
 desired_options |= (0x01 << 4); // WWDG_SW: Hardware window watchdog
 desired_options |= (0x00 << 2); // BOR level 3
 
 // Get current options
 current_options_word = FLASH->OPTCR & ~(0x03);
 
 if (current_options_word != desired_options)
 {
 LOG_W(TAG, "Option bytes not set, setting them...");
 
 // Unlock option bytes
 HAL_FLASH_OB_Unlock();
 
 // Set desired options
 FLASH->OPTCR = desired_options;
 
 // Commit options
 if (HAL_FLASH_OB_Launch() != HAL_OK)
 {
 LOG_E(TAG, "Could not set option bytes (failed to launch)");
 return;
 }
 
 // Relock option bytes
 HAL_FLASH_OB_Lock();
 
 // Reset
 LOG_I(TAG, "Option bytes set, rebooting...");
 HAL_NVIC_SystemReset();
 }
}

Thanks!

This topic has been closed for replies.