mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
add Alex setup
This commit is contained in:
+104
-40
@@ -19,7 +19,7 @@ uses
|
||||
{$ELSE}
|
||||
Sockets, BaseUnix,
|
||||
{$ENDIF}
|
||||
HPSDRProtocol, SyncObjs;
|
||||
HPSDRProtocol, SyncObjs, Settings;
|
||||
|
||||
const
|
||||
DUC_TX_QUEUE_SIZE = 256; // power of two, bounded latency on TX underrun/overrun
|
||||
@@ -141,7 +141,8 @@ type
|
||||
FIsTransmitting: Boolean;
|
||||
FPAEnabled: Boolean;
|
||||
FAlexEnabled: Boolean;
|
||||
FStepAtten: Byte; // ADC0 step attenuator 0-31 dB
|
||||
FAlexConfig: TAlexSettings; // per-band antenna + routing config
|
||||
FStepAtten: Byte; // ADC0 step attenuator 0-31 dB
|
||||
|
||||
FSendLock: TCriticalSection; // защита concurrent UDP sends
|
||||
|
||||
@@ -192,6 +193,7 @@ type
|
||||
procedure UpdateState(RXFreqHz, TXFreqHz: Double; DriveLevel: Byte;
|
||||
Transmitting, PAEnabled, AlexEnabled: Boolean);
|
||||
procedure SetStepAtten(dB: Byte);
|
||||
procedure SetAlexConfig(const A: TAlexSettings);
|
||||
procedure SendFullHP;
|
||||
procedure SendDDCAudio(const LeftRight: array of SmallInt);
|
||||
procedure SendDUCIQ(const IData, QData: array of Integer);
|
||||
@@ -611,6 +613,7 @@ begin
|
||||
FIsTransmitting := False;
|
||||
FPAEnabled := True;
|
||||
FAlexEnabled := True;
|
||||
TSettingsManager.DefaultAlex(FAlexConfig);
|
||||
FSendLock := TCriticalSection.Create;
|
||||
FDUCIQLock := TCriticalSection.Create;
|
||||
FDUCIQSem := RTLEventCreate;
|
||||
@@ -1071,65 +1074,126 @@ end;
|
||||
// Transmitting — режим передачи
|
||||
// IsOrion2 — ANAN-7000/8000 (другие BPF)
|
||||
// ---------------------------------------------------------------------------
|
||||
// Преобразует частоту в индекс диапазона 0=160m..10=6m (Thetis-compatible).
|
||||
function FreqToBandIndex(FreqHz: Double): Integer;
|
||||
begin
|
||||
if FreqHz >= 39850000 then Result := 10 // 6m
|
||||
else if FreqHz >= 26465000 then Result := 9 // 10m
|
||||
else if FreqHz >= 23170000 then Result := 8 // 12m
|
||||
else if FreqHz >= 19584000 then Result := 7 // 15m
|
||||
else if FreqHz >= 16209000 then Result := 6 // 17m
|
||||
else if FreqHz >= 12075000 then Result := 5 // 20m
|
||||
else if FreqHz >= 8700000 then Result := 4 // 30m
|
||||
else if FreqHz >= 6202000 then Result := 3 // 40m
|
||||
else if FreqHz >= 4665000 then Result := 2 // 60m
|
||||
else if FreqHz >= 2750000 then Result := 1 // 80m
|
||||
else Result := 0; // 160m
|
||||
end;
|
||||
|
||||
// Строит 32-битное слово Alex0 для HP-пакета (байты 1432-1435).
|
||||
// Протокол: openHPSDR Ethernet Protocol v4.3, Appendix D.
|
||||
// Все биты 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).
|
||||
function CalcAlex0(RXFreqHz, TXFreqHz: Double;
|
||||
Transmitting, IsOrion2: Boolean): LongWord;
|
||||
Transmitting, IsOrion2: Boolean;
|
||||
const Alex: TAlexSettings): LongWord;
|
||||
var
|
||||
txf: Double;
|
||||
txf: Double;
|
||||
BandIdx: Integer;
|
||||
AntVal: Byte;
|
||||
begin
|
||||
Result := 0;
|
||||
|
||||
// TX relay при передаче
|
||||
// Bit 27 ($08000000) = T/R relay для всех плат
|
||||
// Bit 18 ($00040000) = TxRx Status для Orion MkII / Saturn / G2
|
||||
// Bit 27 = T/R relay (0=RX, 1=TX).
|
||||
// Bit 18 = TxRx Status для Orion MkII 5.2 / 7000DLE / Saturn / G2.
|
||||
if Transmitting then
|
||||
begin
|
||||
Result := Result or $08000000; // ALEX_TX_RELAY bit27
|
||||
Result := Result or $08000000; // bit 27: T/R relay
|
||||
if IsOrion2 then
|
||||
Result := Result or $00040000; // TxRx Status bit18 (ANAN-7/8000, Saturn)
|
||||
Result := Result or $00040000; // bit 18: TxRx Status
|
||||
end;
|
||||
|
||||
// RX HPF (для ANAN-100/200) или BPF (для ANAN-7000)
|
||||
// HPF (ANAN-100/200) или BPF (ANAN-7000/8000/Saturn/G2) — по RX-частоте.
|
||||
if IsOrion2 then
|
||||
begin
|
||||
// Band-pass filters ANAN-7000/8000
|
||||
if RXFreqHz < 1500000 then Result := Result or $00001000 // BYPASS_BPF
|
||||
else if RXFreqHz < 2100000 then Result := Result or $00000040 // 160 BPF
|
||||
else if RXFreqHz < 5500000 then Result := Result or $00000020 // 80/60 BPF
|
||||
else if RXFreqHz < 11000000 then Result := Result or $00000010 // 40/30 BPF
|
||||
else if RXFreqHz < 22000000 then Result := Result or $00000002 // 20/15 BPF
|
||||
else if RXFreqHz < 35600000 then Result := Result or $00000004 // 12/10 BPF
|
||||
else Result := Result or $00000008; // 6m+preamp
|
||||
// Band-pass filters — Orion MkII 5.2, ANAN-7000DLE, Saturn, ANAN-G2
|
||||
if RXFreqHz < 1500000 then Result := Result or $00001000 // bit 12: HF Bypass
|
||||
else if RXFreqHz < 2100000 then Result := Result or $00000040 // bit 6: 160m BPF
|
||||
else if RXFreqHz < 5500000 then Result := Result or $00000020 // bit 5: 80/60m BPF
|
||||
else if RXFreqHz < 11000000 then Result := Result or $00000010 // bit 4: 40/30m BPF
|
||||
else if RXFreqHz < 22000000 then Result := Result or $00000002 // bit 1: 20/15m BPF
|
||||
else if RXFreqHz < 35600000 then Result := Result or $00000004 // bit 2: 12/10m BPF
|
||||
else Result := Result or $00000008; // bit 3: 6m + preamp
|
||||
end
|
||||
else
|
||||
begin
|
||||
// High-pass filters ANAN-100/200
|
||||
if RXFreqHz < 1800000 then Result := Result or $00001000 // BYPASS_HPF
|
||||
else if RXFreqHz < 6500000 then Result := Result or $00000040 // 1.5 MHz HPF
|
||||
else if RXFreqHz < 9500000 then Result := Result or $00000020 // 6.5 MHz HPF
|
||||
else if RXFreqHz < 13000000 then Result := Result or $00000010 // 9.5 MHz HPF
|
||||
else if RXFreqHz < 20000000 then Result := Result or $00000002 // 13 MHz HPF
|
||||
else if RXFreqHz < 50000000 then Result := Result or $00000004 // 20 MHz HPF
|
||||
else Result := Result or $00000008; // 6m preamp
|
||||
// High-pass filters — Atlas, Hermes, ANAN-10/10E/100/100B/100D/200D
|
||||
if RXFreqHz < 1800000 then Result := Result or $00001000 // bit 12: HF Bypass
|
||||
else if RXFreqHz < 6500000 then Result := Result or $00000040 // bit 6: 1.5 MHz HPF
|
||||
else if RXFreqHz < 9500000 then Result := Result or $00000020 // bit 5: 6.5 MHz HPF
|
||||
else if RXFreqHz < 13000000 then Result := Result or $00000010 // bit 4: 9.5 MHz HPF
|
||||
else if RXFreqHz < 20000000 then Result := Result or $00000002 // bit 1: 13 MHz HPF
|
||||
else if RXFreqHz < 50000000 then Result := Result or $00000004 // bit 2: 20 MHz HPF
|
||||
else Result := Result or $00000008; // bit 3: 6m preamp
|
||||
end;
|
||||
|
||||
// TX LPF — при RX через Ant1/2/3 сигнал идёт через TX LPF тоже
|
||||
// (для pre-Orion2 без внешней антенны)
|
||||
// TX LPF — по TX-частоте. В RX-режиме для не-Orion2 плат RX-сигнал идёт
|
||||
// через TX LPF (общий сигнальный путь), поэтому используем RX-частоту.
|
||||
if not Transmitting and not IsOrion2 then
|
||||
txf := RXFreqHz // RX через Ant1: используем RX частоту для LPF
|
||||
txf := RXFreqHz
|
||||
else
|
||||
txf := TXFreqHz;
|
||||
|
||||
if txf > 35600000 then Result := Result or $20000000 // 6m bypass LPF
|
||||
else if txf > 24000000 then Result := Result or $40000000 // 12/10m LPF
|
||||
else if txf > 16500000 then Result := Result or $80000000 // 17/15m LPF
|
||||
else if txf > 8000000 then Result := Result or $00100000 // 30/20m LPF
|
||||
else if txf > 5000000 then Result := Result or $00200000 // 60/40m LPF
|
||||
else if txf > 2500000 then Result := Result or $00400000 // 80m LPF
|
||||
else Result := Result or $00800000; // 160m LPF
|
||||
if txf > 35600000 then Result := Result or $20000000 // bit 29: 6m bypass LPF
|
||||
else if txf > 24000000 then Result := Result or $40000000 // bit 30: 12/10m LPF
|
||||
else if txf > 16500000 then Result := Result or $80000000 // bit 31: 17/15m LPF
|
||||
else if txf > 8000000 then Result := Result or $00100000 // bit 20: 30/20m LPF
|
||||
else if txf > 5000000 then Result := Result or $00200000 // bit 21: 60/40m LPF
|
||||
else if txf > 2500000 then Result := Result or $00400000 // bit 22: 80m LPF
|
||||
else Result := Result or $00800000; // bit 23: 160m LPF
|
||||
|
||||
// TX antenna — ANT1 по умолчанию
|
||||
if not Transmitting then
|
||||
Result := Result or $01000000; // ALEX_TX_ANTENNA_1
|
||||
// Биты 24-26: ANT 1/2/3. Выбор зависит от диапазона и режима TX/RX.
|
||||
// Дефолт ANT1 — безопасен при любом состоянии.
|
||||
BandIdx := FreqToBandIndex(RXFreqHz);
|
||||
if Transmitting then
|
||||
AntVal := Alex.TxAnt[BandIdx]
|
||||
else
|
||||
AntVal := Alex.RxAnt[BandIdx];
|
||||
if AntVal < 1 then AntVal := 1;
|
||||
case AntVal of
|
||||
2: Result := Result or $02000000; // bit 25: ANT 2
|
||||
3: Result := Result or $04000000; // bit 26: ANT 3
|
||||
else Result := Result or $01000000; // bit 24: ANT 1 (дефолт)
|
||||
end;
|
||||
|
||||
// Биты 8-11: вторичный RX вход (Bypass relay, Ext1, Ext2, XvtrDDC).
|
||||
// В режиме TX управляется глобальными флагами; в RX — per-band конфигом.
|
||||
if Transmitting then
|
||||
begin
|
||||
if Alex.RxBypassOnTx then
|
||||
Result := Result or $00000800; // bit 11: Bypass relay
|
||||
if Alex.Ext1OnTx then
|
||||
Result := Result or $00000200 // bit 9: Ext1
|
||||
or $00000800; // bit 11: Bypass relay
|
||||
end
|
||||
else
|
||||
begin
|
||||
case Alex.RxOnly[BandIdx] of
|
||||
1: Result := Result or $00000200 // bit 9: Ext1
|
||||
or $00000800; // bit 11: Bypass relay
|
||||
2: Result := Result or $00000400 // bit 10: Ext2
|
||||
or $00000800; // bit 11: Bypass relay
|
||||
3: Result := Result or $00000100 // bit 8: XVTR DDC In
|
||||
or $00000800; // bit 11: Bypass relay
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure THPSDRNetwork.SetAlexConfig(const A: TAlexSettings);
|
||||
begin
|
||||
FAlexConfig := A;
|
||||
if FConnected then SendFullHP;
|
||||
end;
|
||||
|
||||
procedure THPSDRNetwork.ConfigureDDCs(NumDDCs: Byte; SampleRate: Word;
|
||||
@@ -1274,7 +1338,7 @@ begin
|
||||
if FAlexEnabled then
|
||||
begin
|
||||
Alex0 := CalcAlex0(FCurrentRXFreq, FCurrentTXFreq,
|
||||
FIsTransmitting, IsOrion2);
|
||||
FIsTransmitting, IsOrion2, FAlexConfig);
|
||||
Buf[1432] := (Alex0 shr 24) and $FF;
|
||||
Buf[1433] := (Alex0 shr 16) and $FF;
|
||||
Buf[1434] := (Alex0 shr 8) and $FF;
|
||||
|
||||
Reference in New Issue
Block a user