Skip to main content
DAlbe.3
Associate III
May 27, 2024
Solved

How to set RDP level 1 via software on STM32G030

  • May 27, 2024
  • 4 replies
  • 6682 views

I would like to increase the code readout protection level from 0 to 1 programmatically in an STM32G030.  I must be doing something silly and if anyone sees it, I'd be grateful.  I've stepped through it with the debugger and the flash and option byte locks are indeed removed. The write to the option register doesn't show up in the debugger (still shows 0xAA), There are no errors in the FLASH SR or CR registers after the OPTSTART bit is set.  The debugger loses connection when OBL_LAUNCH is set (presumably due to the reset).  After the reset, the RDP byte in the flash OPTR is still set to 0xAA. It is still 0xAA after the device is power cycled. The code is:

 

 

 

 // Set code readout protection
 __disable_irq();
 // unlock flash memory (LOCK bit in FLASH_CR)
 FLASH->KEYR = 0x45670123;
 FLASH->KEYR = 0xCDEF89AB;
 // wait for flash unlocked
 while (FLASH->CR & FLASH_CR_LOCK);
 // clear option lock (OPTLOCK bit in FLASH_CR)
 FLASH->OPTKEYR = 0x08192A3B;
 FLASH->OPTKEYR = 0x4C5D6E7F;
 // wait for option bytes unlocked
 while (FLASH->CR & FLASH_CR_OPTLOCK);

 // Set flash readout protection level 1
 MODIFY_REG(FLASH->OPTR, FLASH_OPTR_RDP, 0xBB);
 // NOTE: errata 2.2.3: boot mode selection pin cannot be enabled at the
 // same time as RDP level 1 or the uC will intermittently fail to boot
 // So use nBOOT0 bit to select main flash memory for boot
 SET_BIT(FLASH->OPTR, FLASH_OPTR_nBOOT_SEL | FLASH_OPTR_nBOOT0);

 // write the desired values
 while (FLASH->SR & FLASH_SR_BSY1); // wait for flash ready
 FLASH->CR |= FLASH_CR_OPTSTRT; // start write of options
 while (FLASH->SR & FLASH_SR_BSY1); // wait for flash ready
 FLASH->CR |= FLASH_CR_OBL_LAUNCH; // read/use new options

 

In digging into the HAL code, I thought this might be a problem with the option byte region being write protected, but I don't see it and the write attempt doesn't set the WRPERR bit in the FLASH->SR (no error bits are set).

 

 Thanks!

Best answer by Bubbles

The problem is that the OPTR read always return the actual OB value, not the value you are currently programming. So the SET_BIT will read RDP value AA, modify nBOOT bits, and write back the AA!

The boot bits need to be programmed first, then OB programming, OBL and then RDP programming. If you use shutdown/standby to force the OBL on RDP, it's necessary to disable the debug interface during shutdown/standby in DBG CR register, so that the MCU is really going through POR.

The documentation is not totally clear on this, my colleague is now working on updated version.

BR,

J

4 replies

Bubbles
ST Employee
May 28, 2024

Hello @DAlbe.3,

try, instead of setting OBL_LAUNCH, perform a reset to reload the OB. Transition to standby or shutdown mode will also do the job. The RDP is behaving differently here, probably to prevent a deadlock on OB mismatch.

BR,

J

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
DAlbe.3
DAlbe.3Author
Associate III
May 28, 2024

I tried that before posting...no luck.  Reset, power cycle, re-locking flash, nothing has resulted in the RDP change taking effect.  Do you see something obvious that  I might be missing in the code?

Bubbles
BubblesBest answer
ST Employee
May 30, 2024

The problem is that the OPTR read always return the actual OB value, not the value you are currently programming. So the SET_BIT will read RDP value AA, modify nBOOT bits, and write back the AA!

The boot bits need to be programmed first, then OB programming, OBL and then RDP programming. If you use shutdown/standby to force the OBL on RDP, it's necessary to disable the debug interface during shutdown/standby in DBG CR register, so that the MCU is really going through POR.

The documentation is not totally clear on this, my colleague is now working on updated version.

BR,

J

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
aNt
ST Employee
May 30, 2024

Side question - which revision of STM32G030 do you use? The errata 2.2.3 should be fixed on Rev. Y, present only on Rev. Z (refer to actual product ES).

BR

DAlbe.3
DAlbe.3Author
Associate III
May 30, 2024

Thank you @aNt and @Bubbles , I will try separating the read/modify/write.
We are using K6T6 rev Z; we have a few thousand pcs in stock so a solution that works with rev Z would be ideal.
I just purchased some new stock so I'll test with Rev Y and report back shortly.
I appreciate your help with this!

Frantz LEFRERE
ST Employee
May 31, 2024

Hello @DAlbe.3 ,

you can have a look on this video :
https://www.youtube.com/watch?v=f7vs0NwZPFo&list=PLnMKNibPkDnGxKqGyLbiGygmlrvISIBIT&index=4
Those information are also relevant for STM32G0

Frantz

DAlbe.3
DAlbe.3Author
Associate III
May 31, 2024

Hi @Frantz LEFRERE, thank you for the reply.  I watched the video and it appears to confirm what I have reported above: that setting OBL_LAUNCH simply locks up the core until a POR reset. Since a POR causes the option bytes to be read anyway, setting the OBL_LAUNCH seems pointless.

I understand that I can either POR or enter/exit Standby mode to cause the option bytes to be re-loaded.  I will play with the Standby method soon, but because I have to disable the BOOT0 pin selection due to erratum 2.2.3, I've had to remove/re-mount several chips that I bricked in testing.

Is there a scenario where OBL_LAUNCH actually works?  If not, it seems like something that should be added to the erratum. Either I'm not using it properly or it does not work as advertised in the reference manual.

Associate III
July 15, 2025

Why is there no code exemple in the STMCube for this hardware specific function ?

Link to code below the youtube video is off...