User Tools

Site Tools


pps2sdp


This is an old revision of the document!


This page is very much a work in progress, with a focus on standing up a working initial configuration. There is an incredible amount of tuning that can be performed to dial in one of these systems after the fact.

PPS to SDP

There are a few effective ways to feed a PPS signal from a GNSS receiver (or other time source) into a computer. A few examples: on a system with a “standard” serial port, the DCD pin can be used very effectively, on many single board computers (e.g. Raspberry Pi et al) a GPIO pin can be used for PPS input. Purpose built hardware exists as well, network cards like the Solarflare SFN6322F have SMA connectors specifically for PPS in and out. In today's case, we're going to be looking at the Intel i210 ethernet controller. A humble PCIe gigabit network interface that just happens to have four software defined pins (thus, SDP) that can be used for hardware timestamping via IEEE1588 and IEEE 802.1AS.

The i210 and its software defined pins are well supported by the LinuxPTP project, and a number of folks have already put together some documentation on using its SDPs as a way to get hardware timestamps from a GNSS receiver into software like chrony or NTPsec.

Glossary of Terms

There are a lot of acronyms and initialisms in this space, so this terms table should help.

Term Meaning
SDP software defined pin
PPS pulse per second
TS timestamp
PTP precise timing protocol
PHC PTP Hardware Clock
SYS system clock

Prior Work & Documentation

Software

My examples in this section will use Debian (or Debian derived) Linux. Just about everything here is generic and can apply to other systems, such as Gentoo, Arch, or the many RHEL derivatives.

testptp

testptp is a tool that is included with the kernel source and can be easily built and run to verify the operation of a PTP source, as well as configure some parameters.

Build with:

gcc -static testptp.c -o testptp

Show capabilities:

root@ark02:~# testptp -c /dev/ptp0
capabilities:
  62499999 maximum frequency adjustment (ppb)
  0 programmable alarms
  2 external time stamp channels
  2 programmable periodic signals
  1 pulse per second
  4 programmable pins
  0 cross timestamping
  0 adjust_phase

Show pin status:

root@ark02:~# testptp /dev/ptp0 -l
name SDP0 index 0 func 0 chan 0
name SDP1 index 1 func 0 chan 0
name SDP2 index 2 func 0 chan 0
name SDP3 index 3 func 0 chan 0

Change pin 0 (SDP0) to external input:

root@ark02:~# testptp /dev/ptp0 -L0,1
set pin function okay
root@ark02:~# testptp /dev/ptp0 -l
name SDP0 index 0 func 1 chan 0
name SDP1 index 1 func 0 chan 0
name SDP2 index 2 func 0 chan 0
name SDP3 index 3 func 0 chan 0

Read ten timestamp events:

root@ark02:~# testptp /dev/ptp0 -e 10
external time stamp request okay
event index 0 at 1677526111.035729808
event index 0 at 1677526111.935764720
event index 0 at 1677526112.035768568
event index 0 at 1677526112.935803480
event index 0 at 1677526113.035807328
event index 0 at 1677526113.935842232
event index 0 at 1677526114.035846080
event index 0 at 1677526114.935880984
event index 0 at 1677526115.035884832
event index 0 at 1677526115.935919744

ts2phc

Part of the LinuxPTP project, ts2phc is a tool that synchronizes time stamps coming over the SDP with the PHC. The following command can be used to sync the incoming timestamps with the PHC. The system clock must be roughly correct for this to work correctly.

The device can be specified as /dev/ptp# or enp2s0.

ts2phc -c /dev/ptp0 -s generic -l 7 -f /etc/linuxptp/ts2phc.conf -m -q

ts2phc.conf

[global]
use_syslog              0
verbose                 1
logging_level           6
ts2phc.pulsewidth       100000000
max_frequency           1000000
step_threshold          0.05
[enp2s0]
ts2phc.channel          0
ts2phc.extts_polarity   both
ts2phc.pin_index        0
ts2phc.extts_correction 0

For a detailed explanation of the command line flags and config file settings, please check the ts2phc man page.

Note that in the config file,ts2phc.extts_polarity is set to both - this is the only polarity parameter that the i210 supports.

