STM32 gotchas
71.RTC does not work - because of RCC_APBxENR.RTCAPBEN bit in some models

RTC in most STM32 is in the backup power domain (BD), i.e. powered from the switch between VDD and VBAT (controlled by the power voltage detector). To protect registers in the BD from inadvertent changes, there's a protection bit PWR_CR.DBP, which is cleared by reset, and has to be set by user before accessing any register in BD.

So, to enable the RTC, one has to go through a somewhat involved procedure - first enable PWR clock in RCC, then set PWR_CR.DBP, make sure that clock chosen for RTC (LSE or LSI or HSE/N) is up and running, make the selection of that clock in RCC_BDCR and enable RTC using the RTCEN bit in that same RCC_BDCR.

This gets RTC running in most STM32 models, but not in all. The problem is, that somewhere around 2016, ST started introducing a new enable bit, RCC_APBxENR.RTCAPBEN, which has to be set, otherwise there's no access to RTC registers from the processor.

[rant mode on] Btw. a nice way to notify the developer/user community of this kind of changes would be the Technical Updates, but ST stubbornly refuses to renew them. They supply us with ample marketing stuff without material content, instead finally renewed in 2024. [rant mode off]

The exact purpose of this bit is unclear. Apparently, it gates access to the non-backup part of RTC which interfaces to the APB bus, but the only conceivable reason to do that is to spare some power. It's hard to tell how much, as there's no APB-part-of-RTC-specific current in the current consumption tables in datasheets2.

To increase confusion, ST added this bit even to new models of already existing lines3; for example, this bit is present in 'F410, 'F412, 'F413/423, but it is absent in any of the "upper-line" 'F4 and, more notably, it's absent also in 'F401 and 'F411. Similarly, it's absent in the "original" 'F746, but it's present in newer 'F722/723 and 'F767; absent in "original" 'L476 but present in 'L496, the 'L4x2/4x3 and the 'L4+. And it's also present in all the newest lines, i.e. 'H7/'G0/'G4.

ST obviously attempted to mitigate consequences by making this bit being set by default after reset. But they failed to be consistent in this, too: in the 'F4 line, it's not set in 'F410; in the 'F7 it's not set in 'F722/732; in the new lines, it's not set in 'G0.

To add insult to injury, in the CMSIS-mandated device headers, for the 'F4, the symbol for this bit is called - logically and consistently - RCC_APB1ENR_RTCAPBEN, whereas in the 'F7, it's called RCC_APB1ENR_RTCEN, incorrectly and potentially confusing it for the RTCEN bit in RCC_BDCR.


1. In the ancient 'F1 family, which has a different backup-domain/RTC arrangement from all other STM32, there already was a similar enable bit, RCC_APB1ENR.BKPEN.

2. Together with RCC_APBxENR.RTCAPBEN bit, there's also a new low-power equivalent of that bit, RCC_APBxSMENR.RTCAPBSMEN or RCC_APBxLPENR.RTCAPBLPEN depending on the particular model ([rant mode on] as naming of low-power RCC enable registers is a mess, too, and so is their relationship to the "run-time" enable registers and default content [/rant mode off]). Purpose of this bit is even more unclear, as in low-power modes there's no processor available which would access the RTC through its APB interface, anyway.

3. ST otherwise has a very reasonable policy not to make "enhancements" to peripherals in a particular family (except when fixing what's clearly a hardware bug). For example, all the 'F4 models including the abovementioned "junior" models share the same relatively old SPI module which was in the first 'F4 - the 'F405/407, even if when most of other 'F4 models came out, the SPI featuring data packing had been already available on 'F0/'F3.