cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4: How to program BOR/ option bytes?

flyer31
Senior
Posted on April 16, 2012 at 09:24

In STM32F4, TRM, Chapter 4 ''PWR'' it says under 4.2.2 ''BOR...'', there it says ''VBOR is configured through device option bytes.'' It would be very nice, if you could spend a link there to the description of the device option bytes. (Searching the document for ''device option bytes'' leads to no result. These ''option bytes'' seem to be a bit mystical - only 2.3.3 ''Flash memory'' gives a hint of ''16 option bytes''..., but not easy to find their description)

Anybody knows, where I can find the description of these Option Bytes?

... sorry, just found it myself, it is well described in the additional ''Programming manual PM0081 STM32F40xx and STM32F41xx Flash programming manual'' (but it would be nice of course, if the ref. manual would give a link to this programming manual) (further it would be VERY nice, if STM32F4xx.h would have any predefined constants for programming this - as I think BOR is very important, nearly ANY user will be interested in this, and it would be very helpful, if in the STM32F4xx_DSP_StdPeriph_Lib_Examples\Flash there would be an example how to program the BOR level - I find one for the write protection, but I really would appreciate to have an example for BOR directly from STM, as for sure this is a quite sensitive topic).

... meanwhile I saw, that in STM32F4xx_DSP_StdPeriph_Lib there is quite good support through the file STM32F4xx_Flash.c/h. Just one big question: Why there they use the adresses

#define OPTCR_BYTE0_ADDRESS         ((uint32_t)0x40023C14)

#define OPTCR_BYTE1_ADDRESS         ((uint32_t)0x40023C15)

#define OPTCR_BYTE2_ADDRESS         ((uint32_t)0x40023C16)

But in the flash programming manual it says, that these option bytes should be at flash address 0x1FFF C000, 0x1FFF C004 and 0x1FFF C008. Can anybody resolve this contradiction?

9 REPLIES 9
Posted on April 16, 2012 at 19:40

FLASH_OPTCR is located at 0x40023C14, ie +0x14 from 0x40023C000

It is loaded at reset from the value in the flash. ie to be used, elements from the array need to be latched into a buffer, not from wires attached directly to the flash cells themselves. So you write the value into the memory array, it's content gets latched into a register to be used

Page 23, PM0081 (rev 1, Sept 2011)

http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/PROGRAMMING_MANUAL/DM00023388.pdf

1.8.6 Flash option control register (FLASH_OPTCR)

 

The FLASH_OPTCR register is used to modify the user option bytes.

 

Address offset: 0x14

 

Reset value: 0x0FFF AAED. The option bits are loaded with values from Flash memory at reset release.

 

Access: no wait state when no Flash memory operation is ongoing, word, half-word and byte access.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Seems a lot of people have problems programmatically setting the ROP level, I tried using the default code on an STM32F407VGT6 and it doesn't use the 0xBB level to protect at level 1, but 0x55...but it doesn't work.
Cube Programmer allows it to be set to 0xBB and that does work.
So I tried 0xBB programmatically, and it still doesn't work.  Though set, after a reset the 0xAA value returns.

Here is the code if anyone feels inclined to close this issue with a few lines of code that actually work:

    //FLASH_OBProgramInitTypeDef OBInit;
    //HAL_FLASHEx_OBGetConfig(&OBInit);
    if (*(__IO uint8_t*)(OPTCR_BYTE1_ADDRESS) != 0xBB)	//OBInit.RDPLevel != 0xBB)	//OB_RDP_LEVEL_1)	// This does not seem to work with STM32F407VGT6 clone board. Test with STM VGT6U.
    {
  	  HAL_FLASH_OB_Unlock();
  	  /*
  	  OBInit.OptionType = OPTIONBYTE_RDP;
  	  OBInit.RDPLevel = OB_RDP_LEVEL_1;	// 0x55 (0xBB usually, version change?)	Prevent read of prog mem. Can be reset to 0xAA.  0xCC will blow fuses so chip can never to reprogrammed.
  	  HAL_StatusTypeDef result = HAL_FLASHEx_OBProgram(&OBInit);
  	  */

  	  *(__IO uint8_t*)OPTCR_BYTE1_ADDRESS = (uint8_t)0xBB;	// Block prog. read back.
  	  HAL_FLASH_OB_Lock();
    }

 

You need to set the OPTSTART bit to apply changes to the option bytes, as described in the reference manual.

TDK_0-1691860083749.png

 

If you feel a post has answered your question, please click "Accept as Solution".

Posting to an 11 year old thread.

SPL Code

// Flash Readout Protection Level 1
if (FLASH_OB_GetRDP() != SET) {
    FLASH_Unlock();
    FLASH_OB_Unlock();
    FLASH_OB_RDPConfig(OB_RDP_Level_1);
    FLASH_OB_Launch();                        // Option Bytes programming
    FLASH_OB_Lock();
    FLASH_Lock();
}
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

I would say "Finally an answer to an 11-year old thread!"

**bleep**, missed the second unlock, unlock Flash, the unlock option bytes, will try that! Thanks for posting!

Your line:

if (FLASH_OB_GetRDP() != SET) {

looks wrong because FLASH_OB_GetRDP() return the current value, 0xaa, 0x55 or 

0xCC and the line compares against SET, which is defined as !0, so all conditions will return true.

If an invalid value had been set, the function would fail to correct it.

Not sure that's very useful?

Maybe this:-

 

 

 

 

static HAL_StatusTypeDef RDP_Set(uint8_t RDPValue)	// OB_RDP_LEVEL_1 etc
{
	FLASH_OBProgramInitTypeDef FLASH_Handle;

	HAL_FLASH_Unlock();
	FLASH_Handle.RDPLevel = (uint32_t)RDPValue;
	FLASH_Handle.OptionType = OPTIONBYTE_RDP;

	HAL_FLASH_OB_Unlock();
	HAL_FLASHEx_OBProgram(&FLASH_Handle);

	HAL_StatusTypeDef status = HAL_FLASH_OB_Launch();

	HAL_FLASH_OB_Lock();
	HAL_FLASH_Lock();

	if (status != HAL_OK)
	{
		return HAL_ERROR;
	}

	return HAL_OK;
}

 

 

 

 

SPL works differently than HAL.

https://github.com/fpoussin/QStlink2/blob/b0d2fb838667438955f370b9f5baf4e46272fb1c/loaders/src/stm32f0xx_flash.c#L975

If you feel a post has answered your question, please click "Accept as Solution".

Thanks for that info, would be a great idea to add to any code posts whether it's SPL if not HAL, to avoid confusion, which abounds in coding IMO.

Curious that SPL extension libraries are not supporting the H-series processors, or that's what it says on STM's page: https://www.st.com/en/embedded-software/stm32-standard-peripheral-libraries.html 

SPL is deprecated and hasn't been worked on in many years. The STM32H7 came out well after SPL development stopped.

If you feel a post has answered your question, please click "Accept as Solution".