From 3d99cac03b91e22c0fd25fb0d690e32cb7df5358 Mon Sep 17 00:00:00 2001 From: Stan Grams Date: Sun, 15 Mar 2026 09:44:46 +0100 Subject: [PATCH] [feat](trx-backend-soapysdr): add hardware AGC toggle and SDR settings UI row MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add hardware AGC on/off control for SoapySDR backend, wired through the full stack from RigCommand to the web UI: - RigCommand::SetSdrAgc(bool) + ClientCommand::SetSdrAgc in protocol - set_sdr_agc() on RigCat trait (not-supported default) - SoapySdrRig: agc_enabled field, set_sdr_agc() via pipeline agc_cmd, sdr_agc_enabled in filter_state(); removes the "not yet implemented" warning — gain_mode="auto" now properly enables hardware AGC via SoapySDR set_gain_mode() - IqSource::set_gain_mode() trait method; RealIqSource implements it - SdrPipeline: agc_cmd channel, read loop applies it each iteration - POST /set_sdr_agc endpoint in trx-frontend-http - New "SDR settings" full-row in index.html with Hardware AGC checkbox and RF Gain (moved out of WFM controls); row hidden when show_sdr_gain_control is false - app.js: AGC checkbox handler, disables RF gain input while AGC is on, syncs checkbox state from filter.sdr_agc_enabled Co-Authored-By: Claude Sonnet 4.6 Signed-off-by: Stan Grams --- .../trx-frontend-http/assets/web/app.js | 22 ++++++++++++++-- .../trx-frontend-http/assets/web/index.html | 23 +++++++++++------ .../trx-frontend/trx-frontend-http/src/api.rs | 14 +++++++++++ src/trx-core/src/rig/command.rs | 1 + src/trx-core/src/rig/controller/handlers.rs | 1 + src/trx-core/src/rig/mod.rs | 10 ++++++++ src/trx-core/src/rig/state.rs | 2 ++ src/trx-protocol/src/mapping.rs | 2 ++ src/trx-protocol/src/types.rs | 1 + src/trx-server/src/rig_task.rs | 8 ++++++ .../trx-backend-soapysdr/src/dsp.rs | 23 +++++++++++++++++ .../trx-backend-soapysdr/src/lib.rs | 25 +++++++++++++------ .../src/real_iq_source.rs | 6 +++++ 13 files changed, 122 insertions(+), 16 deletions(-) diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js index 956e20a..b4ee328 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js @@ -2755,8 +2755,12 @@ function render(update) { } updateSdrSquelchControlVisibility(); } - if (sdrGainControlsEl && typeof update.show_sdr_gain_control === "boolean") { - sdrGainControlsEl.style.display = update.show_sdr_gain_control ? "" : "none"; + if (typeof update.show_sdr_gain_control === "boolean") { + if (sdrSettingsRowEl) sdrSettingsRowEl.style.display = update.show_sdr_gain_control ? "" : "none"; + } + if (update.filter && sdrAgcEl && typeof update.filter.sdr_agc_enabled === "boolean") { + sdrAgcEl.checked = update.filter.sdr_agc_enabled; + updateSdrGainInputState(); } if (update.status && update.status.freq && typeof update.status.freq.hz === "number") { applyLocalTunedFrequency(update.status.freq.hz, true); @@ -6712,9 +6716,11 @@ const wfmControlsCol = document.getElementById("wfm-controls-col"); const wfmDeemphasisEl = document.getElementById("wfm-deemphasis"); const wfmAudioModeEl = document.getElementById("wfm-audio-mode"); const wfmDenoiseEl = document.getElementById("wfm-denoise"); +const sdrSettingsRowEl = document.getElementById("sdr-settings-row"); const sdrGainControlsEl = document.getElementById("sdr-gain-controls"); const sdrGainEl = document.getElementById("sdr-gain-db"); const sdrGainSetBtn = document.getElementById("sdr-gain-set"); +const sdrAgcEl = document.getElementById("sdr-agc-enabled"); const wfmStFlagEl = document.getElementById("wfm-st-flag"); const sdrSquelchWrapEl = document.getElementById("sdr-squelch-wrap"); const sdrSquelchEl = document.getElementById("sdr-squelch"); @@ -6889,6 +6895,18 @@ function submitSdrGain() { if (!Number.isFinite(parsed) || parsed < 0) return; postPath(`/set_sdr_gain?db=${encodeURIComponent(parsed)}`).catch(() => {}); } +function updateSdrGainInputState() { + if (!sdrAgcEl || !sdrGainEl || !sdrGainSetBtn) return; + const agcOn = sdrAgcEl.checked; + sdrGainEl.disabled = agcOn; + sdrGainSetBtn.disabled = agcOn; +} +if (sdrAgcEl) { + sdrAgcEl.addEventListener("change", () => { + postPath(`/set_sdr_agc?enabled=${sdrAgcEl.checked ? "true" : "false"}`).catch(() => {}); + updateSdrGainInputState(); + }); +} if (sdrGainSetBtn) { sdrGainSetBtn.addEventListener("click", submitSdrGain); } diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html index 0210050..27e271a 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html @@ -232,13 +232,6 @@ -
- - -