2026-03-10 7:38 PM - last edited on 2026-03-11 12:04 AM by Imen.D
STM32WLE5
SYSCLK : MSI 16 MHz (MSIPLL mode Enabled)
LSE : 32.768 kHz crystal
LPTIM2 kernel clock : LSE
Low power mode : Sleep
When configuring LPTIM2 with LSE clock, the following code sometimes blocks because the ARROK flag never sets.
__HAL_LPTIM_AUTORELOAD_SET(&hlptim2, Period); while (!__HAL_LPTIM_GET_FLAG(&hlptim2, LPTIM_FLAG_ARROK));
This occurs after waking up from Sleep mode.
Executing the following code before or after wake-up resolves the issue.
RCC->BDCR |= RCC_BDCR_LSESYSEN;
After writing LSESYSEN, the ARROK flag sets normally.
SystemClock_Config() already enables LSESYSEN. It is CubeMX provided.
LL_PWR_EnableBkUpAccess();
LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_MEDIUMLOW);
LL_RCC_LSE_EnablePropagation();
LL_RCC_LSE_Enable();
while (LL_RCC_LSE_IsReady() != 1)
{
}
LL_RCC_LSE_EnablePropagation() is defined as:
__STATIC_INLINE void LL_RCC_LSE_EnablePropagation(void)
{
SET_BIT(RCC->BDCR, RCC_BDCR_LSESYSEN);
}
Therefore LSESYSEN is set during system initialization.
RM0461 states:
“To be able to use the clock by other peripherals (LPTIMx, TIMx, USARTx, LPUARTx...), the LSE system clock must be enabled with the LSESYSEN bit.”
Also:
“This bit is set and cleared by software.”
And:
“RCC_BDCR is reset only by backup domain reset.”
From this description:
LSESYSEN should remain set unless cleared by software
Sleep mode should not reset RCC_BDCR
Why does LPTIM2 stop receiving the LSE system clock after waking from Sleep mode, even though LSESYSEN was already set during initialization?
Does LSESYSEN require re-writing after low-power mode exit for LPTIM to receive the LSE clock?
Are there documented limitations or errata regarding:
LSE system clock distribution
LSESYSEN behavior after low-power mode
LPTIM using LSE on STM32WL devices
In my case, LSEON & LSERDY bits are set before/after MCU enters sleep mode.
Thanks in advance!
Solved! Go to Solution.
2026-03-17 12:52 AM
Hello members,
It seems I've figured out the cause.
The LL library resets RCC->BDCR and leaves it as is, but HAL doesn't.
This problem occurred because I switched from HAL to the LL library to reduce code size.
LL:
if(LL_RCC_GetRTCClockSource() != LL_RCC_RTC_CLKSOURCE_LSE)
{
/* Update LSE configuration in Backup Domain control register */
/* Requires to enable write access to Backup Domain if necessary */
if (LL_PWR_IsEnabledBkUpAccess () != 1U)
{
/* Enable write access to Backup domain */
LL_PWR_EnableBkUpAccess();
while (LL_PWR_IsEnabledBkUpAccess () == 0U)
{
}
}
LL_RCC_ForceBackupDomainReset();
LL_RCC_ReleaseBackupDomainReset();
LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_MEDIUMLOW);
LL_RCC_LSE_Enable();
/* Wait till LSE is ready */
while(LL_RCC_LSE_IsReady() != 1)
{
}
LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE);
}
HAL: HAL_RCCEx_PeriphCLKConfig is called by HAL_RTC_MspInit
/* Reset the Backup domain only if the RTC Clock source selection is modified */
if (LL_RCC_GetRTCClockSource() != PeriphClkInit->RTCClockSelection)
{
/* Store the content of BDCR register before the reset of Backup Domain */
tmpregister = READ_BIT(RCC->BDCR, ~(RCC_BDCR_RTCSEL));
/* RTC Clock selection can be changed only if the Backup Domain is reset */
__HAL_RCC_BACKUPRESET_FORCE();
__HAL_RCC_BACKUPRESET_RELEASE();
/* Restore the Content of BDCR register */
RCC->BDCR = tmpregister;
}
I hope this example is helpful to someone.
Thanks!
2026-03-16 10:21 PM
Hello community members,
I have identified two additional points regarding the LSESYSEN bit behavior:
Debug Mode: LSESYSEN is set correctly when the MCU is in debug mode.
Power-on Reset (POR): The bit is set correctly immediately after programming (flashing the app). However, if I perform a manual power cycle (Vdd OFF → ON), LSESYSEN fails to set.
2026-03-17 12:52 AM
Hello members,
It seems I've figured out the cause.
The LL library resets RCC->BDCR and leaves it as is, but HAL doesn't.
This problem occurred because I switched from HAL to the LL library to reduce code size.
LL:
if(LL_RCC_GetRTCClockSource() != LL_RCC_RTC_CLKSOURCE_LSE)
{
/* Update LSE configuration in Backup Domain control register */
/* Requires to enable write access to Backup Domain if necessary */
if (LL_PWR_IsEnabledBkUpAccess () != 1U)
{
/* Enable write access to Backup domain */
LL_PWR_EnableBkUpAccess();
while (LL_PWR_IsEnabledBkUpAccess () == 0U)
{
}
}
LL_RCC_ForceBackupDomainReset();
LL_RCC_ReleaseBackupDomainReset();
LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_MEDIUMLOW);
LL_RCC_LSE_Enable();
/* Wait till LSE is ready */
while(LL_RCC_LSE_IsReady() != 1)
{
}
LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE);
}
HAL: HAL_RCCEx_PeriphCLKConfig is called by HAL_RTC_MspInit
/* Reset the Backup domain only if the RTC Clock source selection is modified */
if (LL_RCC_GetRTCClockSource() != PeriphClkInit->RTCClockSelection)
{
/* Store the content of BDCR register before the reset of Backup Domain */
tmpregister = READ_BIT(RCC->BDCR, ~(RCC_BDCR_RTCSEL));
/* RTC Clock selection can be changed only if the Backup Domain is reset */
__HAL_RCC_BACKUPRESET_FORCE();
__HAL_RCC_BACKUPRESET_RELEASE();
/* Restore the Content of BDCR register */
RCC->BDCR = tmpregister;
}
I hope this example is helpful to someone.
Thanks!