Teensy 4.1 RTC failure (low battery) detect

oimdave

New member
Hello,

On a Teensy 4.1 - is it possible to detect, on startup, if the RTC time is no longer valid due to the battery having run too low?

Best regards
 
You could use the timeStatus function as listed below from the time library.
Code:
timeStatus();                    // indicates if time has been set and recently synchronized
                                 // returns one of the following enumerations:
     timeNotSet                       // the time has never been set, the clock started on Jan 1, 1970
     timeNeedsSync                    // the time had been set but a sync attempt did not succeed
     timeSet                          // the time is set and is synced
 
I tried implementing this using timeStatus() as suggested, but after several months it has now been determined that this does *not* work.
Checking the code of Time.cpp shows that timeStatus() will always return "timeSet" once synchronized with the RTC *regardless* of the RTC being successfully backed up by a battery or not.
For clarity, when the battery runs down, the RTC will reset but timeStatus() will still return "timeSet".
From reading the core code I cannot see a suitable way to detect this, except checking the date - it gets reset to 2019-01-01 on battery loss.

To showcase - on a Teensy 4.1 that does not have a battery connected at all:

void setup() {
setSyncProvider([]() { return (time_t)Teensy3Clock.get(); });
if(timeStatus() == timeSet) {
// This code is always reached
}
}
 
The good news: the hardware supports this (supposedly).
The bad news: it doesn't look like the core software has fully implemented it. In fact I'm a bit confused how the rtc_set() function for teensy4 works at all, since it accesses registers and bits that aren't documented/marked as "reserved" in the IMXRT1060 reference manual.

What the manual does say is that there is a register SNVS_LPLVDR that should be written with 0x41736166 after the time (and other non-volatile state) has been set, then clear the "low-voltage event record" bit in SNVS_LPSR. The documentation of the SNVS_LPSR register makes no mention of this bit, so it's impossible to know which one it is! But you should at least be able to check if the value stored in SNVS_LPLVDR is still equal to 0x41736166, since it will change if there's been a low-power event. It won't tell you if a (charged) battery is currently connected since during regular operation the low-power stage runs from the main supply; it can only tell you if there has been a low-power event at some time.

(The SNVS_LPLVDR register appears to be named SNVS_LPPGDR in imxrt.h. I do not know why, nor do I completely trust the reference manual's documentation for the SNVS module - I suspect there is a large chunk of information hidden in the non-public security manual.)
 
Last edited:
Back
Top