This gist covers how to enable PPS input via GPIO for Rock64 SBCs running Armbian legacy (4.4.X) kernels. It may also be applicable to Pine64 SBCs and other kernel versions but I have not personally tested them.
This gist will not cover configuring ntpd or gpsd to utilize the PPS signal, only enabling pps-gpio via modifying the device tree. For help configuring ntpd or gpsd I recommend the links under Motivation
A PPS (Pulse Per Second) signal allows a time server to improve its clock accuracy and therefore achieve Stratum 1 status. Typically a PPS signal is provided via a GPS receiver attached to the server. The GPS receiver also provides a coarse time via USB or serial connection.
Setting up a time server is beyond the scope of this gist but there are many good guides online.
- https://gpsd.gitlab.io/gpsd/gpsd-time-service-howto.html
- https://www.ntpsec.org/white-papers/stratum-1-microserver-howto/
- https://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
The new method utilizes device tree (DT) overlays to apply the PPS changes without modifying the stock DTB. This has the benefit of being simpler to perform, safer, and persists between system updates.
/dts-v1/;
/plugin/;
/ {
compatible = "pine64,rock64", "rockchip,rk3328";
fragment@0 {
target-path = "/";
__overlay__ {
pps: pps@0 {
compatible = "pps-gpio";
gpios = <&gpio2 3 0>;
};
};
};
};
Use the armbian-add-overlay
command to compile, install and activate the overlay/
$ sudo armbian-add-overlay ~/pps-overlay.dts
Check that pps-gpio was loaded and a new PPS source was added. Execute the following
dmesg | grep pps
and look for something similar to
[ 7.338058] pps pps0: new PPS source pps.-1
[ 7.338133] pps pps0: Registered IRQ 120 as PPS source
A pps device should also be present at /dev/ppsX
(e.g. pps0, pps1, etc).
Install the pps-tools
package if not already present.
sudo apt-get install pps-tools
Attach your PPS source to GPIO2_C2
and verify the signal is received with the following
sudo ppstest /dev/pps0
which should report asserts at 1 second intervals.
source 0 - assert 1585239363.054182847, sequence: 253 - clear 0.000000000, sequence: 0
These instructions are outdated and unnecessarily complicated. Please use the DT overlay instructions above.
Backup your system before trying this! I will not be responsible for fixing your system should this fail.
While this process worked for me I can't claim it is foolproof. This involves modifying the system's device tree. The device tree describes the hardware to the kernel and it is very possible that changing it could cause your system to not boot.
To enable pps-gpio we will be modifying the device tree blob (dtb). The device-tree-compiler
package is required to decompile and recompile the device tree.
sudo apt-get instal device-tree-compiler
Locate the existing dtb for your board. Mine was located here: /boot/dtb/rockchip/rk3328-rock64.dtb
Make a backup of the DTB just in case.
sudo cp /boot/dtb/rockchip/rk3328-rock64.dtb /boot/dtb/rockchip/rk3328-rock64.dtb.bak
Decompile the DTB to device tree source (DTS) format which can be edited with a text editor. We will place the DTS in our home directory.
dtc -I dtb -O dts -o ~/rk3328-rock64.dts /boot/dtb/rockchip/rk3328-rock64.dtb
To enable pps-gpio the proper binding must be added to the device tree. The following was used for syntax reference: https://www.kernel.org/doc/Documentation/devicetree/bindings/pps/pps-gpio.txt
Under the root note of the DTS (indicated by / {
) add the following:
pps {
compatible = "pps-gpio";
gpios = <&gpio2 3 0>;
};
This will enable pps-gpio on GPIO2_C2
or Pin 12 on the "PI-2" header.
If you attempt to compile at this point the dtc will fail because &gpio2
is an unknown label. We must add a gpio2
label to the gpio2 binding so that dtc can located it.
Locate the gpio2 binding in the DTS. It should start with
gpio2@ff230000 {
insert a gpio2
label so that the binding now looks like
gpio2: gpio2@ff230000 {
Compile the modified DTS to DTB with the following command.
dtc -I dts -O dtb -o ~/rk3328-rock64-pps.dtb ~/rk3328-rock64.dts
A large number of warnings will be generated but the DTB should compile successfully.
Replace the existing DTB with our PPS enabled DTB and reboot.
sudo cp ~/rk3328-rock64-pps.dtb /boot/dtb/rockchip/rk3328-rock64.dtb
sudo reboot
Hopefully the system boot normally and is accessible.
Check that pps-gpio was loaded and a new PPS source was added. Execute the following
dmesg | grep pps
and look for something similar to
[ 7.338058] pps pps0: new PPS source pps.-1
[ 7.338133] pps pps0: Registered IRQ 120 as PPS source
A pps device should also be present at /dev/ppsX
(e.g. pps0, pps1, etc).
Install the pps-tools
package if not already present.
sudo apt-get install pps-tools
Attach your PPS source to GPIO2_C2
and verify the signal is received with the following
sudo ppstest /dev/pps0
which should report asserts at 1 second intervals.
source 0 - assert 1585239363.054182847, sequence: 253 - clear 0.000000000, sequence: 0