RTC Wakeup does not wakeup system from sleep mode STM32L431?
Hello, I'm using RTC Wakeup to periodically kick WDG while system is in a sleep mode.
I have setup RTC wakeup as following:
/* RTC init function */
void MX_RTC_Init(void)
{
/** Initialize RTC Only
*/
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 127;
hrtc.Init.SynchPrediv = 255;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
if (HAL_RTC_Init(&hrtc) != HAL_OK)
{
Error_Handler();
}
}
void HAL_RTC_MspInit(RTC_HandleTypeDef* rtcHandle)
{
if(rtcHandle->Instance==RTC)
{
/* USER CODE BEGIN RTC_MspInit 0 */
/* USER CODE END RTC_MspInit 0 */
/* RTC clock enable */
__HAL_RCC_RTC_ENABLE();
/* RTC interrupt Init */
HAL_NVIC_SetPriority(RTC_WKUP_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(RTC_WKUP_IRQn);
/* USER CODE BEGIN RTC_MspInit 1 */
/* USER CODE END RTC_MspInit 1 */
}
}and then before going to sleep:
/**************************************************************************************************
* @brief Activates/Deactivates wake up timer to wake up system from sleep mode and reset IWDG. It is configured
with assumption that IWDG will be configured with 32 seconds timeout before entering sleep
mode
* @param None
* @retval None
***************************************************************************************************/
void rtc_sleep_mode_wakeup_timer_ctrl(bool status)
{
/* Enable the WakeUp with period of approximately 30 seconds
* Formula: (Clock/RTC_WAKEUP_DIV_XX)(to us) * Wakeup_counter_value = desired value
*/
if(status)
{
if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 61439, RTC_WAKEUPCLOCK_RTCCLK_DIV16) != HAL_OK)
{
Error_Handler();
}
__HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_IT();
}
else
{
__HAL_RTC_WAKEUPTIMER_EXTI_DISABLE_IT();
if (HAL_RTCEx_DeactivateWakeUpTimer(&hrtc) != HAL_OK)
{
Error_Handler();
}
}
}This is how sleep mode itself looks like.
/*****************************************************************************************
* @brief Enters sleep mode with possibility to wake up from UART1 or CAN ISR.
Also, rtc wakeup timer wkaes up the device to reset IWDG.
Then handles exit from stop mode
* @param None
* @retval None
*****************************************************************************************/
void pwr_handle_sleep_mode(void)
{
PRINT_DEBUG("Enter sleep mode");
HAL_Delay(5);
hwm_enter_sleep_mode();
/* Enforce sleep mode */
is_stay_in_sleep_mode = true;
/* Reduce the System clock to below 2 MHz */
SystemClock_Decrease();
/* Stop tick to avoid wake up from Systick ISR */
HAL_SuspendTick();
/* Enter low-power SLEEP mode */
while(is_stay_in_sleep_mode) // This variable is modified in RTC interrupt
{
is_stay_in_sleep_mode = false;
LOG_DEBUG_MSG("Going back to sleep %d", is_stay_in_sleep_mode);
/* ... SLEEP mode ... */
HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
LOG_DEBUG_MSG("Wake up %d", is_stay_in_sleep_mode);
}
/* System is Low Power Run mode when exiting Low Power Sleep mode,
disable low power run mode and reset the clock to initialization configuration */
HAL_PWREx_DisableLowPowerRunMode();
SystemClock_Config();
hwm_exit_sleep_mode();
HAL_ResumeTick();
PRINT_DEBUG("Exit sleep mode");
}is_stay_in_sleep_mode variable is changed to true in HAL_RTCEx_WakeUpTimerEventCallback()
Now the problem is that RTC Wake up interrupt triggers and it changes is_stay_in_sleep_mode to true, but __WFI() instruction does not exit for some reason. And what happens next is that, when wake up from UART or CAN is received it does not wake up the system, because is_stay_in_sleep_mode is set to true.
Does anyone know WHY Wakeup interrupt does is ignored by HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
