Skip to main content
Graduate II
December 8, 2024
Solved

Losing RTC ticks after wakeup timer

  • December 8, 2024
  • 1 reply
  • 787 views

Hi

   I have a STM32L433 running at 16MHz and having a strange issue.  I have setup the rtc and within the Systimer interupt I display the current time (the systimer is 1KHz and every 1000 ticks I get the second , at this point I read the clock and display on the terminal). The time is accurate , even after a few hours its still perfect. Now if I set the wakup timer to interupt every 5 seconds, it loses some ticks after the interupt.  Below is a snapshot of the terminal app. Every second the time is displayed, and at the point of ****** TIMER 5 secs ****** , this is when I set the wakeup timer. As you can see it always displays the same time twice right after the timer set . After a few timer  interupts, the time is a few seconds out.

SSmit13_0-1733672499603.png

My code is as follows:

1.The inisialisation routine:

 

void InitRTC(void)
{
	if(RTC->BKP1R!=0x1954)
	{
		if((PWR->CR1 & PWR_CR1_DBP) ==0)
		{
			PWR->CR1 |= PWR_CR1_DBP;
			while((PWR->CR1 & PWR_CR1_DBP)==0);
		}

		RCC->BDCR &= ~(RCC_BDCR_LSEON | RCC_BDCR_LSEBYP);
		RCC->BDCR |= RCC_BDCR_BDRST;
		RCC->BDCR &= ~RCC_BDCR_BDRST;
		while((RCC->BDCR & RCC_BDCR_LSERDY)==0)
			RCC->BDCR |= RCC_BDCR_LSEON;

		RCC->BDCR &= ~RCC_BDCR_RTCSEL;
		RCC->BDCR |= RCC_BDCR_RTCSEL_0;

		RCC->BDCR |= RCC_BDCR_RTCEN;

		RTC->WPR = 0xCA;
		RTC->WPR = 0x53;

		RTC->ISR |= RTC_ISR_INIT;

		if((RTC->ISR & RTC_ISR_INITF) == 0)
			RTC->ISR = (uint32_t)0xFFFFFFFFU;

		while((RTC->ISR & RTC_ISR_INITF) == 0);
		while((RTC->ISR & RTC_ISR_ALRAWF)==0);

		RTC->PRER = 0x007F00FF;

		RTC->ISR &=~ RTC_ISR_INIT;
		RTC->WPR = 0xFF;

		RCC->BDCR |= RCC_BDCR_RTCEN;
		RTC->BKP1R=0x1954;
	}
}

 

2. in the systimer routine, running at 1KHz

 

void SysTick_Handler(void)
{
 	static int SecCtr=0;

	if(++SecCtr>=1000)
 {
	 SecReached=1; //volatile
 SecCtr=0;
 }
....
}
		

 

 3. Every 5 seconds the timer gets set.

 

////////////////////////////////////////////
//EXTI 20 RTC Wakeup Timer
void RTC_Set_TransmitSlotTimer(unsigned short int TimeSecs)
{
	RTC->WPR = 0xCA;
	RTC->WPR = 0x53;
	RTC->CR &= ~RTC_CR_WUTE; //clear wakup timer
	while ((RTC->ISR & RTC_ISR_WUTWF) != RTC_ISR_WUTWF)
		;
	RTC->WUTR=TimeSecs; 

	RTC->CR &= ~RTC_CR_WUCKSEL;
	RTC->CR |= RTC_CR_WUCKSEL_2;


	EXTI->RTSR1 |= EXTI_RTSR1_RT20;
	EXTI->IMR1 |= EXTI_IMR1_IM20;
	EXTI->EMR1 |= EXTI_EMR1_EM20;
	EXTI->PR1 |= EXTI_PR1_PIF20;

	RTC->CR |= RTC_CR_WUTIE;
	RTC->CR |= RTC_CR_WUTE;
	RTC->ISR = ~RTC_ISR_WUTF;
	NVIC_EnableIRQ(RTC_WKUP_IRQn);
	NVIC_SetPriority(RTC_WKUP_IRQn,6);
	RTC->WPR = 0xff;
	if(DebugMessage)
	 Debug("\r\n**** WUTF set ****\r\n");
}

 

 4. And in the interupt routine.

 

void RTC_WKUP_IRQHandler(void)
{
 if(RTC->ISR & RTC_ISR_WUTF)
 {
 FiveSecInterupt=1; //volatile char
	 EXTI->PR1 |= EXTI_PR1_PIF20;
 }
}

 

5. And within the main routine.

 

while(1)
{
 if(SecReached) //set in timer interupt.
 {
 ReadTime();
 sprintf(ScrapBuffer," %02d:%02d.%02d\r\n",Tme.Hour,Tme.Min,Tme.Sec);
 Serial_PutString(USART2,ScrapBuffer); 
 }
 if(FiveSecInterupt) //set in wakeup interupt
	{
		 Serial_PutString(USART2,"\r\n****** TIMER 5 secs ******\r\n");
		 RTC_Set_TransmitSlotTimer(5);
 }
}

 

 

Can someone please let me know why I am losing clock ticks ?

 

Many thanks

Scott

    This topic has been closed for replies.
    Best answer by SSmit.13

    Hi

      I have found the issue, after anytime the CR was updated the INIT bit was set for a short time, but enough to cause a delay. The way around it was to clear the INIT bit before locking the RTC registers again.

     

    Thanks

    Scott

    1 reply

    SSmit.13AuthorAnswer
    Graduate II
    December 9, 2024

    Hi

      I have found the issue, after anytime the CR was updated the INIT bit was set for a short time, but enough to cause a delay. The way around it was to clear the INIT bit before locking the RTC registers again.

     

    Thanks

    Scott

    Super User
    December 9, 2024

    Can you please elaborate?

    Are you talking about this line:

    RTC->ISR = ~RTC_ISR_WUTF;

    in RTC_Set_TransmitSlotTimer() function?

    JW