STM32 gotchas
197. Problems with day rollover in 'F1 RTC, if SPL/Cube are used

In the primordial STM32F1xx family, RTC is implemented in a very simple manner. Basically, timekeeping consists just from a prescaler (which is to scale down the input clock to 1Hz) and a single 32-bit counter1. There is no calendar functionality, i.e. hardware does not count minutes-hours-days-etc. separately.

The logical and most straightforward way to tackle this situation is to use functions from the standard C library prototyped in <time.h> to calculate calendar data from the counter, and vice versa. However, ST chose a different and a slightly bizarre approach in their libraries (both the older SPL and the newer Cube/HAL): only time is kept in RTC's counter; date is maintained in one of the backup registers (which are in the same VBAT domain as RTC). When time is read out, that routine check, if time is below 24 hours, and if not, it subtracts 24 hours' worth of seconds from the RTC's counter and increments date in the backup register.

While this procedure may indeed maintain calendar for most of the applications, it also opens opportunity for various bugs. Users of ST libraries for RTC in 'F1 in the past years complained of:

These problems are certainly fixable and/or may have been fixed; but using the long proven methods mentioned above simply avoids this kind of problems.


1. The 32-bit counter is split to two 16-bit registers, as it probably originates from some older 16-bit ST microcontrollers (similarly to some other STM32 peripherals). This results in inconvenience when reading it, as there's also no hardware mechanism for atomic readout.