cancel
Showing results for 
Search instead for 
Did you mean: 

Wakeup from Stop mode via RTC Alarm A failed

Clonimus74
Senior II
Posted on November 10, 2016 at 14:38

Hi,

I try to wakeup from Stop mode by using Alarm A, but it doesn't work. Anyone has any ideas? I use STM32L151VE, and my code is below. I use LSI. I see the RTC is functioning during stop mode since if I wake via power button (EXTI0) I see the RTC advanced as expected.

int main(void)
{
/*Here goes the usual initialization stuff*/
system_flags |= RtcInit();
FLASH_SLEEPPowerDownCmd(ENABLE);
PWR_UltraLowPowerCmd(ENABLE);
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
}
static void RtcClockInit(void)
{
/* Allow access to RTC */
PWR_RTCAccessCmd(ENABLE);
#if defined (RTC_CLOCK_SOURCE_LSI) /* LSI used as RTC source clock*/
/* The RTC Clock may varies due to LSI frequency dispersion. */
/* Enable the LSI OSC */
RCC_LSICmd(ENABLE);
/* Wait till LSI is ready */
while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
{
}
/* Select the RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
synch_prediv = 0x127;
asynch_prediv = 0x7C;
#elif defined (RTC_CLOCK_SOURCE_LSE) /* LSE used as RTC source clock */
/* Enable the LSE OSC */
RCC_LSEConfig(RCC_LSE_ON);
/* Wait till LSE is ready */
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
{
}
/* Select the RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
synch_prediv = 0xFF;
asynch_prediv = 0x7F;
#endif /* RTC_CLOCK_SOURCE_LSI */
/* Enable the RTC Clock */
RCC_RTCCLKCmd(ENABLE);
/* Wait for RTC APB registers synchronisation */
RTC_WaitForSynchro();
}
enum SystemFaultsEnum RtcInit(void)
{
RTC_InitTypeDef RTC_InitStructure;
struct RtcStruct temp_time = {
.hours = 0,
.minutes = 0,
.seconds = 0,
.date = 1,
.month = 5,
.year = 15,
.week_day = 5
};
if (RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x32F2)
{
RtcClockInit();
RTC_InitStructure.RTC_AsynchPrediv = asynch_prediv;
RTC_InitStructure.RTC_SynchPrediv = synch_prediv;
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
if (RTC_Init(&RTC_InitStructure) == ERROR)
return eRTC_ERROR;
if (SetRtcTimeAndDate(&temp_time) == eSYSTEM_OK)
RTC_WriteBackupRegister(RTC_BKP_DR0, 0x32F2);
else
return eRTC_ERROR;
temp_time.hours = 0;
temp_time.minutes = 2;
temp_time.seconds = 0;
return SetRtcAlarmA(&temp_time);
}
else
{
/* Allow access to RTC */
PWR_RTCAccessCmd(ENABLE);
/* Wait for RTC APB registers synchronisation */
RTC_WaitForSynchro();
/* Clear the RTC Alarm Flag */
RTC_ClearFlag(RTC_FLAG_ALRAF);
/* Clear the EXTI Line 17 Pending bit (Connected internally to RTC Alarm) */
EXTI_ClearITPendingBit(EXTI_Line17);
GetRtcTime(&temp_time);
temp_time.minutes += 2;
return SetRtcAlarmA(&temp_time);
}
}
enum SystemFaultsEnum SetRtcAlarmA(struct RtcStruct *alarm_time)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RTC_AlarmTypeDef RTC_AlarmStructure;
/* RTC Alarm A Interrupt Configuration */
EXTI_ClearITPendingBit(EXTI_Line17);
EXTI_InitStructure.EXTI_Line = EXTI_Line17;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Enable the RTC Alarm Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = RTC_Alarm_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Disable the Alarm A */
RTC_AlarmCmd(RTC_Alarm_A, DISABLE);
RTC_AlarmStructure.RTC_AlarmTime.RTC_H12 = RTC_H12_AM;
RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours = alarm_time->hours;
RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes = alarm_time->minutes;
RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = alarm_time->seconds;
/* Set the Alarm A */
RTC_AlarmStructure.RTC_AlarmDateWeekDay = alarm_time->week_day;
RTC_AlarmStructure.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date;
RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay;
/* Configure the RTC Alarm A register */
RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &RTC_AlarmStructure);
/* Enable the RTC Alarm A Interrupt */
RTC_ITConfig(RTC_IT_ALRA, ENABLE);
/* Enable the alarm A */
if (RTC_AlarmCmd(RTC_Alarm_A, ENABLE) == ERROR)
return eRTC_ERROR;
return eSYSTEM_OK;
}
void GetRtcAlarmA(struct RtcStruct *alarm_time)
{
RTC_AlarmTypeDef RTC_AlarmStructure;
RTC_GetAlarm(RTC_Format_BIN, RTC_Alarm_A, &RTC_AlarmStructure);
alarm_time->rtc_h12 = RTC_AlarmStructure.RTC_AlarmTime.RTC_H12;
alarm_time->hours = RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours;
alarm_time->minutes = RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes;
alarm_time->seconds = RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds;
}
void RTC_Alarm_IRQHandler(void)
{
if(RTC_GetITStatus(RTC_IT_ALRA) != RESET)
{
RTC_ClearITPendingBit(RTC_IT_ALRA);
EXTI_ClearITPendingBit(EXTI_Line17);
struct RtcStruct alarm_time;
GetRtcAlarmA(&alarm_time);
alarm_time.minutes += 2;
SetRtcAlarmA(&alarm_time);
} 
}

