Content originally posted in LPCWare by ollopa on Mon Jan 18 17:07:55 MST 2016
Quote:
and has commented out bits which clear the clock value (isn't that the point of a battery-backed RTC, to keep the value?) and disable calibration (why would you?).
I don't think these changes are as sensible as they seem.
[list=1]
[*]The reset doesn't reset the time and date registers, it resets the counter divider that generates 1Hz from 32kHz.
[*]Calibration is a manual process whereby you measure the actual number of counts required to elapse 1 second and load a calibration value into a register to correct for the difference. You don't want to enable calibration (really compensation) without a meaningful value loaded into the calibration compare register. Doing so will just lead to bad results.
[/list]
If you actually read the datasheet:
Quote:
1 CTCRST CTC Reset
0 No effect.
1 When one, the elements in the internal oscillator divider are
reset, and remain reset until this bit is changed to zero. This is
the divider that generates the 1 Hz clock from the 32.768 kHz
crystal. The state of the divider is not visible to software.
Look up CALVAL and CALDIR to understand why you don't want to enable calibration unless you've actually measured and calculated a value for CALVAL.
What NXP doesn't make clear is when you do and don't need to perform this initialization [s]and how you can detect it[/s].
It's clear from the code and the datasheet that running through the initialization routine will disturb the 1Hz timing both by temporarily pausing it and resetting the counter divider. This means the more often you restart the device, the more time slip the RTC will suffer.
It's also intuitive that the 32kHz/1Hz oscillator keeps running off the battery when the CPU is powered down, so I don't see any need to repeat the initialization sequence when powering the CPU back up. A quick test shows empirically that my assumption appears correct -- once the clock is set up and battery-backed, I can remove the calls to Chip_RTC_Init(LPC_RTC) and Chip_RTC_Enable(LPC_RTC, ENABLE) and the RTC continues to keep correct time across CPU power cycles. What's more, the long multi-second wait during initialization goes away.
So how can we detect when power is lost and the RTC clock has stopped? We need to avoid accessing the registers when the clock is stopped or else the CPU may halt, and if we know the clock is running then we can avoid disturbing the clock generator and RTC timing.
On Edit, here is the answer from the datasheet:
Quote:
To confirm that the 32 kHz clock is running, read the Alarm timer counter register (DOWNCOUNTER, see Table 866), which counts down from a preset value using the 1024 Hz clock signal derived from the 32 kHz oscillator.
So it will take about 1ms at startup to determine if the 32kHz oscillator is running. If it is, there is no need to repeat the long initialization code that disturbs the 1Hz timing. If it is not running, start it up and wait 2 seconds before accessing any RTC registers.