Skip to main content
Associate
December 19, 2023
Question

STM32G0 Unstable LSI frequency

  • December 19, 2023
  • 21 replies
  • 5278 views

Dear Everyone,

We use STM32G0B0 MCU and in errata there's a section from the unstable LSI frequency. In some case the LSI frequency about 48 kHz. The workaround not work, after backup domain reset, the LSI frequency still about 48 kHz.

 

My theory is that, the IWDG is running, so the backup domain reset cannot turn off LSI. Someone has a valid workaround or some ideas how I can force the backup domain reset if the IWDG running? Unfortunately POR not an option...

 

Br,

Attila

This topic has been closed for replies.

21 replies

TDK
December 19, 2023

Can you reset the power domain prior to enabling IWDG?

TDK_0-1703004602187.png

Not sure how you're applying the workaround if POR isn't an option. Workaround seems to require it.

RTC clocked with LSI is going to be horribly inaccurate anyway.

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

The bootloader turn on the IWDG.

The problem is when the LSI frequency around 48 kHz, then the IWDG reset time is about 21 seconds and the firmware restart always because of IWDG. I would like to find a solution to reset the LSI in runtime because the device in field no option for full power reset.

Associate III
January 9, 2024

Why does the LSI have +-50% tolerance?

TDK
January 9, 2024

The LSI here does not have +/- 50% tolerance. Perhaps create a new post if you have additional questions.

TDK_0-1704818915935.png

 

To address the general question: Why is the LSI not exact? Because fabrication tolerances, specifically on oscillator circuits like this, contribute to the tolerance.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Associate III
January 9, 2024

Well this one has

mrx23_0-1704835689534.png

How come the tolerance is so much bigger on this one?

Andrei Chichak
Lead
January 9, 2024

LSI is intended to run the independent watchdog, not in lockstep with the external crystal, but independent of the external crystals. The frequency is crappy and varies with temperature, but you don't need external components.

Some figure that it is a 32767 Hz source. No, it's 30kHz, or 40kHz, or 17-47kHz, depending on how the die was laid out on a day, the temperature, and phase of the moon. Don't use it where you expect a reliable, predictable frequency. If you use it as a IWDG, don't set your tolerances too tight or you will be sad.

Note: I am not a silicon layout engineer, but I did stay at a Holiday Inn once.

A

waclawek.jan
Super User
March 30, 2024

Hi @Attila_Horvath

can you please tell us more about your application, so the problem can be reproduced?

- what is the setting of Option Bytes?

- how is your board powered, is that power source permanent?

- do you use Standby or other low-power modes? If yes, how do you exit from them?

- do you use LSI as RTC clock? Do you use it in the LSE CSS?

- how do you observe the LSI frequency?

- do you know, at which moment did LSI switch to higher frequency (i.e. what event lead to the problem)?

Thanks,

JW

 

DAlbe.3
Associate III
May 30, 2024

I am having the same problem. I am using the STM32G030K6 powered at 3v3. I use the LSI to drive the RTC and the device spends most of its time in deep sleep (STOP0) mode. I don't need great accuracy, but I expected it to meet the specs in the datasheet. Like others, I initially measured 48.93kHz at MCO. I have implemented the second workaround from errata 2.2.1: reset backup power domain on POR, and it seems to work MOST of the time, but not always.  Once in a while, the LSI is still running far above its 34kHz max and I know the POR flag was set (and so this code ran) because I display the CSR register at startup.

@TDKare you aware of a way to correct the failure condition in software if the workaround fails?  It looks like once the condition has occurred, BOTH a POR and the workaround are required to clear it; a hard reset will not clear the condition.

Code to reset backup power domain follows. I have also tried removing the PWRRSTF conditional and always running the code to reset the backup power domain at startup and can still occasionally reproduce the high (48.9kHz) LSI frequency.

 

 

 

 

 // See Errata 2.2.1: Unstable LSI after main power domain reset
 // if reset was due to POR or BOR, reset the backup power domain
 if (RCC->CSR & RCC_CSR_PWRRSTF) {
 SET_BIT(RCC->APBENR1, RCC_APBENR1_PWREN); // enable clk to power subsystem
 SET_BIT(PWR->CR1, PWR_CR1_DBP); // enable access to backup power domain
 SET_BIT(RCC->BDCR, RCC_BDCR_BDRST); // reset backup power domain
 CLEAR_BIT(RCC->BDCR, RCC_BDCR_BDRST);
 CLEAR_BIT(PWR->CR1, PWR_CR1_DBP);
 }

 

 

 

 

Amel NASRI
ST Technical Moderator
May 30, 2024

Hi @DAlbe.3 ,

Could you please insert the following wait loops to ensure that required bits are set properly:

  • just after line 5 of your code to ensure that access to backup power domain is enabled:
 while(READ_BIT(PWR->CR1, PWR_CR1_DBP) == RESET);
  • just after "SET_BIT(RCC->BDCR, RCC_BDCR_BDRST);"
