cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G030 readout protection level 1 (errata 2.2.3) POR lockup if boot select via BOOT0 pin enabled

DAlbe.3
Senior

EDITED:
Resolved, but leaving here for the next person who stumbles into this issue.
I'm using the STM32G030K6 and encountered two issues:

  1. Errata 2.2.3 - which correctly describes a serious issue when using readout protection level 1: if nBOOT_SEL is not set in the option bits, the uC will often fail to boot and even a hard reset will not recover, only a power cycle.  The errata correctly describes a workaround: set nBOOT_SEL in the option bits (removes the option to force entry to the bootloader by tying the BOOT0 pin high).
  2. Access to OTP memory is not protected by readout protection level 1.
    This is expected behavior since SystemMemory is not protected by RDP level 1, but it is unfortunate given that OTP is the perfect place to store device-specific persistent data like serial numbers, encryption keys, etc. This is particularly true on devices with limited flash where allocating a separate sector may be painful. Perhaps in a future version of the component, ST will consider protecting OTP as well as the code space.

The rest of this thread is obsolete, it was the result of a failed component where I could not set the nBOOT_SEL bit successfully.  Many thanks to @waclawek.jan for all of the patience and help!

1 ACCEPTED SOLUTION

Accepted Solutions

> The package I'm using (LQFP32 - sorry, that's the K6 variant, not F6 as I'd originally posted) does not have separate VBAT and VDD pins

That does not really matter; the problem is with VBAT reaching a specific low voltage, regardless of what VDD does (as long as VDD is not above the "VDD brownout/POR" level, in which case VBAT is disconnected internally).

> and even if it did, any condition that does not clear with a hard reset should be viewed as a critical failure.

Yes it is; that's why it's in the errata.

> This *never* happens with RDP set to level 0; the product had been in development for months, always using RDP level 0 and we'd never seen this issue..

I hear you; but, during development, did you try to fade the VDD down to the problematic levels?

Or, now, having encountered the problem, did you try to remove RDP1, reprogram without RDP, and fade VDD? Okay I overlooked "does not ever happen if RDP is set back to level 0"

Btw. do you have code there which explicitly tests RDP (or any other bits from the option bytes)?

> I added code (very early in boot) to reset the backup power domain if the reset reason indicated power:

Are you sure that code does reset the backup power domain? Do you have backup domain access enabled in PWR previously (which in turn requires PWR to have clock enabled in RCC)?

 

Note that I don't claim this is certainly the source of your problem; but I see this as a possibility which may act through unexpected relationships.

 

An interesting exercise might be toggling a GPIO output at strategic points of the code startup, and then observing it on the problematic device.

JW

View solution in original post

22 REPLIES 22

> we started setting the readout protection to level 1

How, exactly?

> At this point, the uC frequently would not boot and would not even respond to a hard reset. Only a power cycle clears this condition.

Maybe this?

waclawekjan_0-1716544573564.png

> "Booting from Main Flash memory operates correctly if selected through option bits (nBOOT_SEL and nBOOT0 both set)." This appears not to be true: the same failure occurs whether nBOOT_SEL is set or clear.

What exactly do you do and what are your observations leading to this claim?

JW

 

 

Hi @DAlbe.3 ,

I suspect this is your thread. The problem is formulated there a bit more differently - from the text above I understood that your problem occurs *when* you set RDP1 (i.e. immediately after you set RDP1); but from the stackexchange description, it's something different:

[...] enters a locked up state on power up and is unresponsive until it is power cycled. Importantly, a hard reset does not clear the condition. [...] It only seems to happen after the device has been off for a while so it may be related to a slower-than-normal power ramp as bulk capacitors charge.

If you suspect this is inadvertently started bootloader - as you hint above - you can test this hypothesis by measuring presence of pullups on the bootloader-related pins, or trying to enter some of the bootloader modes (e.g. UART), when the mcu is "frozen".

But my bet is that this is in some way consequence of VBAT brownout; and the fact that it occurs after you set RDP=1 is a coincidence. So my question is, do you use the VBAT domain in any way; and if not, I'd suggest to perform a VBAT-domain reset unconditionally as the first thing in your program.

JW

Hi @waclawek.jan ,

Thanks for the quick reply and yes, I was initially looking for answers on SE and posted it there before coming here once I realized what was happening; I posted here to save others time (I spent a day and a half wrestling with this).

I was setting the option bytes (both RDP and the nBOOT_SEL and nBOOT0 bits) using STM32CubeProgrammer 2.16.0 over the UART interface. The problem only happens after a power cycle.  The package I'm using (LQFP32 - sorry, that's the K6 variant, not F6 as I'd originally posted) does not have separate VBAT and VDD pins and even if it did, any condition that does not clear with a hard reset should be viewed as a critical failure.

This *never* happens with RDP set to level 0; the product had been in development for months, always using RDP level 0 and we'd never seen this issue...it only started happening when we set RDP to level 1 and does not ever happen if RDP is set back to level 0. With RDP set to level 1, it happens fairly often; too often to be a coincidence.

I mentioned in the other thread (but should have mentioned here) that I added code (very early in boot) to reset the backup power domain if the reset reason indicated power:

 

    if (RCC->CSR & RCC_CSR_PWRRSTF) {
        // If reset was due to POR or BOR, reset the backup power domain
        // (see Errata 2.2.1 - Unstable LSI after power domain reset)
        SET_BIT(RCC->BDCR, RCC_BDCR_BDRST);
        CLEAR_BIT(RCC->BDCR, RCC_BDCR_BDRST);
    }

 

 
This is easily repeatable with RDP set to 0xBB (regardless of how nBOOT_SEL and nBOOT0 are set) and cannot be reproduced with RDP set to 0xAA. I have done this *many* times in both configurations. I have not tried 0xCC (RDP level 2), but the cost of not being able to re-flash the uC for a firmware upgrade is unacceptable at this point.

> The package I'm using (LQFP32 - sorry, that's the K6 variant, not F6 as I'd originally posted) does not have separate VBAT and VDD pins

That does not really matter; the problem is with VBAT reaching a specific low voltage, regardless of what VDD does (as long as VDD is not above the "VDD brownout/POR" level, in which case VBAT is disconnected internally).

> and even if it did, any condition that does not clear with a hard reset should be viewed as a critical failure.

Yes it is; that's why it's in the errata.

> This *never* happens with RDP set to level 0; the product had been in development for months, always using RDP level 0 and we'd never seen this issue..

I hear you; but, during development, did you try to fade the VDD down to the problematic levels?

Or, now, having encountered the problem, did you try to remove RDP1, reprogram without RDP, and fade VDD? Okay I overlooked "does not ever happen if RDP is set back to level 0"

Btw. do you have code there which explicitly tests RDP (or any other bits from the option bytes)?

> I added code (very early in boot) to reset the backup power domain if the reset reason indicated power:

Are you sure that code does reset the backup power domain? Do you have backup domain access enabled in PWR previously (which in turn requires PWR to have clock enabled in RCC)?

 

Note that I don't claim this is certainly the source of your problem; but I see this as a possibility which may act through unexpected relationships.

 

An interesting exercise might be toggling a GPIO output at strategic points of the code startup, and then observing it on the problematic device.

JW

Hi @waclawek.jan, thank you again for the quick reply.

Yes, the DBP was set earlier in that code (sorry, I should have included that in the snippet).

I have a unit in that state now; UART1TX appears to be floating (around 0v24) and the UART1RX pin is at 0V.  I tried connecting to the chip via STM32CubeProgrammer via UART and no luck (so I don't think it's sitting in the system bootloader - if it were, it should respond to a hard reset).

I will try diagnosing this further (e.g. toggling a GPIO during startup), putting a scope on Vdd, and I'll also hook up an STLink to see if that gives any more insight, but the failure mode is such that only a power cycle will exit, not a hard reset; that really shouldn't be possible with anything startup code might be doing.  Most importantly, this *never* happens when the RDP level is set to 0 - same hardware, same firmware.  This sure looks like a silicon problem with RDP level 1.  It behaves exactly the same way whether the nBOOT_SEL and nBOOT0 option bits are set or clear.  I think the errata is simply incorrect.

In terms of exactly what's going wrong with the part when configured for RDP level 1, I note that the condition is much easier to replicate when all bulk capacitance on the device has been given time to fully drain (or manually assisted in doing so).  i.e. the problem manifests more readily when Vdd has cycled all the way to 0V and then on.  However again, the issue never happens with RDP level 0; this is not a problem inherent in the power rail ramp.

DAlbe.3
Senior

Interestingly, I was able to connect using an STLinkV2 under SoftwareReset.

DAlbe3_0-1716563717895.png

DAlbe3_1-1716563765739.png
From the STM32CubeProgrammer, I can perform a core or hardware or software reset, but it always lands back  in the above configuration.  I can access the registers, and read OTP (flash is protected with level 1) so if there's something worth looking at, suggestions are welcome!

 

DAlbe.3
Senior

Ugh, I also just found that RDP level 1 does not protect the OTP from read access (at least not when using the STLink).

DAlbe.3
Senior

Some progress!
It seems that STM32CubeProgrammer is not successfully setting the nBOOT_SEL bit.

It claims it does:

 

11:30:31 : Option byte command : -ob  nBOOT_SEL=1 
11:30:31 : PROGRAMMING OPTION BYTES AREA ...
11:30:31 :   Bank          : 0x00
11:30:31 :   Address       : 0x40022020
11:30:31 :   Size          : 108 Bytes
11:30:31 : Reconnecting...
11:30:32 : Reconnected !
11:30:32 : UPLOADING OPTION BYTES DATA ...
11:30:32 :   Bank          : 0x00
11:30:32 :   Address       : 0x40022020
11:30:32 :   Size          : 108 Bytes
11:30:32 :   Bank          : 0x01
11:30:32 :   Address       : 0x40022080
11:30:32 :   Size          : 4 Bytes
11:30:32 : OPTION BYTE PROGRAMMING VERIFICATION:
11:30:32 : Option Bytes successfully programmed
11:30:32 : Time elapsed during option Bytes configuration: 00:00:01.215

 

And reading back the option bytes region shows the bit set,

DAlbe3_0-1716566720576.png

but after power cycle and re-reading the option bytes, you can see that nBOOT_SEL (bit 24) is not set!

DAlbe3_2-1716565218861.png

 

> Ugh, I also just found that RDP level 1 does not protect the OTP from read access (at least not when using the STLink).

That's hummm.

waclawekjan_1-1716566825301.png

> It seems that STM32CubeProgrammer is not successfully setting the nBOOT_SEL bit.

That's also humm and interesting, but I'm not sure how does that explain your findings.

So, how is your PA14/BOOT connected?

Also, note that the erratum you've quoted (2.2.3, Under Level 1 read protection, booting from main flash memory selected through PA14‑ ‑BOOT0 pin is not functional) pertains only to Rev.Z of the chip. So, what revision do you have? The CubeProgrammer screenshot, characteristically unhelpfully, says, Rev 1.1...

JW