cancel
Showing results for 
Search instead for 
Did you mean: 

Wake-up from RTC-alarm works only once

anonymous.8
Senior II

I am trying to set RTC-alarm event to wake up an STM32F103C8T6 from sleep-mode (not standby, not stop) and it works once, but subsequent alarms never wake the MCU up. Nothing I've tried seems to work and I no longer have any idea how to fix this.

The code is on pastebin, since this forum-software doesn't let me paste it here: https://pastebin.com/AzHiAxhw

1 ACCEPTED SOLUTION

Accepted Solutions
anonymous.8
Senior II

Okay, I finally figured it out and most of the stuff I had tried was not needed; my issue was down to me not knowing that I needed to clear the pending IRQ from the NVIC. Basically, it boils down to the following:

//Disable systick so it won't wake the MCU up from sleep
	HAL_SuspendTick();
	HAL_PWR_EnableSEVOnPend();
	//These two lines clear any pending RTC alarm
	__HAL_RTC_ALARM_CLEAR_FLAG(&hrtc, RTC_FLAG_ALRAF);
	NVIC_ClearPendingIRQ(RTC_IRQn);
	//Then just proceed to set up the new alarm and go to sleep
	HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN);
	HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFE);
	HAL_ResumeTick();

Of note is that the RTC alarm must be cleared before clearing the NVIC interrupt pending. Swapping them around or expecting HAL_RTC_SetAlarm_IT() to clear the alarm won't work, the NVIC interrupt won't get cleared successfully until the alarm has first been cleared.

I'm leaving this here in case someone else wants to use WFE instead of WFI with sleep and can't get it working.

View solution in original post

3 REPLIES 3
MM..1
Chief II

Maybe you enable IT but not have handler. Show it.c part code too ...

void setAlarmSeconds(int8_t seconds) {
	HAL_RTC_DeactivateAlarm(&hrtc, RTC_ALARM_A);
	__HAL_RTC_ALARM_CLEAR_FLAG(&hrtc, RTC_FLAG_ALRAF);
	__HAL_RTC_ALARM_EXTI_CLEAR_FLAG();
	RTC_TimeTypeDef time = { 0 };
	RTC_DateTypeDef date = { 0 };
	RTC_AlarmTypeDef sAlarm = { 0 };
	HAL_RTC_GetTime(&hrtc, &time, RTC_FORMAT_BIN);
	HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BIN);
	time.Seconds += seconds;
	if (time.Seconds >= 60) {
		time.Minutes++;
		time.Seconds = time.Seconds - 60;
	}
	if (time.Minutes >= 60) {
		time.Hours++;
		time.Minutes = time.Minutes - 60;
	}
	if (time.Hours > 23) {
		time.Hours = 0;
	}
	sAlarm.Alarm = RTC_ALARM_A;
	sAlarm.AlarmTime.Hours = time.Hours;
	sAlarm.AlarmTime.Minutes = time.Minutes;
	sAlarm.AlarmTime.Seconds = time.Seconds;
	HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN);
}
/* USER CODE END 4 */

No, there is no handler. The RTC isn't connected to NVIC since I am using PWR_SLEEPENTRY_WFE, not PWR_SLEEPENTRY_WFI. Also, as mentioned, it works once, so I don't see how there being a handler or not would be relevant. I mean, if that was the issue, wouldn't it not work at all?

anonymous.8
Senior II

Okay, I finally figured it out and most of the stuff I had tried was not needed; my issue was down to me not knowing that I needed to clear the pending IRQ from the NVIC. Basically, it boils down to the following:

//Disable systick so it won't wake the MCU up from sleep
	HAL_SuspendTick();
	HAL_PWR_EnableSEVOnPend();
	//These two lines clear any pending RTC alarm
	__HAL_RTC_ALARM_CLEAR_FLAG(&hrtc, RTC_FLAG_ALRAF);
	NVIC_ClearPendingIRQ(RTC_IRQn);
	//Then just proceed to set up the new alarm and go to sleep
	HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN);
	HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFE);
	HAL_ResumeTick();

Of note is that the RTC alarm must be cleared before clearing the NVIC interrupt pending. Swapping them around or expecting HAL_RTC_SetAlarm_IT() to clear the alarm won't work, the NVIC interrupt won't get cleared successfully until the alarm has first been cleared.

I'm leaving this here in case someone else wants to use WFE instead of WFI with sleep and can't get it working.