2022-02-03 12:38 PM
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;
}
2022-02-03 01:49 PM
nevermind, you're counting down. sorry for the noise.
2022-02-04 12:31 AM
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
2022-02-04 10:55 AM
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?
2022-02-04 02:24 PM
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.
2022-02-04 10:02 PM
>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)
{
...
2022-02-05 01:54 AM
> ErrCnt is a global variable
Indeed, I stand corrected.
JW
2022-02-06 10:37 AM
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
2022-02-07 01:52 AM
>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.
2022-02-07 04:19 AM
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