cancel
Showing results for 
Search instead for 
Did you mean: 

Losing RTC ticks after wakeup timer

SSmit.13
Senior

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

1 ACCEPTED SOLUTION

Accepted Solutions
SSmit.13
Senior

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

View solution in original post

2 REPLIES 2
SSmit.13
Senior

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

Can you please elaborate?

Are you talking about this line:

RTC->ISR = ~RTC_ISR_WUTF;

in RTC_Set_TransmitSlotTimer() function?

JW