AnsweredAssumed Answered

Wakeup from Stop mode via RTC Alarm A failed

Question asked by Clonimus74 on Nov 10, 2016
Latest reply on Dec 7, 2016 by FTITI.Walid
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);
  }
}

Outcomes