cancel
Showing results for 
Search instead for 
Did you mean: 

Why an STM32L476's RTC counts more than 24h and don't icnreases the day

albert2
Associate II

I've designed a board that has a STM32L476.

This part is supplied using a triple system of dual battery + power ( when it is available)

We've manufactured more than 20k units of them and they are working ok

A few days ago 2 boards came back to our design lab that exhibit the following symptoms :

-> The RTC keeps counting past 23:59:59 until 39:59:59

-> Neither on 23h nor 39h rollover the day gets increased

-> When trying to set the time we get the following data:

If the time is less than 20h, 20h get added to it

Else the hour is correctly set

-> Rollover behavior don't changes

If we force a reset of the CPU, the problem dissapears.

More data:

-> The RTC access is done using HAL libs.

-> The RTC isn't reset when setting the date/time

We still have one untouched board for testing, but any try to use a debugger would trigger a CPU reset, making the probblem dissapear. (This is why we lost ont of the boards )

Does anybody have a hint about what the problem could be ?

32 REPLIES 32
OMira.1
Associate

Hi.

In my case, the CR register was corrupted. I will investigate why this happen and post here if relevant.

Regards,

Oliver

SZieg.11
Associate

Had the same problem and it turned out that the structure sTime that I called like this:

HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN);

had non-initialised members "StoreOperation" and "DayLightSaving" that corrupted the RTC CR in HAL_RTC_SetTime():

  /* Configure the RTC_CR register */

  hrtc->Instance->CR |= (uint32_t)(sTime->DayLightSaving | sTime->StoreOperation);

Didn't I write above:

> The most usual mode of error is an uninitialized locally/dynamically allocated init struct used in the call.

and my usual rants about adult programming vs. clicking for Cube/HAL.

I know this sounds rude, but I'm honestly sorry for folks falling to the same pitfall again and again.

JW

Well I first called HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN) and falsely assumed that it will initialise the sTime structure completely which is not the case. My bad.

If "adult programming" means not taking advantage of existing libraries and always starting from scratch every time, I keep going with the childish way 😉

No. Adult programming means avoiding undocumented and entirely superfluous "libraries".

JW

I was also facing the same problem with an STM8L152R8T6 MCU. And I sorted out it from this reply. THANK YOU

Seng Tak Goh
Associate III

Faced the same issue and managed to find the solution.

The problem is especially pronounced if you are using the init codes from HAL to initialise the RTC, because it basically skips updating the RTC_CR register in every init call after rebooting once the year value in the calendar is not 00 ...

And to update the RTC_CR register, you have to stop the RTC momentarily, and follow the sequence below:

  1. __HAL_RTC_WRITEPROTECTION_DISABLE(&hrtc);
  2. RTC_EnterInitMode(&hrtc);
  3. update RTC_CR by setting FMT to 0
  4. RTC_ExitInitMode(&hrtc);
  5. __HAL_RTC_WRITEPROTECTION_ENABLE(&hrtc);

Hope it helps.

albert2
Associate II

Hi again

Just in case anybody has the same problem :

The HAL lib doesen't mask the bit fields before writing the data to the RTC registers, so any stray 1s in the variables outside the defined fields will corrupt your RTC register's data.

The solution is to make sure all your struct fields are zero before filling in the needed data for the update.

Sorry not answering before, I though I had done it, really.

Albert

Hello @albert2​,

Thanks for your tip! I am suffering with this issue as well.

In my original code this was already done during struct declaration, but it runs only once:

RTC_TimeTypeDef sTime = {0};

RTC_DateTypeDef sDate = {0};

Now I have to initialize all struct members before every update:

sTime.Hours = 0;

sTime.Minutes = 0;

sTime.Seconds = 0;

sTime.SubSeconds = 0;

sTime.SecondFraction = 0;

sTime.TimeFormat = 0;

sTime.DayLightSaving = 0;

sTime.StoreOperation = 0;

HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD);

sDate.WeekDay = 0;

sDate.Month = 0;

sDate.Date = 0;

sDate.Year = 0;

HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD);

Do you think it is enough to solve the issue?

Best regards,

Iaran

> In my original code this was already done during struct declaration, but it runs only once:

>

> RTC_TimeTypeDef sTime = {0};

> RTC_DateTypeDef sDate = {0};

If these variables are defined as *local*, they are automatically allocated on the stack, and also the initialization is performed, every time the given function is called. And this initialization is equivalent of assigning 0 to all members of the given struct.

> Do you think it is enough to solve the issue?

If those structs were local, as I wrote above, they were already cleared when the function was called. Without seeing your particular function it's hard to tell, but it's quite likely that you did not change anything and that the root of your problem is elsewhere.

Start a new thread (perhaps giving a link to this one), stating what's your hardware, what is the problem, its symptoms and how do you observe them.

JW