cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H743 RTC clock resets upon reset, but backup registers are retained?

ron239955_stm1
Associate III

I'm working on a custom board using an STM32H743IIT6. In general, the board is working, but I'm running into an issue with the RTC. The RTC is running accurately, but when I reset the board, the RTC resets. This happens even if I just terminate and restart the connected debugger, without disconnecting power. I've read through about 20 pages of RTC related posts here, and have checked all sorts of things:

- I commented out the Cube/HAL code that initializes the RTC to a specific value
- I checked the battery (1.6V with a 357 battery)
- I tried using a method described on this forum: After initializing the RTC, store a magic number to a backup register. If that magic number is found in the backup register on startup, don't initialize the RTC again. It didn't help. I took this code out, because the RTC itself has a flag that indicates whether it's been initialized or not, and the HAL code skips initialization if the RTC is already initialized, based on that flag.
- My init code looks like this:

(in main())

  __HAL_RCC_BKPRAM_CLK_ENABLE();
  HAL_PWR_EnableBkUpAccess();

(in MX_RTC_Init())

static void MX_RTC_Init(void)
{

  /* USER CODE BEGIN RTC_Init 0 */

  /* USER CODE END RTC_Init 0 */

  RTC_TimeTypeDef sTime = {0};
  RTC_DateTypeDef sDate = {0};

  /* USER CODE BEGIN RTC_Init 1 */

  /* USER CODE END RTC_Init 1 */

  /** Initialize RTC Only
  */
  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;
  hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
  if (HAL_RTC_Init(&hrtc) != HAL_OK)
  {
    Error_Handler();
  }

  /* USER CODE BEGIN Check_RTC_BKUP */
  // RJM: Don't set time and date here!
#if 0
  /* USER CODE END Check_RTC_BKUP */

  /** Initialize RTC and set the Time and Date
  */
  sTime.Hours = 0;
  sTime.Minutes = 0;
  sTime.Seconds = 0;
  sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sTime.StoreOperation = RTC_STOREOPERATION_RESET;
  if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
  {
    Error_Handler();
  }
  sDate.WeekDay = RTC_WEEKDAY_MONDAY;
  sDate.Month = RTC_MONTH_JANUARY;
  sDate.Date = 1;
  sDate.Year = 0;

  if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN RTC_Init 2 */
#endif

  // Wait for RTC to sync up with its shadow registers so that the first read actually works
  (void)HAL_RTC_WaitForSynchro(&hrtc);

  /* USER CODE END RTC_Init 2 */

}

I've run this code in the debugger, putting a breakpoint on the first line of SystemInit(). The RTC is clearly running, but even at that first line, I can see that the time and date have been reset. I can read and write the RTC time all I want while the board is running, and it'll keep time correctly. The RTC registers are correct up until the board resets.

The other notable thing is that the magic number that I put in backup register 0 is still there, even though I removed the code that sets this value, and had the board unplugged for a good while. So, it seems that Vbat is good, but somehow the clock isn't being retained.

Does anyone have any suggestions on how to track this issue down?

 

1 ACCEPTED SOLUTION

Accepted Solutions
ron239955_stm1
Associate III

As is often the case, it turned out to be my fault. I didn't realize that my bootloader had that Cube generated RTC boilerplate code that resets the date and time every time. This explains why power cycling the unit would reset the clock.

The debugger case is a little weirder. The bootloader wasn't supposed to run when I ran the code through the debugger, the entry point is different. Nonetheless, it seems to be retaining the time and date in debugger as well, so I'll call it solved for now.

Thanks for the responses!

 

View solution in original post

7 REPLIES 7
waclawek.jan
Super User

> when I reset the board, the RTC resets

How do you know, how do you observe that and what are exactly the symptoms?

> sDate.Year = 0;

Try some other year.

Other than that:

- read out and check/post RTC registers content

- don't use Cube/HAL functions for RTC if you are unsure what do they do, write your own

JW

This is the process I've been using:

  • Power up the board
  • Use the UI I've written for the board to edit the time & date
  • Interrupt using the debugger, and examine the RTC registers to make sure they're set correctly.
  • Set a breakpoint on the first line of SystemInit()
  • Terminate and restart the debugger
  • At the breakpoint, inspect the RTC registers and see that they've been reset (which happens every time). I can also observe that the RTC is still counting (from 0) and the backup register still has my magic value in it.

As long as I don't reset, the RTC runs fine and I can just let it run for a while, then check the time & date again and verify that the time is still correct.

FYI, all the time/date initialization code (sYear = 0; etc.) is #ifdefed out, I added #ifdefs in a way that won't get overwritten by Cube.

 

waclawek.jan
Super User

Set a different year than 0.

Do you use any bootloder? 

What kind of debugger are you using?

Does the RTC run out of LSE/crystal?

Place a data breakpoint (a.k.a. watchpoint) onto RTC_TR and reset. 

Show us the RTC registers content.

JW

Stop use debuger to reset . Is your design LSE or LSI ? Manage clock init on next starts .

I do have a bootloader in the first 128k of flash, but it doesn't execute at all in the debugger. The debugger jumps straight to the main code.

I'm using ST-Link V2 Isol and the most recent STM32CubeIDE for debugging

Yes, I'm using the typical LSE crystal & capacitors

I tried setting a watchpoint on RTC_TR and it doesn't trigger on reset, it triggers only when I set the clock through my UI.

Here are the registers after I set the time & date, and then immediately after resetting (first line of SystemInit()):

Screenshot 2025-09-17 at 10.30.24 AM.png

Screenshot 2025-09-17 at 10.35.15 AM.png

I was using the debugger to reset just so I could monitor the registers. Also, it would bypass my bootloader, in order to eliminate that variable. However, just power cycling the device results in the same outcome (the clock resets, backup registers do not).

 

 

 

ron239955_stm1
Associate III

As is often the case, it turned out to be my fault. I didn't realize that my bootloader had that Cube generated RTC boilerplate code that resets the date and time every time. This explains why power cycling the unit would reset the clock.

The debugger case is a little weirder. The bootloader wasn't supposed to run when I ran the code through the debugger, the entry point is different. Nonetheless, it seems to be retaining the time and date in debugger as well, so I'll call it solved for now.

Thanks for the responses!