Note to Self: Raspberry Pi & Motorola Oncore UT+ setup

This is the first of (hopefully) several “notes to self”. They are intended as a record of my various tinkerings and processes that I’ve learned. Although publicly readable, they’re meant as notes to myself in the context of my personal setup and are not really intended as complete “how-to” guides. If you find it useful, awesome! If not, sorry.

The version of NTPd packaged in Raspbian Jessie doesn’t have support for PPS (why?!) or the Motorola Oncore driver enabled. It needs to be recompiled to support those options. The Oncore hardware is quite old, so I understand them not wasting a bit of space by enabling the Oncore driver at compile-time (though really, disk space is cheap and abundant), but no PPS? C’mon.

Anyway, here goes:

First, get the source and needed dependencies:

$ apt-get source ntp
$ sudo apt-get build-dep ntp
$ sudo apt-get install pps-tools libcap-dev libssl-dev build-essentials

Next, cd into the source directory. Edit the debian/changelog file to add a note about PPS being added. Append ~pps0 or something to the version. This is needed to generate a package later.

Next, cd into ntp/ntp-4.2.6.p5+dfsg/ntpd/ and edit refclock_oncore.c. If using the Oncore, change syslog(log_level, "%s", Msg); to msyslog(log_level, "%s", Msg);. This allows the chatty Oncore logs to go to a (optional) user-specified log file rather than filling up syslog (and wasting SD card writes).

Next, cd back to the ntp source directory. Configure NTPd to enable the needed modules:

$ ./configure --enable-linuxcaps --enable-ATOM --enable-NMEA --enable-oncore

Next, build the package:

$ dpkg-buildpackage -b -j5 (-j5 lets the compiler use all 4 cores on the Pi, as well as having one compiler thread ready to go. This speeds things up significantly.)

Install the package:
$ sudo dpkg -i <package_name>.deb

Finally, make sure apt doesn’t automatically update it without our knowledge:
$ echo "ntp hold" | sudo dpkg --set-selections (check the status with sudo dpkg --get-selections | grep hold)

Cool. NTP is now ready. Now configure the hardware. Be sure to use 3.3V-level signals — the Pi is not 5V tolerant!

Turn off the serial console:
$ sudo raspi-config
Advanced Options -> Serial -> Would you like a login shell to be accessible over serial? -> No

sudo nano /boot/config.txt

Add dtoverlay=pi3-miniuart-bt,pps-gpio,gpiopin=18 (assuming it’s connected to GPIO 18; use a different pin if desired.) to enable PPS and disable the Bluetooth setup on the hardware UART (only needed on Pi3 and presumably future versions). Presumably pi3-disable-bt would also work but has not been tested; one might need to switch ttyAMA0 and ttyS0 in that case. Add pps-gpio to a new line of /etc/modules.

Make sure enable_uart=1 is enabled. (This is disabled by raspi-config while turning off the console above, but it’s needed to re-enable it here.)

Disable the serial console in /boot/cmdline.txt:

dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
#dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

Prevent the Bluetooth connection from trying to connect to the UART:

$ sudo systemctl disable hciuart
$ sudo systemctl mask serial-getty@ttyAMA0.service


Check if everything works with $ lsmod | grep pps. It should look something like this:

pps_ldisc 1972 0
pps_gpio 2655 1
pps_core 6779 3 pps_ldisc,pps_gpio

Also check this:

$ dmesg | grep pps
[ 3.307915] pps_core: LinuxPPS API ver. 1 registered
[ 3.311030] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti
[ 3.322724] pps pps0: new PPS source pps.-1
[ 3.322784] pps pps0: Registered IRQ 190 as PPS source
[13737.731304] pps_ldisc: PPS line discipline registered
[13737.733650] pps pps1: new PPS source serial0
[13737.733769] pps pps1: source "/dev/ttyS0" added
[17035.124787] pps pps1: removed

Test that serial data is coming in:

$ sudo stty -F /dev/ttyS0 9600

Check PPS:

$ 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 1477954884.000004092, sequence: 26867 - clear 0.000000000, sequence: 0
source 0 - assert 1477954885.000000979, sequence: 26868 - clear 0.000000000, sequence: 0
source 0 - assert 1477954886.000003753, sequence: 26869 - clear 0.000000000, sequence: 0
source 0 - assert 1477954887.000005433, sequence: 26870 - clear 0.000000000, sequence: 0

Configure udev to create symlinks to make it so NTPd knows where to find the serial and PPS source:

$ sudo nano /etc/udev/rules.d/50-oncore.rules, the contents of which are:


For Pi1/2, replace ttyS0 with ttyAMA0.

Set up /etc/ntp.conf for the Oncore:
# Oncore driver. May need to fudge the timing slightly, but seems to work fine out-of-the-box for me.
server minpoll 4 prefer

# The Oncore driver logs are very (once-per-second) chatty. Let's put those in /tmp which is mounted as tmpfs, so I can save on SD writes.
logfile /tmp/ntp.log

If using other servers, be sure to add minpoll 10 to the server line: when using a refclock, NTPd keeps the query time at 64 seconds. This is fine, but a bit impolite to internet servers, so I like to crank it up to 10 (1024 seconds). This can make NTPd slower to detect and respond to the GPS receiver going crazy, but I run non-critical systems so that’s fine.

Setup the /etc/ntp.oncore.N (where N is from 127.127.30.N) file with the necessary configuration options:

# /etc/ntp.oncore.0
# Reference Clock configuration for Motorola Oncore M12
# Five Choices for MODE
# (0) ONCORE is preinitialized, don't do anything to change it.
# nb, DON'T set OD mode, DON'T set Delay, position...
# (1) NO RESET, Read Position, delays from data file, lock it in, go to OD mode.
# (2) NO RESET, Read Delays from data file, do SITE SURVEY to get position,
# lock this in, go to OD mode.
# (3) HARD RESET, Read Position, delays from data file, lock it in, go to OD mode.
# (4) HARD RESET, Read Delays from data file, do SITE SURVEY to get position,
# I have a supercap on the memory backup, so the board should have the almanac and other data ready to go (MODE 1) . If not, the system starts up in MODE 3 automatically.
# NB. If a POSITION is specified in the config file with mode=(2,4)
# then this position is set as the INITIAL position of the ONCORE.
# This can reduce the time to first fix.
# If we open one or the other of the files, we read it looking for
# then initialize using method MODE. For Mode = (1,3) all of (LAT, LON, HT) must
# be present or mode reverts to (2,4).
LAT DD.DDDDDD # Positive is North.
LONG DD.DDDDDDD # Negative is West
HTGPS XX.XX M # Height in meters. Can also use FT for feet.
#SHMEM /var/log/ntpstats/ONCORE.0
DELAY 52.32 NS # Cable delay in nanoseconds. Could also use MS or US for milli and microseconds.
TRAIM YES # Sanity-check the results. Turn off PPS and report errors if something goes wrong.

Now I need to setup logrotate so the logs in /tmp/ don’t grow too large.

Create $ sudo nano /etc/logrotate.d/ntp and add:

rotate 2
su root root

The copytruncate is the important one: NTPd doesn’t close out logfiles on its own, so logrotate needs to copy-and-truncate the existing file when it rotates.

Cool. Everything should now be setup and working!

remote refid st t when poll reach delay offset jitter
oGPS_ONCORE(0) .GPS. 0 l 8 16 377 0.000 0.047 0.004
+bwntp2.bluewin. 2 u 587 1024 3 10.875 -0.048 1.627
* .PPS. 1 u 581 1024 3 8.870 -1.234 1.513 2 u 549 1024 3 10.421 3.085 2.825
+bwntpo.bluewin. 2 u 562 1024 3 9.407 -1.155 1.663
+chilipepper.can 2 u 607 1024 3 26.632 -1.598 1.091

Additional details at: