Repository navigation
Conversation
…ime, retries) The one stage the host cannot time is the chip's own queue. With DEVOURER_TX_REPORT on, the HalMAC firmware's CCX report echoes the descriptor's SW_DEFINE tag; two small library seams make that joinable: IRtlRadio::NextTxReportTag() (the tag the next send_packet will carry, Jaguar2/3) and IRadio::SetTxReportSink() (each decoded report handed to the caller beside the tx.report event; every generation's emit site goes through one DeliverTxReport). The TX timing helper reads the tag before every send into a 256-slot ring (src/StreamTelemetry.h TxReportJoin, selftested), joins the reports on the TX thread, and folds the on-chip queue time (raw firmware units) and retry count into stream.timing (rpt_n, rpt_fail, q_p50_raw, q_max_raw, retries_max, rpt_unmatched) plus a sampled per-frame ledger, stream.txrpt, that also carries the report's host age. Nothing on the air changes. Measured (report per frame, 20 s): steady state joins every frame on the 8812CU (streamtx, ~460 fps) and the 8812BU/T3U (duplex, ~680 fps) -- 1.02 reports per data frame (the markers), 0 unmatched, report age p50 2.2 ms, queue time p50 1 raw, max 41-607. The startup burst (the stdin backlog aired at full rate) is where reports go missing: latency outruns the tag ring and the 8812CU firmware drops reports in gaps of 7-11; the harness's `report` phase judges the second half of the run and says so. Closes #476. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
PR Summary by QodoJoin HalMAC CCX TX reports to stream timing frames
AI Description
Diagram
High-Level Assessment
Files changed (14)
|
Code Review by Qodo
1. Delayed reports can name the wrong frame
|
…al, hop-sync tags - TxReportJoin counts a send that reuses a still-live tag (rpt_overwritten): an eight-bit tag cannot name its generation, so such a window's joins are suspect; selftest covers the late-report-after-reuse case and says what happens. The harness verdict requires zero overwrites in steady state. - IRadio::SetTxReportSink returns only once no earlier sink is still executing (in-flight count + condition variable), so a helper may destroy what its sink captured right after clearing it. - The report queue stamps each report when the host decoded it; age_us is send -> that instant, not the TX thread's drain time. The overflow counter is atomic. - streamtx's hop sync marker records its tag through the helper (note_external_send) so its report joins as a marker. - The duplex join verdict runs only for a positive report divisor; the report phase is documented as Jaguar3's (streamtx runs no RX loop, so a Jaguar2 transmitter is covered by the duplex phase), and the verdict says so when no join window exists. Measured after the changes: report phase 8812CU 1.02 joins/frame, 0 unmatched, 0 overwritten; duplex 8812BU/T3U ch36 1.02, 0, 0; hop + reports on the 8812CU joins 1.30/frame steady (markers included) while ~15% of sends get no report in bursts of 7-13 around retunes -- rpt_overwritten counts that backlog, documented as such. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
What
Follow-up #476 from the stream-timing PR: the chip's own queue time, which no host stage can measure, joined to the per-frame record.
IRtlRadio::NextTxReportTag()— the SW_DEFINE tag the nextsend_packetwill carry (Jaguar2/3 withtx.reporton; nullopt elsewhere).IRadio::SetTxReportSink()— each decoded CCX report handed to the caller beside thetx.reportevent; all four emit sites (J1/J2/J3) now go through oneDeliverTxReport.TxReportJoin, pure, selftested), reports queued by the sink on the C2H thread and joined on the TX thread. Queue time (raw firmware units — the HalMAC unit is undocumented, Jaguar1's 256 µs is) and retries enter thestream.timingwindow (rpt_n,rpt_fail,q_p50_raw,q_max_raw,retries_max,rpt_unmatched,rpt_overflow) and a sampled per-frame ledgerstream.txrptwith the report's host age. Nothing on the air changes; the join is off unlessDEVOURER_TX_REPORTis set.reportphase (streamtx on Jaguar3, whose coex thread drains C2H) andTX_REPORT=1on the duplex phase (how a Jaguar2 transmitter, which needs an RX loop, is covered).Measured (report requested on every frame, 20 s)
The startup burst is where reports go missing, and the doc says so with the numbers: the stdin backlog aired at full rate makes the report latency outrun the tag ring (unmatched) and the 8812CU firmware drops reports in gaps of 7–11 (
tx.reporttag deltas), consistent with the emission ceiling indocs/scheduled-mac.md. From the first paced window on, every frame has its report. The join is exact where a report exists.Headless:
ctest85/85 with the join-ring selftest added. The default matrix (join off) is unchanged: floor on the 8812CU PASS withrpt_join:0.Closes #476.
🤖 Generated with Claude Code