mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
feat(puresignal): PureSignal-предыскажение для openHPSDR P2 + кнопки PS/2TON
Протокол (по pihpsdr new_protocol.c): на PTT при PS DDC0<-ADC0 (RX-feedback), DDC1<-ADC2 (TX DAC loopback), 192к/24бит, sync DDC1->DDC0 (byte 1363=0x02, interleaved в потоке DDC0), частоты DDC0/1 = TX в HP-пакете, Alex0 bit18 (мост обратной связи). Caps.HasPureSignal для плат с DDCBase=2 (Angelia/Orion/Orion2/Saturn); попутно NumADCs=2 для Angelia. WDSPEngine: PushPSFeedback (деинтерлив -> pscc(TXA, tx=DDC1, rx=DDC0) из сетевого потока), PS-параметры calcc в кэше с переприменением после пересоздания TXA; SetTXTwoTone (PostGen mode 1, 700/1900, 0.49+0.49, инверсия LSB/CWL/DIGL, мьют mic как TUN). RadioController: state machine команд (порт Thetis PSForm timer1) в PureSignalTick @10Гц + auto-attenuate (AttOnTX по уровню feedback, цель ~152, через DUC Specific); SetPSMox и перестройка feedback-DDC на T/R; маршрутизация DDC0 в pscc из OnDDCIQ; SetTwoTone с гейтами safety. UI: кнопки PS (ЛКМ = поповер настроек, ПКМ = быстрый toggle) и 2TON в блоке TX; поповер TPureSignalPopup (дочерний контрол, Wayland-safe): PS ON/OFF, CAL, RESET, 2TON, лампа/уровень feedback, cals, corr, GetPk/SetPk, MOX/CAL wait, PH#, Auto-atten, Relax ptol, Pin/Map/Stbl, Tint, тона двухтональника. Персист ps_* в tx-секции per-device. Не проверено на железе; Save/Restore коррекции не реализованы. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+86
-7
@@ -166,6 +166,13 @@ type
|
||||
FAlexEnabled: Boolean;
|
||||
FAlexConfig: TAlexSettings; // per-band antenna + routing config
|
||||
FStepAtten: Byte; // ADC0 step attenuator 0-31 dB
|
||||
// ---- PureSignal ----
|
||||
// FPSEnabled — фича вооружена (кнопка PS). FPSTXActive — активная PTT-фаза:
|
||||
// RebuildDDCSpecific включает feedback-DDC0 (ADC0) + sync DDC1 (TX DAC),
|
||||
// SendFullHP ставит частоты DDC0/1 = TX и Alex bit18. Пишутся из потока
|
||||
// контроллера (дисциплина как у FCurrentRXFreq).
|
||||
FPSEnabled: Boolean;
|
||||
FPSTXActive: Boolean;
|
||||
// ---- XVTR (Transverter) state ----
|
||||
// FXvtrEnable — True когда активен XVTR-диапазон. Используется как
|
||||
// XvtrActive в CalcAlex0 и для управления byte 1400 bit 0.
|
||||
@@ -243,6 +250,9 @@ type
|
||||
procedure SetPanDDC(DDCIdx: Integer; Enabled: Boolean; FreqHz: Double;
|
||||
RateKHz: Word; ADCSource: Byte); override;
|
||||
procedure SetPanDDCFreq(DDCIdx: Integer; FreqHz: Double); override;
|
||||
// PureSignal: вооружение фичи и PTT-фаза (см. TRadioBackend).
|
||||
procedure SetPureSignal(Enabled: Boolean); override;
|
||||
procedure SetPureSignalTX(Active: Boolean); override;
|
||||
procedure SendDUCSpecific(const Pkt: TDUCSpecificPacket); override;
|
||||
procedure SendHighPriority(const Pkt: THighPriorityPacket); override;
|
||||
procedure SetRunAndFreq(Run: Boolean; DDC0FreqHz, DUCFreqHz: Double;
|
||||
@@ -693,12 +703,14 @@ begin
|
||||
// см. doc/SLICES_PLAN.md 3.1). Каждый DDC тюнится независимо.
|
||||
Result.MaxPans := 4;
|
||||
Result.IndependentPanFreq := True;
|
||||
// Два АЦП у ANAN-100D/200D (ORION), 7000/8000 (ORION2) и Saturn/G2 —
|
||||
// Два АЦП у ANAN-100D/200D (ANGELIA/ORION), 7000/8000 (ORION2) и Saturn/G2 —
|
||||
// те же платы, что в RebuildDDCSpecific (Pkt.NumADCs).
|
||||
if FDevice.BoardType in [4, 5, 10] then
|
||||
if FDevice.BoardType in [3, 4, 5, 10] then
|
||||
Result.NumADCs := 2
|
||||
else
|
||||
Result.NumADCs := 1;
|
||||
// PureSignal: нужны свободные DDC0/1 под feedback — платы с DDCBase=2.
|
||||
Result.HasPureSignal := FDevice.BoardType in [3, 4, 5, 10];
|
||||
end;
|
||||
|
||||
constructor THPSDRNetwork.Create;
|
||||
@@ -1328,7 +1340,8 @@ function CalcAlex0(RXFreqHz, TXFreqHz: Double;
|
||||
XvtrRxAnt: Byte = 0;
|
||||
XvtrDisablePA: Boolean = False;
|
||||
XvtrActive: Boolean = False;
|
||||
WidebandBypass: Boolean = False): LongWord;
|
||||
WidebandBypass: Boolean = False;
|
||||
PureSignalTX: Boolean = False): LongWord;
|
||||
var
|
||||
txf: Double;
|
||||
BandIdx: Integer;
|
||||
@@ -1339,10 +1352,15 @@ begin
|
||||
// Bit 27 = T/R relay (0=RX, 1=TX).
|
||||
// Если XvtrDisablePA=True — НЕ устанавливаем bit 27 (PA остаётся в RX
|
||||
// положении, TX-сигнал идёт через XVTR-IF без усиления).
|
||||
// Bit 18 (PureSignal) не ставим — PureSignal не реализован.
|
||||
if Transmitting then
|
||||
if not XvtrDisablePA then
|
||||
begin
|
||||
Result := Result or $08000000; // bit 27: T/R relay
|
||||
// Bit 18 = PureSignal (ALEX_PS_BIT в pihpsdr): на TX подключает
|
||||
// внутренний мост обратной связи PA к RX-тракту ADC0.
|
||||
if PureSignalTX then
|
||||
Result := Result or $00040000;
|
||||
end;
|
||||
|
||||
// HPF (ANAN-100/200) или BPF (ANAN-7000/8000/Saturn/G2) — по RX-частоте.
|
||||
if WidebandBypass and (not Transmitting) then
|
||||
@@ -1545,8 +1563,8 @@ var
|
||||
begin
|
||||
FillChar(Pkt, SizeOf(Pkt), 0);
|
||||
|
||||
// ANAN-7000/8000/Saturn имеют 2 ADC
|
||||
if FDevice.BoardType in [4, 5, 10] then // ORION=4, ORION2=5, SATURN=10
|
||||
// ANAN-100D/200D (ANGELIA/ORION), 7000/8000 (ORION2) и Saturn имеют 2 ADC
|
||||
if FDevice.BoardType in [3, 4, 5, 10] then // ANGELIA=3, ORION=4, ORION2=5, SATURN=10
|
||||
Pkt.NumADCs := 2
|
||||
else
|
||||
Pkt.NumADCs := 1;
|
||||
@@ -1568,6 +1586,21 @@ begin
|
||||
if FPanDDCEnabled[ddc] then
|
||||
AddDDC(ddc, FPanDDCRateKHz[ddc], FPanDDCADC[ddc]);
|
||||
|
||||
// PureSignal feedback (как pihpsdr new_protocol_receive_specific): на время
|
||||
// PTT DDC0 ← ADC0 (RX-feedback с моста PA), DDC1 ← «ADC 2» = TX DAC loopback,
|
||||
// оба 192 кС/с 24 бита, DDC1 синхронизирован с DDC0 (byte 1363 bit1) —
|
||||
// его сэмплы приходят interleaved внутри потока DDC0 (порт 1035).
|
||||
// Enable-бит ставится только DDC0. Только платы с DDCBase=2 (DDC0/1 свободны).
|
||||
if FPSTXActive and (DDCBase = 2) then
|
||||
begin
|
||||
AddDDC(0, 192, 0); // DDC0: enable, ADC0, 192 kSPS, 24 bit
|
||||
Pkt.DDCConfig[1 * 6] := 2; // DDC1: источник = TX DAC (Angelia/Orion)
|
||||
Pkt.DDCConfig[1 * 6 + 1] := 0;
|
||||
Pkt.DDCConfig[1 * 6 + 2] := 192;
|
||||
Pkt.DDCConfig[1 * 6 + 5] := 24;
|
||||
Pkt.SyncDDC[0] := $02; // sync DDC1 → DDC0
|
||||
end;
|
||||
|
||||
SendDDCSpecific(Pkt);
|
||||
FCachedDDCSpec := Pkt;
|
||||
FCachedDDCValid := True;
|
||||
@@ -1596,6 +1629,37 @@ begin
|
||||
if FConnected and FPanDDCEnabled[DDCIdx] then SendFullHP;
|
||||
end;
|
||||
|
||||
procedure THPSDRNetwork.SetPureSignal(Enabled: Boolean);
|
||||
begin
|
||||
// Только платы, где DDC0/1 зарезервированы под feedback (Angelia/Orion/
|
||||
// Orion2/Saturn). На прочих (Hermes: DDC0 = главный) PS не включаем.
|
||||
if Enabled and (DDCBaseIndex <> 2) then Exit;
|
||||
if FPSEnabled = Enabled then Exit;
|
||||
FPSEnabled := Enabled;
|
||||
if not Enabled and FPSTXActive then
|
||||
begin
|
||||
// Выключение посреди передачи: убрать feedback-DDC немедленно.
|
||||
FPSTXActive := False;
|
||||
if FConnected and FRunning then
|
||||
begin
|
||||
RebuildDDCSpecific;
|
||||
SendFullHP;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure THPSDRNetwork.SetPureSignalTX(Active: Boolean);
|
||||
begin
|
||||
Active := Active and FPSEnabled and (DDCBaseIndex = 2);
|
||||
if FPSTXActive = Active then Exit;
|
||||
FPSTXActive := Active;
|
||||
if FConnected and FRunning then
|
||||
begin
|
||||
RebuildDDCSpecific; // включить/убрать DDC0 + sync DDC1
|
||||
SendFullHP; // частоты DDC0/1 = TX, Alex bit18
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure THPSDRNetwork.SendDUCSpecific(const Pkt: TDUCSpecificPacket);
|
||||
var
|
||||
B: TDUCSpecificPacket;
|
||||
@@ -1691,6 +1755,21 @@ begin
|
||||
Buf[12 + ddc*4] := Ph and $FF;
|
||||
end;
|
||||
|
||||
// PureSignal: feedback-DDC0/DDC1 следят за TX-частотой (pihpsdr, bytes 9..16).
|
||||
// DDCBase=2 ⇒ с частотным словом главного DDC (bytes 17..20) не пересекаемся.
|
||||
if FPSTXActive then
|
||||
begin
|
||||
Ph := FreqToPhaseWord(FCurrentTXFreq);
|
||||
Buf[9] := (Ph shr 24) and $FF;
|
||||
Buf[10] := (Ph shr 16) and $FF;
|
||||
Buf[11] := (Ph shr 8) and $FF;
|
||||
Buf[12] := Ph and $FF;
|
||||
Buf[13] := (Ph shr 24) and $FF;
|
||||
Buf[14] := (Ph shr 16) and $FF;
|
||||
Buf[15] := (Ph shr 8) and $FF;
|
||||
Buf[16] := Ph and $FF;
|
||||
end;
|
||||
|
||||
// DUC TX frequency (bytes 329-332)
|
||||
Ph := FreqToPhaseWord(FCurrentTXFreq);
|
||||
Buf[329] := (Ph shr 24) and $FF;
|
||||
@@ -1708,7 +1787,7 @@ begin
|
||||
Alex0 := CalcAlex0(FCurrentRXFreq, FCurrentTXFreq,
|
||||
FIsTransmitting, IsOrion2, FAlexConfig,
|
||||
FXvtrRxAntOverride, FXvtrDisablePA,
|
||||
FXvtrEnable, FWidebandEnabled);
|
||||
FXvtrEnable, FWidebandEnabled, FPSTXActive);
|
||||
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