while(READ_BIT(RCC->BDCR, RCC_BDCR_BDRST) == RESET);

 Does this make a difference?

-Amel

To give better visibility on the answered topics, please click on "Best Answer" on the reply which solved your issue or answered your question.
DAlbe.3
Associate III
May 30, 2024

Hi @Amel NASRI ,

First, many thanks for responding so quickly!

I added the checks for DBP and BDRST and it seemed better at first, but unfortunately I was still able to reproduce the bug (LSI > 48kHz).  It requires 1-25 POR to see it, but it did happen and as always, persists until the next POR. I have been able to reproduce it numerous times.

Separately, I'm interested in your suggestion regarding PWR_CR1_DBP because I enable/disable DBP in several places in my codebase and need to know if I should add this check (to wait for DBP set) before accessing registers in the backup power domain. There's no mention of it in the RM; is this a known issue with setting DBP?

The code run at startup is:

 // See Errata 2.2.1: Unstable LSI after main power domain reset
 // if reset was due to POR or BOR, reset the backup power domain
 if (RCC->CSR & RCC_CSR_PWRRSTF) {
 SET_BIT(RCC->APBENR1, RCC_APBENR1_PWREN); // enable clock to pwr control subsystem
 SET_BIT(PWR->CR1, PWR_CR1_DBP); // enable access to backup power domain
 while(READ_BIT(PWR->CR1, PWR_CR1_DBP) == RESET);
 SET_BIT(RCC->BDCR, RCC_BDCR_BDRST); // reset backup power domain
 while(READ_BIT(RCC->BDCR, RCC_BDCR_BDRST) == RESET);
 CLEAR_BIT(RCC->BDCR, RCC_BDCR_BDRST);
 CLEAR_BIT(PWR->CR1, PWR_CR1_DBP);
 }

Regards,
David

waclawek.jan
Super User
May 30, 2024

@DAlbe.3,

Do you also use IWDG, as @Attila_Horvath does?

JW

 

DAlbe.3
Associate III
May 30, 2024

Yes, I am also using IWDG

waclawek.jan
Super User
June 6, 2024

> Yes, I am also using IWDG

And do you use software or hardware IWDG, i.e. do you start IWDG in software, or do you have the respective Option bit set (cleared) so that IWDG is started automaticallty by hardware upon reset?

In any case, can you please try to reproduce the problem without IWDG? I mean, does the backup-domain reset fix the problem if IWDG is not used?

JW

waclawek.jan
Super User
June 6, 2024

Just to keep all data points at one place, I'm cross-referencing this thread.

JW

DAlbe.3
Associate III
June 6, 2024

Thanks @Attila_Horvath, in my case, I start the IWDG in software after the workaround (reset the backup power domain and start LSI.  The first code that runs in main() is:

 // For development firmware (odd version #), disable IWDG when core stopped in debugger
 if (fw_version & 0x0001) { // development version
 SET_BIT(RCC->APBENR1, RCC_APBENR1_DBGEN);
 SET_BIT(DBG->APBFZ1, DBG_APB_FZ1_DBG_IWDG_STOP);
 }

 // Enable PWR control, SysCfg subsystems, GPIO Ports A, B, C
 SET_BIT(RCC->APBENR1, RCC_APBENR1_PWREN); // enable clock to pwr control subsystem
 SET_BIT(RCC->APBENR2, RCC_APBENR2_SYSCFGEN);
 SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN | RCC_IOPENR_GPIOBEN | RCC_IOPENR_GPIOCEN);

 // Start LSI oscillator used by RTC and IWDG
 SET_BIT(PWR->CR1, PWR_CR1_DBP); // enable access to backup power domain
 while(READ_BIT(PWR->CR1, PWR_CR1_DBP) == RESET);
 // See Errata 2.2.1: Unstable LSI after main power domain reset
 // if reset was due to POR or BOR, reset the backup power domain
 if (RCC->CSR & RCC_CSR_PWRRSTF) {
 SET_BIT(RCC->BDCR, RCC_BDCR_BDRST); // reset backup power domain
 while(READ_BIT(RCC->BDCR, RCC_BDCR_BDRST) == RESET);
 CLEAR_BIT(RCC->BDCR, RCC_BDCR_BDRST);
 }
 // Start LSI and wait until ready
 SET_BIT(RCC->CSR, RCC_CSR_LSION); // turn on LSI oscillator
 while (!(RCC->CSR & RCC_CSR_LSIRDY)); // wait for LSI ready
 CLEAR_BIT(PWR->CR1, PWR_CR1_DBP);

 // Initialize hardware watchdog (depends on LSI)
 watchdog_init(2000); // 2s timeout