Self-learning holdover temperature compensation#9
Draft
peterlewis wants to merge 2 commits into
Draft
Conversation
With `pps = on` in config.txt, emit one proprietary NMEA sentence per PPS edge over the existing CDC stream, carrying the sub-second phase captured at the edge plus calibration / holdover / die-temperature telemetry. Time-critical fields are snapshotted in the PPS ISR; formatting and CDC submission happen in the main loop, serialised against the NMEA passthrough. With no enumerated host the record is dropped before any formatting. mk4-time/Core/Src/main.c: capturePPS(), emitPPSTimestamp(), measure_temp(), a `pps` config key and one main-loop hook. qspi/config.txt documents the key. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Builds on the $PMTXTS telemetry: while GPS-locked the clock learns each oscillator's frequency error vs die temperature (binned, per-oscillator), then during a GPS-loss holdover it steers the SysTick timebase from the HSE model to cancel temperature-driven drift, and optionally trims RTC->CALR from the LSE model so the battery RTC hands over better time across a power loss. - tc_learn / tc_apply / tc_rtc config keys (all default off = stock behaviour) - steering is a Bresenham SysTick->LOAD stretch inside the tick ISR (integer only; all model maths is main-loop); origin-free HSE model so only the temperature DIFFERENCE since GPS loss is applied, and the per-edge PPS phase snap makes re-lock instantly neutral - 'tc_dump = on' over serial prints the learned coefficients as paste-ready config lines (+ a $PMTXTC sentence); pasting them back freezes the model - MODE_TEMPCOMP diagnostic display: die temp / model offset / sample count - ticks-per-ppm derived from the runtime SysTick period (no core-clock assumption) Hardware-validated on an Mk IV: the LSE model learned 18.68 ppm vs 18.9 ppm measured directly (~1%). Survived an adversarial review pass (ISR-safety, integer math, sign conventions, re-lock neutrality, off-means-identical). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft — self-learning holdover temperature compensation, built on the
$PMTXTStelemetry from #5.Stacking note (please read first)
This depends on #5 ($PMTXTS) — it consumes the per-PPS
pps_capsnapshot and die-temperature it adds. Until #5 lands, this PR's diff includes #5's commit too; the temp-comp change is the single top commit,55d0695(the one to review). I'll rebase to just that once #5 merges. Note #5's own text says "no compensation shipped" — this is the deliberate follow-up.What it does
While GPS-locked the clock learns each oscillator's frequency error vs die temperature (binned, weighted least-squares). During a GPS-loss holdover it then steers the SysTick display timebase from the HSE model to cancel temperature-driven drift (
tc_apply), and optionally trimsRTC->CALRfrom the LSE model so the battery RTC hands over better time across a power loss (tc_rtc). All enables default off — stock behaviour unchanged.Design notes
calibrateRTCfloat precedent); the tick ISR does only an integer BresenhamSysTick->LOADstretch — a fractional-ppm rate steer, no phase steps.model(T_now) − model(T_at_loss), so the origin cancels and the per-edge phase snap makes re-lock instantly neutral. (It corrects temperature-driven drift; the absolute TCXO offset at loss is its spec — re-lock anchoring is a possible follow-up.)tc_dump = onover serial prints the learned coefficients as paste-readyconfig.txtlines (+ a$PMTXTCsentence); pasting them back freezes the model. Serial-only, guarded against config-file reload.MODE_TEMPCOMPdiagnostic display pages die temp / model offset / sample count.calibrateRTC); the WPR sequence runs IRQ-off against PendSV'swrite_rtc.Status
Hardware-validated on an Mk IV — the LSE model learned 18.68 ppm vs 18.9 ppm measured directly (~1%). Builds clean; passed an adversarial review pass (ISR-safety, integer math, sign conventions, re-lock neutrality, off-means-identical). Draft pending broader holdover-steering validation.