AnsweredAssumed Answered

STM32F437 IAP Option Byte programming failure

Question asked by hodgson.andrew.001 on Feb 2, 2018

So I have an STM32F437VG processor and I want to change the BOR level to 0 in the Option bytes (leaving all others at their factory defaults). I intend to do this via a one-time change in early startup via the following code snippet (I'm using the Cube libraries not the SPL):

 

HAL_FLASHEx_OBGetConfig(&OBInit);

/* only modify the Brown Out level setting if it needs changing */
if (OBInit.BORLevel != OB_BOR_LEVEL3)
{
    /* Unlock the FLASH Option Control Register */
    HAL_FLASH_OB_Unlock();
    /* set the Brownout level3: 2.7V - 3.6V */
    OBInit.OptionType = OPTIONBYTE_BOR;
    OBInit.BORLevel = OB_BOR_LEVEL3;
   
    status = HAL_FLASHEx_OBProgram(&OBInit);
    if (status == HAL_OK)
    {
        /* Launch the option byte loading */
        status = HAL_FLASH_OB_Launch();
        if (status == HAL_OK)
        {
            FLOperStatus = FLASH_SUCCESS;
        }
    }
   
    /* Lock the FLASH Option Control Register */
    HAL_FLASH_OB_Lock(); 
}
else
{
   /* do nothing and say we suceeded */
    FLOperStatus = FLASH_SUCCESS;
}

 

For 90% of the boards I've tried it on this works fine. The actual OPTCR register ends up containing 0x0FFFAAE1 which appears to be correct after consulting the manual.

 

However, there are a few boards that end up refusing to apply the change. Instead I end up with the value 0xCFFFFFFD in the register, which clearly looks like some kind of error condition. Unfortunately, there doesn't appear to be anything in the manual (or at least, I haven't found it yet) that would indicate what might cause this error.

 

If I fire up ST-LINK and program the option bytes with that, then things seem to work OK even on the boards that refuse to accept the IAP method. I could simply use that to program the option bytes and forget about in-application programming but I like to understand why things don't work!

Outcomes