stm32duino / STM32RTC

Arduino RTC library for STM32.
127 stars 48 forks source link

Adds date retention in the backup memory for the stm32f1xx #58

Closed FRASTM closed 2 years ago

FRASTM commented 2 years ago

This PR adds a RTC date retention for the stm32F1 MCUs. This new feature is saving/restoring the date (year, month, day, weekday) in the backup memory of he MCUs. On the stm32F1, the Date is not present in the RTC peripheral but computed by the RTC driver. The BackUp memory of the stm32F1 is powered by the VBat when VDD is switched off. It is not altered by the system Reset.

Each one-byte element of the RTC Date (DateToUpdate) is well placed in two contiguous 16bit backup registers (RTC_BKP_DATE, RTC_BKP_DATE + 1). The registers are arbitrary selected to store the date and can be easily changed in the rtc.hto choose other memory positions.

Moreover, for the stm32F1, the 'reset' flag is now available in the RTC::begin to reset the content of the backUp register. Note that the reset value of the RTC date in the stm32F1 is '01/01/2000'

A simple RTC examples/backupRTC is given to demonstrate this feature (--> test with different the reset_bkup bool values).

This PR is inspired by the https://github.com/stm32duino/STM32RTC/pull/41

Fixes #32

Signed-off-by: Francois Ramu francois.ramu@st.com

FRASTM commented 2 years ago

update after review: two 16 bit registers LL_RTC_BKP_DR6 & LL_RTC_BKP_DR7 are reserved in the stm32F1 backUp memory to keep the date (RTC_BKP_DATE). Function getBackupRegister/setBackupRegister are used to access ths bakup mem.

FRASTM commented 2 years ago

updates the README.md

FRASTM commented 2 years ago

rename sketch to F1RTCDateRetention.ino change print text with "\n"

FRASTM commented 2 years ago

rebase after merge of PR #57

bxparks commented 2 years ago

Just want to thank you for this PR. I reviewed the code out of curiosity and it looks good.

For future reference for other people who may come here and wonder, I verified that the code actually handles the 2 edge cases that I was worried about:

1) The microcontroller is powered-down during a transition from 23:59:59 to 24:00:00 the next day, and 2) The microcontroller is powered-down for more than 24h.

Both cases are handled because the RTC code in the HAL (stm32f1xx_hal_rtc.c) performs a renormalization of the 32-bit RTC counter every time HAL_RTC_GetTime() is called. The RTC counter counter_time is normalized to be an offset from 00:00:00 of the current date. If more than 24h has passed from the last time HAL_RTC_GetTime() was called, then the the date components are adjusted forward by the number of days that have passed. So if the microcontroller is powered down for more than 24hours, then upon reboot, the date components are restored from the backup registers, fed into the HAL, then HAL_RTC_GetTime() will adjusted the date forward by the whole number of days indicated by the RTC counter. Leap years are accounted for correctly, including those divisible by 400.

If I understand the HAL code correctly, I think there might be a small data-race condition inside HAL_RTC_GetTime(), but it's probably not worth worrying about. In the few microseconds between the call to RTC_ReadTimeCounter() and the call to RTC_WriteTimeCounter() that writes the renormalized counter_time, the hardware RTC could have incremented the RTC_CNT registers by 1. I'm not sure that there's anything that can be done about this under the current architecture of HAL for the STM32F1.

bxparks commented 2 years ago

It occurred to me last night that RTC_WriteTimeCounter() is called only if counter_time is greater than 24h. So the race condition occurs only during that transition. I wrote a test program to try to trigger this race condition by calling HAL_RTC_GetTime() as fast as possible (around 150,000 times/second in my tests) during the 23:59:59 to 24:00:00 transition, but I could not trigger it. The probability of triggering this race condition is so small, and the impact (the loss of one second) is minor, so it is not worth worrying about.