# RTC (Real Time Clock)

Setup a good time source. The built in RTC for Allwinner chips lacks a battery on the Orange Pi boards and has a higher drain than others. Go with the others for the better power use

## Inspiration / Further Reading

- [https://learn.adafruit.com/adding-a-real-time-clock-to-raspberry-pi?view=all](https://learn.adafruit.com/adding-a-real-time-clock-to-raspberry-pi?view=all)
- [https://www.raspberrypi.org/forums/viewtopic.php?t=20619](https://www.raspberrypi.org/forums/viewtopic.php?t=20619)
- [https://www.raspberrypi-spy.co.uk/2015/05/adding-a-ds3231-real-time-clock-to-the-raspberry-pi/](https://www.raspberrypi-spy.co.uk/2015/05/adding-a-ds3231-real-time-clock-to-the-raspberry-pi/)
- [https://unix.stackexchange.com/questions/246605/how-can-the-link-target-of-dev-rtc-be-changed](https://unix.stackexchange.com/questions/246605/how-can-the-link-target-of-dev-rtc-be-changed)
- [https://www.raspberrypi.org/forums/viewtopic.php?t=85683](https://www.raspberrypi.org/forums/viewtopic.php?t=85683)

## Clocks

### Suggestions

- Use cheapest for ultra portable builds
- Use most accurate for mostly permanent builds (RV/similar)
- Use most common rarely used (unless you have good reason, don't)

### Hardware

- [DS1307 (most common | Link)](https://www.adafruit.com/product/3296)
- [PCF8523 (cheapest | Link)](https://www.adafruit.com/product/3295)
- [DS3231 (most accurate | Link](https://www.adafruit.com/product/3013)

### Key Note

This guide assumes the PCF8523. You'll need to adjust lightly for the DS3231 or DS1307.

## Initial Setup

``` bash
armbian-config # enable i2c busses
systemctl reboot # reboot to enable bus(es)
apt install i2c-tools # install tools
i2cdetect -l # check to ensure busses are present
i2cdetect -y 0 # 0 for orange pi zero ; 1 for recent pi's
modprobe rtc-pcf8523 # load the proper rtc module (adafruit cheap model)
echo pcf8523 0x68 > /sys/class/i2c-adapter/i2c-0/new_device # setup device so it's seen
dmesg | grep rtc # verify the kernel sees the rtc
ls /dev/rtc* # should have rtc1
hwclock -f /dev/rtc1 --systohc -D --noadjfile --utc # set / init the rtc
hwclock -r -f /dev/rtc1 # read the value from the rtc
hwclock -w -f /dev/rtc1 # write the current time to the rtc
apt remove --purge fake-hwclock # purge the fake hwclock as we have a real one now

```

## Udev Rules

``` bash
# setup udev rule to setup the new rtc as the primary for the board
# `udevadm info -a -p /sys/class/rtc/rtc1` gets the details for the below entries
cat > /etc/udev/rules.d/99-rtc1.rules <<EOF
KERNEL=="rtc1", SUBSYSTEM=="rtc", DRIVER=="", ATTR{name}=="rtc-pcf8523 0-0068", SYMLINK="rtc", MODE="0666"
EOF
```

## Internal RTC Adjustments

A systemd service to ensure the internal RTC is 'close' to the real time w/o battery.

``` bash

# Set the internal RTC on shutdown to match ntpified time
cat > /etc/systemd/system/rtc0-shutdown-fix.service <<EOF
[Unit]
Description=Set sunxi internal RTC on shutdown
DefaultDependencies=no
Before=shutdown.target reboot.target halt.target

[Service]
Type=oneshot
ExecStart=/sbin/hwclock --systohc -D --noadjfile --utc -f /dev/rtc0

[Install]
WantedBy=halt.target reboot.target shutdown.target
EOF

systemctl daemon-reload
systemctl enable rtc0-shutdown-fix

# Trick for getting the early boot time 'close'
cat > /etc/systemd/system/rtc0-online.service <<EOF
[Unit]
Description=Set system clock to rtc0
DefaultDependencies=no
Before=time-sync.target

[Service]
Type=oneshot
ExecStart=/sbin/hwclock -s -f /dev/rtc0

[Install]
WantedBy=time-sync.target
EOF

systemctl daemon-reload
systemctl enable rtc0-online


```

## External RTC On Boot

A systemd unit that brings the external RTC online during boot

``` bash

cat > /etc/systemd/system/rtc1-online.service <<EOF
[Unit]
Description=Setup rtc1 as primary clock
DefaultDependencies=no
Before=time-sync.target
After=rtc0-online.service

[Service]
Type=oneshot
ExecStart=/bin/sh -c '/sbin/modprobe rtc_pcf8523 \
&& echo pcf8523 0x68 > /sys/class/i2c-adapter/i2c-0/new_device \
&& /sbin/hwclock -s -f /dev/rtc1'

[Install]
WantedBy=time-sync.target
After=rtc0-online
EOF

systemctl daemon-reload
systemctl

```

## Misc Notes

``` bash

date # Wait for this to get sync'd via whatever ntp you're doing
hwclock -r -f /dev/rtc1 # Verify this isn't right
hwclock -w -f /dev/rtc1 # Write ntp system time -> rtc
hwclock -r -f /dev/rtc1 # Verify the write worked
ls -l /dev/rtc* # Check rtc dev node is present
hwclock -r -f /dev/rtc1 # read time from external rtc
hwclock -r -f /dev/rtc0 # read time from internal rtc

```
