cancel
Showing results for 
Search instead for 
Did you mean: 

Please provide correct RTC time readout examples in Cube

RTC examples in Cube e.g. here provide an example how to read out time from RTC.

However, these examples are incorrect in several ways, resulting in inconsistent subseconds/time/date readout. This is mostly hidden by the fact that subseconds are not displayed in these examples and the time-to-date inconsistency would demonstrate itself only on date rollover, which under "normal" setup is rare.

Nevertheless, it is a reasonable expectation that ST provides entirely correct examples.

First problem is, that the examples don't take into account the RTC calendar registers are not locked properly erratum. It can result in the following sequence:

sec:22 subsec: 1

sec:22 subsec: 0

sec:23 subsec: 0 <-- Error

sec:23 subsec: 255

sec:23 subsec: 254

Examples ought to follow the procedure outlined in the erratum - reading SSR (or both time and date) twice, and loop if they don't match.

Second problem was discovered by @Jiří Engelthaler​ and results in a different sequence:

sec:22 subsec: 1

sec:22 subsec: 0

sec:22 subsec: 255 <-- Error

sec:23 subsec: 255

sec:23 subsec: 254

This problem results from the fact, that when BYPSHAD=0, it is necessary to wait at least one RTCCLK periods (which is quite a lot, typically cca 30us) between reading RTC_DR (i.e "unlocking" TR/DR) and subsequent reading of time/date, otherwise we run into risk of reading the "old locked" TR/DR values (while SSR is never locked so it might be read as decremented/reloaded). This *is* documented in RM ( In case the software makes read accesses to the calendar in a time interval smaller than 1 RTCCLK period: RSF must be cleared by software after the first calendar read, and then the software must wait until RSF is set before reading again the RTC_SSR, RTC_TR and RTC_DR registers.) but the example fails to enforce this.

So it may appear that adding HAL_RTC_WaitForSynchro() before HAL_RTC_GetTime() would fix the problem, but as EngyCZ found out the hard way, it does not. It is because Cube (and thus the example) correctly use the RTC write protection (through using __HAL_RTC_WRITEPROTECTION_ENABLE() before the correct exit from HAL_RTC_Init()), and while write protection is on, write of zero into the RSF flag in HAL_RTC_WaitForSynchro() is ignored, thus HAL_RTC_WaitForSynchro() exits immediately. To be fair, this *is* documented for HAL_RTC_WaitForSynchro(), except easy to overlook. Thus, the example ought to incorporate this bit, too.

I personally would suggest incorporating all these directly into a new "time-and-date readout" function in Cube/HAL (new function means the old API won't be broken), which would provide a correct time/date under all circumstances, while using best practices (eg. disabling write protection only for the least necessary time, as in testing RTC update, where write protection ought to be disabled only for clearing RSF and then reenabling it again *before* the loop waiting for RSF to be set by hardware).

JW

@Amel NASRI​ 

1 REPLY 1

Also, please incorporate the Erratum in question into AN4759 and provide clean register-based examples of proper readouts for the v2 RTC for both BYPSHAD=0 and BYPSHAD=1 (discussing merits and drawbacks) therein.

JW