[How to] install RTC hardware clock pcf8563 (I2c)

this device operates at 3.3V (from 3 to 5V) and does not need a voltage level shifter , so you can connect SDA and SCL pins of this device directly to the correspondent Gpio pins of the router.
The pcf8563 is more stable and precise than DS1302 or DS1307, also it is fully supported by OpenWRT 17.xx and 18.xx.

- Prerequisites: install I2c interface

see my previous posts about I2c here:
[How To] Add 20x4 LCD (HD44780) to a OpenWrt router via I2C)
[How To] Add barometric pressure and temperature sensor to Openwrt
[How to] connect a DHT12 I2c humidity and temperature sensor to OpenWrt and display values on LCD

I2c Notes: you can connect many I2c devices to the same bus (SDA and SCL), just wire them in parallel, but pay attention to the total current consumption and operating voltage of each device, you cannot connnect in parallel devices operating at different voltages!
Important: for I2c devices operating at 5V, you need a GPIO voltage level converter from 3.3 to 5V like this one for Raspberry:


Level converter connections:

LV = 3.3V from the router
HV = 5V from the router
GND = GND from the router
2xTX1 = SCL and SDA from the router
2xTX0 = SCL and SDA to the I2c device(s)


- Instructions:

opkg update
opkg install kmod-rtc-pcf8563
opkg install hwclock
opkg install ntpclient #(optional)

reboot the router

check the I2c hw address of the RTC:

i2cdetect -y 0

you should get "0x51"

now edit "/etc/rc.local" file and add the following line after the I2c configuration lines (insmod):

/bin/echo pcf8563 0x51 > /sys/bus/i2c/devices/i2c-0/new_device

reboot again

now you can set the RTC with the following commands:

Usage: hwclock [-r|--show] [-s|--hctosys] [-w|--systohc] [--systz] [--localtime] [-u|--utc] [-f|--rtc FILE]

Query and set hardware clock (RTC)

-r	Show hardware clock time
-s	Set system time from hardware clock
-w	Set hardware clock from system time
--systz	Set in-kernel timezone, correct system time
	if hardware clock is in local time
-u	Assume hardware clock is kept in UTC
--localtime	Assume hardware clock is kept in local time
-f FILE	Use specified device (e.g. /dev/rtc2)

- Configuration:

get current time from internet:

/usr/sbin/ntpclient -l -h ntp1.ien.it -c 1 -s &

write the current time obtained from internet into the RTC:

hwclock -w

(you may change "ntp1.ien.it" with your preferred ntp server)

notes:

