Skip to main content
coppercrimp
Associate III
May 23, 2017
Solved

STM32 RTC loses one second after each reset

Posted on May 23, 2017 at 07:46

I have a custom board based on the STM32F407 device. The board is running well except for one nagging detail: the RTC loses one second each time I power the board on/off

My device uses a low frequency external crystal and a backup coincell battery. The crystal is the CM7V-T1A 32.768kHz from Micro Crystal and it runs fine and keeps accurate time from either the coincell or main battery power. But again, the RTC looses approximately 1 second every time the board is powered on from the main external batteries. If the user powers the board on and off ten times (while keeping the backup coincell connected of course), then approximately 10 seconds of time is lost on the RTC.

I see many postings on this forum of people reporting loss of time when coming out of sleep modes. However my problem happens irregardless of whether the processor ever enters sleep mode. I do check the Wakeup Flag and the Standby Flag on power up though. Below is the first lines of code from my main() function:

int main(void)

{

HAL_Init();

/* Configure the system clock */

SystemClock_Config_HighSpeed();

/* Initialize all configured peripherals */

MX_GPIO_Init();

CheckFlashDefaults();

MX_DMA_Init();

MX_I2C1_Init();

MX_SDIO_SD_Init();

StatusLED_ConfigI2C(&hi2c1);

if(__HAL_PWR_GET_FLAG(PWR_FLAG_WU) != RESET)

{

      __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);

}

/* Check the status of standby flag SB*/

if (__HAL_PWR_GET_FLAG(PWR_FLAG_SB) == RESET)

{

      RTC_Init();

}

else

{

      /*Resuming from standby routine */

      __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);

}

And here is the code that initializes the RTC:

void RTC_Init(void)

{

   RTC_TimeTypeDef sTime;

   RTC_DateTypeDef sDate;

   /**Initialize RTC and set the Time and Date

   */

   hrtc.Instance = RTC;

   hrtc.Init.HourFormat = RTC_HOURFORMAT_24;

   hrtc.Init.AsynchPrediv = 127;

   hrtc.Init.SynchPrediv = 255;

   hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;

   hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;

   hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;

   HAL_RTC_Init(&hrtc);

   /* Read the Back Up Register 0 Data */

   if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) != 0x32F2)

   {

      /* Configure RTC Calendar */

      sTime.Hours = 4;

      sTime.Minutes = 0;

      sTime.Seconds = 0;

      sTime.SubSeconds = 0;

      sTime.TimeFormat = RTC_HOURFORMAT12_AM;

      sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;

      sTime.StoreOperation = RTC_STOREOPERATION_RESET;

      HAL_RTC_SetTime(&hrtc, &sTime, FORMAT_BCD);

      sDate.WeekDay = RTC_WEEKDAY_MONDAY;

      sDate.Month = RTC_MONTH_JANUARY;

      sDate.Date = 1;

      sDate.Year = 0;

      HAL_RTC_SetDate(&hrtc, &sDate, FORMAT_BCD);

      /*♯♯-3- Writes a data in a RTC Backup data Register0 ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

      HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR0,0x32F2);

   }

}

#stm32f4 #rtc
This topic has been closed for replies.
MSine
MSineBest answer
Visitor II
February 21, 2019

I solved this problem in the following way:

0690X000006DkvIQAS.png

35 replies

Czhih.1837
Visitor II
December 2, 2019

thanks a lot! This does work.

best Regards,

Albert

Adsou.1
Visitor II
December 11, 2019

Hello Robert, Siddharth,

Actually i also see this exact same issue and was wondering if you guys managed to figure this out. Any pointers would be greatly appreciated.

I work with the STM32f779i on a custom board and use HAL.

Thanks,

Abel

MSine
Visitor II
December 11, 2019

Perhaps because you are using a different series of microcontroller. Other drivers may be used for your series. Try to debug the code step by step in all method implementations. That’s how I fixed this problem myself

Adsou.1
Visitor II
January 24, 2020

Than you. Yes we should not be calling RTC init at every boot up. We have also fixed this. thanks for your reply.

ALABSTM
ST Employee
February 1, 2022

Hi @Community member​,

We are actively working on this issue. Once a fix is available, we would make it available on GitHub, pending its integration in a new Cube firmware release. We will keep you informed.

With regards, 

ALABSTM
ST Employee
May 30, 2022

Hi,

I hope  everybody's fine. Just to let you know this issue has been fixed and the fix is available on GitHub here.

The idea is to check whether the RTC needs to be initialized by reading the status of bit RTC_FLAG_INITS.

As the fix is implemented at the HAL RTC driver's level, the user needs no more to handle the point at their application's level.

Do not hesitate should you have any feedback related to this topic.

As for other series whose RTC drivers suffer the same issue (I saw STM32F1 mentioned), the fix should be implemented and published too. Unfortunately, we cannot share a date for the moment. Thank you all for your comprehension.

With regards,

PS: Please note this fix is still to be integrated into a new STM32CubeF4 firmware version.

Alec Davis 2021
Associate III
July 2, 2022

I'm using an STM32L151 and have the same problem, after every reset I lose about 1 second.

Thus the check on the INITS flag isn't perfect as it relies on the YEAR being set.

extract from manual

Bit 4 INITS: Initialization status flag This bit is set by hardware when the calendar year field is different from 0 (power-on reset value state). 0: Calendar has not been initialized 1: Calendar has been initialized

But finally I know a work around, set the year.

Also after applying the above fix I found that calling HAL_RTCEx_SetCoarseCalib( &hrtc, RTC_CALIBSIGN_NEGATIVE, value ) at reset also lost time, best to only call it when an adjustment is made.

As I only use time, the workaround was to set the year to 22, now in 78 years time for 1 year the device will lose time :beaming_face_with_smiling_eyes:

Piranha
Principal III
July 9, 2022

> As I only use time, the workaround was to set the year to 22

Setting a year to 1 seems like the best choice.

waclawek.jan
Super User
July 2, 2022

 > Thus the check on the INITS flag isn't perfect as it relies on the YEAR being set.

Indeed.

I personally check RCC_BDCR.RTCEN.

JW

Piranha
Principal III
July 9, 2022
const uint32_t rBDCR = RCC_BDCR_RTCEN | _VAL2FLD(RCC_BDCR_RTCSEL, 1) | RCC_BDCR_LSEON;
 
if ((RCC->BDCR & (RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL | RCC_BDCR_LSEDRV | RCC_BDCR_LSEBYP | RCC_BDCR_LSEON)) != rBDCR) {
	RCC->BDCR = RCC_BDCR_BDRST;
	RCC->BDCR = rBDCR;
}

I'm doing it like this. The bonus is that if something got wrong with any of those bits, they (and the whole backup domain) will be reconfigured on the next boot.

waclawek.jan
Super User
July 11, 2022

Nice.

Btw. _VAL2FLD() macro was added to CMSIS in v4.20, somewhen in 2015, quite late to the dance.

Roughly in the same timeframe (for STM32, with the advent of Cube) the ***_Pos and ***_Msk macros - upon which the _VAL2FLD() macro depends - appeared in the CMSIS-mandated device headers. This just shows how woefully inexperienced both ARM and STM32 crew were.

JW