AnsweredAssumed Answered

STM32L152C6 LSE RTC WakeUp

Question asked by mihaylov.kaloyan on Aug 26, 2013
Latest reply on Aug 21, 2014 by shah.monil
Hello. I'm trying to use the RTC WakeUp feature to as a countdown timer.

I've tried the code from the StdLib examples:
01.void RTC_Config(void)
02.{
03.  NVIC_InitTypeDef NVIC_InitStructure;
04.  EXTI_InitTypeDef EXTI_InitStructure;
05. 
06.  /* Enable the PWR clock */
07.  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
08. 
09.  /* Allow access to RTC */
10.  PWR_RTCAccessCmd(ENABLE);
11. 
12./* LSI used as RTC source clock */
13./* The RTC Clock may varies due to LSI frequency dispersion. */  
14.  /* Enable the LSI OSC */
15.  RCC_LSICmd(ENABLE);
16. 
17.  /* Wait till LSI is ready */ 
18.  while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
19.  {
20.  }
21. 
22.  /* Select the RTC Clock Source */
23.  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
24.    
25.  /* Enable the RTC Clock */
26.  RCC_RTCCLKCmd(ENABLE);
27. 
28.  /* Wait for RTC APB registers synchronisation */
29.  RTC_WaitForSynchro();
30. 
31.  /* Calendar Configuration */
32.  RTC_InitStructure.RTC_AsynchPrediv = 0x7F;
33.  RTC_InitStructure.RTC_SynchPrediv =  0x120; /* (37KHz / 128) - 1 = 0x120*/
34.  RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
35.  RTC_Init(&RTC_InitStructure); 
36. 
37.  /* EXTI configuration *******************************************************/
38.  EXTI_ClearITPendingBit(EXTI_Line20);
39.  EXTI_InitStructure.EXTI_Line = EXTI_Line20;
40.  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
41.  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
42.  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
43.  EXTI_Init(&EXTI_InitStructure);
44.   
45.  /* Enable the RTC Wakeup Interrupt */
46.  NVIC_InitStructure.NVIC_IRQChannel = RTC_WKUP_IRQn;
47.  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
48.  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
49.  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
50.  NVIC_Init(&NVIC_InitStructure); 
51. 
52.  /* Configure the RTC WakeUp Clock source: CK_SPRE (1Hz) */
53.  RTC_WakeUpClockConfig(RTC_WakeUpClock_CK_SPRE_16bits);
54.  RTC_SetWakeUpCounter(0x0);
55. 
56.  /* Enable the RTC Wakeup Interrupt */
57.  RTC_ITConfig(RTC_IT_WUT, ENABLE);
58.   
59.  /* Enable Wakeup Counter */
60.  RTC_WakeUpCmd(ENABLE);
61.}

Here is the interrupt code:
1.void RTC_WKUP_IRQHandler(void)
2.{
3.  if(RTC_GetITStatus(RTC_IT_WUT) != RESET) {
4.    GPIO_ToggleBits( GPIOB, GPIO_Pin_6 );
5.    RTC_ClearITPendingBit(RTC_IT_WUT);
6.    EXTI_ClearITPendingBit(EXTI_Line20); //OK
7.  }
8.}

The problem is that this usually doesn't work. I've also changed the LSI to LSE with no success.

Later I decided to modify the registers by hand:
01.RTC->CR = ( 0 << 14 );
02.RTC->WPR = 0xCA;
03.RTC->WPR = 0x53;
04.RTC->CR = ( 0 << 10 ); // 19.6.3 from manual
05.while( ! (RTC->ISR && (1 << 10)) );
06.RTC->WUTR = 0x0;
07.RTC->CR |= (0x4 << 0);
08.RTC->CR |= ( 1 << 10 );
09.RTC->CR |= ( 1 << 14 );
10.RTC->WPR = 0xFF;

Actually the code above is doing right that:
1.RTC_WakeUpClockConfig(RTC_WakeUpClock_CK_SPRE_16bits);
2.RTC_SetWakeUpCounter(0x0);
3. 
4./* Enable the RTC Wakeup Interrupt */
5.RTC_ITConfig(RTC_IT_WUT, ENABLE);
6. 
7./* Enable Wakeup Counter */
8.RTC_WakeUpCmd(ENABLE);

When I ran this code, the MCU enters the interrupt immediately, then it enters again after the period programmed (for example 5 seconds) and after that it doesn't execute the interrupt code.

Please, can you point me to the right way to initialize and run the LSE WakeUp timer, so I can execute arbitrary code in the interrupt's handler function AND to wakeup the MCU from standby mode (in this case I should re-initialize the MCU).

When the MCU is externally powered, then I need to use the WakeUp timer just as a countdown timer, but if the user runs it w/o external power, then it should use the WakeUp timer both to start the MCU and to execute some code.

Outcomes