2024-05-27 01:07 PM - edited 2024-05-27 02:58 PM
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!
Solved! Go to Solution.
2024-05-30 07:42 AM
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.
2024-05-28 08:41 AM
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.
2024-05-28 11:12 AM
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?
2024-05-30 07:42 AM
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.
2024-05-30 08:10 AM
No need to do separately boot bits programming before RDP programming. Just avoid read-modify-write instructions on FLASH_OPTR and rather just write there your desired 32-bit value directly.
2024-05-30 08:14 AM
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
2024-05-30 11:37 AM - edited 2024-05-30 11:41 AM
2024-05-30 03:59 PM - edited 2024-06-03 08:48 PM
Thank you again @Bubbles and @aNt that was indeed the issue. I revised the code to read to a local variable, modify it, and then write it back and that does the trick. Thank you!
My remaining issue is how to get the change to take effect. @Bubbles mentioned a few potential issues. Setting OBL_LAUNCH didn't seem to do the trick. I have the debug interface enabled (because I'm debugging this). I tried an NVIC_SystemReset() instead of the OBL_LAUNCH and appear to have bricked the chip. I'll replace it and try again, but if there is a recommended mechanism for reloading the option bytes, I'd appreciate it. Here's what I'm currently doing (that doesn't seem to work...a POR or maybe a hard reset seems to be required).
// write the desired values
FLASH->OPTR = optr;
while (FLASH->SR & FLASH_SR_BSY1); // wait for flash ready
SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT); // start write of options
while (FLASH->SR & FLASH_SR_BSY1); // wait for flash ready
// Read/use new options
SET_BIT(FLASH->CR, FLASH_CR_OBL_LAUNCH);
// Lock Flash
SET_BIT(FLASH->CR, FLASH_CR_LOCK | FLASH_CR_OPTLOCK);
Thanks again!
2024-05-30 09:26 PM
> 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
Is the OBL_LAUNCH functionality broken? When I set OBL_LAUNCH, the CPU simply hangs until it is power cycled. There are quite a few threads discussing this in a variety of ways. Is it a missing errata or is there something special needed to make it work?
2024-05-30 10:59 PM
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