cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H563 LSE does not always start

PieterG
Associate II

I am using an stm32h563 nucleo 144 board, and I am frequently running into the issue that after a power cycle the LSE does not start.

This is the relevant part of my SystemClock_Config:

 

LL_PWR_EnableBkUpAccess();
while (LL_PWR_IsEnabledBkUpAccess () == 0U)
{
}
 
LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_LOW);
LL_RCC_LSE_Enable();
 
/* Wait till LSE is ready */
while (LL_RCC_LSE_IsReady() != 1)
{
}
 
and LL_RCC_LSE_IsReady() never returns 1 in that case, no matter how long I wait.
Also, I can reflash a debug firmware via SWD, attach the debugger, and still end up in the same loop.
I need to power cycle the board again, to resolve this issue.
 
However, I will need a software workaround, which does not require a power cycle, because I fear that we will get the same issue in the field, with our final product (which will be based on the STM32H563, and will be using an LSE in the same configuration as the nucleo board)
 
This is what I came up with as a workaround:
 
LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_LOW);
LL_RCC_LSE_Enable();
 
/* Wait till LSE is ready */
int count = 0;
while (LL_RCC_LSE_IsReady() != 1 && count < 10000000)
{
    count++;
}
if  (count >= 10000000)
{
    /*
     * NOTE: the timing of this is quite critical.
     * If we do not wait for LSE_IsReady long enough, the backupdomain reset does not fix the issue.
     * So even though after a few attempts we can already conclude the LSE is not going to start,
     * we still wait for 10000000 attempts, because we should not reset too early.
     */
    LL_RCC_ForceBackupDomainReset();
    LL_RCC_ReleaseBackupDomainReset();
    __NVIC_SystemReset();
}
 
But, I found that the timing is quite critical. When I use 1000000 loops instead of 10000000, the workaround still works with a debug build (-O0), but not with a release build (-Os).
Also, when the LSE starts normally, LL_RCC_LSE_IsReady() returns 1 right away, without even a single loop. So even after a few cycles we could already conclude the LSE does not start. But somehow we need to wait for quite some time (almost 3 seconds) before the backup domain reset causes the situation to be recovered.
 
My questions:
Do you have an explanation for this issue?
Do you perhaps have a better way to work around it (or even avoid it)?
5 REPLIES 5
Bubbles
ST Employee

Hi @PieterG,

this is not normal behavior. Low drive should be fine with Nucleo.

Please also try the Example/RTC/RTC_ActiveTamper example from the cube package. It uses similar configuration of the LSE and should work every time on non-faulty Nucleo.

Generally, if there's a HW problem preventing the LSE from working in low drive, try adding more driving power. In some cases, having more driving power for startup and then lowering it once oscillations are established works well.

For additional robustness consider Clock security systerm (CSS).

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.

Bubbles
ST Employee

PS I noticed you mentioned power cycle. If loss of power is really short, the backup domain may not be reset and could be blocking. Try going for backup domain reset if it solves the issue.

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.

PieterG
Associate II

Thank you Bubbles for your replies.

I have done some more testing about how this issue can be reproduced, and I found that it is always the first power cycle after I either plug or unplug my JLink from the SWD interface, that causes this LSE failure to occur.

 

On your suggestion I checked the Example/RTC/RTC_ActiveTamper example, and I see that it always resets the backup domain before starting the LSE.

Because I want to use the backup registers to pass status between bootloader and application, or keep status between soft resets, I decided to only do a backup domain reset after power cycle related resets (low power of brownout),

This is what I'm currently using:

 

LL_PWR_EnableBkUpAccess();
while (LL_PWR_IsEnabledBkUpAccess () == 0U)
{
}
 
if (LL_RCC_IsActiveFlag_LPWRRST() || LL_RCC_IsActiveFlag_BORRST())
{
    LL_RCC_ForceBackupDomainReset();
    LL_RCC_ReleaseBackupDomainReset();
}
 
LL_RCC_ClearResetFlags();
 
LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_LOW);
LL_RCC_LSE_Enable();
 
/* Wait till LSE is ready */
while (LL_RCC_LSE_IsReady() != 1)
{
}
 
This code gives me reliable starts when power cycling, also in combination with SWD connect/disconnects.
I like this better than the 10000000 limit on the LL_RCC_LSE_IsReady() loop.
AScha.3
Chief

Hi, try setting the LSE drive medium or hi (i use always hi - most reliable .)

And if any doubt - see H563 errata :

AScha3_0-1712688454010.png

 

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

Thanks for bringing this to my attention, I was not aware of that.

I did some quick tests with drive setting HIGH, but I could still reproduce the issue of LSE not starting, after connecting/disconnecting SWD.

So I'll keep the backup domain reset as a workaround, but I will also be using HIGH drive mode to be sure.