to set system time from hardware clock at boot, add the following line at the end of "/etc/rc.local" file (just before the "exit 0" line:

/sbin/hwclock -s

to read the current time from RTC:

hwclock -r

example:

root@OpenWrt:~# hwclock -r
2019-08-29 08:45:53.221025+02:00

To set the RTC with a custom time (without internet connection):

hwclock --set --date="2019-08-29 06:00:12"  --ut
6 Likes

if you don't want to open your router and solder any pin inside, simply buy an USB to I2C dongle and install kmod-i2c-tiny-usb :grinning:

That is not really necessary as this supposed to be done by /etc/init.d/sysfixtime script on startup.
However, since the RTC device is not yet available at the beginning of the boot process, the script above will fail. To fix this I had to add a line to /etc/rc.local:

/etc/init.d/sysfixtime start
2 Likes

First of all thanks for the topic, and thanks for the rc.local + sysfixtime hint.


Looks like the START=00 is still too early for /etc/init.d/sysfixtime to catch /dev/rtc0, as /sbin/kmodloader is called from /etc/init.d/boot:

# grep kmod -r /etc/rc.d/S*
/etc/rc.d/S10boot:	/sbin/kmodloader

/etc/rc.local trigger works nicely (added extra logging):

# logread |grep rtc
Fri Oct 15 11:38:56 2021 kern.info kernel: [    1.178812] hctosys: unable to open rtc device (rtc0)
Fri Oct 15 11:38:56 2021 kern.warn kernel: [    6.637920] rtc rtc0: invalid alarm value: 2021-10-09T28:06:00
Fri Oct 15 11:38:56 2021 kern.info kernel: [    6.639046] rtc-pcf8563 0-0051: registered as rtc0
Fri Oct 15 11:40:00 2021 user.notice sysfixtime: loaded 'Fri Oct 15 11:40:00 UTC 2021' from /dev/rtc0

It triggers at ~8 seconds of uptime (~2 seconds after loading modules):

# logread |grep rtc -A 5 -B 3
Fri Oct 15 11:38:56 2021 kern.debug kernel: [    1.149692] meson-gx-mmc ffe07000.mmc: Looking up vmmc-supply from device tree
Fri Oct 15 11:38:56 2021 kern.debug kernel: [    1.149736] meson-gx-mmc ffe07000.mmc: Looking up vqmmc-supply from device tree
Fri Oct 15 11:38:56 2021 kern.info kernel: [    1.149799] meson-gx-mmc ffe07000.mmc: allocated mmc-pwrseq
Fri Oct 15 11:38:56 2021 kern.info kernel: [    1.178812] hctosys: unable to open rtc device (rtc0)
Fri Oct 15 11:38:56 2021 kern.info kernel: [    1.194906] EXT4-fs (mmcblk0p2): mounted filesystem without journal. Opts: (null)
Fri Oct 15 11:38:56 2021 kern.info kernel: [    1.196773] VFS: Mounted root (ext4 filesystem) readonly on device 179:2.
Fri Oct 15 11:38:56 2021 kern.info kernel: [    1.203616] Freeing unused kernel memory: 384K
Fri Oct 15 11:38:56 2021 kern.info kernel: [    1.248852] Run /sbin/init as init process
Fri Oct 15 11:38:56 2021 user.info kernel: [    1.305853] init: Console is alive
--
Fri Oct 15 11:38:56 2021 kern.notice kernel: [    6.617603] random: crng init done
Fri Oct 15 11:38:56 2021 kern.notice kernel: [    6.618000] random: 4 urandom warning(s) missed due to ratelimiting
Fri Oct 15 11:38:56 2021 kern.info kernel: [    6.633216] usbcore: registered new interface driver r8152
Fri Oct 15 11:38:56 2021 kern.warn kernel: [    6.637920] rtc rtc0: invalid alarm value: 2021-10-09T28:06:00
Fri Oct 15 11:38:56 2021 kern.info kernel: [    6.639046] rtc-pcf8563 0-0051: registered as rtc0
Fri Oct 15 11:38:56 2021 kern.info kernel: [    6.645812] usbcore: registered new interface driver usbhid
Fri Oct 15 11:38:56 2021 kern.info kernel: [    6.649132] usbhid: USB HID core driver
Fri Oct 15 11:38:56 2021 kern.info kernel: [    6.656185] xt_time: kernel timezone is -0000
Fri Oct 15 11:38:56 2021 kern.info kernel: [    6.663253] PPP generic driver version 2.4.2
Fri Oct 15 11:38:56 2021 kern.info kernel: [    6.663707] NET: Registered protocol family 24
--
Fri Oct 15 11:38:57 2021 user.notice ucitrack: Setting up /etc/config/system reload trigger for non-procd /etc/init.d/led
Fri Oct 15 11:38:57 2021 user.notice ucitrack: Setting up /etc/config/system reload dependency on /etc/config/luci_statistics
Fri Oct 15 11:38:57 2021 user.notice ucitrack: Setting up /etc/config/system reload dependency on /etc/config/dhcp
Fri Oct 15 11:40:00 2021 user.notice sysfixtime: loaded 'Fri Oct 15 11:40:00 UTC 2021' from /dev/rtc0
Fri Oct 15 11:40:00 2021 daemon.notice procd: /etc/rc.d/S96led: setting up led n2:blue
Fri Oct 15 11:40:00 2021 daemon.info procd: - init complete -
Fri Oct 15 11:40:00 2021 daemon.err odhcpd[1704]: Failed to send to ff02::1%lan@br-lan (Address not available)
Fri Oct 15 11:40:02 2021 kern.info kernel: [   11.120280] meson8b-dwmac ff3f0000.ethernet eth0: Link is Up - 1Gbps/Full - flow control rx/tx
Fri Oct 15 11:40:02 2021 kern.info kernel: [   11.123250] br-lan: port 1(eth0) entered blocking state