Jump to content

Proper way to enumerate a PPS device on odroid-C2 (Focal, 5.9.14)


Recommended Posts


Hello all!

I have an ODROID-C2 that I am trying to use with a GPS connected over UART for timing purposes, which requires the use of pps. Based on my searching and reading in this forum, I have determined that for my OS and kernel (Focal, 5.9.14) I should be able to do so by adding overlay=pps-gpio to armbianEnv.txt. What is not clear to me, however, is how to specify which pin to use! 


In this thread I see windysea said:


Optionally param_pps_* may be used to configure, such as pin.


But I don't know how to use this information! I have found no documentation on param_pps_*, and my attempts at guessing based on information from other threads and resources have failed to work so far. I have been fiddling with this for a few days to no avail now, so any assistance would be greatly appreciated.




Link to comment
Share on other sites


*EDIT - For the interested, looks like the gpio_pin argument is nonstandard, see this post*


Hi John,


The short version is that I'm not sure you've provided enough information here. The answer really depends on what you have, and where you have it connected (if at all).


Most GPS units I've seen provide PPS signalling through a DB-9 serial connection at RS-232 levels (~12V), often on one of the modem control pins on that connector such as DCD.


If you have one of these units on a USB to serial adapter, you might be able to use it via ldattach (https://www.crc.id.au/2016/09/24/adding-a-pps-source-to-ntpd/). Note that DCD is not always standard, and some USB to serial adapters don't connect DCD at all as it's not always used.


If you have a GPS providing 3.3V signalling, and you have your PPS hooked up to the GPIO header, then you should consult the documentation to find out what GPIO goes to what pin (https://wiki.odroid.com/odroid-c2/hardware/expansion_connectors). Note that these GPIO assignments can change with kernel version. I don't have my C2 in front of my at the moment so can't check this for you. But you can always look at /sys/kernel/debug/gpio and see what the valid ranges are.


If you do need to experiment, note that you can dynamically load the pps-gpio driver and experiment a bit. The ODroid wiki has more on the subject (https://wiki.odroid.com/odroid-c2/application_note/gpio/pps).


# Load PPS on given pin
sudo modprobe pps-gpio pin=XXX

# Unload PPS
sudo rmmod pps-gpio


And I wouldn't worry about doing anything with the DTB until you're sure what pin it's on.

Edited by tparys
Clearing up bad information
Link to comment
Share on other sites

Hi tprays,

Thanks for the response! I am using a GPS module connected directly via UART, so I don't need to mess with any RS232 stuff. Also, for what it's worth, USB-RS232 adapters are terrible for timing-related applications because of the latency associated with USB. If you do use an RS232 GPS for timing, it should be connected to a real hardware serial port where the PPS signal can issue an interrupt.




I have 3v3 level PPS running to pin 7 (GPIO 249 / GPIOX.21). I wasn't aware that I could specify the pin when loading the pps-gpio module, but I'm assuming I would load it as:

sudo modprobe pps-gpio pin=249


I don't have my C2 in front of me at the moment, but I can test this out later today and report back. Thank you!

Link to comment
Share on other sites

No progress so far. According to /sys/kernel/debug/gpio pin 11 is gpio-489. Why I try and run any variant of sudo modprobe pps-gpio pin=XXX, dmesg just spits back:

pps_gpio: unknown parameter 'pin' ignored


So, I don't know what to think here, honestly. I have read through the odroid wiki notes on using PPS on this board but none of it seems to relevant in Armbian, it seems like maybe pieces are missing?





Link to comment
Share on other sites

Blech, I figured as much. I like the C2, and I like the Armbian project, but stuff like this is why the Raspberry Pi/Raspbian have such a strong following. Once I get this figured out I'll do my best to post a definitive solution on here because it seems like people have been having this question for years to no avail.

Link to comment
Share on other sites

Hello Millerjs,


have you solved this issue? I'm in the same scenario with a NanoPi Neo 3 (RK3328) and stuck with "pps_gpio: unknown parameter 'pin' ignored" as I can't set the gpio.
My suspicion is that the pps_gpio module has no defined parameters to take hence the error in dmesg.

The command at the bottom is supposed to show parameters for the module but since there are none in the output then it would appear that it won't accept any.

It is not clear to me if this can be solved with a customized dtb. For example my SBC uses /boot/dtb/rockchiprk3328-nanopi-neo3-rev02.dtb that I can decompile into plain text and add to it before recompiling it...


I have found some reference to something like the snippet below but it is not working, can't compile it back into a dtb...

pps {
  compatible = "pps-gpio";
  gpios = <&gpio1 2 0>;



modinfo pps_gpio

root@DietPiNTP:/boot# modinfo pps_gpio
filename:       /lib/modules/5.10.21-rockchip64/kernel/drivers/pps/clients/pps-gpio.ko
version:        1.2.0
license:        GPL
description:    Use GPIO pin as PPS source
author:         James Nuss <jamesnuss@nanometrics.ca>
author:         Ricardo Martins <rasm@fe.up.pt>
srcversion:     DC2C20835E78E639C78ED8B
alias:          of:N*T*Cpps-gpioC*
alias:          of:N*T*Cpps-gpio
intree:         Y
name:           pps_gpio
vermagic:       5.10.21-rockchip64 SMP preempt mod_unload aarch64
sig_id:         PKCS#7
signer:         Build time autogenerated kernel key
sig_key:        6E:AA:FB:15:C6:2A:4C:E0:0C:E1:53:9F:10:36:C1:FF:68:CC:6E:CC
sig_hashalgo:   sha1
signature:      B8:CB:6F:BC:D7:D0:5B:1D:80:29:46:EF:1E:BC:58:69:8C:61:01:FF:



Link to comment
Share on other sites


My suspicion is that the pps_gpio module has no defined parameters to take hence the error in dmesg


The pps_gpio module does not take parameters. Definitions of a PPS device must be in the DTB, or overlay: https://mjmwired.net/kernel/Documentation/devicetree/bindings/pps/pps-gpio.txt



can't compile it back into a dtb...


That's because you're missing parts of the DTB overlay. Notably, you need to specify that:

  • It's an overlay
  • Where it applies ("target" or "target-path")
  • What you're doing there (overlay or fixup)
  • And in this case, what you're adding ...

You probably meant to do something like this instead. Note that I don't have your setup, nor your board, so can't test this. But probably a better start than where you are.



/ {
	compatible = "rockchip,rk3328";

	// Define a PPS device on GPIO Bank 1, pin 2
	fragment@0 {
		target-path = "/";
		__overlay__ {
			pps0: pps-gpio0 {
				compatible = "pps-gpio";
				gpios = <&gpio1 2 0>;


Link to comment
Share on other sites

I've thrashed through this here with an Odroid-C2 running PRETTY_NAME="Armbian 23.02.1 Bullseye" 


I confirmed that with current, "stock" kernels, the suggestions to manually configure a pin for the pps-gpio module are no longer useful.


At least on the C2 and perhaps on other devices, the gpioinfo utility can reveal the proper line (and chip) for a given pin, without needing to refer to the DTS, such as at https://elixir.bootlin.com/linux/v6.1.11/source/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts#L304 



$ sudo gpioinfo | egrep 'gpiochip|Pin7'
gpiochip0 - 15 lines:
	line  11: "J7 Header Pin7" unused input active-high 
gpiochip1 - 119 lines:
	line 113: "J2 Header Pin7" unused input active-high 


Decompiling the "live" device tree with dtc -I fs -O dts /sys/firmware/devicetree/base or similar will reveal the phandle for the GPIO bank


                                bank@4b0 {
                                        reg-names = "mux\0pull\0pull-enable\0gpio";
                                        gpio-line-names = "Eth MDIO\0Eth MDC\0Eth RGMII RX Clk\0Eth RX DV\0Eth RX D0\0Eth RX D1\0Eth RX D2\0Eth RX D3\0Eth RGMII TX Clk\0Eth TX En\0Eth TX D0\0Eth TX D1\0Eth TX D2\0Eth TX D3\0Eth PHY nRESET\0Eth PHY Intc\0HDMI HPD\0HDMI DDC SDA\0HDMI DDC SCL\0\0eMMC D0\0eMMC D1\0eMMC D2\0eMMC D3\0eMMC D4\0eMMC D5\0eMMC D6\0eMMC D7\0eMMC Clk\0eMMC Reset\0eMMC CMD\0\0\0\0\0\0\0\0SDCard D1\0SDCard D0\0SDCard CLK\0SDCard CMD\0SDCard D3\0SDCard D2\0SDCard Det\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0I2C A SDA\0I2C A SCK\0I2C B SDA\0I2C B SCK\0PWM D\0PWM B\0Revision Bit0\0Revision Bit1\0\0J2 Header Pin35\0\0\0\0J2 Header Pin36\0J2 Header Pin31\0\0\0\0TF VDD En\0J2 Header Pin32\0J2 Header Pin26\0\0\0J2 Header Pin29\0J2 Header Pin24\0J2 Header Pin23\0J2 Header Pin22\0J2 Header Pin21\0J2 Header Pin18\0J2 Header Pin33\0J2 Header Pin19\0J2 Header Pin16\0J2 Header Pin15\0J2 Header Pin12\0J2 Header Pin13\0J2 Header Pin8\0J2 Header Pin10\0\0\0\0\0\0J2 Header Pin11\0\0J2 Header Pin7\0\0\0\0\0";
                                        reg = <0x00 0x4b0 0x00 0x28 0x00 0x4e8 0x00 0x14 0x00 0x520 0x00 0x14 0x00 0x430 0x00 0x40>;
                                        phandle = <0x23>;
                                        #gpio-cells = <0x02>;
                                        gpio-ranges = <0x20 0x00 0x00 0x77>;


Knowing the line that you wish to use, you can then construct an overlay. The pps-gpio bindings are described at https://www.kernel.org/doc/Documentation/devicetree/bindings/pps/pps-gpio.txt


In my case, I needed the pin to be active high, without any pull-up/down. When you create the file, use the .dts extension for compatibility with the Armbian compile/install script.



 * bank@4b0 is at phandle = <0x23>;
 * GPIO 113 is "J2 Header Pin7"

/ {
	compatible = "hardkernel,odroid-c2", "amlogic,meson-gxbb";

	fragment@0 {
		target-path = "/";
		__overlay__ {
			pps0: pps-gpio0 {
				compatible = "pps-gpio";
				gpios = <0x23 113 0>;


Running sudo armbian-add-overlay pps-gpio.dts will compile the source, install it into /boot/overlay-user/ and add a line to /boot/armbianEnv.txt to load it through U-Boot. It won't add the line if it is already there, so re-running the utility should be "safe".


While looking at /boot/armbianEnv.txt it is worth noting that the boot script has two useful U-Boot variables, extraargs and extraboardargs. At least on the C2 these seem to be unused elsewhere. 


setenv bootargs "root=${rootdev} rootwait rootfstype=${rootfstype} ${consoleargs} consoleblank=0 coherent_pool=2M loglevel=${verbosity} ubootpart=${partuuid} libata.force=noncq usb-storage.quirks=${usbstoragequirks} ${usbhidquirks} ${extraargs} ${extraboardargs}"


These can be set in /boot/armbianEnv.txt to adjust the kernel cmdline, such as adding




if appropriate for your application.


Success should create /dev/pps0 and gpioinfo now showing


gpiochip1 - 119 lines:
	line 113: "J2 Header Pin7" "pps-gpio0" input active-high [used]


With a source connected to the expected pin, the function can be checked with


$ 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 1678986077.000000404, sequence: 44681 - clear  0.000000000, sequence: 0
source 0 - assert 1678986078.000000575, sequence: 44682 - clear  0.000000000, sequence: 0
source 0 - assert 1678986079.000000371, sequence: 44683 - clear  0.000000000, sequence: 0


Configuration of gpsd and chronyd did not seem to have any notable differences from other platforms. That is a topic on its own, but not specific to Armbian.

Edited by Jeffsf
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...

Important Information

Terms of Use - Privacy Policy - Guidelines