mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
feat(oc): OC Control — Open Collector выходы Penny/Alex (эталон Thetis)
Byte 1401 High Priority packet: per-band (HF 160m-6m) и per-slot (XVTR) RX/TX-маски на 7 пинов + TX pin action (MOX/TUNE/2TON и комбинации). Только openHPSDR — у Pluto/AD936x такого выхода нет, вкладка Settings скрывается на этом бэкенде. Настройки — вкладка "OC Control" в SettingsForm. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+98
-5
@@ -169,6 +169,11 @@ type
|
||||
FAlexEnabled: Boolean;
|
||||
FAlexConfig: TAlexSettings; // per-band antenna + routing config
|
||||
FStepAtten: Byte; // ADC0 step attenuator 0-31 dB
|
||||
// ---- OC Control (Open Collector выходы Penny/Alex, byte 1401) ----
|
||||
FOCConfig: TOCSettings;
|
||||
FTuning: Boolean; // TUN активен (для TX pin action)
|
||||
FTwoTone: Boolean; // 2TON активен (для TX pin action)
|
||||
FXvtrSlot: Integer; // активный слот XVTR (0..7) или -1 = HF-группа
|
||||
// ---- PureSignal ----
|
||||
// FPSEnabled — фича вооружена (кнопка PS). FPSTXActive — активная PTT-фаза:
|
||||
// RebuildDDCSpecific включает feedback-DDC0 (ADC0) + sync DDC1 (TX DAC),
|
||||
@@ -261,16 +266,21 @@ type
|
||||
procedure SetRunAndFreq(Run: Boolean; DDC0FreqHz, DUCFreqHz: Double;
|
||||
DriveLevel: Byte = 100); override;
|
||||
procedure UpdateState(RXFreqHz, TXFreqHz: Double; DriveLevel: Byte;
|
||||
Transmitting, PAEnabled, AlexEnabled: Boolean); override;
|
||||
Transmitting, PAEnabled, AlexEnabled: Boolean;
|
||||
Tuning: Boolean = False; TwoTone: Boolean = False); override;
|
||||
procedure SetStepAtten(dB: Byte); override;
|
||||
procedure SetFreqCalPPM(P: Double); override;
|
||||
// Частота с поправкой опорника — для частотного слова DDC/DUC.
|
||||
function CalFreq(Hz: Double): Double;
|
||||
procedure SetAlexConfig(const A: TAlexSettings); override;
|
||||
// OC Control (Open Collector выходы) — конфиг применяется мгновенно.
|
||||
procedure SetOCConfig(const O: TOCSettings); override;
|
||||
// Включение/настройка XVTR-режима. Все параметры применяются мгновенно
|
||||
// (отправляется HP-пакет). Когда AEnable=False, XVTR-bit гасится,
|
||||
// антенна и Alex routing возвращаются к per-band дефолту.
|
||||
procedure SetXvtrMode(AEnable, ADisablePA: Boolean; ARxAnt: Byte); override;
|
||||
// антенна и Alex routing возвращаются к per-band дефолту. ASlot — активный
|
||||
// слот трансвертера (0..7), для per-slot OC-масок; -1 если не применимо.
|
||||
procedure SetXvtrMode(AEnable, ADisablePA: Boolean; ARxAnt: Byte;
|
||||
ASlot: Integer = -1); override;
|
||||
procedure SendFullHP; override;
|
||||
// Отдельная отправка PTT: переключает реле (bit27) и drive ДО, потом PTT.
|
||||
// Не меняет FIsTransmitting — вызывать после UpdateState+SendFullHP.
|
||||
@@ -750,6 +760,10 @@ begin
|
||||
FPAEnabled := True;
|
||||
FAlexEnabled := True;
|
||||
TSettingsManager.DefaultAlex(FAlexConfig);
|
||||
TSettingsManager.DefaultOC(FOCConfig);
|
||||
FTuning := False;
|
||||
FTwoTone := False;
|
||||
FXvtrSlot := -1;
|
||||
FSendLock := TCriticalSection.Create;
|
||||
FHPSendLock := TCriticalSection.Create;
|
||||
FDUCIQLock := TCriticalSection.Create;
|
||||
@@ -1510,7 +1524,8 @@ begin
|
||||
if FConnected then SendFullHP;
|
||||
end;
|
||||
|
||||
procedure THPSDRNetwork.SetXvtrMode(AEnable, ADisablePA: Boolean; ARxAnt: Byte);
|
||||
procedure THPSDRNetwork.SetXvtrMode(AEnable, ADisablePA: Boolean; ARxAnt: Byte;
|
||||
ASlot: Integer);
|
||||
begin
|
||||
FXvtrEnable := AEnable;
|
||||
FXvtrDisablePA := AEnable and ADisablePA;
|
||||
@@ -1518,9 +1533,79 @@ begin
|
||||
FXvtrRxAntOverride := ARxAnt
|
||||
else
|
||||
FXvtrRxAntOverride := 0;
|
||||
if AEnable and (ASlot >= 0) then
|
||||
FXvtrSlot := ASlot
|
||||
else
|
||||
FXvtrSlot := -1;
|
||||
if FConnected then SendFullHP;
|
||||
end;
|
||||
|
||||
procedure THPSDRNetwork.SetOCConfig(const O: TOCSettings);
|
||||
begin
|
||||
FOCConfig := O;
|
||||
if FConnected then SendFullHP;
|
||||
end;
|
||||
|
||||
// Строит 8-битное слово OC (byte 1401 HP-пакета, биты 0..6 = пины 1..7).
|
||||
// Портировано из Thetis (Penny.UpdateExtCtrl/adjustForTXAction), урезано:
|
||||
// без PA-override и split-pins VFO A/B (см. project_oc_control память).
|
||||
// RX: маска банда/слота как есть. TX: маска банда/слота, каждый включённый
|
||||
// пин дополнительно гейтится своим TX pin action (MOX/TUNE/TWOTONE и их
|
||||
// комбинации) — тот же tx-флаг остаётся True на всём протяжении TUN/2TON
|
||||
// (см. TRadioController.SetTune/SetTwoTone), поэтому "чистый MOX" явно
|
||||
// исключает Tuning/TwoTone.
|
||||
function CalcOCBits(RXFreqHz, TXFreqHz: Double;
|
||||
Transmitting, Tuning, TwoTone: Boolean;
|
||||
XvtrSlot: Integer;
|
||||
const OC: TOCSettings): Byte;
|
||||
var
|
||||
RxMask, TxMask: Byte;
|
||||
Actions: TOCPinActions;
|
||||
i: Integer;
|
||||
Fire: Boolean;
|
||||
Band: Integer;
|
||||
begin
|
||||
Result := 0;
|
||||
if not OC.Enabled then Exit;
|
||||
|
||||
if (XvtrSlot >= 0) and (XvtrSlot < CFG_XVTR_COUNT) then
|
||||
begin
|
||||
RxMask := OC.RxMaskXvtr[XvtrSlot];
|
||||
TxMask := OC.TxMaskXvtr[XvtrSlot];
|
||||
Actions := OC.ActionXvtr;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if Transmitting then Band := FreqToBandIndex(TXFreqHz)
|
||||
else Band := FreqToBandIndex(RXFreqHz);
|
||||
RxMask := OC.RxMaskHF[Band];
|
||||
TxMask := OC.TxMaskHF[Band];
|
||||
Actions := OC.ActionHF;
|
||||
end;
|
||||
|
||||
if not Transmitting then
|
||||
begin
|
||||
Result := RxMask;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
for i := 0 to OC_PIN_COUNT - 1 do
|
||||
begin
|
||||
if (TxMask and (1 shl i)) = 0 then Continue;
|
||||
case Actions[i] of
|
||||
OCA_MOX: Fire := (not Tuning) and (not TwoTone);
|
||||
OCA_TUNE: Fire := Tuning;
|
||||
OCA_TWOTONE: Fire := TwoTone;
|
||||
OCA_MOX_TUNE: Fire := not TwoTone;
|
||||
OCA_MOX_TWOTONE: Fire := not Tuning;
|
||||
OCA_TUNE_TWOTONE: Fire := Tuning or TwoTone;
|
||||
OCA_MOX_TUNE_TWOTONE: Fire := True;
|
||||
else Fire := False;
|
||||
end;
|
||||
if Fire then Result := Result or (1 shl i);
|
||||
end;
|
||||
end;
|
||||
|
||||
function THPSDRNetwork.DDCBaseIndex: Integer;
|
||||
begin
|
||||
// Для ANGELIA/ORION/ORION2/SATURN DDC начинается с индекса 2 (DDC0/1 — PureSignal)
|
||||
@@ -1690,7 +1775,8 @@ end;
|
||||
|
||||
procedure THPSDRNetwork.UpdateState(RXFreqHz, TXFreqHz: Double;
|
||||
DriveLevel: Byte;
|
||||
Transmitting, PAEnabled, AlexEnabled: Boolean);
|
||||
Transmitting, PAEnabled, AlexEnabled: Boolean;
|
||||
Tuning: Boolean; TwoTone: Boolean);
|
||||
begin
|
||||
FCurrentRXFreq := RXFreqHz;
|
||||
FCurrentTXFreq := TXFreqHz;
|
||||
@@ -1698,6 +1784,8 @@ begin
|
||||
FIsTransmitting := Transmitting;
|
||||
FPAEnabled := PAEnabled;
|
||||
FAlexEnabled := AlexEnabled;
|
||||
FTuning := Tuning;
|
||||
FTwoTone := TwoTone;
|
||||
end;
|
||||
|
||||
function THPSDRNetwork.CalFreq(Hz: Double): Double;
|
||||
@@ -1847,6 +1935,11 @@ begin
|
||||
if not FSpeakerAudioEnabled then
|
||||
Buf[1400] := Buf[1400] or $02;
|
||||
|
||||
// OC Control — Open Collector outputs (byte 1401)
|
||||
if FOCConfig.Enabled then
|
||||
Buf[1401] := CalcOCBits(FCurrentRXFreq, FCurrentTXFreq, FIsTransmitting,
|
||||
FTuning, FTwoTone, FXvtrSlot, FOCConfig);
|
||||
|
||||
// Step attenuators ADC0/ADC1 (bytes 1443/1442)
|
||||
// 0 dB = 0, max 31 dB
|
||||
Buf[1443] := FStepAtten; // ADC0 attenuation
|
||||
|
||||
Reference in New Issue
Block a user