add trancverter

This commit is contained in:
2026-05-14 20:24:50 +03:00
parent aea9f02df8
commit 020b9422e0
6 changed files with 1083 additions and 66 deletions
+71 -3
View File
@@ -143,6 +143,21 @@ type
FAlexEnabled: Boolean;
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: Boolean;
// FXvtrRxAntOverride — если 1..3, использовать эту антенну вместо
// Alex.RxAnt[band] (per-XVTR RX antenna). 0 = не переопределять.
FXvtrRxAntOverride: Byte;
// FXvtrDisablePA — при TX подавляет бит 27 Alex (T/R relay): внутренний
// PA остаётся в RX-положении, TX-сигнал идёт через XVTR-IF.
FXvtrDisablePA: Boolean;
// FXvtrUseRxDDCIn — True если RX тракт XVTR подключён к XVTR DDC IN пину
// Alex (Alex bit 8 + bit 11). Эквивалент Alex.RxOnly=3, но включается
// динамически при выборе XVTR-band, не привязан к band-индексу.
FXvtrUseRxDDCIn: Boolean;
FSendLock: TCriticalSection; // защита concurrent UDP sends
@@ -194,6 +209,11 @@ type
Transmitting, PAEnabled, AlexEnabled: Boolean);
procedure SetStepAtten(dB: Byte);
procedure SetAlexConfig(const A: TAlexSettings);
// Включение/настройка XVTR-режима. Все параметры применяются мгновенно
// (отправляется HP-пакет). Когда AEnable=False, XVTR-bit гасится,
// антенна и Alex routing возвращаются к per-band дефолту.
procedure SetXvtrMode(AEnable, AUseRxDDCIn, ADisablePA: Boolean;
ARxAnt: Byte);
procedure SendFullHP;
procedure SendDDCAudio(const LeftRight: array of SmallInt);
procedure SendDUCIQ(const IData, QData: array of Integer);
@@ -1095,9 +1115,20 @@ end;
// Все биты active-high. Bit 27 = T/R relay (0=RX, 1=TX).
// Биты 24-26: ANT1/ANT2/ANT3. Биты 20-23,29-31: LPF. Биты 1-12: HPF/BPF.
// Биты 8-11: вторичный RX вход (XVTR/Ext1/Ext2/Bypass relay).
//
// XvtrRxAnt — override антенны для RX (1..3) если активен трансвертер;
// 0 = не переопределять, использовать Alex.RxAnt[band].
// XvtrUseRxDDCIn — True: при RX подключить XVTR DDC IN (Alex bit 8 + bit 11).
// Применяется только в RX и только когда XvtrRxAnt активен.
// XvtrDisablePA — True: при TX НЕ устанавливать bit 27 (T/R relay):
// внутренний PA не активируется, IF-сигнал идёт по тракту
// XVTR без усиления.
function CalcAlex0(RXFreqHz, TXFreqHz: Double;
Transmitting, IsOrion2: Boolean;
const Alex: TAlexSettings): LongWord;
const Alex: TAlexSettings;
XvtrRxAnt: Byte = 0;
XvtrUseRxDDCIn: Boolean = False;
XvtrDisablePA: Boolean = False): LongWord;
var
txf: Double;
BandIdx: Integer;
@@ -1107,9 +1138,13 @@ begin
// Bit 27 = T/R relay (0=RX, 1=TX).
// Bit 18 = TxRx Status для Orion MkII 5.2 / 7000DLE / Saturn / G2.
// Если XvtrDisablePA=True — НЕ устанавливаем bit 27 (PA остаётся в RX
// положении). Bit 18 (TxRx status) всё равно устанавливаем — это просто
// индикатор состояния для логики платы, не управление реле.
if Transmitting then
begin
Result := Result or $08000000; // bit 27: T/R relay
if not XvtrDisablePA then
Result := Result or $08000000; // bit 27: T/R relay
if IsOrion2 then
Result := Result or $00040000; // bit 18: TxRx Status
end;
@@ -1155,9 +1190,14 @@ begin
// Биты 24-26: ANT 1/2/3. Выбор зависит от диапазона и режима TX/RX.
// Дефолт ANT1 — безопасен при любом состоянии.
// Если активен XVTR с RX antenna override (XvtrRxAnt 1..3) — он переопределяет
// RX антенну. TX антенна для XVTR всё равно берётся из Alex.TxAnt[band] —
// обычно та же что для основного HF-band за этой IF-частотой.
BandIdx := FreqToBandIndex(RXFreqHz);
if Transmitting then
AntVal := Alex.TxAnt[BandIdx]
else if (XvtrRxAnt >= 1) and (XvtrRxAnt <= 3) then
AntVal := XvtrRxAnt
else
AntVal := Alex.RxAnt[BandIdx];
if AntVal < 1 then AntVal := 1;
@@ -1169,6 +1209,8 @@ begin
// Биты 8-11: вторичный RX вход (Bypass relay, Ext1, Ext2, XvtrDDC).
// В режиме TX управляется глобальными флагами; в RX — per-band конфигом.
// Когда активен XVTR с XvtrUseRxDDCIn=True — переопределяем на XVTR DDC IN
// вне зависимости от Alex.RxOnly[band].
if Transmitting then
begin
if Alex.RxBypassOnTx then
@@ -1177,6 +1219,11 @@ begin
Result := Result or $00000200 // bit 9: Ext1
or $00000800; // bit 11: Bypass relay
end
else if XvtrUseRxDDCIn then
begin
Result := Result or $00000100 // bit 8: XVTR DDC In
or $00000800; // bit 11: Bypass relay
end
else
begin
case Alex.RxOnly[BandIdx] of
@@ -1196,6 +1243,19 @@ begin
if FConnected then SendFullHP;
end;
procedure THPSDRNetwork.SetXvtrMode(AEnable, AUseRxDDCIn, ADisablePA: Boolean;
ARxAnt: Byte);
begin
FXvtrEnable := AEnable;
FXvtrUseRxDDCIn := AEnable and AUseRxDDCIn;
FXvtrDisablePA := AEnable and ADisablePA;
if AEnable and (ARxAnt >= 1) and (ARxAnt <= 3) then
FXvtrRxAntOverride := ARxAnt
else
FXvtrRxAntOverride := 0;
if FConnected then SendFullHP;
end;
procedure THPSDRNetwork.ConfigureDDCs(NumDDCs: Byte; SampleRate: Word;
ADCSource: Byte);
var
@@ -1338,13 +1398,21 @@ begin
if FAlexEnabled then
begin
Alex0 := CalcAlex0(FCurrentRXFreq, FCurrentTXFreq,
FIsTransmitting, IsOrion2, FAlexConfig);
FIsTransmitting, IsOrion2, FAlexConfig,
FXvtrRxAntOverride, FXvtrUseRxDDCIn, FXvtrDisablePA);
Buf[1432] := (Alex0 shr 24) and $FF;
Buf[1433] := (Alex0 shr 16) and $FF;
Buf[1434] := (Alex0 shr 8) and $FF;
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 не используем.
if FXvtrEnable then
Buf[1400] := Buf[1400] or $01;
// Step attenuators ADC0/ADC1 (bytes 1443/1442)
// 0 dB = 0, max 31 dB
Buf[1443] := FStepAtten; // ADC0 attenuation