~ # ts2phc -c /dev/ptp0 -s generic -l 7 -f /etc/linuxptp/ts2phc.conf -m -q
[2220.318]: locked item global.use_syslog as 0
ts2phc[2220.319]: config item (null).message_tag is '(null)'
ts2phc[2220.319]: config item (null).verbose is 1
ts2phc[2220.319]: config item (null).use_syslog is 0
ts2phc[2220.319]: config item (null).logging_level is 7
ts2phc[2220.319]: config item eth0.ts2phc.master is 0
ts2phc[2220.319]: config item eth0.ts2phc.pin_index is 0
ts2phc[2220.319]: config item eth0.ts2phc.channel is 0
ts2phc[2220.319]: config item eth0.ts2phc.extts_polarity is 6
ts2phc[2220.319]: config item eth0.ts2phc.extts_correction is 0
ts2phc[2220.319]: config item eth0.ts2phc.pulsewidth is 100000000
ts2phc[2220.320]: config item (null).clock_servo is 0
ts2phc[2220.320]: config item (null).pi_proportional_const is 0.000000
ts2phc[2220.320]: config item (null).pi_integral_const is 0.000000
ts2phc[2220.320]: config item (null).pi_proportional_scale is 0.000000
ts2phc[2220.320]: config item (null).pi_proportional_exponent is -0.300000
ts2phc[2220.320]: config item (null).pi_proportional_norm_max is 0.700000
ts2phc[2220.320]: config item (null).pi_integral_scale is 0.000000
ts2phc[2220.320]: config item (null).pi_integral_exponent is 0.400000
ts2phc[2220.320]: config item (null).pi_integral_norm_max is 0.300000
ts2phc[2220.320]: config item (null).step_threshold is 0.050000
ts2phc[2220.320]: config item (null).first_step_threshold is 0.000020
ts2phc[2220.320]: config item (null).max_frequency is 1000000
ts2phc[2220.320]: config item (null).servo_offset_threshold is 0
ts2phc[2220.320]: config item (null).servo_num_offset_values is 10
ts2phc[2220.320]: PI servo: sync interval 1.000 kp 0.700 ki 0.300000
ts2phc[2220.320]: config item (null).free_running is 0
ts2phc[2220.320]: PPS sink eth0 has ptp index 0
ts2phc[2220.321]: UTC-TAI offset not set in system! Trying to revert to leapfile
ts2phc[2220.321]: config item (null).leapfile is '(null)'
ts2phc[2220.409]: eth0 SKIP extts index 0 at 1677618447.517148882 src 1677618485.77395669
ts2phc[2221.309]: adding tstamp 1677618448.417140794 to clock /dev/ptp0
ts2phc[2221.309]: /dev/ptp0 offset -37582859206 s0 freq      -0
ts2phc[2221.409]: eth0 SKIP extts index 0 at 1677618448.517139874 src 1677618486.77376579
ts2phc[2222.309]: adding tstamp 1677618449.417131786 to clock /dev/ptp0
ts2phc[2222.309]: /dev/ptp0 offset -37582868214 s1 freq   -9008
ts2phc[2222.409]: eth0 SKIP extts index 0 at 1677618487.099993986 src 1677618487.77376960
ts2phc[2223.309]: adding tstamp 1677618487.999993989 to clock /dev/ptp0
ts2phc[2223.309]: /dev/ptp0 offset      -6011 s2 freq  -15019
ts2phc[2223.409]: eth0 SKIP extts index 0 at 1677618488.099994569 src 1677618488.77372770
ts2phc[2224.309]: adding tstamp 1677618488.999999998 to clock /dev/ptp0
ts2phc[2224.309]: /dev/ptp0 offset         -2 s2 freq  -10813
ts2phc[2224.409]: eth0 SKIP extts index 0 at 1677618489.100000161 src 1677618489.77367493
ts2phc[2225.309]: adding tstamp 1677618490.000001797 to clock /dev/ptp0
ts2phc[2225.309]: /dev/ptp0 offset       1797 s2 freq   -9015
ts2phc[2225.409]: eth0 SKIP extts index 0 at 1677618490.100001779 src 1677618490.77370482
ts2phc[2226.309]: adding tstamp 1677618491.000001804 to clock /dev/ptp0
ts2phc[2226.309]: /dev/ptp0 offset       1804 s2 freq   -8469

