BPI-R3 RTC and PPS

Looks better now. Although it seems like ntpsec is not seeing the pps yet

root@bpi-r3:~#  zcat /proc/config.gz | grep PPS
CONFIG_PPS=y
# CONFIG_PPS_DEBUG is not set
CONFIG_NTP_PPS=y
# PPS clients support
# CONFIG_PPS_CLIENT_KTIMER is not set
# CONFIG_PPS_CLIENT_LDISC is not set
CONFIG_PPS_CLIENT_GPIO=y
# PPS generators support
root@bpi-r3:~#  zcat /proc/config.gz | grep HZ
CONFIG_HZ_PERIODIC=y
# CONFIG_NO_HZ_IDLE is not set
# CONFIG_NO_HZ_FULL is not set
# CONFIG_NO_HZ is not set
CONFIG_HZ_100=y
# CONFIG_HZ_250 is not set
# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=100



root@bpi-r3:~# dmesg | grep pps
[    0.040431] pps_core: LinuxPPS API ver. 1 registered
[    0.040438] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <[email protected]>
[    1.837968] pps pps0: new PPS source pps.-1
[    1.842234] pps pps0: Registered IRQ 80 as PPS source

refclock pps unit 0 minpoll 3 maxpoll 3 flag3 1 prefer server 127.127.28.0 minpoll 4 maxpoll 4

refclock pps unit 0 minpoll 3 maxpoll 3 flag3 1 prefer server 127.127.28.0 minpoll 4 maxpoll 4

root@bpi-r3:~# tail -f /var/log/ntp.log | grep PROTO
2022-08-07T09:31:42 ntpd[3951]: PROTO: 0.0.0.0 c012 02 freq_set kernel 500.000000 PPM
2022-08-07T09:31:42 ntpd[3951]: PROTO: 0.0.0.0 c016 06 restart
2022-08-07T09:31:45 ntpd[3951]: PROTO: SHM(0) 801b 8b clock_event clk_no_reply

Actually, now I see this entry in the ntp.log after fixing the /dev/pps0 permissions, so it might start working.

2023-04-19T12:29:06 ntpd[4024]: PROTO: PPS(0) 8014 84 reachable

Also seeing this in dmesg

[ 604.634856] pps pps0: bound kernel consumer: edge=0x1

Yup, that’s what you want to see.

If you run ntpq -4 -u -c peer <SERVER>, you should see something similar to:

 remote           refid      st t when poll reach   delay   offset   jitter
===============================================================================
oPPS(0)          .PPS.            0 l    3    8  377      0ns   -343ns    676ns
+SHM(0)          .SHM.            0 l    -   16  377      0ns    -44ns    350ns

You want to see that o against PPS.

You may have to set $PYTHONPATH appropriately.

Immediately after the ’ bound kernel consumer’ event I see this message on the console, this is repeated non-stop. I tried rebooting just in case without any luck

bpi-r3 login: [  176.115399] pps pps0: bound kernel consumer: edge=0x1
[  177.535097] hardpps: PPSJITTER: bad pulse
[  178.534036] hardpps: PPSJITTER: bad pulse
[  179.532968] hardpps: PPSJITTER: bad pulse

The ntp log never shows ‘kern PPS enabled status’ and the offset/jitter increases over time

 remote                                  refid      st t when poll reach   delay   offset   jitter
======================================================================================================
 16.14.168.192.wifi                     .DNS.           16 u    -   64    0      0ns      0ns    477ns
xPPS(0)                                 .PPS.            0 l    4    8  377      0ns 394.19ms 20.674ms
xSHM(0)                                 .SHM.            0 l    3   16  377      0ns 149.68ms 65.476ms

‘PPSJITTER: bad pulse’ seems to indicate just that, a bad pulse. Even though I can see it with ppstest, so it’s there, and shows a high offset as well.

root@bpi-r3:~# 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 1681926577.526630572, sequence: 779 - clear  0.000000000, sequence: 0
source 0 - assert 1681926578.526065270, sequence: 780 - clear  0.000000000, sequence: 0
source 0 - assert 1681926579.525500430, sequence: 781 - clear  0.000000000, sequence: 0
source 0 - assert 1681926580.524934436, sequence: 782 - clear  0.000000000, sequence: 0
source 0 - assert 1681926581.524368134, sequence: 783 - clear  0.000000000, sequence: 0
source 0 - assert 1681926582.523802910, sequence: 784 - clear  0.000000000, sequence: 0

Ugh, does not look good. Assuming systemd, does the unit file have:

ConditionCapability=CAP_SYS_TIME

listed and it must run as root (I think)?

You may also want to look at the output of journalctl -u <unit> and see what it produces. Mine is:

Apr 10 10:46:47 feeder systemd[1]: Starting Network Time Service...
Apr 10 10:46:47 feeder ntpd[1152]: INIT: ntpd ntpsec-1.2.1+110-ga49d53b7f-dirty: Starting
Apr 10 10:46:47 feeder ntpd[1152]: INIT: Command line: /opt/ntpsec-20220626/sbin/ntpd -g -N -u ntp:ntp -c /opt/ntpsec-conf/etc/ntp.conf
Apr 10 10:46:47 feeder ntpd[1152]: 2023-04-10T10:46:47 ntpd[1152]: INIT: ntpd ntpsec-1.2.1+110-ga49d53b7f-dirty: Starting
Apr 10 10:46:47 feeder ntpd[1152]: 2023-04-10T10:46:47 ntpd[1152]: INIT: Command line: /opt/ntpsec-20220626/sbin/ntpd -g -N -u ntp:ntp -c /opt/ntpsec-conf/etc/ntp.conf
Apr 10 10:46:47 feeder ntpd[1160]: INIT: precision = 0.370 usec (-21)
Apr 10 10:46:47 feeder ntpd[1160]: INIT: successfully locked into RAM
Apr 10 10:46:47 feeder ntpd[1160]: CONFIG: readconfig: parsing file: /opt/ntpsec-conf/etc/ntp.conf
Apr 10 10:46:47 feeder ntpd[1160]: CONFIG: requestkey is a no-op because ntpdc has been removed.
Apr 10 10:46:47 feeder ntpd[1160]: LOG: switching logging to file /var/log/ntpstats/ntp.log
Apr 10 10:46:47 feeder systemd[1]: Started Network Time Service.

Yes, it’s systemd and has ConditionCapability=CAP_SYS_TIME

It was running as ntpsec:ntpsec I switched to root:root but that didnt make a different, same “bad pulse” message and offset increasing.

Do you have a BPI-R3? what OS ?

I’m running opensuse on a Pi4. I’m waiting on kernel 6.3 and opensuse updating the tumbleweed release with it before trying it on my BPi-R3, so it will be a few weeks as I learn how to build it.

I wonder if the offset is too great for the PPS signal. At 0.5s, the system may not know whether to go up or down to the nearest seconds, so…

First step, comment out the server 127.127.28.0 minpoll 4 maxpoll 4 line in ntp.conf and replace it with a server somewhere on the internet and see it can sync with that.

If that works, find the fastest stable serial sync speed from the gps device. And from that speed, calculate the line delay for ~80 characters and use that as an offset.

Next, configure the gps to only send out the minimum required sentences for ntp/gpsd to function.

There are some dire gps units out there. The one I had from Adafruit, the “ultimate”, was poor, so please tell us which device it actually is.

What you said about 0.5s and the system not knowing to go up or down go me thinking…

Comparing the output of ntpq -pcrv on the RPI, frequency=-2.153992 whereas BPI shows a fixed value of frequency=500.0. This is described as “frequency offset (PPM) relative to hardware clock”, I wonder if a fixed value is expected

#  rpi: ntpq -pcrv
     remote                                   refid      st t when poll reach   delay   offset   jitter
=======================================================================================================
oPPS(0)                                  .PPS.            0 l   13   16  377   0.0000  -0.0055   0.0006
*SHM(0)                                  .GPS.            0 l   12   16  377   0.0000   3.8226   3.5603
status=0115 leap_none, sync_pps, 1 event, clock_sync,
leap=00, stratum=1, precision=-19, rootdelay=0.0, rootdisp=1.195, refid=PPS, reftime=e7eafce9.84e618c4 2023-04-19T23:51:05.519Z, tc=4, peer=17768, offset=-0.005473, **frequency=-2.153992,** sys_jitter=0.000619,
clk_jitter=0.000742, clock=e7eafcf7.3766f7f7 2023-04-19T23:51:19.216Z, processor="aarch64", system="Linux/5.15.84-v8+", version="ntpd ntpsec-1.2.0 2021-06-17T05:15:04Z", clk_wander=0.001296, tai=37,
leapsec="2017-01-01", expire="2023-06-28T", mintc=0

