Goal

1ms or better accuracy on a USB-connected GPS.

Hardware

stm32f4 discovery board using a 10.5mhz internal timer is measuring the PPS interval from a Fastrax UP501 GPS reciever (claims "+/- 50 ns (RMS) accuracy"). The stm32f4 is connected via full-speed usb to a pc

Software

See: usb gps

Trials


Run 1 - 6ms window between actual time and the PC's reception

After investigating these results, I found that the code was only responding to every 5th USB start of frame. Since USB SOF are every 1 ms with USB full speed, this increased the error by 5ms.


Run 2 - 2ms window between actual time and the PC's reception

Changed the micro to respond on every USB SOF if it has data, and this lowered the error


Run 3 - under 500µs window between actual time and the PC's reception

Changed the microcontroller from doing "send message on PPS" to "respond to USB poll with the current time". This way, the data is sent with the smallest buffering/transferring delay possible


Run 4 - under 50µs window between actual time and the PC's reception

Changed the timer signal to a one byte message and sent the timestamps/offsets to NTP via the shm driver


Run 5 - 90.4% of samples within 40 µs of mean

Changed the NMEA data to go through the microcontroller and over USB, as well as changing the timestamp measurement software on the PC to run under a realtime scheduler


Run 6 - 90.9% of samples within 22 µs of mean

The timestamps of the USB byte are now measured in the kernel


Run 7 - 90.8% of samples within 20 µs of mean

Experimented with a 32 second NTP poll instead of a 16 second poll


Run 8 - 90.8% of samples within 19 µs of mean

Switched back to a 16 second NTP poll, worked around a bug where the GPS module would send the same NMEA timestamp twice, switched the micro to send its clock info at 2HZ. No significant difference with run 7.


Run 9 - 91.2% of samples within 19 µs of mean

Added a simple filter of dropping samples 10us outside of the running average offset


Run 10 - 90.6% of samples within 18 µs of mean

Filter now measures the difference between the moving average offset and the measured offsets for the past 192 seconds, and selects a filter that discards 80% of the samples before selecting the offset to send to NTP. The micro's PLL now uses 2mhz as its intermediate frequency instead of 1mhz, to evaluate its effect on jitter