BPI-M2 Zero: how to define the PPS-GPIO pin - a GNSS solution

Hi!

I’m building a GNSS/GPS disciplined (stratum 1) network time server and need to feed the PPS (Pulse Per Second) into a GPIO pin. I’m using a BPi-M2 Zero (Allwinner H2+/H3 SoC) and a u-blox NEO-6M via UART3, with Armbian Linux 24.2.1 (Ubuntu/Jammy).

This is how i’ve resolved the issue. You can look at older versions of this post if you want to see the problem.

It is not required to write and compile a complicated device tree overlay (DTS/DTO/DTBO).

My /boot/armbianEnv.txt

verbosity=1
bootlogo=false
console=both
disp_mode=1920x1080p60
overlay_prefix=sun8i-h3
rootdev=UUID=[redacted]
rootfstype=ext4
user_overlays=bananapi-m2-zero-eth0
overlays=i2c1 pps-gpio uart3
param_pps_pin=PA16
usbstoragequirks=0x2537:0x1066:u,0x2537:0x1068:u

pps-gpio defines the driver name. param_pps_pin=PA16 refers to GPIO18, which is pin 12 on the 40-pin header (CON2), also known as PA16/SPI1_MISO/UART3_CTS/PA_EINT16 in the schematic.

The kernel knows what to do with it.

user@banana:~$ dmesg | grep pps
[    0.729786] pps_core: LinuxPPS API ver. 1 registered
[    0.729797] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <[email protected]>
[    9.135007] pps pps0: new PPS source [email protected]
[    9.135142] pps pps0: Registered IRQ 57 as PPS source
[  109.071165] pps_ldisc: PPS line discipline registered
[  109.073945] pps pps1: new PPS source serial3
[  109.074062] pps pps1: source "/dev/ttyS3" added
user@banana:~$ lsmod | grep pps
pps_ldisc              16384  2
pps_gpio               12288  0

ppstest gets useful data, once the u-blox is warmed up.

user@banana:~$ sudo ppstest /dev/pps0
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1710800322.998550998, sequence: 4264 - clear  0.000000000, sequence: 0
source 0 - assert 1710800323.998539513, sequence: 4265 - clear  0.000000000, sequence: 0
source 0 - assert 1710800324.998561318, sequence: 4266 - clear  0.000000000, sequence: 0
source 0 - assert 1710800325.998549750, sequence: 4267 - clear  0.000000000, sequence: 0

Credits: thank you, Konstantin from Austria (not Australia :upside_down_face:), who pointed me in the right direction. He made 2 videos about his project: https://www.youtube.com/watch?v=tSesbsUGvmU and https://www.youtube.com/watch?v=ELKOLY2P5c4. He used an Orange Pi, but it’s the same Allwinner H3 SoC.

I’d like to update my project progress:

by now, i’ve abandoned the idea of using a GPIO pin as the PPS line.

Instead, i’m using a USB serial adaptor - a Prolific PL-2303HX based specimen in particular. I’ve soldered a wire between the u-blox PPS pin and pin 10 of the PL2303. Pin 10 of the PL2303 is the DCD / Data Carrier Detect line. That’s exactly what gpsd expects (the DCD signal / pulse)! (see also /etc/default/gpsd) No need to enable pps-gpio in /boot/armbianEnv.txt. It seems, gpsd creates /dev/pps0 automatically. “It works on my box!” gpsmon recognises the PPS signal automatically, and prints the offset (upon fix, 2D or better).

This is the most hassle-free solution i can think of, if you’re willing to throw a negligible amount of money at the problem - about 5€$£ delivered.

However, i’ve stumbled across an alternative solution - using pps-gpio; it seems, one can specify more than 1 device in /etc/default/gpsd, e.g.

DEVICES="/dev/ttyS3 /dev/pps0"

It seems, once you’ve got PPS-GPIO going, it’s just a matter of actually telling gpsd, where exactly it’s going - gpsd seems to be smart enough to figure things out. I didn’t test this in gpsmon, but i’m mildly confident that this might work as intended.

Also, in my dmesg example, above, there are 2 PPS devices, /dev/pps0 and /dev/pps1 - it might help, telling gpsd about both, in /etc/default/gpsd - just a hunch, i didn’t test specifying 3 devices.

…just a few pointers, hopefully in the right direction …feedback appreciated

@platymew ,

I think that you succeeded in the first case (using pps-gpio on armbianEnv.txt) because you already had the pps_gpio.dtob available for your device.

pps_ldisc is a device driver to get the pps input from a pps signal connected to the DCD input from a serial RS232 device. pps_gpio get the pps input from an available interrupt pin.

gpsd is the gps daemon that will get the GPS signal and pps (if available, for greater accuracy), so the reason for the two inputs in DEVICES.

Take a look in other discussions abou GPS fed ntp devices, I think that I read something about USB-RS232 devices introducing a certain amount of lag that dimishes the accuracy.