# bpi: ntpq -pcrv
     remote                                   refid      st t when poll reach   delay   offset   jitter
=======================================================================================================
oPPS(0)                                  .PPS.            0 l    -    8  377   0.0000  20.1187   0.0053
xSHM(0)                                  .SHM.            0 l    9   16  377   0.0000 -251.056  10.1729
status=0138 leap_none, sync_pps, 3 events, no_sys_peer,
leap=00, stratum=1, precision=-21, rootdelay=0.0, rootdisp=20.252, refid=PPS, reftime=e7eafde4.b4d050fa 2023-04-19T23:55:16.706Z, tc=3, peer=17768,
offset=20.118738, frequency=500.0, sys_jitter=0.005303, clk_jitter=0.00157, clock=e7eafde5.b4bdf9fa 2023-04-19T23:55:17.706Z, processor="aarch64",
system="Linux/6.3.0-rc6-bpi-r3-pwm", version="ntpd ntpsec-1.2.0 2021-06-17T05:15:04Z", clk_wander=0.0, tai=37, leapsec="2017-01-01", expire="2023-12-28T",
mintc=0

Well, that looks better. I assume SHM is not being used due to the offset being ~250ms. If you give the -u switch to ntpq (ntpsec version only), as in ntpq -u -pcrv, it give you the units which you really want it to be in nanoseconds. You’ll also see that frequency is in units ofppm`.

So, as per my previous reply, configure an external ntp time source in conjunction with PPS, just to ensure that it does work given a sane time signal.

Once that is done, start by increasing the serial baud rate, 9600 is too slow, and modifying the offset times.

You’ll also need to reduce the sentence type the gps emits to the bare minimum.

Still like to know what device you are using.

I tried with a ublox neo6m and now I’m using ATGM336H attached to uart2 and GPIO 65

Here’s the output with -u. It seems like the offset decreased but it’s really floating.

# ntpq -u -pcrv
     remote                                  refid      st t when poll reach   delay   offset   jitter
======================================================================================================
+16.14.168.192.wifi                     .GPS.            1 u   56   64  377 2.3518ms 62.608ms 32.305ms
oPPS(0)                                 .PPS.            0 l    6   16  377      0ns 72.997ms 8.6598ms
*SHM(0)                                 .GPS.            0 l    8   16  377      0ns -30.32ms 14.851ms
status=0118 leap_none, sync_pps, 1 event, no_sys_peer,
leap=00, stratum=1, precision=-21, rootdelay=0us, rootdisp=94.499ms, refid=PPS,
reftime=e7eb98f9.bcaa7f90 2023-04-20T10:56:57.736Z, tc=4, peer=17768, offset=83.056912ms,
frequency=500.000000ppm, sys_jitter=0ns, clk_jitter=19.942439ms,
clock=e7eb9910.a042667c 2023-04-20T10:57:20.626Z, processor="aarch64",
system="Linux/6.3.0-rc6-bpi-r3-pwm", version="ntpd ntpsec-1.2.0 2021-06-17T05:15:04Z",
clk_wander=2.291196ppm, tai=37s, leapsec="2017-01-01", expire="2023-12-28T", mintc=0

I would say user side is now setup correctly, but kernel side is not. The o & + should mean they are working together.

From ntpq, you do not want to see no_sys_peer, but you do want kern, and I assume you are missing either of:

Apr 10 10:46:13 feeder kernel: pps pps0: new PPS source [email protected]
Apr 10 10:46:13 feeder kernel: pps pps0: Registered IRQ 67 as PPS source

So, it would seem you are not loading the pps-gpio dts.

You need someway to load:

dtoverlay=pps-gpio,gpiopin=18

Where, as you may expect, 18 is the gpio pin number the pps is connected to. And you should also have the pps-gpio kernel module loaded.

Out of curiosity, you mentioned these 2 lines…

Did you really mean:

refclock pps unit 0 minpoll 3 maxpoll 3 flag3 1 prefer
server 127.127.28.0 minpoll 4 maxpoll 4
refclock pps unit 0 minpoll 3 maxpoll 3 flag3 1 prefer
server 127.127.28.0 minpoll 4 maxpoll 4

Yes, correct, formatting issues, it’s two lines

refclock pps unit 0 minpoll 3 maxpoll 3 flag3 1 prefer
server 127.127.28.0 minpoll 4 maxpoll 4
refclock pps unit 0 minpoll 3 maxpoll 3 flag3 1 prefer
server 127.127.28.0 minpoll 4 maxpoll 4

I did more testing, tried a different GPIO, different GPS module and the results are consistent, as soon as the PPS led starts blinking on the GPS, I see the entry below repeated over and over. So that means it does detect the PPS on the configured GPIO.

[  627.134839] pps pps0: bound kernel consumer: edge=0x1
[  627.694284] hardpps: PPSJITTER: bad pulse
[  628.693223] hardpps: PPSJITTER: bad pulse
[  629.692160] hardpps: PPSJITTER: bad pulse

If the GPS lock goes away, it stops

I think this is the problem causing ntpsec to not work properly. No use troubleshooting from ntpsec angle until the PPS is properly read up by the OS

2023-04-20T12:57:21 ntpd[5136]: PROTO: 0.0.0.0 c018 08 no_sys_peer
2023-04-20T13:02:25 ntpd[5136]: PROTO: 0.0.0.0 011d 0d kern PPS enabled status: 2301 -> 0007
2023-04-20T13:02:25 ntpd[5136]: CLOCK: kernel reports TIME_ERROR: 0x2307: PPS Time Sync wanted but PPS Jitter exceeded
2023-04-20T13:02:25 ntpd[5136]: CLOCK: kernel reports TIME_ERROR: 0x2307: PPS Time Sync wanted but PPS Jitter exceeded

Both of your GPS’s run at 9600 baud as default. This speed is far too slow. You really, really, REALLY need to increase this to 115200. Alternatively, see if you can use the USB interface on the ublox device.

At 9600, with 8n1 and a sentence length of 80 characters, each sentence is going to take around 0.1 seconds. 10 sentences a second and the line is saturated. If the time changes, are there are 4 sentences queued, then that fifth, with the time change will mean it will exceed the 0.5 second threshold.

Since you do not know when it will change, it will vary from 0.1 seconds to goodness know what.

You really need to increase the transfer rate.

It’s been a while, I gave up for a while.

Turns out this issue seems related to ntpsec. I switched to chrony and it worked right away, I got the BPI-r3 serving stable nano second precision time from GPSD and PPS0.

Thanks for the help

Hi, I have add a bash script and auto run at start up to function a RTC DS3231 (DS1307 compatible) module successfully. Here is the script.

*#!/bin/sh*

*sleep_time=15 #Sleep time in seconds*

*chgidx=0 #Change time action index*

*chgtigg=0 #Change time trigger*

*timsyncdone=0 #Exit change time loop*

*i2cdetect -y -r -a 0*

*modprobe rtc-ds1307*

*echo ds1307 0x68 > /sys/bus/i2c/devices/i2c-0/new_device*


*while [ "$timsyncdone" -eq 0 ]*

*do*

*wanonline="$(ping -c 1 1.1.1.1 &> /dev/null && echo 1 || echo 0)"*

*if [ "$wanonline" -eq "$chgidx" ] && [ "$chgtigg" -eq "$chgidx" ]; then*

*hwclock -s*

*chgtigg=1*

*fi*

*if [ "$wanonline" -gt "$chgidx" ] && [ "$chgtigg" -eq "$chgidx" ]; then*

*hwclock -w*

*timsyncdone=1*

*fi*

*if [ "$wanonline" -gt "$chgidx" ] && [ "$chgtigg" -gt "$chgidx" ]; then*

*chgtigg=0*

*fi*

*sleep $sleep_time*

*done*