FreeBSD 14 USB M8T - BYO-NTP/recipes GitHub Wiki

date server os gnss daemon 🎯 🗣️
2025-05 Chuwi Larkbox X
Raspberry Pi 5
FreeBSD
14
Huawei WD22UGRC
u-blox LEA-M8T
chrony
NTPsec
ntp
12µs link

1. Install OS

Install FreeBSD

2. Configure the GNSS

There's a Bill of Materials and assembly instructions below.

Once assembled, plug the USB adapter into a Windows computer with u-blox u-center installed. Configure your device per recommendations on the gnss page.

3. Configure USB

Plug the USB adapter into the FreeBSD server and a few lines of text should be emitted to the console, dmesg, and /var/log/messages:

dmesg | grep -i ftdi
ugen1.7: <FTDI FT232R USB UART> at usbus1
uftdi0 on uhub2
uftdi0: <FTDI FT232R USB UART, class 0/0, rev 2.00/6.00, addr 6> on usbus1

This tells us that FreeBSD recognized the USB adapter and ucom has connected the serial port to the system.

Get some data from it (Control-C to disconnect):

stty -f /dev/cuaU0 raw 115200 cs8 clocal -cstopb
cat /dev/cuaU0
$GNRMC,203047.00,A,4746.15203,N,12219.54384,W,0.000,,120525,,,A,V*06
$GNZDA,203047.00,12,05,2025,00,00*79
$GNRMC,203048.00,A,4746.15203,N,12219.54384,W,0.000,,120525,,,A,V*09
$GNZDA,203048.00,12,05,2025,00,00*76
$GNRMC,203049.00,A,4746.15203,N,12219.54
^C

It works!

The NTP daemons look to /dev/gps0 by default, so link gps0 to the serial port using devfs:

test -L /dev/gps0 && rm /dev/gps0
grep -q gps0 /etc/devfs.conf && sed -i '' -e 's/^link.*gps0$//g' /etc/devfs.conf
echo 'link	cuaU0	gps0' >> /etc/devfs.conf
service devfs restart

4. Configure PPS

Enable PPS on the UART CTS pin (to match the wiring, see ucom for details):

sysctl hw.usb.ucom.pps_mode=1
sysrc -f /boot/loader.conf hw.usb.ucom.pps_mode=1

Create PPS devfs links for the NTP daemons:

test -L /dev/pps0 && rm /dev/pps0
grep -q pps0 /etc/devfs.conf && sed -i '' -e 's/^link.*pps0$//g' /etc/devfs.conf
cat >> /etc/devfs.conf <<EOL
link	cuaU0	pps0
link	cuaU0	gpspps0
EOL

service devfs restart

5. Install a NTP daemon

Each section heading is a link with many more details about installing, configuring, and verifying that particular NTP daemon.

export NTP_REFCLOCKS=$(cat <<EO_CHRONY
refclock SHM 0 refid NMEA offset 0.140 precision 0.02
refclock PPS /dev/pps0 refid PPS lock NMEA trust poll 2
EO_CHRONY
)
curl -sS https://byo-ntp.github.io/tools/chrony/install.sh | sh
export NTP_REFCLOCKS=$(cat <<EO_NTPSEC
refclock nmea refid NMEA minpoll 3 maxpoll 4 time2 0.135 prefer mode 8 baud 115200
refclock pps  refid PPS  minpoll 1 maxpoll 2 time1 0.101 prefer
EO_NTPSEC
)
curl -sS https://byo-ntp.github.io/tools/ntpsec/install.sh | sh

Alternatively, using the GPSD JSON driver:

export NTP_REFCLOCKS=$(cat <<EO_NTPSEC
refclock gpsd unit 0   refid NMEA minpoll 3 maxpoll 4 time2 0.068
refclock gpsd unit 128 refid PPS  minpoll 1 maxpoll 2 time1 0.000004 flag1 1 prefer
EO_NTPSEC
)
curl -sS https://byo-ntp.github.io/tools/ntpsec/install.sh | sh
export NTP_REFCLOCKS=$(cat <<EO_NTP
server 127.127.20.0 minpoll 3 maxpoll 4 mode 88 prefer
fudge  127.127.20.0 refid NMEA time2 0.134 minjitter 0.3

server 127.127.22.0 minpoll 3 maxpoll 4
fudge  127.127.22.0 refid PPS time1 0.1 minjitter 0.005
EO_NTP
)
curl -sS https://byo-ntp.github.io/tools/ntp/install.sh | sh

Alternatively, using ntp's GPSD-NG driver with gpsd:

export NTP_REFCLOCKS=$(cat <<EO_NTP_NG
server 127.127.46.0 minpoll 3 maxpoll 4 mode 0 prefer
fudge 127.127.46.0 refid NMEA time2 0.15 

server 127.127.46.128 minpoll 3 maxpoll 4 prefer
fudge 127.127.46.128 refid PPS flag1 1 time1 0.0
EO_NTP_NG
)
curl -sS https://byo-ntp.github.io/tools/ntp/install.sh | sh

Observe

  • watch the status in near real time (requires installing gnu-watch):
    • printf '\e[8;9;80t'; ssh -t pi5 gnu-watch -n2 chronyc sources
    • printf '\e[8;9;80t'; ssh -t pi5 gnu-watch -n2 ntpq -c peer
  • Measure the offset
  • Gather statistics with telegraf + influxdb + grafana or similar.

References

Bill of Materials

Item Vendor(s) Cost
Huawei WD22UGRC GPS module eBay $25
USB to TTL Serial adapter Amzn $12
SMA-F to SMB-F connector Amzn $5
Active GPS Antenna Amzn $11
2P-F to 1P-F 2mm to 2.54mm Jumper wires Amzn $8
Total $61

Assembly

Since the Larkbox X has no serial ports, add one with a USB to TTL serial adapter.

The Huawei GPS module has a LEA-M8T chip which supports GPS, Galileo, Beidou, and GLONASS. In the PNW, I regularly get simultaneous 3D fixes from both GPS and Galileo satnav systems.

There's a flood of the USB to TTL serial adapters available for ~ $15. Most will work with FreeBSD if they have a FTDI or Silicon Labs USB chip. Sadly, they are all USB 2.0. I've been unable to locate one with a USB 3.0 chip, which would decrease the USB latency.

This photo shows the pinouts on the board. Note that you MUST cross the TxD and RxD pins. If the module isn't spewing data, check that the pins are reversed.

Pins: 1 ANT 3V3, 2 3V3/VCC, 3 TXD, 4 NC, 5 RXD, 6 TP1/1PPS, 7 NC TP2, 8 GND

Huawei-WD22UGRC-LEA-M8T

And this photo shows it all wired up:

Huawei-WD22UGRC-assembled

Performance

chrony

NTPsec

ntp

⚠️ **GitHub.com Fallback** ⚠️