TS-7250-V3 Supervisory RTC

From embeddedTS Manuals

The supervisory microcontroller also provides a real time clock to backup system time when power is lost. This RTC features:

  • Unsigned 32-bit counter
  • Alarm to wake the board up from power off
  • Alarm can be configured as a slow watchdog
  • Battery detection
  • Offset support to tune rtc in ppb
  • Can retain time for ~8 years with the CR1632 battery

The typical RTC features are provided by the rtc-tssupervisor driver present in our kernels. This includes setting/getting the latest epoch time. On most distributions this requires no user interaction and systemd will sync the hardware clock when it syncs to a network time protocol (NTP) server.

To manually interact with the RTC the hwclock command is typically used:

# Set the RTC from the system time
hwclock --systohc

# Set the system time from the RTC
hwclock --hctosys

# Just print the RTC time, do not set either clock
hwclock --show

Our RTC also has several sysfs entries to support the nonstandard features:

### VBATT:
## Returns 0 or 1 to indicate if VBATT is > 1.8-2.0V
## Does not indicate a sufficient voltage to keep time, but can be used to detect
## no battery or a malfunctioning battery
## This is only checked on power on
cat /sys/class/rtc/rtc0/device/batt_present 

### RTC Alarm Wake up:
## The RTC can be used to wake the system after shutting down.
# The hwclock call can be skipped if system time is already set:
hwclock --systohc

# Takes the current time and adds 60 seconds
echo $(($(date +%s)+60)) > /sys/class/rtc/rtc0/device/alarm
echo 1 > /sys/class/rtc/rtc0/device/alarm_en
shutdown -h now
# The system will go into the low power state, and power back up when the alarm expires.

### RTC Alarm Watchdog:
## If its not being used for waking the system, the RTC alarm can be used to
## Reset the system if the time is not updated. This can be used as a very slow watchdog, setting
## a reset time of minutes/hours/days ahead instead of a typical 128 seconds a typical
## watchdog allows as the largest timer, but it is slower to feed so it should not be fed quickly.
## Keep in mind this reset is immediate and can corrupt any filesystems mounted read/write when the watchdog
## trips.
# The hwclock call can be skipped if system time is already set:
hwclock --systohc

# Takes the current time and adds 10 seconds
echo $(($(date +%s)+10)) > /sys/class/rtc/rtc0/device/alarm
echo 1 > /sys/class/rtc/rtc0/device/alarm_cause_reboot
echo 1 > /sys/class/rtc/rtc0/device/alarm_en

A typical RTC crystal is approximately ±20 ppm accurate which results in drift while the system is offline of approximately ±631 seconds per year. Our circuit, operating temperature, crystal age (~±3 ppm per year), all influence the accuracy of the crystal. An NTP client like chrony can be used to determine the PPM offset at a board at a given temperature, and the RTC can automatically apply this offset correction. This relies on having access to an accurate NTP server to calibrate the RTC.

Eg, on Debian:

apt-get update && apt-get install chrony -y

In case there was a previous offset applied which may affect the calibration:

echo 0 > /sys/class/rtc/rtc0/offset

Open /etc/chrony/chrony.conf, and add the line:

rtcfile /var/lib/chrony/rtcfile

Make sure there is no 'rtcsync' in the file since it cannot sync the hardware clock during this test, and that cannot be set with rtcfile.

Then restart chrony, and force a sync:

service chrony restart
chronyc makestep

At this step we must wait for the system clock to get in sync with the upstream NTP server. From our testing with a good network connection this can take 15-30 minutes until the RTC offset settles. From here we can query chrony for the RTC offset.

root@tsimx6:~# chronyc rtcdata
RTC ref time (UTC) : Fri Nov 18 13:38:36 2022
Number of samples  : 64
Number of runs     : 40
Sample span period : 254m
RTC is fast by     :    -0.198639 seconds
RTC gains time at  :   -21.674 ppm

In this example, the RTC is offset is -21.674 ppm. Linux expects this value to be in parts per billion, and it should be indicated what value will correct the crystal. Multiply the ppm by 1000 * -1 to get a value we can write to the offsets file. For example:

# Parse rtcdata and get the PPM value
# Eg, with the above example this is:
# PPM=-21.674
PPM=$(chronyc rtcdata | grep ppm | awk '{print $6}')
# Convert to parts per billion and invert the value to apply a correction.
# Eg, with the above example this is:
# PPB_CORRECTION=21674
PPB_CORRECTION=$(echo "scale=0; ${PPM}*-1000/1" | bc)

echo $PPB_CORRECTION > /sys/class/rtc/rtc0/offset

Once this is calibrated at a given temperature the ppm offset range can be calculated with:

For example, if the RTC is calibrated to the offset at 22C:

, or roughly ±139 ppm at 85 C.

To calculate the seconds drift per year with this PPM offset: