cancel
Showing results for 
Search instead for 
Did you mean: 

Can't wake from stop mode with low power timer event

Kraal
Senior III

Hello everyone,

I'm having problems with a STM32L010K8 in stop mode.

I'm trying to use the low power timer clocked by the LSI and having it to wake up the device from stop mode once the timer reaches ARR value.

I configured the EXTI event line 29 and deactivated the corresponding IMR bit (it is not clear in the L010 RM, but for L4 micros the IMR is prevalent on the EMR bits).

-> the device stays asleep

Then I enabled the autoreload interrupt bit (but not the NVIC)

-> the device wakes up only once. I believe because the interrupt flag stays set.

On the L4 I did not have such annoying issues, the event system was working fine.

On a side note, when debugging with the debugger connected, the event is firing up every time, not just once.

5 REPLIES 5
Anton Chaban
Associate III

As far as i undersnad for L0x you need to enable NVIC to wakeup from stop mode

Table 35. Stop mode: Mode exit

If WFI or return from ISR was used for entry:

Any EXTI Line configured in Interrupt mode (the corresponding EXTI Interrupt vector must be enabled in the NVIC). Refer to Table 48: List of vectors.

if you are using LPTIM with LSI

NVIC_SetPriority(LPTIM1_IRQn, 30);

NVIC_EnableIRQ(LPTIM1_IRQn);

Also you can check my post about WLE, where i've placed code for L0x devices that work well for me. I confgire it for LSE but for LSI it work well too

https://community.st.com/s/question/0D53W000004nA0PSAU/huge-repetitive-lptim-interrupts

Thank you for the answer.

However, I'm using WFE at the moment. According to the same table you mentioned (as SEVONPEND = 0 in my case) Stop mode exit:

"Any EXTI Line configured in event mode. Refer to Section 12.3.2: Wakeup event management on page 237"

I also read your thread and I saw this line

__HAL_RCC_LPTIM1_CLK_SLEEP_ENABLE(); // enable clock to LPTIM peripheral also in low power mode

Which I believe refers to APB1SMENR, but according to the datasheet it should already be set. So no dice here.

I believed I have no other choice than use WFI instead and configure the interrupt as usual.

Still I would like to understand why it is working fine with the debugger and not working without it...

Best regards

Anton Chaban
Associate III

If in DBGMCU CR_DBG_STOP = 1 your device wouldn't enter into stop mode. Also my debuger stop working when controller enter into STOP mode.

Correct, the core still feed HCLK and FCLK...

I switched to WFI and NVIC. It is working as expected.

Does anybody had managed to use events (specifically LPTIM) with L0 devices ?

In any case, thank you Anton for the suggestions.

MSipo
Senior II

Here are some code snippets I have implemented on an STM32L151:

#define SLEEP_TIME_SECONDS 2.0 // The amount of time to sleep
#define LSI_FREQUENCY_HZ 38000 // typical value
 
void goToSleep(void)
{
    __disable_irq();
    
    // Disable systick interrupt (else this will wake up the MCU from Sleep).
    // Note: This only happened when debugging with IAR I-Jet, not with ST-Link
    SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk);
  
    // Clear old settings
    HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
    // Enable the RTC Wakeup Interrupt
    HAL_NVIC_SetPriority(RTC_WKUP_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(RTC_WKUP_IRQn);
    HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, (uint32_t)((LSI_FREQUENCY_HZ / 4) * SLEEP_TIME_SECONDS ) - 1, RTC_WAKEUPCLOCK_RTCCLK_DIV4);
          
    // Enable Ultra Low Power mode
    HAL_PWREx_EnableUltraLowPower();
 
    // Disable the Fast WakeUp from Ultra Low Power mode
    HAL_PWREx_DisableFastWakeUp();
 
    // Enters STOP mode
 
    // Note: To guarantee that we enter stop mode we must clear the event register or else the stop mode will not be entered.
 
    // Make sure event register is cleared before enabling interrupts or entering stop mode
    __SEV(); // Manally set an event
    __WFE(); // Then wait for event. This will then immediately clear the event register
 
    __enable_irq();
 
    HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFE); // Go to sleep
 
    // When wakeup
 
    __disable_irq();
 
    HAL_NVIC_DisableIRQ(RTC_WKUP_IRQn);
    HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
 
    // Enable systick interrupt
    SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
 
    __enable_irq();
}
 
/**
 * @brief Interrupt handler for real time clock wake up interrupt
 */
void RTC_WKUP_IRQHandler(void)
{
  // Note: Used HAL_RTCEx_WakeUpTimerIRQHandler() as a templete for this implementation
 
  // Get the pending status of the WAKEUPTIMER Interrupt
  if (__HAL_RTC_WAKEUPTIMER_GET_FLAG(&hrtc, RTC_FLAG_WUTF) != 0U)
  {
 
    // Clear the WAKEUPTIMER interrupt pending bit
    __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hrtc, RTC_FLAG_WUTF);
  }
 
  // Clear the EXTI's line Flag for RTC WakeUpTimer
  __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG();
}