Skip to content

transport: stamp breaks by dma from tim3 for the drift tracker - #303

Merged
aq1018 merged 1 commit into
mainfrom
transport-dma-break-stamps
Oct 7, 2026
Merged

aq1018 merged 1 commit into
mainfrom
transport-dma-break-stamps

Conversation

@aq1018

@aq1018 aq1018 commented Oct 6, 2026 •

Copy link
Copy Markdown
Collaborator

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_whole and 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, unit merged_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's bound_hits / cleared counters 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

@aq1018
aq1018 force-pushed the transport-dma-break-stamps branch 7 times, most recently from acf569f to 4d41e00 Compare October 6, 2026 23:38
@aq1018
aq1018 force-pushed the transport-dma-break-stamps branch from 4d41e00 to 2773353 Compare October 7, 2026 02:10
@aq1018
aq1018 merged commit 2ee1321 into main Oct 7, 2026
9 checks passed
@aq1018
aq1018 deleted the transport-dma-break-stamps branch October 7, 2026 03:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant