From 1368f249c43c8c1e0310f691c01a4ea5b2ac7de7 Mon Sep 17 00:00:00 2001 From: Uladzimir Karpenka Date: Sat, 16 May 2026 22:05:08 +0300 Subject: [PATCH] Remove XVTR RF checkbox; fix XVTR Enable bit to match Thetis MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit XVTR RF (xvtr_rf in Thetis) is dead code — GetXVTRRF() is never called. Remove the field, UI column, save/load from TXvtrEntry. UseDDCIn is now always True when in XVTR mode (previous default behaviour, XVTRRF=False). Byte 1400 bit 0 (XVTR Enable / VHF T/R relay output) now follows Thetis: - XVTR mode: set only when DisablePA=True (external T/R relay needed) - HF mode: set when Alex.EnableXvtrHf is checked (Antenna tab) Co-Authored-By: Claude Sonnet 4.6 --- HPSDRNetwork.pas | 23 +++++++++++++++-------- MainForm.pas | 5 +---- Settings.pas | 5 ----- SettingsForm.pas | 11 ++--------- 4 files changed, 18 insertions(+), 26 deletions(-) diff --git a/HPSDRNetwork.pas b/HPSDRNetwork.pas index fa1731b..6ba5dbd 100644 --- a/HPSDRNetwork.pas +++ b/HPSDRNetwork.pas @@ -145,9 +145,8 @@ type FAlexConfig: TAlexSettings; // per-band antenna + routing config FStepAtten: Byte; // ADC0 step attenuator 0-31 dB // ---- XVTR (Transverter) state ---- - // FXvtrEnable — устанавливает bit 0 байта 1400 HP-пакета: включает выход - // XVTR на трансивере (управляющий пин/реле). Обычно True, пока активный - // диапазон — трансвертер. + // FXvtrEnable — True когда активен XVTR-диапазон. Используется как + // XvtrActive в CalcAlex0 и для управления byte 1400 bit 0. FXvtrEnable: Boolean; // FXvtrRxAntOverride — если 1..3, использовать эту антенну вместо // Alex.RxAnt[band] (per-XVTR RX antenna). 0 = не переопределять. @@ -1417,12 +1416,20 @@ begin Buf[1435] := Alex0 and $FF; end; - // XVTR enable bit (byte 1400 bit 0) - // openHPSDR Ethernet Protocol v4.3: byte 1400 — Transverter/audio enable. - // bit 0 = XVTR enable, bit 1 = Audio Codec enable (на платах с поддержкой). - // Audio codec бит оставляем 0 — мы IQ-mic не используем. + // XVTR enable bit (byte 1400 bit 0) — управляет выходом VHF T/R relay платы. + // Логика как в Thetis: + // в XVTR-режиме: бит = DisablePA (внешний T/R relay нужен только если PA подавлен) + // в HF-режиме: бит = Alex.EnableXvtrHf (галочка "Enable XVTR HF" в Antenna tab) if FXvtrEnable then - Buf[1400] := Buf[1400] or $01; + begin + if FXvtrDisablePA then + Buf[1400] := Buf[1400] or $01; + end + else + begin + if FAlexConfig.EnableXvtrHf then + Buf[1400] := Buf[1400] or $01; + end; // Step attenuators ADC0/ADC1 (bytes 1443/1442) // 0 dB = 0, max 31 dB diff --git a/MainForm.pas b/MainForm.pas index 5dfbdf3..5b6a751 100644 --- a/MainForm.pas +++ b/MainForm.pas @@ -5604,10 +5604,7 @@ begin FXvtrSettings.Entries[FCurrentXvtr].Enabled then begin En := True; - // XVTRRF=True означает что трансвертер использует HF тракт — не нужно - // переключаться на отдельный XVTR DDC IN на Alex. Default False → - // подключаем XVTR-IF к выделенному пину XVTR DDC IN. - UseDDCIn := not FXvtrSettings.Entries[FCurrentXvtr].XVTRRF; + UseDDCIn := True; DisablePA := FXvtrSettings.Entries[FCurrentXvtr].DisablePA; RxAnt := FXvtrSettings.Entries[FCurrentXvtr].RXAntenna; end diff --git a/Settings.pas b/Settings.pas index 839b393..e2b262d 100644 --- a/Settings.pas +++ b/Settings.pas @@ -118,8 +118,6 @@ type RXGain: Double; // dB, компенсация усиления RX тракта RXOnly: Boolean; // True — запрещает TX на этом трансверторе TXPower: Integer; // 0..100 % (drive level специально для XVTR) - XVTRRF: Boolean; // True — трансвертер использует основной HF RF путь - // (а не отдельный XVTR DDC IN на Alex) DisablePA: Boolean; // True — отключить внутренний PA при TX (XVTR имеет свой) RXAntenna: Byte; // 0=по-умолчанию(основной band), 1=ANT1, 2=ANT2, 3=ANT3 LastFreq: Double; // Hz — последняя tuned visible частота (BandStack) @@ -1058,7 +1056,6 @@ begin X.Entries[i].RXGain := 0.0; X.Entries[i].RXOnly := False; X.Entries[i].TXPower := 100; - X.Entries[i].XVTRRF := False; X.Entries[i].DisablePA := False; X.Entries[i].RXAntenna := 0; X.Entries[i].LastFreq := 0.0; @@ -1104,7 +1101,6 @@ begin X.Entries[i].RXGain := JD(EObj, 'rx_gain', X.Entries[i].RXGain); X.Entries[i].RXOnly := JB(EObj, 'rx_only', X.Entries[i].RXOnly); X.Entries[i].TXPower := EnsureRange(JI(EObj, 'tx_pwr', X.Entries[i].TXPower), 0, 100); - X.Entries[i].XVTRRF := JB(EObj, 'xvtr_rf', X.Entries[i].XVTRRF); X.Entries[i].DisablePA := JB(EObj, 'dis_pa', X.Entries[i].DisablePA); X.Entries[i].RXAntenna := EnsureRange(JI(EObj, 'rx_ant', X.Entries[i].RXAntenna), 0, 3); X.Entries[i].LastFreq := JD(EObj, 'last_freq', X.Entries[i].LastFreq); @@ -1135,7 +1131,6 @@ begin JW(EObj, 'rx_gain', X.Entries[i].RXGain); JW(EObj, 'rx_only', X.Entries[i].RXOnly); JW(EObj, 'tx_pwr', X.Entries[i].TXPower); - JW(EObj, 'xvtr_rf', X.Entries[i].XVTRRF); JW(EObj, 'dis_pa', X.Entries[i].DisablePA); JW(EObj, 'rx_ant', Integer(X.Entries[i].RXAntenna)); JW(EObj, 'last_freq', X.Entries[i].LastFreq); diff --git a/SettingsForm.pas b/SettingsForm.pas index 1ce5d47..234e85a 100644 --- a/SettingsForm.pas +++ b/SettingsForm.pas @@ -218,7 +218,6 @@ type FXvtrRXGain: array[0..CFG_XVTR_COUNT-1] of TFloatSpinEdit; // dB FXvtrRXOnly: array[0..CFG_XVTR_COUNT-1] of TCheckBox; FXvtrPower: array[0..CFG_XVTR_COUNT-1] of TSpinEdit; // 0..100 - FXvtrRF: array[0..CFG_XVTR_COUNT-1] of TCheckBox; FXvtrDisPA: array[0..CFG_XVTR_COUNT-1] of TCheckBox; FXvtrRXAnt: array[0..CFG_XVTR_COUNT-1] of TComboBox; // 0=def..3=ANT3 FChkXvtrTunPwr: TCheckBox; @@ -2662,9 +2661,8 @@ const GAIN_X = 504; GAIN_W = 62; // 1 десятичная, dB RXO_X = 574; RXO_W = 56; // chk центрирован PWR_X = 638; PWR_W = 58; // целое % - RF_X = 704; RF_W = 56; - PA_X = 768; PA_W = 66; - ANT_X = 842; ANT_W = 78; // combo default/ANT1/ANT2/ANT3 + PA_X = 704; PA_W = 66; + ANT_X = 778; ANT_W = 78; // combo default/ANT1/ANT2/ANT3 GRP_W = ANT_X + ANT_W + 14; // 934 var Grp, GrpOpts: TPanel; @@ -2795,7 +2793,6 @@ begin MakeHdr(Grp, 'RX Gain' + LineEnding + 'dB', GAIN_X, Y, GAIN_W); MakeHdr(Grp, 'RX' + LineEnding + 'Only', RXO_X, Y, RXO_W); MakeHdr(Grp, 'TX Pwr' + LineEnding + '%', PWR_X, Y, PWR_W); - MakeHdr(Grp, 'XVTR' + LineEnding + 'RF', RF_X, Y, RF_W); MakeHdr(Grp, 'Disable' + LineEnding + 'PA', PA_X, Y, PA_W); MakeHdr(Grp, 'RX' + LineEnding + 'Antenna', ANT_X, Y, ANT_W); @@ -2814,7 +2811,6 @@ begin // Чекбокс RX Only центрируем FXvtrRXOnly[i]:= MakeChk(Grp, RXO_X + (RXO_W - 22) div 2, Y + 2); FXvtrPower[i] := MakeInt(Grp, PWR_X, Y, PWR_W, 0, 100); - FXvtrRF[i] := MakeChk(Grp, RF_X + (RF_W - 22) div 2, Y + 2); FXvtrDisPA[i] := MakeChk(Grp, PA_X + (PA_W - 22) div 2, Y + 2); FXvtrRXAnt[i] := MakeCmb(Grp, ANT_X, Y, ANT_W); FXvtrRXAnt[i].Items.Add('default'); @@ -2876,7 +2872,6 @@ begin if FXvtrRXGain[Idx]<> nil then FXvtrRXGain[Idx].Enabled:= En; if FXvtrRXOnly[Idx]<> nil then FXvtrRXOnly[Idx].Enabled:= En; if FXvtrPower[Idx] <> nil then FXvtrPower[Idx].Enabled := En; - if FXvtrRF[Idx] <> nil then FXvtrRF[Idx].Enabled := En; if FXvtrDisPA[Idx] <> nil then FXvtrDisPA[Idx].Enabled := En; if FXvtrRXAnt[Idx] <> nil then FXvtrRXAnt[Idx].Enabled := En; end; @@ -2895,7 +2890,6 @@ begin if FXvtrRXGain[i]<> nil then FXvtrConfig.Entries[i].RXGain := FXvtrRXGain[i].Value; if FXvtrRXOnly[i]<> nil then FXvtrConfig.Entries[i].RXOnly := FXvtrRXOnly[i].Checked; if FXvtrPower[i] <> nil then FXvtrConfig.Entries[i].TXPower := FXvtrPower[i].Value; - if FXvtrRF[i] <> nil then FXvtrConfig.Entries[i].XVTRRF := FXvtrRF[i].Checked; if FXvtrDisPA[i] <> nil then FXvtrConfig.Entries[i].DisablePA := FXvtrDisPA[i].Checked; if (FXvtrRXAnt[i]<> nil) and (FXvtrRXAnt[i].ItemIndex >= 0) then FXvtrConfig.Entries[i].RXAntenna := Byte(FXvtrRXAnt[i].ItemIndex); @@ -2938,7 +2932,6 @@ begin if FXvtrRXGain[i]<> nil then FXvtrRXGain[i].Value := X.Entries[i].RXGain; if FXvtrRXOnly[i]<> nil then FXvtrRXOnly[i].Checked:= X.Entries[i].RXOnly; if FXvtrPower[i] <> nil then FXvtrPower[i].Value := X.Entries[i].TXPower; - if FXvtrRF[i] <> nil then FXvtrRF[i].Checked := X.Entries[i].XVTRRF; if FXvtrDisPA[i] <> nil then FXvtrDisPA[i].Checked := X.Entries[i].DisablePA; if FXvtrRXAnt[i] <> nil then FXvtrRXAnt[i].ItemIndex := EnsureRange(X.Entries[i].RXAntenna, 0, 3);