Enabling PPS on Xavier AGX

I’m trying to enable a PPS input from a GPIO pin on the Jetson Xavier carrier board but cant seem to get it to work.

I have rebuilt the kernel with the following config(s)

# PPS support
CONFIG_PPS=y
# CONFIG_PPS_DEBUG is not set
# PPS clients support
# CONFIG_PPS_CLIENT_KTIMER=y
# CONFIG_PPS_CLIENT_LDISC=y
# CONFIG_PPS_CLIENT_GPIO=y
# PPS generators support
# CONFIG_NVPPS is not set

This gave me a device /dev/pps0 which was the KTIMER but I want to be using a GPIO input and there was no /dev/pps1. So I tried with CONFIG_PPS_CLIENT_KTIMER disabled as well but that didn’t really change the situation.

I have also edited the device tree and added a pps device with one of the 40 header pins selected.

pps {
gpios = <&gpio TEGRA_GPIO(Z, 6) 0>;
compatible = "pps-gpio";
assert-falling-edge;
status = "okay";
};

After this I built the image and flashed the Xavier and couldn’t find a pps device for the GPIO.

Is there something that I could be missing / doing wrong?

I have read through the forums and the most similar topic I can find is doing exactly what I’m asking except on the Jetson Nano ( Enabling PPS on Jetson Nano with Jetpack 4.3 ). In fact in that thread there’s a link to a decent blog post ( https://msadowski.github.io/pps-support-jetson-nano/ ) that seems to explain everything fairly thoroughly - however I can’t seem to get it to work on the Xavier AGX.

Any help would be appreciated.
Thanks

what would be the output of
ppstest /dev/pps0
given the pps timepulse is conencted to corresponding GPIO pin?
What is the output of
sudo cat /dev/ttyTHS0
given GPIO UART TX&RX are connected to corresponding pins RX & TX of GPS unit?

NB! The former is for readnig timepulse, while the latter is for reading NMEA sentences, etc.

Which of the two are you trying to implement? Former? Latter? Both? Neither of the two?

what would be the output of
`ppstest /dev/pps0`
given the pps timepulse is conencted to corresponding GPIO pin?

With CONFIG_PPS_CLIENT_KTIMER=y enabled the output of ppstest /dev/pps0 is the ktimer clock. With
CONFIG_PPS_CLIENT_KTIMER not enabled there is no output for /dev/pps0 because it doesn’t exist.

What is the output of
`sudo cat /dev/ttyTHS0`
given GPIO UART TX&RX are connected to corresponding pins RX & TX of GPS unit?

To my understanding I shouldn’t need the GPS plugged into serial, I was hoping to just have a single wire interface between the GPS and AGX where the GPS is outputting the PPS signal and the AGX is reading the incoming PPS signal on pin 24 - the pin I added in the device tree with gpios = <&gpio TEGRA_GPIO(Z, 6) 0>;.

Which of the two are you trying to implement? Former? Latter? Both? Neither of the two?

I am trying to implement the former. I want to read the timepulse.

modprobe pps-ktimer
ppstest /dev/pps1
so this one won’t show the timepulse if you run it? with connected gps device? without connected gps device? what will be the output?
On NX I was able to use jetson.io & dtb update in order to add the timepulse;
Pin number is to be checked with reference documentation. The example below matches pin7 of NX GPIO.
In my implementation I used following steps for NX:

  1. creatednew file pps.dts at /boot folder
/dts-v1/;
/plugin/;
/ {
    overlay-name = "Jetson PPS";
    compatible = "nvidia,p3509-0000+p3668-0001";
    fragment {
        target-path = "/";
        __overlay__ {
                        pps: pps_gpio {
                                compatible = "pps-gpio";
                                gpios = <&tegra_main_gpio 148 1>;
                                assert-falling-edge;
                                status = "okay";
                        };
        };
    };
};
  1. processed it with
    sudo dtc -I dts -O dtb -@ -o pps.dtbo pps.dts
  2. sudo /opt/nvidia/jetson-io/config-by-hardware.py -l
  3. sudo /opt/nvidia/jetson-io/config-by-hardware.py -n "Jetson PPS"
    then reboot; the referenced tegra_main_gpio 148 corresponds to the pin7 of nx jetson; for AGX you will have to check with the documentation

Thank you for the input Andrey,

so this one won’t show the timepulse if you run it? with connected gps device? without connected gps device? what will be the output?

I’ll get back to you on the output when I have the GPS available. For now all I can say is that modprobe pps-ktimer returns:

modprobe pps-ktimer
modprobe: FATAL: Module pps-ktimer not found in directory /lib/modules/4.9.140-tegra

But I have currently disabled the ktimer, and even when I do enable it and re-flash the TX2 I don’t load it as a module.

I have been reading through the thread “Time sensitive networking [TSN] on NX” and noticed that you may have been missing the /dts-v1/; at the top of the pps.dts file you have included. However, this still doesn’t fix my problem. I run into the same issue you seem to have had with the gpio warnings.

$ sudo dtc -I dts -O dtb -@ -o pps.dtbo pps.dts
     pps.dtbo: Warning (gpios_property): Property 'gpios', cell 1 is not a phandle reference in 
     /fragment/__overlay__/pps_gpio
     pps.dtbo: Warning (gpios_property): Could not get phandle node for /fragment/__overlay__/pps_gpio:gpios(cell 1)

It looks like these warnings aren’t an issue judging by that thread but It seems like I still can’t get that dts file to compile. When I run sudo /opt/nvidia/jetson-io/config-by-hardware.py -l the Jetson PPS configuration does not appear.

$ sudo /opt/nvidia/jetson-io/config-by-hardware.py -l
    Configurations for the following hardware modules are available:
    1. Adafruit SPH0645LM4H
    2. FE-PI Audio Z V2

I assume that the name needs to be changed for the board judging by the ‘valid names’ shown for the agx here: https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide/adaptation_and_bringup_xavier.html .

So the current dts file I am using looks like this (using pin 24 on the 40 pin GPIO header):

/dts-v1/;
/plugin/;

/ {
    overlay-name = "Jetson PPS";
    compatible = "p2972-0000-devkit,devboard";

    fragment {
        target-path = "/";
        __overlay__ {
                        pps: pps_gpio {
                                compatible = "pps-gpio";
                                gpios = <&tegra_main_gpio 206 1>;
                                assert-falling-edge;
                                status = "okay";
                        };
        };
    };
};

So It is working now!

I followed gtj’s steps from Time sensitive networking [TSN] on NX with a few modifications (really just the names to work with the AGX instead of the NX).

I saved this file to /boot/pps.dts where the pin has been set to 24 on the 40 pin header.

/dts-v1/;
/plugin/;

/ {
    overlay-name = "Jetson PPS";
    compatible = "p2822-0000+p2888-0001,p2972-0000-devkit,devboard";
    fragment {
        target-path = "/";
        __overlay__ {
                        pps: pps_gpio {
                                compatible = "pps-gpio";
                                gpios = <&tegra_main_gpio 206 1>;
                                assert-falling-edge;
                                status = "okay";
                        };
        };
    };
};

Then compiled the dts files and ignored the warnings that I don’t understand…

 sudo dtc -I dts -O dtb -@ -o pps.dtbo pps.dts

Then created the custom dtb

sudo fdtoverlay -i tegra194-p2888-0001-p2822-0000.dtb -o tegra194-p2888-0001-p2822-0000-user-custom.dtb tegra194-p2888-0001-p2822-0000-hdr40.dtbo pps.dtbo

Finally edited /boot/extlinux/extlinux.conf by adding the extra entry:

    LINUX ...
    INITRD ...
    FDT /boot/tegra194-p3668-all-p3509-0000-user-custom.dtb
    APPEND ...

and rebooted.

Thanks @gtj and @Andrey1984

Sorry if this is a bit of a duplicate question (although I guess it’s specific to the AGX as opposed to the NX).

What I don’t understand is why does the device tree need to be edited after the kernel has been flashed?

Editing ~/nvidia/nvidia_sdk/JetPack_4.3_Linux_P3448/Linux_for_Tegra/sources/hardware/nvidia/soc/t210/kernel-dts/tegra210-soc/tegra210-soc-base.dtsi to include

pps: pps_gpio {
    compatible = "pps-gpio";
    gpios = <&tegra_main_gpio 206 1>;
    assert-falling-edge;
    status = "okay";
    };

should be the same as including it after the flash by editing the device tree overlay right?

Thank you for sharing your success;
In the example above the default stock kernel has been used.

1 Like

Yeah, it’s just a matter using the device tree overlay to experiment because it’s easier to change on the fly, and putting the final result into the source tree’s dtsi file for permanent inclusion. There’s no function difference.

1 Like

So you do need to recompile the kernel ?
I’m trying on my AGX dev kit and can’t activate with just the modification on the device tree.
Also it didn’t find this blob :

Couldn't open blob from 'tegra194-p2888-0001-p2822-0000-hdr40.dtbo': No such file or directory

Failed to read overlay tegra194-p2888-0001-p2822-0000-hdr40.dtbo

Here is my pps.dts

 /dts-v1/;
 /plugin/;
 
 / {
     overlay-name = "Jetson PPS";
     compatible = "nvidia,jetson-xaviernvidia,tegra194";
     fragment {
         target-path = "/";
         __overlay__ {
                         pps: pps_gpio {
                                 compatible = "pps-gpio";
                                 gpios = <&tegra_main_gpio 206 1>;
                                 assert-falling-edge;
                                 status = "okay";
                         };
         };
     };
 };

yes and no
it either requires to recompile the kernel
or could be done with updating the dtb on-the-fly
without recompilling the kernel
dtbo file needs to be presented in the corresponding folder
what is the set of commands you execute step by step before running into the error?

@Tomlogan501
iit looks liike you are executing from wrong folder?
try locatiing the file at Host PC/ Jetson with

sudo apt install mlocate -y
sudo updatedb
locate  tegra194-p2888-0001-p2822-0000-hdr40.dtbo

I have it both at the Jetson also Host PC Jetpack folder
hope that helps

@Andrey1984 Thanks for the reply.
It’s only on my host computer , seems that the installed kernel didn’t got it .
Should I recompile it or copy the dtbo ?

Also I got to stay on jetpack 4.2.1 for software compatibility

after flashing with the moost recent jetpack the file will likely be presented at the jetson OS
I did not try , but it might also be the case for 4.2.1

Ok I will give it a try with 4.2.1 and level up if not

EDIT:

  • 4.2.3 : no file tegra194-p2888-0001-p2822-0000-hdr40.dtbo, I try few things but didn’t work
  • 4.3 : file tegra194-p2888-0001-p2822-0000-hdr40.dtbo exist and I apply the method of @aspen.eyers but when I update extlinux.conf with the same FTD sentence , it bricked the AGX, I tried with FTD /boot/tegra194-p2888-0001-p2822-0000-user-custom.dtb without any success

I think I can stick to 4.3 but I will need to recompile the kernel, no ? like the end of the answer of @aspen.eyers

If I edit the dtsi file, should I recompile ?

EDIT2 : I just follow this tutorial with some modifications https://msadowski.github.io/pps-support-jetson-nano/ and it’s the better result I got; just pps0 no pps1

Still missing one :(

Finally I got something for the PPS injection in the AGX Xavier

For those with the same issues, here is what I did :

  • Activate PPS support, as mentioned in the thread, on the kernel in the file .config

      # PPS support
      CONFIG_PPS=y
      # CONFIG_PPS_DEBUG is not set
      # PPS clients support
      CONFIG_PPS_CLIENT_KTIMER=y
      CONFIG_PPS_CLIENT_LDISC=y
      CONFIG_PPS_CLIENT_GPIO=y
      # PPS generators support
      # CONFIG_NVPPS is not set
    
  • Then edit the file tegra194-soc-base.dtsi in nvidia/nvidia_sdk/JetPack_4.3_Linux_JETSON_AGX_XAVIER/Linux_for_Tegra/sources/hardware/nvidia/soc/t19x/kernel-dts/tegra194-soc by adding

      pps: pps_gpio {
      compatible = "pps-gpio";
      gpios = <&tegra_main_gpio 206 1>;
      assert-falling-edge;
      status = "okay";
      };
    
  • Then recompile the kernel and flash it, check pps0 and pps1 with pps-tools

Now, I try to configure ntp and ptp with this configuration.

For now, my configuration for ntp is :

server 127.127.20.0 mode 24 minpoll 3 burst iburst prefer
fudge 127.127.20.0 stratum 1 flag1 1 flag2 0 flag3 1 flag4 0 time1 0.0 time2 0.0 refid GPS0
server 127.127.28.0 minpoll 4
fudge  127.127.28.0 time1 0.0 refid NMEA
server 127.127.28.1 minpoll 4 prefer
fudge  127.127.28.1 refid PPS

ls -la /dev/gps*
lrwxrwxrwx 1 root root 12 déc.  18 15:10 /dev/gps0 -> /dev/ttyTHS0
lrwxrwxrwx 1 root root  9 déc.  18 15:10 /dev/gpspps0 -> /dev/pps1

nptime seems to be disagree to my setup

  $ntptime 
  ntp_gettime() returns code 0 (OK)
  time e3874a4a.9fb22000  Fri, Dec 18 2020 16:33:30.623, (.623812),
  maximum error 1205016 us, estimated error 16 us, TAI offset 0
  ntp_adjtime() returns code 0 (OK)
  modes 0x0 (),
  offset 0.000 us, frequency 0.000 ppm, interval 1 s,
  maximum error 1205016 us, estimated error 16 us,
  status 0x1 (PLL),
  time constant 7, precision 1.000 us, tolerance 500 ppm,

Any advises ?

Seems there is an issue again with the kernel

déc. 20 19:57:15 nvidia-desktop ntpd[8788]: refclock_params: time_pps_kcbind: Operation not supported

I read on this forum https://forum.odroid.com/viewtopic.php?t=39595 that I need to add CONFIG_NTP_PPS to the kernel but the compilation overwrite the config file.

How did you manage to activate it @Andrey1984 ?
Also is there other options I need to activate for NTP/PTP/PPS kernel for Xavier AGX that I’m not aware of ? That would really need a full tutorial from NVIDIA :(

@Tomlogan501
are you able to get pps output with
sudo ppstest /dev/pps0
are you able to read the NMEA sequence with
sudo cat /dev/tty[custom_ending]?
is the NMEA connected over usb or UART/ gpio?

@Andrey1984
I can get the pps output and the nmea sequence.
It’s when I configure NTP with PPS support that I got issues.

Does the NMEA come from USB or UART?
Both? Neither of the two?