#stm32l1 #stop-mode #rtc #wakeup
1 ACCEPTED SOLUTION

Accepted Solutions
Clonimus74
Senior II
Posted on December 07, 2016 at 15:04

I feel so silly LOL

Right before I enter stop mode I de-init all my system and turn off all peripheral in my hardware, part of it is de-init the EXTI interrupts except for the power button. I prevented the de-init of the alarm EXTI before stop mode and now it works....

View solution in original post

14 REPLIES 14
Nesrine M_O
Lead II
Posted on November 10, 2016 at 15:10

Hi Clonimus74,

I recommend you to have a look to the PWR STOP example under the STM32L1 standard peripheral library it may be helpful: 

STM32L1xx_StdPeriph_Lib_V1.3.1\Project\STM32L1xx_StdPeriph_Examples\PWR\STOP

This example shows how to enters the system to STOP mode and wake-up from this

mode using RTC Wakeup Timer Event connected to EXTI Line 20.

-Syrine-

Clonimus74
Senior II
Posted on November 13, 2016 at 09:11

This example doesn't use Alarm A for wakeup, it uses RTC_IT_WUT interrupt

I need to wake from RTC_IT_ALRA but it doesn't work.

Posted on November 13, 2016 at 15:06

Not sure if I've built a similar example for the L1, have for other STM32 parts. Most of the code looks to be here, but I'm doubting it was cut from a working demo. It always helps if the presented code is free standing, and complete. There is no diagnostic output via USART/LED to see if it is working as expected, the debugger will be unhelpful here.

You likely need to be more careful how you advance minutes. Shouldn't leave main()

Are you using a .CPP file?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Clonimus74
Senior II
Posted on November 14, 2016 at 09:42

Clive,

Thank you for your reply. My code is based on working example of RTC calendar + Alarm A interrupt. I don't use the RTC interval wakeup interrupt and so the following code is missing from my code snippet:

RTC_WakeUpClockConfig(RTC_WakeUpClock_CK_SPRE_16bits);
RTC_SetWakeUpCounter(wakeup_interval);
RTC_ITConfig(RTC_IT_WUT, ENABLE);

Regardless, my code here is complete, I just removed unrelated code not to clatter the post. The Main I have is an endless loop, what I wrote here in the OP was just to show how I initialize the RTC and how I enter the Stop mode. What I do is I see the RTC time, enter stop mode (by pressing the power button of my system) and wait for the Alarm, which is set for 2 minutes. Nothing happens. I turn on the device (Exit stop mode by pressing the button) and see the RTC time advanced but the system didn't wake. The debugger works, by the way, it will not function while I'm in stop mode, but before and after waking it functions just fine, and I have a break point in the Alarm interrupt and it gets there only if I don't go to Stop mode. I tried adding the code I wrote above (which applies only for interval wakeup, but what the hell, right?) and it didn't work either. Interval wakeup by RTC works (wakes up the system from Stop mode), but I need it for different scenario.
Clonimus74
Senior II
Posted on November 16, 2016 at 12:34

