2020-03-16 11:51 AM
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!