Skip to content

TX-power override + thermal/gain experiment; fix CCK band-tracking bug#106

Merged
josephnef merged 1 commit into
masterfrom
feat/thermal-gain-experiment
Jun 26, 2026
Merged

TX-power override + thermal/gain experiment; fix CCK band-tracking bug#106
josephnef merged 1 commit into
masterfrom
feat/thermal-gain-experiment

Conversation

@josephnef

Copy link
Copy Markdown
Collaborator

What

Adds an absolute TXAGC-index override and a continuous TX-gain ramp to WiFiDriverTxDemo, plus a USRP-backed harness that measures the chip thermal meter against a swept TX gain. Built to answer "does the 8812AU thermal meter degrade over time under sustained TX?"

Answer: no. On a bus-powered 8812AU, the meter stays flat (raw pinned, delta ~+11/+12 "warm") across 5 min at max gain + ~100% duty (2.4 GHz) and 100 s (5 GHz), despite the SDR confirming a real +11.6 dB on-air power swing. The reading reflects steady-state die temperature, not TX-induced PA heating; the thermal-probe "backing off / may degrade the PA" warning never approaches its threshold.

Bug fixed along the way (the important bit)

While validating the gain knob with SDR ground truth, register read-back showed CCK (0xc20) stuck at the EFUSE value while OFDM (0xc24) tracked the override. Root cause:

phy_SwBand8812 only updates current_band_type when an actual hardware band-switch runs. init_hw_mlme_ext resets the shadow to BAND_MAX; the following same-band channel-set finds the chip already on 2.4 GHz, skips the switch, and leaves the shadow at BAND_MAX permanently. That makes bIsIn24G false, so:

  • CCK TX power is never re-programmed after init, and
  • BAND_MAX is fed to the thermal power-tracker (TickThermalMeter) and IQK.

Fix: set current_band_type = BandToSW unconditionally in phy_SwBand8812 — the channel's band is authoritative whether or not a HW switch is needed.

After the fix (SDR-verified): CCK on-air power tracks the index −40 → −21 dBFS over 0→40; 5 GHz still correctly skips CCK; ctest green; 5 GHz TX still works.

Changes

  • RadioManagementModuleSetTxPowerOverride(idx) override branch in PHY_SetTxPowerIndexByRateArray; ApplyTxPower() re-applies TX power without a channel switch; the current_band_type fix.
  • RtlJaguarDeviceSetTxPowerOverride / ApplyTxPower / ReadBBReg passthroughs.
  • txdemo/main.cppDEVOURER_TX_PWR_START/STOP/STEP/STEP_MS ramp (<devourer-txpwr> markers), DEVOURER_TX_GAP_US duty knob, gated DEVOURER_TX_PWR_READBACK diagnostic.
  • tests/ (uv) — thermal_gain_sweep.py orchestrator (merges thermal / txpwr / SDR → CSV + verdicts), sdr_power_probe.py (UHD B200/B210 relative dBFS), run_thermal_gain_sweep.sh.
  • CLAUDE.md — documents the new knobs.

Test

sudo ./tests/run_thermal_gain_sweep.sh --channel 6 --ht --gap-us 0 --start 20 --stop 45 --duration 300

ctest passes; verified on RTL8812AU (0bda:8812) with a LibreSDR B210 at 2.4 and 5 GHz.

🤖 Generated with Claude Code

…cking bug

Adds an absolute TXAGC-index override and a continuous TX-gain ramp to
WiFiDriverTxDemo, plus a USRP-backed harness to measure the chip thermal
meter (PR #103 probe) against a swept TX gain. Built to answer "does the
8812AU thermal meter degrade over time under sustained TX" — empirically
no: SDR-verified ~12-19 dB on-air power swings leave the meter flat
(steady-state die temp, not TX-induced PA heating).

Driver/demo:
- RadioManagementModule: SetTxPowerOverride(idx) forces the per-rate TXAGC
  index in PHY_SetTxPowerIndexByRateArray (bypassing the EFUSE table);
  ApplyTxPower() re-runs PHY_SetTxPowerLevel8812 for the current channel
  (SetMonitorChannel early-returns on an unchanged channel, so it can't
  re-push TX power mid-session).
- RtlJaguarDevice: SetTxPowerOverride / ApplyTxPower / ReadBBReg passthroughs.
- txdemo: DEVOURER_TX_PWR_START/STOP/STEP/STEP_MS gain ramp (emits
  <devourer-txpwr> markers), DEVOURER_TX_GAP_US duty knob, and a gated
  DEVOURER_TX_PWR_READBACK diagnostic.

Bug fix (surfaced by the override + SDR ground truth):
- phy_SwBand8812 only updated current_band_type when an actual HW band-switch
  ran. After init_hw_mlme_ext resets it to BAND_MAX, a same-band channel-set
  finds the chip already on 2.4G, skips the switch, and leaves the shadow at
  BAND_MAX permanently. That made bIsIn24G false, so CCK TX power was never
  re-programmed after init, and BAND_MAX was fed to the thermal pwrtrk and
  IQK. Fix: set current_band_type = BandToSW unconditionally (the channel's
  band is authoritative). SDR-confirmed CCK on-air power now tracks the index
  (-40 -> -21 dBFS over 0..40); 5G still correctly skips CCK; ctest green.

Harness (tests/, uv): thermal_gain_sweep.py orchestrator merges
<devourer-thermal>/<devourer-txpwr>/SDR streams to CSV + verdicts;
sdr_power_probe.py (UHD B200/B210 relative dBFS); run_thermal_gain_sweep.sh.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@josephnef josephnef merged commit 7303aa9 into master Jun 26, 2026
6 checks passed
@josephnef josephnef deleted the feat/thermal-gain-experiment branch June 26, 2026 06:36
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