STM32F4 / STM32H7 RTC HW BUG - Shadow registers for seconds and subseconds are inconsistent
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎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;
}
- Labels:
-
Bug-report
-
RTC
-
STM32F4 Series
-
STM32H7 Series
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-02-07 5:48 AM
ad LSI / LSE)
- My board runs with LSE which has SYNCH_PREDIV = 0xFF
- STM32Cube example for EVAL board is configured for LSI which has SYNCH_PREDIV = 0xF9
I have no tamper input activated.
Can @Community member​ send me​ your test SW for your F429 Disco? I will check it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-02-13 6:55 AM
We've discussed this further with @Jiřà Engelthaler​ off-forum and he made several observations:
- HAL_RTC_WaitForSynchro() as called above fails to wait for synchonization, as HAL_RTC_Init() (correctly) enables RTC write protection, and the RSF flag indicating shadow registers reload is write protected. Thus, writing zero to RSF is ignored and HAL_RTC_WaitForSynchro() sees RSF being (remaining) set and exits immediately. I've written this up in more detail here.
- HAL_RTC_WaitForSynchro(), if called immediately after a previous such call, waits 2 RTCCLK periods, which is 60us - and that's an unjustifiable time period just to read out RTC registers. Because of that, EngyCZ looked into ways of using BYPSHAD=1 . I've told about the method suggested by @Piranha​ in this thread (below "More Answers", reload if you don't see that). However, by experimenting, EngyCZ found out that while BYPSHAD=1, RTC SSR/TR/DR readouts can be not only mutually inconsistent, but they can be entirely incorrect (some bits flipped). Strict reading of RM revealed that this indeed is documented, although IMO entirely unexpected and unpleasantly surprising: "Additionally, the value of one of the registers may be incorrect if an RTCCLK edge occurs during the read operation.". RM provides solution, though, in repeated reading of all three registers until two successful readouts are identical in all three of them, or at least in SSR.
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-02-14 1:10 PM
In the end, I used the solution with BYPSHAD=1 because it doesn't have a problem with locking registers described in errata and doesn't have to wait an unreasonable amount of time (60 µs).
I tested this code 500,000x / 1sec for several tens of hours without any problem.
void ReadDateTime(void)
{
volatile u32 subsec, timereg, datereg;
volatile u32 subsec2, timereg2, datereg2;
do
{
datereg = RTC->DR;
timereg = RTC->TR;
subsec = RTC->SSR;
datereg2 = RTC->DR;
timereg2 = RTC->TR;
subsec2 = RTC->SSR;
} while (datereg != datereg2 ||
timereg != timereg2 ||
subsec != subsec2
);
... process subsec,timereg & datereg ...

- « Previous
-
- 1
- 2
- Next »