From b89cb9a6516234a655194a34950aabe378c8a169 Mon Sep 17 00:00:00 2001 From: Jan Svabenik Date: Fri, 3 Apr 2026 11:42:40 +0200 Subject: [PATCH] fix: decouple composite drive from hardware TX gain Clarify that outputDrive controls only the composite signal path while PlutoSDR hardware gain stays fixed at 0 dB. Relax outputDrive validation to allow stronger composite drive during hardware tuning and update the Pluto example config accordingly. --- cmd/fmrtx/main.go | 5 +++-- docs/config.plutosdr.json | 2 +- internal/config/config.go | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/cmd/fmrtx/main.go b/cmd/fmrtx/main.go index 7ca6311..3f234d6 100644 --- a/cmd/fmrtx/main.go +++ b/cmd/fmrtx/main.go @@ -147,11 +147,12 @@ func runTXMode(cfg cfgpkg.Config, driver platform.SoapyDriver, autoStart bool) { defer cancel() // Configure driver - // Gain mapping: outputDrive 1.0 = max power (0 dB atten), 0.0 = min (-89 dB) + // OutputDrive controls composite signal level, NOT hardware gain. + // Hardware TX gain is always 0 dB (max power). Use external attenuator for power control. soapyCfg := platform.SoapyConfig{ Driver: cfg.Backend.Device, CenterFreqHz: cfg.FM.FrequencyMHz * 1e6, - GainDB: (1.0 - cfg.FM.OutputDrive) * 89, // 1.0→0dB(max), 0.5→44.5dB atten, 0.0→89dB(min) + GainDB: 0, // 0 dB = max TX power on PlutoSDR } soapyCfg.SampleRateHz = cfg.EffectiveDeviceRate() diff --git a/docs/config.plutosdr.json b/docs/config.plutosdr.json index 99ad041..52cbf9d 100644 --- a/docs/config.plutosdr.json +++ b/docs/config.plutosdr.json @@ -19,7 +19,7 @@ "pilotLevel": 0.1, "rdsInjection": 0.05, "preEmphasisTauUS": 50, - "outputDrive": 1.0, + "outputDrive": 1.8, "compositeRateHz": 228000, "maxDeviationHz": 75000, "limiterEnabled": true, diff --git a/internal/config/config.go b/internal/config/config.go index f569af5..584d189 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -128,8 +128,8 @@ func (c Config) Validate() error { if c.FM.RDSInjection < 0 || c.FM.RDSInjection > 0.15 { return fmt.Errorf("fm.rdsInjection out of range") } - if c.FM.OutputDrive < 0 || c.FM.OutputDrive > 1 { - return fmt.Errorf("fm.outputDrive out of range") + if c.FM.OutputDrive < 0 || c.FM.OutputDrive > 3 { + return fmt.Errorf("fm.outputDrive out of range (0..3)") } if c.FM.CompositeRateHz < 96000 || c.FM.CompositeRateHz > 1520000 { return fmt.Errorf("fm.compositeRateHz out of range")