-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
stm32_common/periph/rtc: current implementation broken/poor accuracy #8746
Comments
+1. Resetting RTC_DR and RTC_TR at boot time is not a good idea, but checking if the RTC has been initialized or not before going through Did you already work on fixes for these issues? |
Currently I've fixed it by guarding everything in
There may be more (an improved test would show), but with this I can at least get ~12ppm, with calibration even below that. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions. |
This sound related to a problem I currently have when using I added some LED toggling to see where my app is and according to this it hangs right in or after @MichelRottleuthner do you plan to open a PR with your fixes, or how do we proceed - to me this seems a severe problem. Specifically for use-cases as you described, i.e. RTC with low power stuff. |
I almost forgot this one, good to have that verbose description^^ Yeah we should just open a PR. For handling it from within the init function I see the following points: +no interface change needed (the current documentation is not violated) |
Description
In the current implementation
rtc_unlock()
doesn't, like the name indicates, only unlocks the rtc but also enters init mode. Looking at the datasheet this is not a really good idea. Refering to "Calendar initialization and configuration":1. Set INIT bit to 1 in the RTC_ISR register to enter initialization mode. In this mode, the
calendar counter is stopped and its value can be updated.
(...)
5. (...) Exit the initialization mode by clearing the INIT bit. The actual calendar counter value is
then automatically loaded and the counting restarts after 4 RTCCLK clock cycles.
So every operation that calls
rtc_unlock()
will delay the rtc by the time the operation itself takes, plus at minimum the 4 RTCCLK cycles. This is for example true forrtc_set_alarm()
. So if you happen to use the alarm feature to wake up every few seconds your time reference will become borked up pretty quickly.The next problem comes up when using the rtc in combination with pm. This is only visible when your application makes use of power modes that issue a system reset when exiting this mode (namely Shutdown mode in my case). On reset
rtc_init()
, which is only conditioned by MODULE_PERIPH_RTC, is always called if the rtc is available. Since this is part ofperiph_init()
it also doesn't help to disable auto_init.One thing that was really nasty to debug here, came from the fact that
rtc_init()
isn't actually resetting the RTC_DR and RTC_TR registers. So testing if the rtc works together with pm looks "working ok" if you only observe the system over a short period of time, because thertc_init()
will effectively only loose the SSR (sub second regiser).What do you think about using the INITS flag in RTC_ISR to only init the rtc if it wasn't already initialized before?
The fact that the current tests/periph_rtc doesn't highlight any of the problems brings me to the conclusion that the test needs improvement.
I'd like to exchange opinions on the following thoughts:
IMO It's absolutely necessary to add some quantifiable output on the accuracy. For example sntp could be used as a reference here.
This should also be tested with pm&rtc - particularly since rtc is a feature that will often be combined with low power modes.
Another thing that came to my mind: is it intentional that the rtc api doesn't provide functions to perform calibration?
Steps to reproduce the issue
taking tests/periph_rtc/ as starting point:
add
USEMODULE += pm_layered
to tests/periph_rtc/Makefileadd
#include "pm_layered.h"
to main.creplace main() with this:
Expected results
Accuracy near the oscillator specifications (e.g. <20 ppm on nucleo-l476 in my case).
Actual results
Accuracy dependent on application beaviour (duty cycle etc.) and for some use cases in fact abysmal.
Watching pyterms time stamps for the above code gives an error of ~220ms per minute. This translates to 3666 ppm.
Fun fact: this is more than seven times greater than the maximum this chips calibration feature could compensate, if it were implemented ;)
Versions
current master
The text was updated successfully, but these errors were encountered: