BeagleBone Black GPS PPS and Chrony for time sync

Hello,
My goal is to make an ultra-precise clock on the beaglebone black by using the 1 pps signal from my adafruit GPS. I have been readying about the device overlays / capes but there seems to be a lot of outdated information out there that is very confusing.

My 1 pps is connected to P9_12
GPS Rx: P9_24
GPS Tx: P9_26

I found the following DTS file: https://github.com/ddrown/pps-gmtimer/blob/master/DD-GPS-00A0.dts

I then edited this file, and replaced the pins with my pins as listed above. After compiling the file, I get the following warning:

root@AD1:/lib/firmware# dtc -O dtb -o /lib/firmware/DD-GPS-00A0.dtbo -b 0-@ DD-GPS-00A0.dts
/lib/firmware/DD-GPS-00A0.dtbo: Warning (unit_address_vs_reg): Node /fragment@0 has a unit name, but no reg property
/lib/firmware/DD-GPS-00A0.dtbo: Warning (unit_address_vs_reg): Node /fragment@1 has a unit name, but no reg property
/lib/firmware/DD-GPS-00A0.dtbo: Warning (unit_address_vs_reg): Node /fragment@2 has a unit name, but no reg property

Then, I edited my /boot/uEnv.txt and pointed: uboot_overlay_addr0=/lib/firmware/DD-GPS-00A0.dtbo

I next rebooted, and expected to see something in dmesg about the 1pps signal, but I didn’t. I do see the following:

root@AWD1:/lib/firmware# dmesg |grep pps
[ 0.725865] pps_core: LinuxPPS API ver. 1 registered

1 Like

Use this overlay as an example:

https://github.com/beagleboard/bb.org-overlays/blob/master/src/arm/PB-UART4-GNSS-5-CLICK.dts

https://download.mikroe.com/documents/add-on-boards/click/gnss-5/gnss-5-click-schematic-v101.pdf

Regards,

Robert,

Thank you for the fast reply.

So I assume that I need to edit your lines:

P2_01_pinmux { status = “disabled”; }; /* gpio1_18 - EXTINT */

P2_03_pinmux { status = “disabled”; }; /* gpio0_23 - PULSE */

P2_05_pinmux { status = “disabled”; }; /* gpio0_30 - TXD */

P2_07_pinmux { status = “disabled”; }; /* gpio0_31 - RXD /
P1_04_pinmux { status = “disabled”; }; /
gpio2_25 - RST */

I am unsure how you are getting the naming convention for these pins. Can you shed some light on it for me?

Thank you

Those pin defintion’s are tied to the PocketBeagle…

For the older BeagleBone use this example for the usart pis

https://github.com/beagleboard/bb.org-overlays/blob/master/src/arm/BB-UART1-00A0.dts#L36-L66

and expand that for P9_12, look at P8_26 here for help:

https://github.com/beagleboard/bb.org-overlays/blob/master/src/arm/BB-RTC-01-00A0.dts#L39

https://github.com/beagleboard/bb.org-overlays/blob/master/src/arm/BB-RTC-01-00A0.dts#L61-L65

The main thing to take away from the PB-UART4-GNSS-5-CLICK.dts example is the pps node…

https://github.com/beagleboard/bb.org-overlays/blob/master/src/arm/PB-UART4-GNSS-5-CLICK.dts#L46-L58

and the test it with the ppstest binary:

[ 30.902060] pps_core: LinuxPPS API ver. 1 registered
[ 30.907113] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 30.945900] pps pps0: new PPS source pps.-1
[ 30.956911] pps pps0: Registered IRQ 74 as PPS source
debian@beaglebone:~$ 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 1523553378.571630304, sequence: 15 - clear 0.000000000, sequence: 0
source 0 - assert 1523553379.571678846, sequence: 16 - clear 0.000000000, sequence: 0

Regards,

Robert,
Thank you again for your assistance. I am stuck trying to get the overlay to compile and am assuming that I have something incorrect. Below is the overlay that I created:

/*
* Copyright (C) 2013 CircuitCo

Hi Robert,
So I was able to get the file compiled. Basically, I pulled down your bb.org-overlays project from github, then added my custom dbs file to the /src/arm directory and finally ran ./install.sh This seemed to compile and install the new dtbo in the /lib/firmware directory.

Next, I made sure the new dtbo was added in my uEnv.txt file and rebooted. Success, now I have a pps0. However, when I check it with ppstest, it just times out.

I have checked my pin 9-12 with an oscilliscope, and I do see a squarewave once per second on that pin. So I am assuming there is a problem with my overlay file. Do you happen to have or know where to find an overlay that is just the PPS? Or perhaps just the PPS and the UART pins for gps/nmea strings?

This has been quite the learning curve so I am sure I have something wrong in my file. Below is the dts file that I edited and am testing with: I know it has a lot of extra stuff in it, but I was just trying to get something to work before I started removing stuff from the file.

/dts-v1/;
/plugin/;

#include <dt-bindings/board/am335x-bbw-bbb-base.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/am33xx.h>

/ {
compatible = “ti,beaglebone”, “ti,beaglebone-black”, “ti,beaglebone-green”;

/* identification */
part-number = “CLOCK”;
version = “00A0”;

exclusive-use =
“P9.24”, “P9.26”, “P9.15”, “uart1”, // gps and pps
“P9.17”, “P9.18”, “P9.21”, “P9.22”, “spi0”, // spi display
“P9.19”, “P9.20”, “i2c2”, “P9.12”, “P9.14”; // rtc

fragment@0 {
target = <&ocp>;
overlay {
P9_24_pinmux { status = “disabled”; };
P9_26_pinmux { status = “disabled”; };
P9_15_pinmux { status = “disabled”; };

P9_17_pinmux { status = “disabled”; };
P9_18_pinmux { status = “disabled”; };
P9_21_pinmux { status = “disabled”; };
P9_22_pinmux { status = “disabled”; };

P9_19_pinmux { status = “disabled”; };
P9_20_pinmux { status = “disabled”; };
P9_12_pinmux { status = “disabled”; };
P9_14_pinmux { status = “disabled”; };
};
};

fragment@1 {
target = <&am33xx_pinmux>;
overlay {
bb_uart1_pins: pinmux_bb_uart1_pins {
pinctrl-single,pins = <
BONE_P9_24 (PIN_OUTPUT | MUX_MODE6)
BONE_P9_26 (PIN_INPUT | MUX_MODE6)

;
};

bb_gps_pps_pins: pinmux_bb_gps_pps_pins {
pinctrl-single,pins = <
BONE_P9_12 (PIN_INPUT_PULLDOWN | MUX_MODE7)

;
};

bb_spi0_pins: pinmux_bb_spi0_pins {
pinctrl-single,pins = <
BONE_P9_22 (PIN_INPUT_PULLUP | MUX_MODE0)
BONE_P9_21 (PIN_INPUT_PULLUP | MUX_MODE0)
BONE_P9_18 (PIN_OUTPUT_PULLUP | MUX_MODE0)
BONE_P9_17 (PIN_OUTPUT_PULLUP | MUX_MODE0)

;
};

bb_i2c2_pins: pinmux_bb_i2c2_pins {
pinctrl-single,pins = <
BONE_P9_20 (SLEWCTRL_SLOW | PIN_INPUT_PULLUP | MUX_MODE3)
BONE_P9_19 (SLEWCTRL_SLOW | PIN_INPUT_PULLUP | MUX_MODE3)

;
};

bb_rtc_pps_pins: pinmux_bb_rtc_pps_pins {
pinctrl-single,pins = <
BONE_P9_14 (PIN_INPUT_PULLUP | MUX_MODE7)

;
};

bb_rtc_32k_pins: pinmux_bb_rtc_32k_pins {
pinctrl-single,pins = <
BONE_P9_15 (PIN_INPUT_PULLUP | MUX_MODE7)

;
};
};
};

fragment@2 {
target = <&uart1>;
overlay {
status = “okay”;
pinctrl-names = “default”;

pinctrl-0 = <&bb_uart1_pins>;
};
};

fragment@3 {
target = <&ocp>;
overlay {
gps_pps {
status = “okay”;
compatible = “pps-gpio”;
pinctrl-names = “default”;
pinctrl-0 = <&bb_gps_pps_pins>;
gpios = <&gpio1 16 0>;
};

rtc_pps {
status = “okay”;
compatible = “pps-gpio”;
pinctrl-names = “default”;
pinctrl-0 = <&bb_rtc_pps_pins>;
gpios = <&gpio1 18 0>;
};
};
};

fragment@4 {
target = <&spi0>;
overlay {
#address-cells = <1>;
#size-cells = <0>;
status = “okay”;

pinctrl-names = “default”;
pinctrl-0 = <&bb_spi0_pins>;

display@0 {
status = “okay”;
compatible = “spidev”;
spi-max-frequency = <10000000>;
reg = <0>;
};
};
};

fragment@5 {
target = <&i2c2>;
overlay {
status = “okay”;
pinctrl-names = “default”;
pinctrl-0 = <&bb_i2c2_pins>;
clock-frequency = <400000>;
#address-cells = <1>;
#size-cells = <0>;

ds3231: ds3231@51 {
status = “okay”;
compatible = “maxim,ds3231”;
reg = <0x68>;
#clock-cells = <1>;
};
};
};
fragment@6 {
target-path=“/”;
overlay {
aliases {
rtc0 = “/ocp/i2c@4819c000/ds3231@51”;
rtc1 = “/ocp/rtc@44e3e000”;
};
};
};
};

        fragment@3 {
                target = <&ocp>;
                __overlay__ {
                        gps_pps {
                                status = "okay";
                                compatible = "pps-gpio";
                                pinctrl-names = "default";
                                pinctrl-0 = <&bb_gps_pps_pins>;
                                gpios = <&gpio1 16 0>;
                        };

                        rtc_pps {
                                status = "okay";
                                compatible = "pps-gpio";
                                pinctrl-names = "default";
                                pinctrl-0 = <&bb_rtc_pps_pins>;
                                gpios = <&gpio1 18 0>;
                        };
                };
        };

This pps node, needs to be under / not ocp

target = <&ocp>; -> target-path="/";

Regards,

Robert,
Your help is much appreciated! Making progress I think... Well, kind of...

So I attempted to replace target = <&ocp>; with target = "/" (when it should have been target-path)

I didnt notice the typo and applied the overlay in uEnv.txt and rebooted. Now, I can not connect to the device. When I hit the reset button, the networking stack is brought up, so I can ping the device, but that is it. No SSH. So I connected a USB cable, and it appears that I am having issues with it also... The PC is not creating the ethernet adapter when the cable is connected.

Any thoughts as to how to recover from this state besides trying to re-flash the device?

Thanks!

If you were using the microSD, i'd say to just fix it.. But with the
eMMC, you'll pretty much need a reflash. U-Boot currently doesn't
have any error detection when applying overlays.. Everything just
breaks in bootup..

Regards,

Thats what I was afraid of. Ok, Ill give it a shot, fix my typo, recompile then report back.

Thanks again!

Hi.
Is posible to boot from an microsd and modify the uEnv file on the emmc after mounting it?
Sorry if i misunderstood the problem

Pablo

Good point, yeah it is…

Regards,

I have re-imaged my BBB and made the correction to the typo in my overlay file. However, it appears as if I am having the same issue. When I install the overlay in the uEnv.txt file and reboot, I am never able to ssh back into the BBB.

My file is below for your review. I can't seem to find any problems with it, and seem to be stuck again. Do you have any recommendations on how to proceed?

/dts-v1/;
/plugin/;

#include <dt-bindings/board/am335x-bbw-bbb-base.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/am33xx.h>

/ {
        compatible = "ti,beaglebone", "ti,beaglebone-black", "ti,beaglebone-green";

        /* identification */
        part-number = "CLOCK";
        version = "00A0";

        exclusive-use =
                "P9.12", "P9.24", "P9.26", "uart1"; // gps and pps

        fragment@0 {
                target = <&ocp>;
                __overlay__ {
                        P9_12_pinmux { status = "disabled"; };
                        P9_24_pinmux { status = "disabled"; };
                        P9_26_pinmux { status = "disabled"; };
                };
        };

        fragment@1 {
                target = <&am33xx_pinmux>;
                __overlay__ {
                        bb_uart4_pins: pinmux_bb_uart1_pins {
                                pinctrl-single,pins = <
                                        BONE_P9_24 (PIN_OUTPUT | MUX_MODE6)
                                        BONE_P9_26 (PIN_INPUT | MUX_MODE6)
                                >;
                        };

                        bb_gps_pps_pins: pinmux_bb_gps_pps_pins {
                                pinctrl-single,pins = <
                                        BONE_P9_12 (PIN_INPUT_PULLDOWN | MUX_MODE7)
                                >;
                        };

                };
        };

        fragment@2 {
                target = <&uart1>;
                __overlay__ {
                        status = "okay";
                        pinctrl-names = "default";
                        pinctrl-0 = <&bb_uart1_pins>;
               };
        };

        fragment@3 {
                target-path = "/";
                __overlay__ {
                        gps_pps {
                                status = "okay";
                                compatible = "pps-gpio";
                                pinctrl-names = "default";
                                pinctrl-0 = <&bb_gps_pps_pins>;
                                gpios = <&gpio1 16 0>;
                        };
                };
        };

};

1 Like

I have re-imaged my BBB and made the correction to the typo in my overlay file. However, it appears as if I am having the same issue. When I install the overlay in the uEnv.txt file and reboot, I am never able to ssh back into the BBB.

My file is below for your review. I can't seem to find any problems with it, and seem to be stuck again. Do you have any recommendations on how to proceed?

Your very close, just change one "4" to a "1".. :wink:

        fragment@1 {
                target = <&am33xx_pinmux>;
                __overlay__ {
                        bb_uart4_pins: pinmux_bb_uart1_pins {

These don't match..

                        pinctrl-0 = <&bb_uart1_pins>;

just change:

bb_uart1_pins: pinmux_bb_uart1_pins {

Then it loads correctly..

uboot_overlays: [fdt_buffer=0x60000] ...
uboot_overlays: loading /lib/firmware/CLOCK.dtbo ...
1607 bytes read in 377 ms (3.9 KiB/s)
uboot_overlays: loading /lib/firmware/BB-BONE-eMMC1-01-00A0.dtbo ...
1440 bytes read in 272 ms (4.9 KiB/s)
uboot_overlays: loading /lib/firmware/BB-HDMI-TDA998x-00A0.dtbo ...
5127 bytes read in 149 ms (33.2 KiB/s)
uboot_overlays: loading /lib/firmware/BB-ADC-00A0.dtbo ...
711 bytes read in 77 ms (8.8 KiB/s)
uboot_overlays: loading /lib/firmware/AM335X-PRU-RPROC-4-14-TI-00A0.dtbo ...
3513 bytes read in 459 ms (6.8 KiB/s)

debian@beaglebone:~$ dmesg | grep pps
[ 0.617569] pps_core: LinuxPPS API ver. 1 registered
[ 0.617576] pps_core: Software ver. 5.3.6 - Copyright 2005-2007
Rodolfo Giometti <giometti@linux.it>
[ 40.470657] pps pps0: new PPS source gps_pps.-1
[ 40.470808] pps pps0: Registered IRQ 115 as PPS source

debian@beaglebone:~$ ls /dev/pps0
/dev/pps0
debian@beaglebone:~$ sudo ppstest /dev/pps0
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
time_pps_fetch() error -1 (Connection timed out)
^C

(i don't have anything wired, so it'll time out)

Regards,

Robert,
I can't thank you enough for helping me through this. There is very little information available online regarding this procedure with this kernel version...

First, I made the edit that you recommended.. Now, the BBB reboots and I can see NEMA data coming from the GPS chip. However, when I run PPSTEST on /dev/pps0, I get the following:

trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
time_pps_fetch() error -1 (Connection timed out)
time_pps_fetch() error -1 (Connection timed out)
time_pps_fetch() error -1 (Connection timed out)
^C

I just measured the P9_12 pin, and I see 2.2v and a 100ms pulse width square wave coming from the Adafruit GPS receiver. Any other thoughts as to what might be causing the timeout?

Just looked it up, in the pps node you have:

gpios = <&gpio1 16 0>;

However P9_12 is:

gpio1 28

So swap the 16 for 28

Regards,

Perfect! That seems to have fixed my issues! Ill be sure to add a post on the web describing the procedures we went through to help others!

I do have one other question for you. If this is out of scope, Ill ask it on another forum, but I figured I would start here...

Now I have confirmed that I see NEMA messages on /dev/ttyS1 and I have pps data on /dev/pps0.

I next installed gpsd via apt-get and also chrony via apt-get.

using cgps, I do have a fix, but at the bottom it flashes pps:false

32","activated":"2018-08-30T19:35:48.716Z","flags":1,"native":0,"bps":9600,"parity":"N","stopbits":1,"cycle":1.00,"mincycle":0.20}]}
{"class":"WATCH","enable":true,"json":true,"nmea":false,"raw":0,"scaled":false,"timing":false,"split24":false,"pps":false}
{

Not sure about that one, so I checked chronyc sources, and get the following:
210 Number of sources = 2
MS Name/IP address Stratum Poll Reach LastRx Last sample

First off, Thanks Robert for all your help. Looks like we are up and running!

Next, I wanted to post a few notes in case others run into the issues that I had.

  1. From a clean install, apt-get update then apt-get upgrade

  2. git clone https://github.com/beagleboard/bb.org-overlays.git

  3. cd bb.org-overlays/src/arm

  4. Create your *.dbs file in this directory (above in thread)

  5. back up two levels to /bb.org-overlays/ and issue ./install.sh

  6. edit /boot/uEnv.txt and add: uboot_overlay_addr0=/lib/firmware/DD-GPS-00A0.dtbo

  7. reboot

  8. Here is some short python code to check your NMEA stream:

import serial
import Adafruit_BBIO.UART as UART
GPS = serial.Serial(’/dev/ttyS1’, 9600)
while(1):
while GPS.inWaiting()==0:
pass
NMEA=GPS.readline()
print NMEA

If all is well, you will see a stream of NMEA data coming across.

  1. Run pps-test /dev/pps0 to confirm you have a good pps signal
  2. install gpsd from apt-get
  3. gpsd -D 5 -n -N /dev/ttyS1 /dev/pps0
  4. then run cgps. You should see a valid fix and also in the raw data at the bottom, several lines about pps.
  5. install chrony from apt-get
  6. edit config:

change the clock slower for less jitter

minsamples 10

get NMEA data from gpsd over shared memory

refclock SHM 0 offset 0.395 delay 0.2 refid NMEA noselect

get PPS data from pps-gpio, summarize every 16 seconds, prefer it

#refclock PPS /dev/pps0 refid PPS poll 4 prefer
refclock PPS /dev/pps0 lock NMEA
keyfile /etc/chrony/chrony.keys
commandkey 1
driftfile /var/lib/chrony/chrony.drift
log tracking measurements statistics
logdir /var/log/chrony
maxupdateskew 100.0
dumponexit
dumpdir /var/lib/chrony

if local stratum is configured and there’s a local clock issue, the PPS changes stratum to match this stratum

#local stratum 10
allow
logchange 0.5
rtconutc

change this to the proper country code

#pool us.pool.ntp.org iburst offline

Make sure you start gpsd before chronyd.

Then run chronyc sources and you should be good to go!

Thanks again for all the help!

Hi,
I have gps with pps and signal level is measured in scope and is ok. The problem is that when ppstest command is run the pps output is displayed as ok but after arround 180 to 230 seconds i get error connection timed out error. I have gpsd amd chrony installed.
Strangely when i restart gpsd then ppstest gives correct output but then it shows connection timed out error again.

Hello,

I am trying to run NTP server on my PocketBeagle with GPS and PPS time source. To establish that I am following your notes.

However when I try to run gpsd it is giving me output like this:

:blush: gpsd -D 5 -n -N /dev/ttyO4 /dev/pps0
gpsd:INFO: launching (Version 3.17)
gpsd:IO: opening IPv4 socket
gpsd:ERROR: can’t bind to IPv4 port gpsd, Address already in use
gpsd:ERROR: maybe gpsd is already running!
gpsd:IO: opening IPv6 socket
gpsd:ERROR: can’t bind to IPv6 port gpsd, Address already in use
gpsd:ERROR: maybe gpsd is already running!
gpsd:INFO: command sockets creation failed, netlib errors -1, -1

Deep-dive into systemctl shows:

systemctl status gpsd.service
● gpsd.service - GPS (Global Positioning System) Daemon
Loaded: loaded (/lib/systemd/system/gpsd.service; disabled; vendor preset: enabled)
Active: failed (Result: timeout) since Tue 2021-03-09 18:48:39 UTC; 28min ago

Mar 09 18:47:09 beaglebone systemd[1]: Starting GPS (Global Positioning System) Daemon…
Mar 09 18:47:31 beaglebone systemd[1]: gpsd.service: Current command vanished from the unit file, execution of the command list won’t be resumed.
Mar 09 18:48:39 beaglebone systemd[1]: gpsd.service: Start operation timed out. Terminating.
Mar 09 18:48:39 beaglebone systemd[1]: gpsd.service: Failed with result ‘timeout’.
Mar 09 18:48:39 beaglebone systemd[1]: Failed to start GPS (Global Positioning System) Daemon.

Running cgps is giving normal output but when I start chrony it is updating only PPS.

Could you please help me with that?