2016-12-14 02:50 PM
I am trying to write code to set the BOR Level under program control but cannot get the result I need. I have the following:
if ((FLASH_GetUserOptionByte() & 0x0F) != OB_BOR_LEVEL4)
{
FLASH_UnlockOptionByte();
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR |
FLASH_FLAG_PGAERR | FLASH_FLAG_SIZERR | FLASH_FLAG_OPTVERR);
FLASH_SetBORResetLevel(OB_BOR_LEVEL4);
FLASH_LockOptionByte();
FLASH_OBLLaunch();
}
If I have a current BOR level 3, it remains at level 3. The attempt to write level 4 fails. I am using IAR and single step. I see the bits reset in the PECR register, and the attempt to write OBR register with level 4, but it does not update with the correct value.
What am I doing wrong in the code?
2016-12-14 02:52 PM
I forgot to specify: STM32L151
2016-12-14 03:53 PM
Hi Art
I have moved this thread to the
‌ where a product related questions are held.Thanks
Oli
2016-12-14 06:27 PM
Would you need to unlock the flash controller, and erase the option bytes?
2016-12-14 08:48 PM
Thanks for trying to help me.
The User Manual - RM0038 (STM32L151) - doesn't show a specific mechanism for unlocking the controller as a whole. Instead there are separate bits for locking/unlocking the program, data, and option bytes. If you know of an additional place/register where this takes please I would appreciate knowing about it.
As for erasing, wouldn't the act of writing a new value altogether suffice?
2016-12-15 01:35 AM
Hi
,try to apply similar code as the one implemented in the 'BOR' example inside the STM32L1xx standard peripheral library as follow:
/* Get BOR Option Bytes */ BOROptionBytes = FLASH_OB_GetBOR(); if((BOROptionBytes & 0x0F) != BOR_LEVEL) { /* Unlocks the option bytes block access */ FLASH_OB_Unlock();/* Clears the FLASH pending flags */ FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_SIZERR | FLASH_FLAG_OPTVERR);/* Select the desired V(BOR) Level ---------------------------------------*/ FLASH_OB_BORConfig(BOR_LEVEL);/* Launch the option byte loading */ FLASH_OB_Launch(); }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
Hope this clarify and respond to you question. If the response is correct, you press correct button.
-Walid F-
2016-12-15 03:21 AM
I think you need to lock after launch. Flash_OB_Launch() launches the programming process so it would make sense to lock afterwards.
Using the standard peripheral library, here is what I do to make sure my BOR is set to what I want:
if(FLASH_OB_GetBOR() !=
OB_BOR_LEVEL3
) { FLASH_OB_Unlock(); FLASH_OB_BORConfig(OB_BOR_LEVEL3
); FLASH_OB_Launch(); FLASH_OB_Lock(); }Note: it is unnecessary to mask out any bits after the call to
FLASH_OB_GetBOR() as the necessary masking is performed within that function (at least in my version of the standard peripherals lib: STM32F4xx_DSP_StdPeriph_Lib_V1.7.1 source code file: stm32f4xx_flash.c)
Instructions from stm32f4xx_flash.c (standard peripheral library):
Any operation of erase or program should follow these steps:
(#) Call the FLASH_OB_Unlock() function to enable the FLASH option control register access(#) Call one or several functions to program the desired Option Bytes:
(++) void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState) => to Enable/Disable the desired sector write protection (++) void FLASH_OB_RDPConfig(uint8_t OB_RDP) => to set the desired read Protection Level (++) void FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY) => to configure the user Option Bytes. (++) void FLASH_OB_BORConfig(uint8_t OB_BOR) => to set the BOR Level(#) Once all needed Option Bytes to be programmed are correctly written,
call the FLASH_OB_Launch() function to launch the Option Bytes programming process. -@- When changing the IWDG mode from HW to SW or from SW to HW, a system reset is needed to make the change effective.(#) Call the FLASH_OB_Lock() function to disable the FLASH option control
register access (recommended to protect the Option Bytes against possible unwanted operations)