STM32WLE5xC slow start up to main()

We have been using mbedos on a custom board that uses the STM32WLE5CCU7 ST MPU for about a year. Generally it has been working well. We did have to create a custom target for this, but the mbedos changes were minimal just adding the TARGET definition in targets.json and a directory with the PinNames.h, PeripheralPins.c and CMakeLists.txt for the board based on those for the NUCLEO_WL55JC target.

We are currently trying to reduce the power usage of a Lorawan node, and we have a problem in that we see a large delay of about 220ms, using power, before main is called. With a simple test example based on mbed-os-example-blinky we have been trying to find out where this large delay comes from. We have got it down to the OS_Tick_Enable() call in mbed_rtx_idle.cpp and specifically the " os_timer = new (os_timer_data) OsTimer(get_lp_ticker_data());" in init_os_timer().
Unfortunately, the mbedos code is complex with large number of redirections and C++ templated, inherited constructors at that point.

  1. Has anyone else this sort of startup delay ?
  2. Anyone any ideas on what may be going on or where to look ?

Terry

I have worked out what is happening. By default the OSTimer uses the STM32WL’s low power timer and by default uses the LSE clock. It looks like the LSE clock startup time is in the order of 200ms or more. I didn’t realise it would be so long.
I have changed our board TARGET to use the LSI timer and this 220ms start-up delay is gone.
Mind you now I see that Watchdog.::start(30000) is taking about 38ms. Possibly a similar issue …

1 Like

Just for others information, the STM32WL’s IWDG watchdog timer hardware can have a very long setup time if you want a long watchdog timeout. With a 30 second timeout it will take about 38ms to complete the setup. This is due to a hardware limitation when writing to the registers. With a 0.5 second time it would be about 0.6 ms. It might be possible to circumvent this with changes to the HAL driver and watchdog usage.

Hmm, another thing to potentially try is increasing the LSE drive strength to high. STM32 chips tend to use very low LSE drive currents by default, which can be a pain point on custom boards. Maybe the default current is juuuust enough to get the LSE running, but takes a long time to do it.

Per here, it looks like you can fix this with the code

LL_PWR_EnableBkUpAccess();
LL_RCC_ForceBackupDomainReset();
LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_HIGH);

This code has to be run before the lp ticker boots up. Try adding it after the following block in lp_ticker.c:

    /* Check if LPTIM is already configured */
    if (LPTICKER_inited) {
        lp_ticker_disable_interrupt();
        return;
    }
    LPTICKER_inited = 1;

I’ve also heard that for the drive strength change to take effect, you have to re-power (not just reset) the chip, so make sure to try that.

I’m not a crystal expert though, so if this has any effect, you should review the board design and see what drive strength setting is best for your crystal following ST’s application notes.

Thanks for the info and ideas. For our very low power sensor usage the LSI based timer is fine and better than using the LSE. I actually assumed that would be the default configuration as all STM32WL boards would have the LSI.
In our particular sensor usage and with a 30 year battery life, we use an external extremely low power RTC to switch on the power to the STM32WL. The 220 ms startup time was about 10x our actual needed processing time, and the poor HAL code sits in a tight CPU loop waiting so was using huge amounts of battery.
In a more normal STM32WL system, where its internal RTC would wake the STM32WL from a deep sleep, I’m not sure if the current mbed code would try and restart the LSE on every power up or not. If not, the LSE startup time would not be an issue.