cancel
Showing results for 
Search instead for 
Did you mean: 

STM32WLE5: LPTIM2 ARROK flag never sets after Sleep wake-up unless LSESYSEN is written again

DinD
Associate II

 

Device

STM32WLE5


Clock configuration

SYSCLK : MSI 16 MHz (MSIPLL mode Enabled)
LSE : 32.768 kHz crystal
LPTIM2 kernel clock : LSE
Low power mode : Sleep


Observed behavior

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.


Workaround

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.


Initialization code

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 description

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


Questions

  1. Why does LPTIM2 stop receiving the LSE system clock after waking from Sleep mode, even though LSESYSEN was already set during initialization?

  2. Does LSESYSEN require re-writing after low-power mode exit for LPTIM to receive the LSE clock?

  3. 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!

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
DinD
Associate II

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!

View solution in original post

2 REPLIES 2
DinD
Associate II

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.

DinD
Associate II

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!