No one has any ideas why it doesn't work?

Have anyone managed to wake from Stop mode using Alarm A or Alarm B of the RTC?
Clonimus74
Senior II
Posted on December 06, 2016 at 10:04

Still, no one can help?

Walid FTITI_O
Senior II
Posted on December 06, 2016 at 17:10

Hi

,

I see that you missed to enable the PWR clock . Try to add the following before allowing access to RTC:

/* Enable the PWR clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);�?�?

For other requests related to the subject, I recommend that you

check the ready-to-use example 'Calendar' which uses AlarmA under

STM32L1 standard peripheral library

at this path :STM32L1xx_StdPeriph_Lib_V1.3.1\Project\STM32L1xx_StdPeriph_Examples\RTC\Calendar

For the new libraySTM32Cube, check the ready-to-use example '

RTC_Alarm'

inside the STM32CubeL1 at this path:STM32Cube_FW_L1_V1.6.0\Projects\STM32L152D_EVAL\Examples\RTC\RTC_Alarm

Try to compare the code there with your own to figure out what you have missed.

------------------------------------------------------------------------------------------------------------------------------------

Ifthe response is useful, you would mention that by clicking the correct bottom. Thank you for the contribution

------------------------------------------------------------------------------------------------------------------------------------

-Walid FTITI-

Posted on December 07, 2016 at 09:04

Thanks, but actually I didn't miss it, I just forgot to add it to my code snippet in the OP.

As I wrote, the RTC works and the wakeup interval interrupt works, but the Alarm wakeup doesn't work.

I have CubeMX installed, does it have the example as well? I will look for it.

Posted on December 07, 2016 at 10:43

Hi

,

I have checked your code, and I found that before the first enter

to

stop mode ( case where

RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x32F2 ) you are not well configuring the AlarmA .

You should add the few configuration code lines to make it work as follow:

enum SystemFaultsEnum RtcInit(void){ RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);if (RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x32F2){RtcClockInit();RTC_InitStructure.RTC_AsynchPrediv = asynch_prediv;RTC_InitStructure.RTC_SynchPrediv = synch_prediv;RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;if (RTC_Init(&RTC_InitStructure) == ERROR)return eRTC_ERROR;if (SetRtcTimeAndDate(&temp_time) == eSYSTEM_OK)RTC_WriteBackupRegister(RTC_BKP_DR0, 0x32F2);elsereturn eRTC_ERROR;temp_time.hours = 0;temp_time.minutes = 2;temp_time.seconds = 0;/* Allow access to RTC */PWR_RTCAccessCmd(ENABLE);/* Wait for RTC APB registers synchronisation */RTC_WaitForSynchro();/* Clear the RTC Alarm Flag */RTC_ClearFlag(RTC_FLAG_ALRAF);/* Clear the EXTI Line 17 Pending bit (Connected internally to RTC Alarm) */EXTI_ClearITPendingBit(EXTI_Line17);GetRtcTime(&temp_time);temp_time.minutes += 2;return SetRtcAlarmA(&temp_time);}else{/* Allow access to RTC */PWR_RTCAccessCmd(ENABLE);/* Wait for RTC APB registers synchronisation */RTC_WaitForSynchro();/* Clear the RTC Alarm Flag */RTC_ClearFlag(RTC_FLAG_ALRAF);/* Clear the EXTI Line 17 Pending bit (Connected internally to RTC Alarm) */EXTI_ClearITPendingBit(EXTI_Line17);GetRtcTime(&temp_time);temp_time.minutes += 2;return SetRtcAlarmA(&temp_time);}}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Another thing : you should make the structure's variables as global variables and not local, in order to avoid any dependencies issue:

[

EXTI_InitTypeDef EXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RTC_AlarmTypeDef RTC_AlarmStructure;

RTC_InitTypeDef RTC_InitStructure;

]

Ifthe response is useful, you would mention that by clicking the correct bottom. Thank you for the contribution

-Walid F-