Repository navigation
transport: stamp breaks by dma from tim3 for the drift tracker - #303
Merged
Merged
Conversation
aq1018
force-pushed
the
transport-dma-break-stamps
branch
7 times, most recently
from
October 6, 2026 23:38
acf569f to
4d41e00
Compare
aq1018
force-pushed
the
transport-dma-break-stamps
branch
from
October 7, 2026 02:10
4d41e00 to
2773353
Compare
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.
Hardware break stamps: DMA1 CH2 on TIM2_UP copies TIM3 CNT (free-running at the SysTick tick) into a 32 x u16 ring per break-detector overflow. The drift tracker takes each frame's stamp at the frame's verdict, after the reply is sequenced, so the TIM2 break body carries no tracker work; 16-bit stamps are placed by ring position against the ladder (no SysTick/TIM3 read at take); stale orphans are skipped (at most 8 per verdict); nothing clears the ring outside CAL marks and rescue.
Framer::settle/settle_wholeand the tracker's same-cursor check go away. Transport doc sec 2, 5.1, 7 and 8 describe the mechanism.Killed along the way: interrupt-entry stamps (the ISR-entry lag beat gates every pair at 1M); the break-body take (turnaround +3/+4 us and a bimodal 3M read, because short frames' deadlines pend behind the break body); the end-of-service clear (the frontier frame's stamp is legitimately latched at any service end, so a clear always drops a live one). SysTick cannot be a DMA source (core-private, reads 0); TIM1 CNT aliases near a turnaround.
Tests: DES
saturated_backlog_stamps_every_break(18/30/5 us bodies + 130 us per frame, 257-frame flood: 19 frames in one body, stamps 257/257, drops 0),coalesced_breaks_each_stamp,drift_stamps_ignore_isr_entry_lag,own_breaks_never_stamped, unitmerged_wake_stamps_each_break_once(asserts the verdict-time take). Honest note: the backlog test also passes on the round-2 driver in the simulator, where SysTick beats TIM2 in arbitration so a break body never meets a bound-hit backlog; the round-2 stamp loss (cleared == unstamped == span_many on the bench) is therefore not reproduced in DES, and the bench probe'sbound_hits/clearedcounters discriminate it.Counts vs merge base 2bb2adc: drive_framer 354 = 354, serve_break 300 -> 92, TIM2 trampoline 221 -> 225, SysTick 204 = 204, USART1 394 = 394, route_frame 786 -> 720, verify 264 -> 233, drift_record 245 (new, out of line). Sizes: .text -92 B, .bss +64 B (ring 32 entries). Idle %: bench.
Bench gate (round 3, pre-registered): turnaround alone per baud within 0.5 us of same-session main on ping, read and write; detune at 1M 10/10; TRIM_PROBE after one detune run and after plain_flood: unstamped 0, stamps == frames == HOSTCOUNT, span_many 0, gated < 5%, cleared == bare breaks after detune and 0 after flood, bound_hits reported; HIGH_PROBE tim2 busy per entry within 0.3 us of main-probe; suite at 3M >= 16/17; idle within 0.3 pts; walk table |delta| <= 2. Falsifiers: turnaround off by more than 0.5 us means the break body is still on the reply path; unstamped > 0 with cleared at its design count means the detector raised no overflow for that break; cleared above its design count means a clear outside the design points.
Rounds 1 and 2 on the bench: detune and walk table passed each time; round 1 lost 207 of 1114 stamps and cost +3 us at 1M; round 2 lost 105 with cleared == unstamped and moved turnaround +/-3-6 us (captures servo-pass/trim/pr303/, pr303-r2/).
Final gate on the rebased image (2773353 vs main ebe8558, torque off, captures servo-pass/trim/pr303-rebase/): detune 10/10 at 1M and at 3M; TRIM_PROBE after one detune at each baud: stamps == frames (3M 1115, 1M 1114; the host tally reads one low at 3M, its baud-switch write, tooling follow-up), unstamped / span_many / stale 0, cleared 36 == bare breaks, gated 4.14 / 4.17 %; hardware suite at 3M 17/17; walk table 0 / 0 / 0 / +1 with stamps == frames; idle 31.36 % vs main 31.22-31.62 (+0.14). Sizes vs main: .text +80 B, .bss +64 B. Turnaround PR - main (us, 0.5 / 1 / 2 / 3M): ping -4.28 / -4.16 / +0.73 / -2.82; read +3.13 / +2.27 / +0.87 / -2.94; write -4.65 / +1.70 / +0.31 / -3.17 (main A-B spread <= 0.24). Accepted as is: the 0.5M read carries one ISR exit and re-entry (the frame-end work returns under the CRC tail and re-enters, likely, unconfirmed by its probe) and the 2M ping +0.73 repeats across rounds; an in-place frame-end service is a possible follow-up.
https://claude.ai/code/session_016NV5eybqhfjQPnesWHUCRs