I’ve spent a few hours sifting through information about how to get a PPS input from a GPIO pin, and specifically I wanted to see if it was possible to do so with the stock Jetpack 6.2.1 image. I’m fairly new to the platform, but I was able to figure it out, and I’m hopeful this will be able to save time for other newcomers who want to do the same. Perhaps there are further improvements to be made too.
Step 0: Is it possible?
First, ensure GPIO over PPS is actually enabled on your kernel. If you’re using the stock image, it should be. Use the following command:
zcat /proc/config.gz | grep CONFIG_PPS_CLIENT_GPIO
If the output is CONFIG_PPS_CLIENT_GPIO=y, we’re in business. If it’s set to n, you won’t be able to proceed with these steps.
Step 1: Select a pin
Select a GPIO pin to use. See the image below for the pinout:
Ideally, choose one of the ones that says “GPIOxx”. I chose GPIO9 for this.
Step 2: Determine the pin identifier
Visit the download center and get the “pinmux config template”, which contains the IDs of each pin. https://developer.nvidia.com/embedded/secure/jetson/agx_orin/jetson_agx_orin_pinmux_config_template.xlsm
Look for the row of your desired pin under the leftmost column “Orin AGX CVM Connector”. Then, find the “Customer Usage” readout for that row, which should say GPIO3_ followed by letters, then a dot, then numbers, for example PBB.00 for GPIO09. The letters indicate the port, in this case “BB”, and the number indicates the pin number on that port. Remember those.
Also, be aware of whether your pin is in the always-on (“AON”) or main GPIO. If the port number starts with a double letter, like BB or CC, it’s in the AON section. If it starts with two different letters (AC) or only a single letter (R), it’s in the main GPIO.
Step 3: Determine the pin number
Take a look at this table to help determine the pin number: Jetson AGX Orin Platform Adaptation and Bring-Up — Jetson Linux<br/>Developer Guide 34.1 documentation. Find the offset listed for that port, then add the pin number for your port.
For example, if you’ve selected pin PBB.03, you’d look for “Port BB”, which is at offset 8, then add 3, to get pin number 11. I’ll continue using GPIO09, which is PBB.00, meaning my pin number is 8.
An alternative, simpler way to determine the pin number is to use the following command to print all available GPIO pins, and subtract the listed GPIO number from the GPIO start number:
sudo cat /sys/kernel/debug/gpio
My output looks like this:
gpiochip1: GPIOs 316-347, parent: platform/c2f0000.gpio, tegra234-gpio-aon:
gpio-316 (PAA.00 )
gpio-317 (PAA.01 )
gpio-318 (PAA.02 )
gpio-319 (PAA.03 )
gpio-320 (PAA.04 )
gpio-321 (PAA.05 )
gpio-322 (PAA.06 )
gpio-323 (PAA.07 )
gpio-324 (PBB.00 )
gpio-325 (PBB.01 )
gpio-326 (PBB.02 )
gpio-327 (PBB.03 )
gpio-328 (PCC.00 )
...
If I want to use pin PBB.00, which is gpio-324, under gpiochip1 which starts at 316, I would take 324 - 316 = 8.
Step 4: Create overlay file
Create /boot/pps.dts (or use another filename of your choice) and add the following contents:
/dts-v1/;
/plugin/;
/ {
compatible = "nvidia,p3737-0000+p3701-0000";
overlay-name = "Jetson PPS Overlay";
jetson-header-name = "Jetson 40pin Header";
fragment@0 {
target-path = "/";
__overlay__ {
pps: pps-gpio {
status = "okay";
compatible = "pps-gpio";
gpios = <&gpio_aon 8 0>;
assert-falling-edge;
};
};
};
};
Then, adapt the gpios = line to the details you’ve determined for your pin (but leave the <> around it). The values <&gpio_aon 8 0> are correct for my setup with pin GPIO9.
- If your pin is in the AON section, use
&gpio_aonas the first parameter, otherwise use&gpio. (remember: AON pins are identified by ports with double letters) - The next parameter should be the pin number you determined.
- 0 is for active-high, which works for me. Active-low would be 1.
Note: if you’ve been reviewing other posts on the topic, you may see the use of some shortcuts like
TEGRA_MAIN_GPIOin similar files. As far as I can tell, those shortcuts are only usable when compiling the kernel; I get a syntax error when trying to use those in this overlay.
Step 5: Generate the .dtbo file
Run the following command to compile the .dts file into a .dtbo file.
sudo dtc -O dtb -o /boot/pps.dtbo -@ /boot/pps.dts
Step 6: Load the .dtbo file on boot
Use ls /boot/dtb/ to check the name of the file there. Mine is kernel_tegra234-p3737-0000+p3701-0005-nv.dtb, but yours may be slightly different. Copy the filename to your clipboard.
Edit /boot/extlinux/extlinux.conf and add the following lines between the line that starts with INITRD and the line that starts with APPEND:
FDT /boot/dtb/FILE
OVERLAYS /boot/pps.dtbo
Replace the word FILE with the name of the file in /boot/dtb/.
Note: there is a way to do this with
sudo /opt/nvidia/jetson-io/jetson-io.py, but I found it much more convenient to simply add the two lines to the file manually.
Step 7: Reboot and validate
After rebooting, use the following command to check that one of the pins has PPS enabled on it:
sudo grep pps /sys/kernel/debug/gpio
If you see the name of your chosen pin in the output, the PPS should be loaded. If you see the name of a different pin, you may have chosen the wrong pin number. If you don’t see any output at all, you may have chosen a really wrong pin number, or made some other sort of mistake. sudo dmesg | grep gpio may help troubleshoot.
Step 8: Test
Ensure your PPS source is connected to your chosen pin. Use ls /dev/pps* to check which PPS devices are available. The GPIO PPS is probably the one with the highest number; mine is /dev/pps1 but I also have /dev/pps0 which is something else.
Then, use sudo ppstest /dev/pps1 where /dev/pps1 is your PPS device. If you don’t have ppstest installed, use sudo apt install pps-tools to install it. If you see a new line of output once per second, congratulations, your PPS input is working! If you get “timed out” errors, check that your PPS source is functioning properly and connected to the pin you intended.
See also
Similar solutions that shaped this post:
