2022-03-08 06:53 AM
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);
Solved! Go to Solution.
2022-03-09 04:27 AM
Anyway, since RTC does not wake up system anymore, I have removed is_stay_in_sleep_mode, and now it simply waits in HAL_PWR_EnterSLEEPMode() until wake up ISR from other peripherals is triggerred.
2022-03-09 03:35 AM
is_stay_in_sleep_mode variable is volatile ?
And check if wakeup is designed or setup for wake from sleep. Normal usage is wake from standby...
2022-03-09 04:26 AM
Also update on behaviour.
When the wake up interrupt is generated, system does not leave __WFI() instruction.
But when interrupt from UART comes, then it moves out form ISR instruction, and on the next wake up interrupt it starts working as it should.
2022-03-09 04:27 AM
Anyway, since RTC does not wake up system anymore, I have removed is_stay_in_sleep_mode, and now it simply waits in HAL_PWR_EnterSLEEPMode() until wake up ISR from other peripherals is triggerred.