Skip to main content
greffeb
Associate II
October 2, 2020
Question

[STM32L0] Wake up Flag for RTC does not rise when an alarm occurs

  • October 2, 2020
  • 3 replies
  • 4146 views

Hi,

I have a STM32L071 on a custom board

The code was generated with CubeMx for TrueSTUDIO.

I have an alarm set on the RTC to wake up the chip from standby mode everyday at 2 AM.

I tested it and the system does wake up ! good.

My problem is that I need to differentiate the origin of the wake up between RTC alarm and WKUP pin 1.

I check for PWR_FLAG_WU which does not give much information to differentiate the two.

My understanding from the reference manual (RM0377 DocID025942 Rev 8 p559) is that the bit ALRAF in the RTC initialization and status register (RTC_ISR) is the one that might be useful for me.

But even tho the system wakes up from RTC, the ALRAF flag is not set

same with RTC_IT_ALRA and RTC_FLAG_WUTF

Is there a way to know if the origin of wake up is the WKUP pin ?

regards,

Benjamin GREFFE.

code used to check the flags :

 if(__HAL_RTC_ALARM_GET_IT(&hrtc, RTC_IT_ALRA))
 {
	 lbWakedUpByRTC_IT = true;
 }
 if (__HAL_RTC_ALARM_GET_FLAG(&hrtc, RTC_FLAG_ALRAF))
 {
	 lbWakedUpByRTC_ALRAF = true;
 }
 if (__HAL_RTC_WAKEUPTIMER_GET_FLAG(&hrtc, RTC_FLAG_WUTF))
 {
	 lbWakedUpByRTC_WUTF = true;
 }

code to initialize the rtc

static void MX_RTC_Init(void)
{
 RTC_AlarmTypeDef sAlarm = {0};
 
 /** Initialize RTC Only 
 */
 hrtc.Instance = RTC;
 hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
 hrtc.Init.AsynchPrediv = 125;
 hrtc.Init.SynchPrediv = 296;
 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();
 }
 
 /** Enable the Alarm A
 */
 sAlarm.AlarmTime.Hours = 0x2;
 sAlarm.AlarmTime.Minutes = 0x0;
 sAlarm.AlarmTime.Seconds = 0x0;
 sAlarm.AlarmTime.SubSeconds = 0x0;
 sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
 sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
 sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY;
 sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
 sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
 sAlarm.AlarmDateWeekDay = 0x1;
 sAlarm.Alarm = RTC_ALARM_A;
 if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK)
 {
 Error_Handler();
 }
}

code to go to sleep

	HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1);
	__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
	HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
	HAL_PWR_EnterSTANDBYMode();
	while (1)
	{
	 NVIC_SystemReset();
	}

This topic has been closed for replies.

3 replies

MFahl.1
Visitor II
March 5, 2021

Hi, I have the same or similar problem. ALRAF is not set when returning from standby. I am on a different MCU, STM32F100.

For me all works according to the datasheets when I run in the debugger (ST-Link). However when I run outside the debugger the ALRAF bit never reads as 1. The MCU is returning (reset) perfectly from standby on RTC but I am not able to read a correct value on ALRAF.

Did you find a solution somewhere?

/Mats

MFara.1346
Visitor II
September 12, 2022

Any one found a solution for this?

greffeb
greffebAuthor
Associate II
September 12, 2022

I have found a workaround to differentiate source of wakeup

after the  SystemClock_Config(); i clear all wakeup flags.

 /* Check and handle if the system was resumed from StandBy mode */
 if(__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET)
 {
 /* Clear Standby flag */
 __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
 }
 /* Disable all used wakeup sources: PWR_WAKEUP_PIN1 */
 HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1);
 
 /* Clear all related wakeup flags*/
 __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);

then i compare current RTC date with expected Calendar alarm

 /**** check alarm wakeup ****/
 /* read programmed alarm */
 uint32_t tmpregalarm = (uint32_t) RTC->ALRMAR;
 int alr_hour = bcd2int((uint8_t)((tmpregalarm & (RTC_ALRMAR_HT | RTC_ALRMAR_HU )) >> 16));
 int alr_min = bcd2int((uint8_t)((tmpregalarm & (RTC_ALRMAR_MNT | RTC_ALRMAR_MNU)) >> 8 ));
 int alr_sec = bcd2int((uint8_t) (tmpregalarm & (RTC_ALRMAR_ST | RTC_ALRMAR_SU )) );
 /* read current RTC */
 uint32_t tmpregrtc = (uint32_t) RTC->TR;
 int rtc_hour = bcd2int((uint8_t)((tmpregrtc & (RTC_TR_HT | RTC_TR_HU )) >> 16));
 int rtc_min = bcd2int((uint8_t)((tmpregrtc & (RTC_TR_MNT | RTC_TR_MNU)) >> 8 ));
 int rtc_sec = bcd2int((uint8_t) (tmpregrtc & (RTC_TR_ST | RTC_TR_SU )) );
 /* if current date= alarm -> alarm wakeup */
 if(alr_hour==rtc_hour && alr_min==rtc_min && alr_sec==rtc_sec){lbSystemWakedUpByRtcAlarm = true ;}
 else {lbSystemWakedUpByRtcAlarm = false;}

if true, the source of wakeup was the alarm. If false, the source of wakeup was from another source( WKUP PIN or RST in my case)

MFara.1346
Visitor II
September 12, 2022

Many thanks. Really appreciated. I also asked this question from ST if I get any different reply I will share it here for everyone to use.

Associate II
October 20, 2023

I don't know if it is the same case for the STM32L071 as the STM32F103, but after many attempts and tests, I have opened a ticket with ST, and I've got this answer:

"It turns out that the ALRF flag (and indeed the whole register) is not kept through system reset - which occurs at wake up. Although this is not explicitly documented. The only similar flag that is kept is WUF in PWR_CSR register but this is combines wakeup from button and RTC alarm so not helpful in your case.
The solution is then the one you already applied - compare the current time to a predefined one from Flash/backup registers."

Check the following post if you have not solved this topic yet: