TCXO RTC Raspberry Pi Hat


I'm bringing my RTC Hats back online (source code and hardware design is on github). I originally designed it for frequency synchronization without phase alignment. I was going to write my own program to handle the synchronization, but chrony added the ability to use a local frequency reference clock.

My original design was to take PWM from the Raspberry Pi as an input to measure its frequency. But the chrony design wants to receive a PPS, so I'll need to change the firmware on the RTC hats.

Data collection

Since these hats have been offline for a few years, the first thing I wanted was to make sure their frequency vs temperature data was still correct. I had measured their frequency at different temperatures and fit an estimated curve using gnuplot's gradient descent.  That data changes over time, so I wanted to see how much it changed.

The original data was gathered with hardware input capture from a GPS module's PPS and the internal temperature sensor on the RTC (a stm32f031). This data, I'm using i2c to read a 32 bit counter and comparing it to NTP synchronized time (stratum 1s on the local network). I started the system clock and the RTC hat clock at zero offset and let the RTC hat clock drift without synchronization for a few days. I have two RTC hats, one on an Odroid C2 and one on a STM32MP157a-dk1.

RTC Hat offsets

After six days, the odroid c2's RTC hat clock has only drifted a total of 1ms (about 1 ppb). While the stm32mp1's RTC hat clock drifted from -2ms to +6ms over five days (about 20 ppb).

Looking at the RTC hat's frequency vs temperature after my compensation shows the odroid c2's estimated curve still fits decently well, with a slight tilt:

Odroid C2's RTC hat frequency vs temperature after temperature compensation

While the stm32mp1's RTC hat had a much more obvious tilt, which is why it has a larger offset:

stm32mp1's RTC hat frequency vs temperature after temperature compensation

I'll need to adjust the temperature compensation on that RTC hat.

Preparing for programming

I had originally designed the RTC hats to be programmed from a Raspberry Pi using openocd's Raspberry Pi support. OpenOCD speaks SWD to the microcontroller using GPIO bit banging. The RTC hat already connects the microcontroller's SWD pins to the Raspberry Pi GPIO, so that is very convenient.

In the years since I wrote the original code, openocd added sysfs gpio support. This means that I can use the same strategy for bitbanging SWD on non-Raspberry Pi platforms. I added config files for openocd on the Odroid C2 as well as openocd on the stm32mp1. This makes the iterative development process easier, as I can compile and flash updates with a make command.

Next steps

The next steps I'll be taking are: converting my RTC firmware from PWM input to PPS output, having the RTC firmware do the temperature compensation (instead of the system), making sure my systems have the pps-gpio kernel module, updating my devicetrees to connect the pps-gpio module to the RTC hat's PPS output, and running chrony with a "local refclock".