Summary
A local, closed-RF hardware-in-the-loop bench that exercises the full real
signal path of this firmware and is drivable by a local Claude Code /goal:
QDX (TX, known message) -> attenuators -> RX888 -> FX3 firmware (this repo)
-> radiod (rx888.so) -> decoder -> decoded message -> single pass/fail line
Design + plan: docs/local-hwil-plan.md. Each rung is structured so the
operator independently verifies it (re-runs the check / observes their own
gear); the verdict line is a check, not a claim.
Why
The firmware already has strong off-hardware coverage (CI builds arm-none-eabi;
tests/ has host-unit tests). Missing: verification that exercises the real
ADC/clock/GPIF/USB path + the radiod driver against an actual signal.
Goal ladder (status)
Each rung is a single /goal (one verdict line + exit code) and a commit
under this issue. "HW" = which hardware it needs (off-hardware rungs run in CI).
Tooling (validated off-hardware)
- FT8:
gen_ft8 / decode_ft8 (ft8_lib@9fec6ca); independent cross-decoder jt9 (WSJT-X) for operator verification.
- WSPR:
wsprsimwav (wspr-cui@839b86f) renders 48 kHz audio; wsprd decodes.
sox for sample-rate/format conversion only (48k↔12k) — never signal synthesis.
Real encoders/decoders own the protocol; encoder independence was intentionally
waived for generation, with operator-side cross-decode as the independent check.
RF safety pre-gate (rungs 3/5/7)
Each transmit-into-RX888 rung prints a red DANGER!! banner before keying.
The first attenuator stage must be power-rated for full QDX output (~+37 dBm);
the operator confirms the RX888-input level is in range. Operator pre-flight —
gates the rung, not discovered by it.
Operator interface contract (must be supplied)
- Total attenuation dB + first-stage power rating; target level at RX888 input.
- QDX: ALSA device, CAT serial port/baud, band/dial freq, drive level, fw version.
- RX888/radiod: band(s), sample-rate/center config.
- Pass criteria: test callsign/grid, freq tolerance (Hz), min SNR, window, N-of-M quorum.
Out of scope (separate plan)
Remote self-hosted GitHub Actions runner, Actions/cron wiring, and the runner
security model (untrusted-fork code on a machine wired to a transmitter).
Not validated by this bench
A wired bench validates the firmware + software path at a controlled level. It
does not validate antenna, propagation, or real-world RFI.
Summary
A local, closed-RF hardware-in-the-loop bench that exercises the full real
signal path of this firmware and is drivable by a local Claude Code
/goal:Design + plan:
docs/local-hwil-plan.md. Each rung is structured so theoperator independently verifies it (re-runs the check / observes their own
gear); the verdict line is a check, not a claim.
Why
The firmware already has strong off-hardware coverage (CI builds
arm-none-eabi;tests/has host-unit tests). Missing: verification that exercises the realADC/clock/GPIF/USB path + the
radioddriver against an actual signal.Goal ladder (status)
Each rung is a single
/goal(one verdict line + exit code) and a commitunder this issue. "HW" = which hardware it needs (off-hardware rungs run in CI).
out/so the operator can independently decode it (jt9,wsprd).FROMthe ka9q-radio image; reproduces the existing smoke-test output. (RX888)powers: peak within 300 Hz, ≥20 dB over noise. (RX888+QDX+RF, DANGER pre-gate)Tooling (validated off-hardware)
gen_ft8/decode_ft8(ft8_lib@9fec6ca); independent cross-decoderjt9(WSJT-X) for operator verification.wsprsimwav(wspr-cui@839b86f) renders 48 kHz audio;wsprddecodes.soxfor sample-rate/format conversion only (48k↔12k) — never signal synthesis.Real encoders/decoders own the protocol; encoder independence was intentionally
waived for generation, with operator-side cross-decode as the independent check.
RF safety pre-gate (rungs 3/5/7)
Each transmit-into-RX888 rung prints a red DANGER!! banner before keying.
The first attenuator stage must be power-rated for full QDX output (~+37 dBm);
the operator confirms the RX888-input level is in range. Operator pre-flight —
gates the rung, not discovered by it.
Operator interface contract (must be supplied)
Out of scope (separate plan)
Remote self-hosted GitHub Actions runner, Actions/cron wiring, and the runner
security model (untrusted-fork code on a machine wired to a transmitter).
Not validated by this bench
A wired bench validates the firmware + software path at a controlled level. It
does not validate antenna, propagation, or real-world RFI.