STM32F4 / STM32H7 RTC HW BUG - Shadow registers for seconds and subseconds are inconsistent
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;
}