Skip to content

LA-mode IQ capture: per-tone CSI from Jaguar silicon, offline H(k) tools, SDR notch validation#266

Merged
josephnef merged 1 commit into
masterfrom
la-mode-iq-capture
Jul 12, 2026
Merged

LA-mode IQ capture: per-tone CSI from Jaguar silicon, offline H(k) tools, SDR notch validation#266
josephnef merged 1 commit into
masterfrom
la-mode-iq-capture

Conversation

@josephnef

Copy link
Copy Markdown
Collaborator

Closes #150.

What

phydm's LA (logic-analyzer / ADC-sampling) mode is the debug escape hatch that DMAs a raw baseband sample bus into the top of the TX packet buffer, host-readable through the 0x0140-page + 0x8000 window. An offline FFT of a captured L-LTF is the full per-tone channel estimate H(k) — this PR productizes that path on all three Jaguar generations, turning any supported dongle into a one-shot per-subcarrier channel sounder. Full write-up: docs/la-capture.md.

  • src/LaCapture.{h,cpp} — one shared module (NhmReader pattern: per-chip LaRegs, one algorithm). MAC half (0x7c0 trigger/poll/finish + readback) identical across families; BB half in two dialects (11AC 0x95c/0x8fc, JGR3 0x1ce4/0x1cf4/0x1c3c). BbDbgportReader-grade safety: every touched register snapshot/restored, liveness checks between phases, sticky wedge latch with the documented recovery ladder.
  • Per-device research method la_capture() on all three device classes (dynamic_cast pattern, not on IRtlDevice), incl. 8821C cut-A LA-clock gating and the 8812A/8821A no-block probe path.
  • rxdemo knobs DEVOURER_LA_CAPTURE=<trig>/<rate>M/dma<N>/port:0xNNN[...] + _OUT/_MAX/_DELAY_MS, on both the USB and PCIe demo paths; DVLA dump file + la.capture/la.timeout/la.nosupport/la.wedged events.
  • Offline tools: tools/la_decode.py (layout unpack/score/plot), tools/la_csi.py (L-LTF locate with STF rejection, multi-period CFO refine, GI-backoff FFT → per-tone H(k) mag/phase; synthetic 2-tap-channel selftest wired as the la_csi_math ctest, numpy-less runners skip).

Hardware findings the vendor code hides

  • The manual REG trigger edge (0x7c0[5] 0→1) must be pulsed after the dump-enable bit — the vendor's order never completes on real silicon.
  • dma_type alone doesn't select a live bus: the dbg-port value routes it, and dbg_port=0 is dead. ADC pairing: dma0+0x880 (path A), dma1+0xa80 (path B).
  • Sample packing (established with a B210 CW at known offsets, tests/la_cw_score.sh): one complex sample per 64-bit word, 12-bit two's complement, I=[11:0], Q=[23:12] (qi12_l) on every chip — the naive order is spectrally inverted. JGR3 additionally carries the second RX path in the high dword: a coherent two-chain capture per trigger.
  • The 8812A/8821A genuinely lack the block (0x7c0 never latches) — matching PHYDM_IC_SUPPORT_LA_MODE, now detected explicitly instead of returning stale TXFF bytes.

Validation (all bench-run)

chip smoke (manual / crcok / capture→TX→capture) CW layout score
8822BU 3/3 23.6 dB
8814AU 3/3 19.1 dB
8821C (8811CU) 3/3 36.8 dB
8822CU / 8822EU 3/3 / 3/3 50.8 dB
8821CE (PCIe, radxa-x4) capture ok, readback 8 ms vs ~2 s USB
8812AU / 8821AU clean la.nosupport

SDR cross-validation (tests/la_sdr_crosscheck.sh): the B210 transmits an L-LTF train with an asymmetric tone set zeroed; the chip's H(k) must reproduce the notch at exactly those tones. 8822BU: 21–31 dB depth on all six tones, clean-tone ripple 1.2 dB. The issue's original chip-vs-SDR |H(k)|-correlation idea was measured and rejected: receivers at different antennas see independent fading (~0 correlation while both sides are self-consistent); the compare subcommand survives as that diagnostic. Known J3 caveat (documented): ~8 dB adjacent-tone leakage floor on both RX paths (common LO); features ≥2 tones wide resolve at 15–23 dB.

ctest 19/19 incl. the new la_csi_math; full build and Jaguar1-only subset build verified clean.

🤖 Generated with Claude Code

…ols, SDR notch validation (#150)

One shared module (src/LaCapture) ports phydm's logic-analyzer ADC
capture to all three generations: the baseband DMAs a raw sample bus
into the top of the TX packet buffer, host-read through the 0x0140-page
window. MAC half (0x7c0 trigger/poll/readback) is identical across
families; the BB half is two register dialects (11AC 0x95c/0x8fc, JGR3
0x1ce4/0x1cf4/0x1c3c) carried by per-chip LaRegs. Wired as a research
method on each device class + rxdemo env knobs (DEVOURER_LA_CAPTURE,
USB and PCIe paths), with BbDbgportReader-grade safety: full register
snapshot/restore, liveness checks, sticky wedge latch.

Hardware-bisected deviations from the vendor flow: the manual REG
trigger edge (0x7c0[5]) must be pulsed after the dump-enable bit or the
capture never completes; dbg_port routing selects the sampled bus and 0
is dead (ADC pairing is dma0+0x880 / dma1+0xa80); 0x0106 TXFF debug
access is restored instead of leaked.

Sample packing established empirically (tests/la_cw_score.sh, B210 CW
at known offsets): one complex sample per 64-bit word, 12-bit two's
complement, I=[11:0] Q=[23:12] (qi12_l) on every chip, at the
configured rate; JGR3 carries the second RX path in the high dword — a
coherent two-chain capture per trigger. tools/la_decode.py scores
candidate layouts; tools/la_csi.py locates the L-LTF (STF-rejecting),
refines CFO over the repetition train, and FFTs to per-tone H(k)
mag/phase, with a synthetic 2-tap-channel ctest (la_csi_math).

Validation: tests/la_capture_smoke.sh 3/3 on 8822BU / 8814AU / 8821C /
8822CU / 8822EU, plus the 8821CE over PCIe (8 ms MMIO readback vs ~2 s
USB); 8812A/8821A report la.nosupport (0x7c0 never latches — the
silicon lacks the block, matching PHYDM_IC_SUPPORT_LA_MODE).
tests/la_sdr_crosscheck.sh validates H(k) against SDR ground truth via
a notch protocol — the B210 transmits an L-LTF train with an asymmetric
tone set zeroed and the chip's estimate must reproduce it (8822BU:
21-31 dB depth, clean-tone ripple 1.2 dB). Chip-vs-SDR |H(k)|
correlation was measured and rejected as a methodology: receivers at
different antennas see independent fading (~0 correlation, both sides
self-consistent). Known J3 caveat: ~8 dB adjacent-tone leakage floor on
both paths (common LO); features two or more tones wide resolve at
15-23 dB.

Closes #150

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@josephnef josephnef merged commit f0073c5 into master Jul 12, 2026
15 checks passed
@josephnef josephnef deleted the la-mode-iq-capture branch July 12, 2026 05:29
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.

Frequency-resolved link quality (2/3): LA-mode IQ capture + offline FFT — true per-tone CSI from Jaguar silicon

1 participant