cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 / STM32H7 RTC HW BUG - Shadow registers for seconds and subseconds are inconsistent

EngyCZ
Associate II

Hi.

I found a bug in RTC shadow registers inconsistency of seconds and subseconds.

Subseconds are counted from PREDIV_S down to 0. Then the seconds are incremented and subseconds start again from PREDIV_S.

Sometimes subseconds contain PREDIV_S value and seconds contain the old value (not incremented).

Example of correct sequence:

sec:22 subsec: 2

sec:22 subsec: 1

sec:22 subsec: 0

sec:23 subsec: 255

sec:23 subsec: 254

sec:23 subsec: 253

Example of incorrect sequence:

sec:22 subsec: 2

sec:22 subsec: 1

sec:22 subsec: 0

sec:22 subsec: 255 <-- Error

sec:23 subsec: 255

sec:23 subsec: 254

sec:23 subsec: 253

I have tested it with our own design and also with STM32H743I-EVAL board.

Call this in the loop:

RTC_TimeTypeDef Laststimestructureget;
int ErrCnt;
static void RTC_CalendarShow(void)
{
 RTC_DateTypeDef sdatestructureget;
 RTC_TimeTypeDef stimestructureget;
 
 HAL_RTC_WaitForSynchro(&RtcHandle);
 /* Get the RTC current Time */
 HAL_RTC_GetTime(&RtcHandle, &stimestructureget, RTC_FORMAT_BIN);
 /* Get the RTC current Date */
 HAL_RTC_GetDate(&RtcHandle, &sdatestructureget, RTC_FORMAT_BIN);
 
 if (Laststimestructureget.Hours != 0 &&
     Laststimestructureget.Seconds == stimestructureget.Seconds &&
     Laststimestructureget.SubSeconds < stimestructureget.SubSeconds)
 {
   ErrCnt++; // <--- Error detected
 }
 Laststimestructureget = stimestructureget;
}

//=======================

I found a note in STM32H7 Errata but the workaround doesn't work.

Chapter 2.11.1 https://www.st.com/resource/en/errata_sheet/es0392-stm32h742xig-and-stm32h743xig-device-limitations-stmicroelectronics.pdf

"If BYPSHAD = 0, read SSR again after reading SSR/TR/DR to confirm that SSR is still

the same, otherwise read the values again."

RTC_TimeTypeDef Laststimestructureget;
int ErrCnt;
static void RTC_CalendarShow(void)
{
 RTC_DateTypeDef sdatestructureget, sdatestructureget2;
 RTC_TimeTypeDef stimestructureget, stimestructureget2;
 
 do
 {
   HAL_RTC_WaitForSynchro(&RtcHandle);
   /* Get the RTC current Time */
   HAL_RTC_GetTime(&RtcHandle, &stimestructureget, RTC_FORMAT_BIN);
   /* Get the RTC current Date */
   HAL_RTC_GetDate(&RtcHandle, &sdatestructureget, RTC_FORMAT_BIN);
 
   HAL_RTC_WaitForSynchro(&RtcHandle);
   /* Get the RTC current Time */
   HAL_RTC_GetTime(&RtcHandle, &stimestructureget2, RTC_FORMAT_BIN);
   /* Get the RTC current Date */
   HAL_RTC_GetDate(&RtcHandle, &sdatestructureget2, RTC_FORMAT_BIN);
 } while (stimestructureget.SubSeconds != stimestructureget2.SubSeconds);
 
 if (Laststimestructureget.Hours != 0 &&
     Laststimestructureget.Seconds == stimestructureget.Seconds &&
     Laststimestructureget.SubSeconds < stimestructureget.SubSeconds)
 {
 ErrCnt++; // <--- Error detected
 }
 Laststimestructureget = stimestructureget;
}

12 REPLIES 12
TDK
Guru

nevermind, you're counting down. sorry for the noise.

If you feel a post has answered your question, please click "Accept as Solution".

Do you use RTOS? Isn't this routine called from multiple threads?

Don't you read RTC registers somewhere else in the program?

Try writing a minimal but complete compilable example exhibiting the problem and post.

JW

EngyCZ
Associate II

Hi @Community member​ 

No RTOS, reading time only on one place.

Step to reproduce:

Download STM32CubeH7 and replace

STM32CubeH7\Projects\STM32H743I-EVAL\Examples\RTC\RTC_TimeStamp

with this https://filetransfer.io/data-package/eaM3elQ1#link

Can anyone confirm this HW bug on his/her HW?

In RTC_CalendarShow(), ErrCnt is a local variable and is not initialized anywhere. This may give you the impression that the reads fail. [see below]

JW

[EDIT] Experimenting with a 'F429 and it appears that you may be up to something. Need more time.

>In RTC_CalendarShow(), ErrCnt is a local variable and is not initialized anywhere. This may give you the impression that the reads fail.

ErrCnt is a global variable that is initialized to 0. If you make a breakpoint on ErrCnt++ you will see the bug.

"Laststimestructureget.Hours != 0" is only for first-pass initialization. Yes, not nice but it is only for testing this bug.

Thank you for trying to confirm the bug.

...

int ErrCnt; // <---

static void RTC_CalendarShow(void)

{

...

> ErrCnt is a global variable

Indeed, I stand corrected.

JW

Can you please try replacing HAL_RTC_WaitForSynchro() by

     RTC->ISR &= (uint32_t)~(RTC_ISR_RSF | RTC_ISR_INIT);

     while ((RTC->ISR AND RTC_ISR_RSF) == 0);

Thanks,

JW

>Can you please try replacing HAL_RTC_WaitForSynchro() by

>     RTC->ISR &= (uint32_t)~(RTC_ISR_RSF | RTC_ISR_INIT);

>     while ((RTC->ISR AND RTC_ISR_RSF) == 0);

Hello. Thanks for the suggestion, but it doesn't help. I still see the RTC error.

I was not able to reproduce your problem.

I don't use 'H7 and don't use Cube, so I wrote my own version of the readout and run it on an 'F429 Disco, and as long as RSF is cleared/tested before each readout, the problem does not occur.

Also, the problem described in Errata would result in:

sec:22 subsec: 2

sec:22 subsec: 1

sec:22 subsec: 0

sec:23 subsec: 0 <-- Error

sec:23 subsec: 255

sec:23 subsec: 254

sec:23 subsec: 253

so what you observe has a different source.

Also, what puzzles me, the source you've provided appears to select LSI as clock source in main.h:

#define RTC_CLOCK_SOURCE_LSI

/*#define RTC_CLOCK_SOURCE_LSE*/

and the synchrononous prescaler for LSI appears to be 0xF9 rather than 0xFF

#ifdef RTC_CLOCK_SOURCE_LSI

#define RTC_ASYNCH_PREDIV   0x7F

#define RTC_SYNCH_PREDIV    0xF9

#endif

so I don't understand how could subseconds be 255. But maybe I'm overlooking something, as I've said, I don't use Cube/HAL.

Can you please read out and post RCC_BDCR and RTC registers content.

Also, please try to remove/block/disable the tamper interrupt. I believe you don't activate it (don't press the PC13-connected button), and I also don't see anything in the ISR code which would be suspicious, but just to be sure.

Thanks,

JW