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-07 05:48 AM
ad LSI / LSE)
I have no tamper input activated.
Can @Community member send me your test SW for your F429 Disco? I will check it.
2022-02-13 06:55 AM
We've discussed this further with @Jiří Engelthaler off-forum and he made several observations:
JW
2022-02-14 01: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 ...