PPS driver, assigning gpio

Apparently the idea of a gps derived time server for ~$35 was my tipping point. I bought a GL-iNet GL-MT300N-V2 and a Beitian BN-180 gps module (*1). I think I've wired things up well. But I've stalled on getting the pps kernel module to work.

My question: Is there any way to configure pps-core or pps-gpio via kernel module option, config file, or anything else short of custom compiling OpenWRT? I can't tell if I'm missing something in the documentation or if it's really impossible to just tell the module which gpio to use somehow, some comments direct me to editing the dts files before compiling, other comment refer to dtoverlays but it's not clear that applies to OpenWRT or something else (mostly Rasp Pi discussions).

For reference or for other's who might be interested.
Hardware: GL-iNet GL-MT300N-V2 and Beitian BN-180 gps module
The BN-180 does NOT have a pps output pin so I don't really recommend it but it's common, available, and cheap. I happen to be able to solider an additional wire on to the correct end of the pps led resistor.
I flashed the device to OpenWrt 19.07.4, disabled dhcp, renamed the lan IP to something that wasn't the same as my home network, enable the wifi as a client so I could easy download software.
Installed stty, and kmod-pps-core, kmod-pps-gpio.
If I:
stty -F /dev/ttyS0 9600
cat </dev/ttyS0
I get regular GPS NEMA lines so good there.
If I:
echo 46 >/sys/class/gpio/export
while true; do cat /sys/class/gpio/gpio46/value ; done
it looks a lot like the pps signal is working
If I:
echo 46 >/sys/class/gpio/export
echo "rising" > /sys/class/gpio/gpio46/edge
cat /proc/interrupts
it looks to me like the gpio is triggering regular, once a second interrupts.

I think at this point if I can figure out how to get the kernel pps stuff working I could install ntpd and maybe gpsd and have a working stratum one.

@nulluser3782 did you ever get this working? I've been beating my head against the wall all weekend on this. Basically I'm in the same state as you (except pin 18 instead of 46). I've read countless docs all over the Interwebs, but most of them point to one of:

  • Adding dtoverlay=pps-gpio,gpiopin=18 to /boot/config.txt, which appears to be Raspberry Pi specific.
  • Using pps-gpio-poll, which allows setting the pin in the module config, but the module isn't available for OpenWrt.
  • Rebuilding the kernel. E.g., this article, which should work for me as my device is a Turris Omnia but I'd rather not commit to anything beyond using the Custom Image Builder.

So is there any way to get this to work w/o building my own kernel? GPIO is available in user-space so there ought to be a way to make this work, but it seems gpsd requires /dev/pps and there's no way to point pps-gpio to a specific gpio pin except on a Raspberry Pi? IDK, it sounds like boot.txt is specific to the Pi boot environment, but maybe there's a way in U-Boot to pass the same setting to the kernel?

I've made some progress. So keep in mind this is a learning exercise -- I realize I don't really need 3 stratum 1's on my home network, but it's forcing me to learn some things.

So first off I could use some help assigning the GPIO pin on my AR150. I've tried or considered:

  • Locating image-ar9330_glinet_gl-ar150.dtb on the device like I did for my Turris Omnia below. It seems the boot process on the AR150 doesn't use it.
  • Updating image-ar9330_glinet_gl-ar150.dtb in the imagebuilder directory and building a new image, but despite the file existing in the tree, the imagebuilder doesn't seem to make use of it.
  • Building from the SDK: I can't get it to work following Build system usage. The step make kernel_menuconfig fails with make: *** [/home/mjf/OpenWrt/openwrt-sdk-22.03.2-ath79-generic_gcc-11.2.0_musl.Linux-x86_64/include/toplevel.mk:223: toolchain/install] Error 1
  • Some patches on GitHub look promising, but if I can't get the SDK working, that probably won't help.
  • More mods from a very detailed Blog look even more promising, again perhaps if I could get the SDK to work.

So help on the above would be appreciated.

Things I did get working: on my Turris Omnia, it's as easy as mount /dev/mmcblk0p1 /boot to access the .dtb file and dtc -I dtb <armada-385-turris-omnia.dtb >armada-385-turris-omnia.dts to access the device tree file. Then just patch it similar to the previously mentioned article:

*** armada-385-turris-omnia.dts.orig	2022-11-20 08:43:35.081744891 -0800
--- armada-385-turris-omnia.dts	2022-11-08 08:20:56.000000000 -0800
***************
*** 476,481 ****
--- 476,483 ----
  				#interrupt-cells = <0x02>;
  				interrupts = <0x00 0x35 0x04 0x00 0x36 0x04 0x00 0x37 0x04 0x00 0x38 0x04>;
  				clocks = <0x04 0x00>;
+ 				linux,phandle = <0x1f>;
+ 				phandle = <0x1f>;
  			};
  
  			gpio@18140 {
***************
*** 1097,1100 ****
--- 1099,1108 ----
  		status = "disabled";
  		phandle = <0x11>;
  	};
+ 
+ 	pps@18 {
+ 		gpios = <0x1f 0x12 0x00>;
+ 		compatible = "pps-gpio";
+ 		status = "okay";
+ 	};
  };

and turn it back into a dtb file with dtc -I dts <armada-385-turris-omnia.dts >armada-385-turris-omnia.dtb (obviously you'll want to make a backup) and /dev/pps0 magically appears.

Other articles and things I found useful:

  • Stratum 1 NTP server using USB GPS for necessary OpenWRT packages and configs.
  • Microsecond accurate NTP with a Raspberry Pi and PPS GPS for doing this on a Pi (which I also did in the antenna picture below, and the electronics info there and NTP / Chrony config still apply to OpenWrt).
  • UART GPS NEO-6M: you can find these for 9-12 USD on Amazon and the like, but make sure you get one with the PPS pin.
  • Antennas are weird. I was having difficulty getting enough of a lock for PPS indoors. After reading various sites and my GPS' documentation, I saw reference to a ground plane for improving reception. So you can buy a 7cm ground plane on Amazon for like 15 USD (5 more than the GPS itself), or you can wrap a beer coaster in aluminum foil like I did, and voila! GPS lock and PPS output:

I set up a GL-MT300N-V2 as an NTP server with a uBlox NEO-7M GPS/PPS reference clock in 2018 using an openwrt 18.06 snapshot. See https://forum.gl-inet.com/t/success-gl-mt300n-v2-with-pps-gps-ntp-time-source/3732 for a very brief write up.

It ran for a couple of years until the rats nest of wires was disturbed. Over the weekend I decided to revisit the project. I searched for new information and noticed this post.

Looking back I see that I didn't document this very well. The original hardware still works and I have another GL-MT300N-V2 and GPS module to play with. I probably have some working notes hidden away.