phc2sys

Also a part of LinuxPTP, phc2sys is a utility included as part of the linuxptp project for syncing clocks - usually syncing PHC to SYS.

phc2sys -c eth0 -s CLOCK_REALTIME -O +37 -m -q

The +37 second offset aligns the clock with TAI.

~# phc2sys -c eth0 -s CLOCK_REALTIME -O +37 -m -q
phc2sys[2638.904]: eth0 sys offset  22822213 s0 freq   -9007 delay   2054
phc2sys[2639.905]: eth0 sys offset  22822277 s1 freq   -8943 delay   2067
phc2sys[2640.905]: eth0 sys offset     -5994 s2 freq  -14937 delay   2097
phc2sys[2641.905]: eth0 sys offset         7 s2 freq  -10734 delay   2071
phc2sys[2642.906]: eth0 sys offset      1780 s2 freq   -8959 delay   2061
phc2sys[2643.906]: eth0 sys offset      1789 s2 freq   -8416 delay   2101
phc2sys[2644.906]: eth0 sys offset      1275 s2 freq   -8393 delay   2071
phc2sys[2645.907]: eth0 sys offset       734 s2 freq   -8552 delay   2071
phc2sys[2646.907]: eth0 sys offset       355 s2 freq   -8711 delay   2071
phc2sys[2647.907]: eth0 sys offset       115 s2 freq   -8844 delay   2071
phc2sys[2648.907]: eth0 sys offset       -26 s2 freq   -8951 delay   2041
phc2sys[2649.908]: eth0 sys offset        -4 s2 freq   -8936 delay   2101
phc2sys[2650.908]: eth0 sys offset         8 s2 freq   -8926 delay   2071
phc2sys[2651.908]: eth0 sys offset       -24 s2 freq   -8955 delay   2071
phc2sys[2652.909]: eth0 sys offset       -19 s2 freq   -8957 delay   2071
phc2sys[2653.909]: eth0 sys offset       -11 s2 freq   -8955 delay   2071
phc2sys[2654.909]: eth0 sys offset       -10 s2 freq   -8957 delay   2081
phc2sys[2655.910]: eth0 sys offset        16 s2 freq   -8934 delay   2071
phc2sys[2656.910]: eth0 sys offset        -6 s2 freq   -8952 delay   2071
phc2sys[2657.910]: eth0 sys offset        -8 s2 freq   -8955 delay   2076
phc2sys[2658.910]: eth0 sys offset       -12 s2 freq   -8962 delay   2101
phc2sys[2659.911]: eth0 sys offset        23 s2 freq   -8930 delay   2071
phc2sys[2660.911]: eth0 sys offset        16 s2 freq   -8930 delay   2071
phc2sys[2661.911]: eth0 sys offset        -7 s2 freq   -8949 delay   2071
phc2sys[2662.912]: eth0 sys offset       -45 s2 freq   -8989 delay   2036
phc2sys[2663.912]: eth0 sys offset        16 s2 freq   -8941 delay   2071
phc2sys[2664.912]: eth0 sys offset        23 s2 freq   -8929 delay   2071

chrony

Example chrony configuration

server time-a.nist.gov
server time-a-wwv.nist.gov

refclock PHC /dev/ptp0 tai refid PTP dpoll -4 poll -2

leapsectz right/UTC

logdir /var/log/chrony
log statistics tracking

driftfile /var/lib/chrony/chrony.drift
rtcsync

allow
cmdallow

Hardware

Thankfully, the i210 is a common and popular chip, supported in most current operating systems. It can be found on PCIe cards, as well as on the motherboards of many systems. The intel reference design PCIe card is one of the best options - it exists with both low profile and full height PCIe backets, and the software defined pins are immediately accessible via a 6 pin header.

The SDP pins are rated for 3v3, which makes them very well suited to the 3v3 PPS output from many readily available GNSS modules.

i210 on ARK-1123H i210 on PCIe Card
i210_amo.jpeg
i210 on NANO-6050 (with SDP0 wire!) i210 on PC Engines apu2e0 (SDPs exposed as test pads)
i210_apu_gps.jpg
pps2sdp.1677715346.txt.gz · Last modified: 2024/11/14 02:30 (external edit)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki