Skip to content

Chip STBC TX diversity + txdemo event-loop EINTR fix (#132)#144

Merged
josephnef merged 4 commits into
masterfrom
stbc-tx-diversity
Jul 2, 2026
Merged

Chip STBC TX diversity + txdemo event-loop EINTR fix (#132)#144
josephnef merged 4 commits into
masterfrom
stbc-tx-diversity

Conversation

@josephnef

Copy link
Copy Markdown
Collaborator

Summary

Transmit-side spatial diversity (chip STBC), the TX dual of the #130 RX-MRC
result — plus a real TX bug fix uncovered along the way. Scoped to #132.

The bug fix (worth merging on its own)

txdemo's async-TX completion event loop broke out permanently on any
non-timeout return from libusb_handle_events_timeout_completed, including the
transient LIBUSB_ERROR_INTERRUPTED (EINTR)
. Once that thread exits, TX
completion callbacks stop firing, submitted URBs are never freed, and within a
few frames every libusb_submit_transfer fails — a "TX works briefly then every
send fails" wedge, seen intermittently under concurrent-RX load. Now EINTR is
ignored like TIMEOUT and other errors are logged (rate-limited) without breaking.
(Provable-by-inspection bug matching the symptom; couldn't be verified against
the intermittent failure because it stopped reproducing.)

The measurement enablers

  • txdemo: DEVOURER_USB_BUS/PORT topology selector (mirror of the RX demo —
    lets you TX-select one of several identical adapters).
  • txdemo: DEVOURER_TX_STBC_TOGGLE=1 alternates the STBC bit every frame; the
    RX reports the received STBC bit per frame, so one moving capture compares STBC
    vs single-stream on the same fading, tagged for free.
  • tests/stbc_sanity.sh: confirms the chip emits decodable STBC on-air (TX 8814
    MCS1/STBC → RX 8812 reads the STBC bit).

The result (see #132)

Chip STBC TX works on-air (sanity gate: 6336/6336 stbc=1). At a marginal rate
(MCS5), alternating STBC vs single-stream from a moving TX:

single-stream STBC advantage
Static 325 630 1.94×
Moving 792 2588 3.27×

STBC's advantage grows under motion (coding gain static, + diversity moving), and
it helps even a single-antenna receiver because the win is TX-side — the
moving-drone FPV case.

Testing

  • Sanity gate PASS; static + moving measurements clean (0 send-errors after the
    EINTR fix); STBC toggle verified ~50/50 alternating by sequence number.
  • Full build (all chips) green.

🤖 Generated with Claude Code

josephnef and others added 4 commits July 2, 2026 14:51
WiFiDriverTxDemo could only pick a TX adapter by first-match VID:PID, so two
identical RTL8814AU dongles (same VID:PID:serial) couldn't be told apart on the
TX side — the RX demo already had this (demo/main.cpp). Needed to TX-select one
of several identical adapters, e.g. for the #132 chip-STBC TX-diversity
measurement. Same semantics: DEVOURER_USB_BUS + optional DEVOURER_USB_PORT
(dotted libusb port path); unset falls back to the VID:PID open loop.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
tests/stbc_sanity.sh: TX canonical beacons at MCS1/STBC from an 8814 (chip
encodes Alamouti internally), RX on an 8812 (whose descriptor exposes the
received STBC bit, unlike the 8814 RX), and report whether frames arrive with
stbc=1. PASS = chip emits decodable STBC; FAIL(stbc=0) = descriptor STBC ignored
(would need CSD); INCONCLUSIVE = link too weak. The gate that decides whether the
#132 chip-STBC TX-diversity measurement can proceed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bare `wait` blocked on the still-running TX beacon, so the script never printed
its verdict. Capture the RX pid and wait on it alone.
…STBC toggle

Two changes from the #132 chip-STBC TX-diversity work:

1. FIX: usb_event_loop() broke out of the loop on any non-TIMEOUT return from
   libusb_handle_events_timeout_completed, including the transient
   LIBUSB_ERROR_INTERRUPTED (EINTR — a signal hitting the underlying poll, more
   likely under concurrent USB load). Exiting that thread permanently stops
   servicing async TX-completion callbacks, so submitted URBs are never freed and
   within a few frames every libusb_submit_transfer fails — a "TX works briefly
   then every send fails" wedge, seen intermittently while an RX ran concurrently.
   Now INTERRUPTED is ignored like TIMEOUT and other errors are logged (rate-
   limited) without breaking. This is a provable-by-inspection bug matching the
   observed symptom; it could not be verified against the intermittent failure
   because that no longer reproduces.

2. FEATURE: DEVOURER_TX_STBC_TOGGLE=1 alternates the STBC bit every frame (rate
   from DEVOURER_TX_RATE, must be HT/VHT). The RX reports the received STBC bit
   per frame, so an alternating TX lets one moving capture compare STBC vs
   single-stream delivery on the same fading — the transmit-side mobility
   measurement, tagged for free by the receiver. Verified: RX sees ~50/50
   stbc=0/stbc=1, alternating per sequence number.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@josephnef josephnef added enhancement New feature or request spatial-diversity Spatial-diversity axis: exploiting idle RF chains for the single-stream link labels Jul 2, 2026
@josephnef josephnef merged commit 72d7094 into master Jul 2, 2026
12 checks passed
@josephnef josephnef deleted the stbc-tx-diversity branch July 2, 2026 12:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request spatial-diversity Spatial-diversity axis: exploiting idle RF chains for the single-stream link

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant