2020-07-10 05:50 AM
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.
2020-07-10 06:05 AM
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
2020-07-10 06:32 AM
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
2020-07-10 06:38 AM
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.
2020-07-10 07:02 AM
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.
2020-07-10 07:13 AM
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();
}