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
14 REPLIES 14
Walid FTITI_O
Senior II
Posted on December 07, 2016 at 14:08

Hi

Ofri.Igal

,

In this case , since there is many dependencies in your code ,

I recommend that you start to use

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

Compare the parts there ith your own to figure out what you missed.

-Walid F-

Posted on December 07, 2016 at 13:54

It was a good try, I added those lines, though they do appear in RtcClockInit function, and it didn't work.

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....

Posted on December 07, 2016 at 14:17

That's what I'm doing, though I can't find anything wrong.

I'm not sure what you mean by a lot of dependencies, my code is built from small independent functions, each one does a specific task and they are non-dependent.

Posted on December 07, 2016 at 16:49

Thas happens sometimes. Keep the good work and thank your for contibution.

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