Beaglebone Cape for Navspark NS-T


My next goal in the quest for a better NTP server is to improve the TCLKIN source. Previously, I was experimenting with TCXO's. I bought a Navspark NS-T (a timing-grade GPS receiver) and designed an adapter cape for it. This is my first time designing a circuit board, so I am expecting to run into problems.

I tried to design my board to minimize how expensive those problems would be to fix. The Navspark board is connected via headers, so it can be re-used in newer revision capes. The eagle files and PDFs are up on github.

Configuring the NS-T

After ordering all the parts, I got the Navspark first. I used their "GNSS Viewer" to configure it:

  • Binary > Configure Power Mode > Normal
  • 1PPS Timing > Configure 1PPS Frequency Output > 12MHz
  • 1PPS Timing > Configure Timing > Static, [Lat/Long/Elevation]

A few seconds after a reset, the TIMEPULSE2 pin looks like this:

TIMEPULSE2 pulse width

I believe the micro in this GPS receiver to be running at 81.84MHz, so this makes sense. It uses something like PWM to generate its 12MHz signal.

Turning all the scope's measurements on:

TIMEPULSE2 measurements

Assembling the cape

The boards arrived from Singapore:

Circuit Boards

I put the headers, the PLL, and the EEPROM on one of them:

Assembled Cape

Tested for obvious problems with a multimeter, then put it on the BBB:

Rev1 Final

Unfortunatly, TCLKIN didn't work right away. The PLL isn't producing an output. The first problem is Output Enable is low on the PLL and it should be high. I hacked around that by clipping the package's pin and relying on the internal pullup. The second problem was input voltage. Putting a 10nf cap between NS-T's TIMEPULSE2 and the PLL's X1 was enough to move the DC offset.

The PPS signal, the GPS UART receive, and the EEPROM (at i2c address 0x54) worked right away.

After inserting the cap, the last 10 PPS counter cycles (should be 24M):


Output from chrony's status. clock.lan is a rpi-based NTP server:

# chronyc sources ; chronyc sourcestats ; chronyc tracking
210 Number of sources = 4
MS Name/IP address      Stratum Poll Reach LastRx Last sample
#? NMEA                       0   6   377    52    -82ms[  -82ms] +/-  100ms
#* PPS                        0   4   377    17    -39ns[  -40ns] +/-   27ns
^? sandfish.lan               0  10   377   10y     +0ns[   +0ns] +/-    0ns
^+ clock.lan                  1   6   377    18    +31us[  +31us] +/-  260us
210 Number of sources = 4
Name/IP Address         NP  NR  Span  Frequency  Freq Skew  Offset  Std Dev
NMEA                     4   3   199    -64.792   1032.478    -80ms  4793us
PPS                     58  30   913     +0.000      0.000     -1ns    17ns
sandfish.lan             0   0     0     +0.000   2000.000     +0ns  4000ms
clock.lan               18  12   18m     -0.003      0.093    +19us    32us
Reference ID    : (PPS)
Stratum         : 1
Ref time (UTC)  : Sun Mar 22 20:29:51 2015
System time     : 0.000000001 seconds fast of NTP time
Last offset     : -0.000000001 seconds
RMS offset      : 0.000000001 seconds
Frequency       : 0.000 ppm fast
Residual freq   : -0.000 ppm
Skew            : 0.000 ppm
Root delay      : 0.000000 seconds
Root dispersion : 0.000018 seconds
Update interval : 16.0 seconds
Leap status     : Normal

After running for over 3 hours, the PPS interval counter looks like this:

# awk '$1 > 1427043760 {print}' int.log | ~/bin/stats -f2
          Field:  2
          lines:  12729
           mean:  24000000.000000000000
       variance:  0.000000000000
        std dev:  0.000000000000
            sum:  305496000000.000000000000
            min:  23999999.000000000000
            max:  24000001.000000000000


Check out the current status after five and a half days.