Skip to content

Instantly share code, notes, and snippets.

@mill1000
Last active February 20, 2023 09:03
Show Gist options
  • Save mill1000/44172617640c9b66cf7cd682f8b8ba51 to your computer and use it in GitHub Desktop.
Save mill1000/44172617640c9b66cf7cd682f8b8ba51 to your computer and use it in GitHub Desktop.
PPS-GPIO on Rock64 with Armbian legacy (4.4.X) kernel

PPS-GPIO on Rock64 with Armbian legacy (4.4.X) kernel

About

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

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.

DT Overlay Method

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.

1. Create the DT overlay, or download the attached file pps-overlay.dts

/dts-v1/;
/plugin/;

/ {
  compatible = "pine64,rock64", "rockchip,rk3328";

  fragment@0 {
    target-path = "/";
    __overlay__ {
      pps: pps@0 {
        compatible = "pps-gpio";
        gpios = <&gpio2 3 0>;
      };
    };
  };
};
  

2. Add the overlay

Use the armbian-add-overlay command to compile, install and activate the overlay/

$ sudo armbian-add-overlay ~/pps-overlay.dts 

3. Verify pps-gpio was enabled

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).

4. Test PPS signal

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.

Disclaimer

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.

Prerequisites

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

Steps

1. Locate existing Device Tree Blob (DTB)

Locate the existing dtb for your board. Mine was located here: /boot/dtb/rockchip/rk3328-rock64.dtb

2. Backup the 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

3. Decompile the DTB

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

4. Add pps-gpio binding to DTS

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 {

5. Compile the DTS to DTB

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.

6. Replace the existing DTB

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.

7. Verify pps-gpio was enabled

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).

8. Test PPS signal

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
/dts-v1/;
/plugin/;
/ {
compatible = "pine64,rock64", "rockchip,rk3328";
fragment@0 {
target-path = "/";
__overlay__ {
pps: pps@0 {
compatible = "pps-gpio";
gpios = <&gpio2 3 0>;
};
};
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment