mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 19:45:09 +00:00
feat(cat): CAT-порт на каждый слайс + Auto TX (эталон SmartSDR CAT)
Внешняя программа управляет отдельным слайсом как отдельным трансивером
через свой TCP-порт. COM-порты и 19090 остаются за главным приёмником
(слайс A) и не тронуты.
Протокол не дублируется: TCATEngine — чистый парсер поверх записи
callback'ов TCATContext, TCATTcpServer — транспорт поверх движка, поэтому
слайс-CAT = тот же движок с другим контекстом. Новый TCATSliceEndpoint
(движок + TCP-сервер на слот), массивом владеет TCATAdapter. Привязка к
СЛОТУ (буква B..G), не к Id: порт живёт, даже когда слайса нет (PS0).
Auto TX = «Auto Switch TX Slice» из SmartSDR CAT. Вся логика в одной точке
— TRadioController.RequestSliceTx, исполняется в потоке контроллера:
• пока кто-то уже в эфире (любой источник) — заявка игнорируется,
перехвата передачи нет никогда;
• без Auto TX слайс передаёт, только если уже выбран TX-источником;
• RX; снимает только СВОЮ передачу;
• TX-источник после отпускания остаётся на слайсе (как в SmartSDR).
На флаге слайса бейдж TX → AutoTX.
Частота слайса — TuneSliceInBand: свобода в пределах ВКЛЮЧЁННОГО диапазона
(трансвертер → его FreqBegin/FreqEnd, иначе band-план), другой диапазон —
отказ. Вне захваченной полосы окно DDC переезжает: доп. пан — центром на
цель (rfPanFreq → UI перекладывает флаги/шапку/зум-бар), пан 0 — центр
посередине между целью и главным VFO и только если оба влезают (общее
железное окно, главный приёмник не оглушаем).
Настройки: вкладка Slices (enable/порт 19091../Auto TX на слайс), персист
в секции cat + device-blob.
Попутно:
• ZZFL/ZZFH больше не заглушки — новые callback'и кромок фильтра
(у главного nil → прежний дефолт режима), хелпер SignedPad;
• FilterIdxFor, AGCModeToUI, BoardUtils.BandEdges;
• DSP-состояние слайса (NR/NB/SNB/ANF) зеркалится в TCtrlSlice — флаг
слайса рисовал нули и AGC главного;
• FUIReady в TMainForm.OnControllerState: адаптеры, создаваемые по ходу
FormCreate, больше не могут уронить старт рендером до постройки
виджетов (на этом падал Auto TX из настроек).
Проверено вживую: все порты 19091..19096 слушают, PS;/ZZFA;/MD;/ID;/SM0;/
ZZTX; отвечают; старт со всеми включёнными слайсами чист под gdb.
Документ — doc/CAT_SLICES.md.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -235,6 +235,10 @@ type
|
||||
// --- CAT ---
|
||||
FCATAdapter: TCATAdapter; // адаптер CAT поверх контроллера (движок+транспорты+контекст)
|
||||
FCATLastGlobal: TGlobalSettings; // текущие CAT-настройки (UI/persist; ApplySettings → адаптер)
|
||||
// Виджеты построены (конец FormCreate). До этого рендер состояния запрещён:
|
||||
// адаптеры (CAT/web), создаваемые по ходу FormCreate, могут дёрнуть
|
||||
// Changed() раньше, чем появятся кнопки/панадаптер.
|
||||
FUIReady: Boolean;
|
||||
// Временные поля для передачи параметров в Synchronize-методы
|
||||
FWebSyncFreq: Double;
|
||||
FWebSyncInt: Integer;
|
||||
@@ -574,6 +578,10 @@ type
|
||||
const SerBaud, SerDataBits, SerStopBits, SerParity: array of Integer;
|
||||
const SerAndromeda: array of Boolean;
|
||||
TcpEnabled: Boolean; TcpPort: Integer);
|
||||
procedure OnSliceCATSettingsChange(
|
||||
const Enabled: array of Boolean;
|
||||
const Port: array of Integer;
|
||||
const AutoTX: array of Boolean);
|
||||
procedure OnAlexSettingsChange(const A: TAlexSettings);
|
||||
procedure OnXvtrSettingsChange(const X: TXvtrSettings);
|
||||
procedure PushXvtrToWeb;
|
||||
@@ -1102,6 +1110,8 @@ begin
|
||||
PushBandsToWeb;
|
||||
FillChar(FCATLastGlobal, SizeOf(FCATLastGlobal), 0);
|
||||
FCATLastGlobal.CATTcpPort := 19090;
|
||||
for i := 0 to CFG_CAT_SLICE_COUNT - 1 do
|
||||
FCATLastGlobal.CATSlicePort[i] := CFG_CAT_SLICE_PORT0 + i; // 19091, 19092, …
|
||||
for i := 0 to 3 do
|
||||
begin
|
||||
FCATLastGlobal.CATSerialBaud[i] := 9600;
|
||||
@@ -1266,6 +1276,7 @@ begin
|
||||
{$IFDEF WINDOWS}
|
||||
FirewallEnsureAllowed(ParamStr(0), 'OpenHPSDR Transceiver');
|
||||
{$ENDIF}
|
||||
FUIReady := True; // с этого момента состояние контроллера можно рендерить
|
||||
end;
|
||||
|
||||
procedure TMainForm.FormDestroy(Sender: TObject);
|
||||
@@ -1329,6 +1340,7 @@ var
|
||||
i: Integer;
|
||||
SavedFilter, SavedFilterBW: Integer;
|
||||
begin
|
||||
if not FUIReady then Exit; // виджетов ещё нет — рисовать нечего
|
||||
FSyncingFromController := True;
|
||||
try
|
||||
case Field of
|
||||
@@ -1703,6 +1715,20 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
rfPanFreq:
|
||||
begin
|
||||
// Центр доп. пана переехал не из UI (CAT слайса перестроил его за
|
||||
// пределы захваченной полосы) — переложить флаги/шапку/зум-бар.
|
||||
for i := 0 to MAX_PANS - 1 do
|
||||
if FPans[i] <> nil then
|
||||
begin
|
||||
SyncPanZoomUI(FPans[i]);
|
||||
FPans[i].LayoutFlags;
|
||||
FPans[i].PushAllSliceFlagStates;
|
||||
MarkPanDirty(FPans[i]);
|
||||
end;
|
||||
UpdatePanHeaders;
|
||||
end;
|
||||
rfDeviceList:
|
||||
begin
|
||||
// Discovery обновил список устройств (или завершился без них).
|
||||
@@ -8449,6 +8475,7 @@ begin
|
||||
SF.OnAnt936xChange := OnAnt936xChange;
|
||||
SF.OnVHFCalChange := OnVHFCalSettingsChange;
|
||||
SF.OnCATChange := OnCATSettingsChange;
|
||||
SF.OnSliceCATChange := OnSliceCATSettingsChange;
|
||||
SF.OnThemeChange := SetLightTheme;
|
||||
SF.OnFreqMhzDigitsChange := ApplyFreqMhzDigits;
|
||||
SF.OnTXChange := OnTXSettingsChange;
|
||||
@@ -8486,6 +8513,10 @@ begin
|
||||
FCATLastGlobal.CATSerialAndromeda,
|
||||
FCATLastGlobal.CATTcpEnabled,
|
||||
FCATLastGlobal.CATTcpPort);
|
||||
SF.LoadSliceCATSettings(
|
||||
FCATLastGlobal.CATSliceEnabled,
|
||||
FCATLastGlobal.CATSlicePort,
|
||||
FCATLastGlobal.CATSliceAutoTX);
|
||||
// Перечисляем PA устройства
|
||||
SF.RefreshAudioDevices(FController.FAudioOut, FController.FAudioIn);
|
||||
SF.LoadVisibility(FController.FShowSpectrum, FController.FShowWaterfall, FController.FShowWideband, FController.FWidebandFill,
|
||||
@@ -8588,4 +8619,29 @@ begin
|
||||
FController.FSettings.Save;
|
||||
end;
|
||||
|
||||
procedure TMainForm.OnSliceCATSettingsChange(
|
||||
const Enabled: array of Boolean;
|
||||
const Port: array of Integer;
|
||||
const AutoTX: array of Boolean);
|
||||
// CAT дополнительных слайсов. Хранится там же, где остальные CAT-настройки
|
||||
// (корневая секция + device-blob), применяется тем же ApplySettings: адаптер
|
||||
// поднимет/опустит порты эндпоинтов и положит Auto TX в контроллер.
|
||||
var i: Integer;
|
||||
begin
|
||||
for i := 0 to CFG_CAT_SLICE_COUNT - 1 do
|
||||
begin
|
||||
if i <= High(Enabled) then FCATLastGlobal.CATSliceEnabled[i] := Enabled[i];
|
||||
if i <= High(Port) then FCATLastGlobal.CATSlicePort[i] := Port[i];
|
||||
if i <= High(AutoTX) then FCATLastGlobal.CATSliceAutoTX[i] := AutoTX[i];
|
||||
end;
|
||||
FController.FLoadedGlobal.CATSliceEnabled := FCATLastGlobal.CATSliceEnabled;
|
||||
FController.FLoadedGlobal.CATSlicePort := FCATLastGlobal.CATSlicePort;
|
||||
FController.FLoadedGlobal.CATSliceAutoTX := FCATLastGlobal.CATSliceAutoTX;
|
||||
FCATAdapter.ApplySettings(FCATLastGlobal);
|
||||
FController.FSettings.SaveCATSettings(FCATLastGlobal);
|
||||
FController.SaveGlobalSettings;
|
||||
FController.FSettings.Save;
|
||||
RefreshTxIndicators; // бейджи AutoTX на флагах слайсов — сразу
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
Reference in New Issue
Block a user