From bare crystal to pseudo-TCXO#

Why#

The Raspberry Pi 5 carries no metrology-grade oscillator: a bare quartz crystal (XO) clocks the SoC, with no temperature-compensation circuit whatsoever. This server’s own measurements confirm it: about 3.8 ppm of frequency swing between 38.5 and 57.5 °C, with local slopes of 0.06 to 0.2 ppm/°C depending on the zone. That is an order of magnitude beyond what a TCXO specification would tolerate, and consistent with the characteristic S-shaped curve of an AT-cut crystal (an inflection was even observed around 38.5-39 °C).

This chapter recaps how the steps of this guide, taken together, rebuild in software what the “TC” of a TCXO does in hardware, then places the result in the oscillator hierarchy, cost included.

How: the five steps of the pseudo-TCXO#

Nothing here is new: each step points to a chapter already applied. It is their combination that constitutes the pseudo-TCXO.

  1. Measure before acting. The log tracking measurements tempcomp logging (Chrony chapter) provides timestamped temperature/frequency pairs: the raw material for everything else. Without several days of data, none of the following steps can be calibrated honestly.
  2. Eliminate fan cycling. The 4-tier PWM profile with wide hysteresis, continuously active from 40 °C (Firmware chapter), pins the thermal operating point instead of letting temperature oscillate at the whim of an on/off thermostat.
  3. Insulate the crystal. The polyurethane foam between the crystal and the enclosure smooths fast transients. Measured counterpart: it also delays the crystal’s response relative to the SoC probe, which makes measurements taken during a thermal shock misleading (Chrony chapter, tempcomp section).
  4. Hold a setpoint (optional). The controlled CPU load ntpheat (Thermal stabilization chapter) targets a fixed temperature at the cost of about 1 W permanently; this guide leaves it disabled by default.
  5. Compensate the residual. The tempcomp directive and its point table, rebuilt daily by tempcomp-refit (Chrony chapter), subtract the predictable part of the drift before the discipline loop even has to correct it.

Measured result in production: Residual freq on the order of 0.01 to 0.02 ppm (Chrony verification chapter) and RMS offset down from ~1.7 µs to ~0.2-0.4 µs on the first readings (snapshots, to be confirmed over time).

Thermal compensation curve deployed by tempcomp-refit, correction in ppm against SoC temperature.
tempcomp table actually deployed (35 points). The correction decreases monotonically but not perfectly smoothly (measurement noise dots the slope, cf. "not a clean parabola"), crosses zero around 55.5 °C, and a flat margin is added on both ends beyond the actually measured range (38.5 to 58.5 °C) to keep chrony from extrapolating with no ceiling beyond the last reliable point.

The oscillator hierarchy#

FamilyPrincipleTemperature stability (order of magnitude)Indicative costWithout hardware modification?
XO (the Pi 5’s)bare crystala few ppm to a few tens of ppm over 0-70 °C (measured here: ~3.8 ppm over 19 °C)< 1 €already in place
TCXOcrystal + built-in compensation circuit±0.1 to ±2.5 ppm over -30/+85 °C2 to 20 €no
OCXOcrystal held in a thermostated oven±0.001 to ±0.01 ppm50 to 300 €, plus 1 to 3 W of permanent heatingno
CSACminiaturized atomic clock (cesium)~±0.0005 ppm4,000 to 6,000 €, ~120 mWno
Rubidium (RbXO)Rb atomic reference disciplining a crystal~±0.0001 ppm500 to 2,000 €, ~10 Wno
Pseudo-TCXOXO + tiered fan + insulation + tempcomp~0.01 to 0.02 ppm residual after compensation (Residual freq, measured at +0.016 ppm in production)~0 € of extra hardware (the fan is needed anyway)yes

Two ways to read this table:

  • In raw stability, the pseudo-TCXO does not play in the league of OCXOs and atomic references, and does not claim to. Its real bound lies elsewhere: the GNSS PPS pulls the clock back onto true time permanently, so the local oscillator only needs to be good between two corrections, a matter of seconds.
  • In marginal cost, it is unbeatable: every component was already there (the fan is needed anyway, the SoC thermal probe is standard), all that is left to invest is setup time, reusable as-is on any other Pi.

A better oscillator would not replace GNSS: it does not know the time, only the cadence. Its real contribution would be holdover, the ability to stay right through a prolonged GNSS outage. With the pseudo-TCXO, orphan mode (Chrony chapter) honestly degrades the stratum; with a rubidium, the server would hold for days while drifting by a few microseconds. That criterion, and it alone on this project, is what would justify moving up the range.

Pitfalls to avoid#

  • Comparing datasheet figures to field measurements. The table mixes by necessity manufacturer specifications (TCXO, OCXO, CSAC) and real measurements (the Pi’s XO, the pseudo-TCXO). A specification is a worst-case guaranteed envelope, a measurement is one point under given conditions: the orders of magnitude are valid, fine-grained comparisons would be meaningless.
  • Forgetting the probe measures the SoC, not the crystal. The whole compensation rests on /sys/class/thermal/thermal_zone0, away from the crystal and behind the foam. In steady state, the difference is a simple offset the table absorbs; during a fast transient, the two temperatures diverge and measurements become misleading.
  • Believing the work is done. A crystal ages (slow drift, on the order of a ppm over the first year, then decreasing): that is precisely why the tempcomp table keeps being recomputed on an ongoing basis, and reread at each restart, rather than frozen at first calibration.

Verify#

# The residual after compensation: Residual freq should stay close to 0
chronyc -h /run/chrony/chronyd.sock tracking | grep -E "Residual|Skew|RMS"

# The compensation applied continuously (Comp. column, non-zero)
tail -5 /var/log/chrony/tempcomp.log

📚 Going further

  • John R. Vig, Quartz Crystal Resonators and Oscillators, A Tutorial: the free, encyclopedic reference on the frequency/temperature curves of quartz cuts (including the AT cut’s cubic), aging, and oscillator families.
  • Related chapters: Firmware (fan profile), Thermal stabilization (ntpheat), Chrony (tempcomp and its dynamic table).