cancel
Showing results for 
Search instead for 
Did you mean: 

RTC_ISR.INIT is not quite write protected by PWR_CR.DBP

waclawek.jan
Super User

In 'F427 (and all RTCv2-containing STM32), some RTC registers are write protected: prior writing to them, it is necessary:

1.enable backup domain access by setting PWR_CR.DBP

2. unlock a RTC write protection by writing two key values into RTC_WPR 

Breakpoint 4, main () at rrr.c:37873
37873     int main(void) {
(gdb) p /x *RTC
$91 = {TR = 0x150002, DR = 0x258717, CR = 0x20, ISR = 0x17, PRER = 0x7f00ff, WUTR = 0xffff, CALIBR = 0x0,
(gdb) p /x *RTC
$92 = {TR = 0x150007, DR = 0x258717, CR = 0x20, ISR = 0x17, PRER = 0x7f00ff, WUTR = 0xffff, CALIBR = 0x0,
  --- we see clock is running (RTC_CR.BYPSHAD = 1 so we don't need to worry about the readout locks)
(gdb) set RTC->ISR=RTC_ISR_INIT
(gdb) p /x *RTC
$93 = {TR = 0x150024, DR = 0x258717, CR = 0x20, ISR = 0x17, PRER = 0x7f00ff, WUTR = 0xffff, CALIBR = 0x0,
  --- we see writing RTC_ISR_INIT had no effect, we haven't removed either of the protections
(gdb) set RCC->APB1ENR|=RCC_APB1ENR_PWREN
(gdb) set PWR->CR|=PWR_CR_DBP
(gdb) set RTC->ISR=RTC_ISR_INIT
(gdb) p /x *RTC
$96 = {TR = 0x150244, DR = 0x258717, CR = 0x20, ISR = 0x17, PRER = 0x7f00ff, WUTR = 0xffff, CALIBR = 0x0,
  --- still no change, we've removed only the first protection, the second holds
(gdb) set RTC->WPR=0xCA
(gdb) set RTC->WPR=0x53
(gdb) p /x *RTC
$97 = {TR = 0x150339, DR = 0x258717, CR = 0x20, ISR = 0x17, PRER = 0x7f00ff, WUTR = 0xffff, CALIBR = 0x0,
  --- protection removed but we haven't written to protected registers yet
(gdb) set RTC->WUTR=0x1234
(gdb) p /x *RTC
$98 = {TR = 0x150354, DR = 0x258717, CR = 0x20, ISR = 0x17, PRER = 0x7f00ff, WUTR = 0x1234, CALIBR = 0x0,
  --- OK so this went through
(gdb) set RTC->ISR=RTC_ISR_INIT
(gdb) p /x *RTC
$99 = {TR = 0x150412, DR = 0x258717, CR = 0x20, ISR = 0xd7, PRER = 0x7f00ff, WUTR = 0x1234, CALIBR = 0x0,
  --- and so did the RTC_ISR.INIT write, as indicated by both that and the INITF bits being set

But, did you know, that lock #2 is *not* reset by *system reset*, only by backup-domain reset (i.e. removing battery/power from VBAT in the usual case of using RTC) (yes, the lock is renewed also by writing an invalid value to RTC_WPR, which is what software ought to do etc. but that's not the point here).

Still, after reset the PWR_CR.DBP protection holds, even if we forget to explicitly lock the RTC_WPR protection, right?

Turns out, not quite.

Following sequence is *after a system reset* (which resets PWR_CR.DBP thus sets that protection), but without removing the RTC_WPR protection before that:

Breakpoint 4, main () at rrr.c:37873
37873     int main(void) {
(gdb) p /x *RTC
$100 = {TR = 0x150416, DR = 0x258717, CR = 0x20, ISR = 0x17, PRER = 0x7f00ff, WUTR = 0x1234,
(gdb) set RTC->WUTR=0x4321
(gdb) p /x *RTC
$101 = {TR = 0x150425, DR = 0x258717, CR = 0x20, ISR = 0x17, PRER = 0x7f00ff, WUTR = 0x1234,
  --- i.e. the PWR_CR.DBP protection holds against this write
(gdb) set RTC->ISR=RTC_ISR_INIT
(gdb) p /x *RTC
$102 = {TR = 0x150443, DR = 0x258717, CR = 0x20, ISR = 0x97, PRER = 0x7f00ff, WUTR = 0x1234,
  --- but not against the RTC_ISR.INIT write... still, INIT mode is not entered, as indicated
      by RTC_ISR.INITF not being set, also clock continues to run (see below)
(gdb) set RCC->APB1ENR|=RCC_APB1ENR_PWREN
(gdb) set PWR->CR|=PWR_CR_DBP
(gdb) p /x *RTC
$103 = {TR = 0x150541, DR = 0x258717, CR = 0x20, ISR = 0xd7, PRER = 0x7f00ff, WUTR = 0x1234,
  --- and after removing the PWR_CR.DBP protection, INITF gets set, so INIT mode is entered 
      without further need to write into RTC_ISR.INIT - to verify that that indeed happens,
      I waited a couple of seconds to see whether the clock stopped...
(gdb) p /x *RTC
$104 = {TR = 0x150541, DR = 0x258717, CR = 0x20, ISR = 0xd7, PRER = 0x7f00ff, WUTR = 0x1234,
  --- so yes, it did, and also the following write
(gdb) set RTC->TR=0x150000
(gdb) p /x *RTC
$105 = {TR = 0x150000, DR = 0x258717, CR = 0x20, ISR = 0xd7, PRER = 0x7f00ff, WUTR = 0x1234,
  --- went through, so this is a genuine INIT mode

So, while RTC_ISR.INIT is indeed protected by RTC_WPR, it is *not* protected by PWR_CR.DBP.

JW

0 REPLIES 0