AnsweredAssumed Answered

RTC with LSI working ... sometimes ...

Question asked by VDM on Oct 5, 2013
Latest reply on Oct 6, 2013 by VDM
Hi all,

I need a bit help, since I can't get the RTC based on LSI making a robust timer.

I try to generate an interrupt every 10 seconds.
Here the code that concerns the RTC :
void main(void)
{
    EXTI_Configuration();
 
    RTC_Configuration();
 
    NVIC_Configuration();
 
    RTC_SetAlarm(RTC_GetCounter()+ 1);
    RTC_WaitForLastTask();
     
    /* Start IT */
    while(1)
    {
                PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
    }
}
 
 
void NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
 
    /* Configure the NVIC Preemption Priority Bits */ 
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    
    NVIC_InitStructure.NVIC_IRQChannel = RTCAlarm_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}
 
 
void EXTI_Configuration(void)
{
  EXTI_InitTypeDef EXTI_InitStructure;
 
  /* Configure EXTI Line17(RTC Alarm) to generate an interrupt on rising edge */
  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);
}
 
 
void RTC_Configuration(void)
{
  /* Enable PWR and BKP clocks */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
 
  /* Allow access to BKP Domain */
  PWR_BackupAccessCmd(ENABLE);
 
  /* Reset Backup Domain */
  BKP_DeInit();
 
  /* 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);
 
  /* Enable RTC Clock */
  RCC_RTCCLKCmd(ENABLE);
 
  /* Wait for RTC registers synchronization */
  RTC_WaitForSynchro();
 
  /* Set RTC prescaler: set RTC period to 1sec */
  RTC_SetPrescaler(40000);
 
  /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();
   
  /* Enable the RTC Alarm interrupt */
  RTC_ITConfig(RTC_IT_ALR, ENABLE);
  /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();
}
 
void RTCAlarm_IRQHandler(void)
{
  if(RTC_GetITStatus(RTC_IT_ALR) != RESET)
  {
    /* Clear RTC Alarm interrupt pending bit */
    RTC_ClearITPendingBit(RTC_IT_ALR);
    /* Wait until last write operation on RTC registers has finished */
    RTC_WaitForLastTask();
 
    /* Alarm in 3 second */
    RTC_SetAlarm(RTC_GetCounter()+ 10);
 
    if (GPIOB->ODR & LCD_BL)
    {
        GPIOB->BRR = LCD_BL;
    }
    else
    {
     GPIOB->BSRR = LCD_BL;
    }
    G_SEQ_Timestamp += 10;
     
    /* Clear EXTI line17 pending bit */
    EXTI_ClearITPendingBit(EXTI_Line17);
 
    /* Check if the Wake-Up flag is set */
    if(PWR_GetFlagStatus(PWR_FLAG_WU) != RESET)
    {
      /* Clear Wake Up flag */
      PWR_ClearFlag(PWR_FLAG_WU);
    }
  }
}

Sometimes I get an IT every 10 seconds, sometimes every x minutes, sometimes ever seconds ... well, it's just not reliable.

Any help would be appreciated.

Best regards,
Vincent.

Outcomes