cancel
Showing results for 
Search instead for 
Did you mean: 

Is there a way to maintain RTC ticking without any shifts while performing a power reset?

tarasov.alex.m
Associate III

/*UPDATE*/

It turned out that im my case the problem was in the start up routine:

There was a "Start up" project (written not by me) that was downloaded at 0 flash address and it was jumping to another address where my project was located.

I did not know that in this "Start up" project there was an RTC initialization (which prevented my RTC from running continuously).

Everything below this sentence is what I wrote before I knew where the problem is.

Good day!

I'm using RTC in a STM32F407VG controller.

I configured RTC_ALARM_A to generate an interrupt every second (this indicates when a second changes in RTC). By this interrupt, an oscilloscope and a reference 1Hz clock from another device (that is not being reset) I watch whether my RTC is ticking consistently.

With this setting it can be seen if MCU's RTC is shifting during power reset. And that's exactly what I'm observing (don't know the absolute value of the time shift, but I see that the phase of MCU's 1Hz clock output is changing randomly after power reset is done).

Can anyone tell me if there is anything that can be done to make RTC run continгously, even when a power reset is performed?

Also this things need to be mentioned:

  • I do use a battery for RTC and clocks are ticking while MCU is not powered.
  • I am not reinitializing the RTC periphery each time.
  • Backup registers preserve their values, so no "Backup domain reset" occures.
  • RTC clock is consistent during "System reset", this behavior is only seen when "Power reset" is done
1 ACCEPTED SOLUTION

Accepted Solutions

And in the startup code, i.e. before main(), what code is there?

JW

View solution in original post

15 REPLIES 15

> Is there a way to maintain RTC ticking without any shifts while performing a power reset?

Yes, don't call the Cube/HAL init routine.

https://community.st.com/s/question/0D50X00009XkgBWSAZ/stm32-rtc-loses-one-second-after-each-reset and maybe a dozen of other threads here.

JW

tarasov.alex.m
Associate III

Here's my code 

void MX_RTC_Init(void){
 
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
  RCC_OscInitTypeDef RCC_OscInitStruct;
  
  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
  PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
 
  hrtc.Instance = RTC;
  hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
  hrtc.Init.AsynchPrediv = RTC_ASYNCH_DIV - 1;
  hrtc.Init.SynchPrediv = RTC_SYNCH_DIV - 1;
  hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
  
  if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) != RTC_SECRET_DATA){/*if RTC 
    was not previously iinitialized*/
    RCC_OscInitStruct.LSEState = RCC_LSE_ON;
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
    HAL_RCC_OscConfig(&RCC_OscInitStruct);
    HAL_RTC_Init(&hrtc) ;
    rtc_date_time_config_frst_time();
  }else{/*if RTC was initialized, we only need to call HAL_RTC_MspInit*/
    HAL_RTC_MspInit(&hrtc);
  }
  rtc_alarm_a_set_it();
}
 
void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc)
{
  __HAL_RCC_RTC_ENABLE();
  HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 1, RTC_ALARM_IRQ_PRIO);
  HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
}
 
void rtc_alarm_a_set_it(void){
  RTC_AlarmTypeDef  sAlarm;
  /**Enable the Alarm A 
  */
  sAlarm.AlarmTime.Hours = 0;
  sAlarm.AlarmTime.Minutes = 0;
  sAlarm.AlarmTime.Seconds = 0;
  sAlarm.AlarmTime.SubSeconds = 0;
  sAlarm.AlarmTime.TimeFormat = RTC_HOURFORMAT_24;
  sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
  sAlarm.AlarmMask = RTC_ALARMMASK_ALL;
  sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_None;
  sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
  sAlarm.AlarmDateWeekDay = 1;
  sAlarm.Alarm = RTC_ALARM_A;
  HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, FORMAT_BIN);
}

turboscrew
Senior III

CubeMX puts the RTC initialization there for every reset.

You need to make the change every time you generate code with CubeMX.

But if you have the backup battery, and you edit the code CubeMX generates, the RTC is reset only when you program the backup domain reset.

Thanks for your answer, but I'd seen this thread. It didn't help. As I mentioned, I'm not reinitializing RTC each time the MCU restarts.

Posting my code below. 

Hi. I'm not using CubeMX's code, I do use a battery (I've checked the voltage on VBAT pin, is constanty 3V) and I don't see a backup domain reset taking place.

> if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) != RTC_SECRET_DATA){/*if RTC

So, did you verify that this expression evaluates always false?

JW

Yes I did. I use a debug LED in "rtc_date_time_config_frst_time"(line 22), so I know whether it was called.

tarasov.alex.m
Associate III

Also I found out that after power reset "RTC_PRER" register (the one that contains prescaler values) resets to its default value. That event takes place before executing anything in "main()". I placed a loop at the begining to ckeck that. This loop can be skipped only in debug mode, so when I enter debug mode after performing a power reset I know that nothing was previously executed in "main()".

And in the startup code, i.e. before main(), what code is there?

JW