mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-26 20:57:32 +00:00
Add full CAT support (serial + TCP)
New units: CATEngine (Kenwood + Thetis ZZ* commands), CATSerial (up to 4 serial ports), CATTcp (multi-client TCP server on port 4992). MainForm wired with TCATContext callbacks reusing existing WebOn* handlers. SettingsForm gets a new CAT tab with 4 serial port groups and TCP section. Settings.pas extended with CAT config fields (per-device, JSON-persisted). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+308
-1
@@ -29,7 +29,8 @@ uses
|
||||
WDSP, WDSPEngine, AudioOutput, AudioInput,
|
||||
IntfGraphics, FPImage,
|
||||
Settings,
|
||||
WebServer;
|
||||
WebServer,
|
||||
CATEngine, CATSerial, CATTcp;
|
||||
|
||||
const
|
||||
CLR_BG = TColor($00101010);
|
||||
@@ -286,6 +287,12 @@ type
|
||||
// --- Settings ---
|
||||
FSettings: TSettingsManager;
|
||||
FWebServer: TWebServer; // веб-интерфейс (порт 8080)
|
||||
// --- CAT ---
|
||||
FCATEngine: TCATEngine;
|
||||
FCATSerial: TCATSerialManager;
|
||||
FCATTcp: TCATTcpServer;
|
||||
FCATSyncFreq: Double;
|
||||
FCATLastGlobal: TGlobalSettings; // текущие CAT-настройки (для сохранения)
|
||||
// Временные поля для передачи параметров в Synchronize-методы
|
||||
FWebSyncFreq: Double;
|
||||
FWebSyncInt: Integer;
|
||||
@@ -532,6 +539,45 @@ type
|
||||
procedure SyncWebCenter;
|
||||
procedure SyncWebMOX;
|
||||
procedure SyncWebDrive;
|
||||
// --- CAT callbacks -------------------------------------------------------
|
||||
function CATGetVfoA: Double;
|
||||
function CATGetVfoB: Double;
|
||||
function CATGetMode: Integer;
|
||||
function CATGetActiveVfo: Integer;
|
||||
function CATGetAGCMode: Integer;
|
||||
function CATGetVolume: Integer;
|
||||
function CATGetDriveLevel: Integer;
|
||||
function CATGetFilterIdx: Integer;
|
||||
function CATGetFilterBW: Integer;
|
||||
function CATGetNRMode: Integer;
|
||||
function CATGetNBMode: Integer;
|
||||
function CATGetSNB: Boolean;
|
||||
function CATGetANF: Boolean;
|
||||
function CATGetTX: Boolean;
|
||||
function CATGetRunning: Boolean;
|
||||
function CATGetSMeter: Double;
|
||||
function CATGetBand: Integer;
|
||||
procedure CATSetVfoA(V: Double);
|
||||
procedure CATSetVfoB(V: Double);
|
||||
procedure CATSetFilterIdx(V: Integer);
|
||||
procedure CATDoBandUp;
|
||||
procedure CATDoBandDown;
|
||||
procedure CATDoTuneUp;
|
||||
procedure CATDoTuneDown;
|
||||
procedure SyncCATVfoA;
|
||||
procedure SyncCATVfoB;
|
||||
procedure SyncCATBandUp;
|
||||
procedure SyncCATBandDown;
|
||||
procedure SyncCATTuneUp;
|
||||
procedure SyncCATTuneDown;
|
||||
procedure InitCATEngine;
|
||||
procedure CATApplySettings(const G: TGlobalSettings);
|
||||
procedure OnCATSettingsChange(
|
||||
const SerEnabled: array of Boolean;
|
||||
const SerPort: array of string;
|
||||
const SerBaud, SerDataBits, SerStopBits, SerParity: array of Integer;
|
||||
TcpEnabled: Boolean; TcpPort: Integer);
|
||||
// -------------------------------------------------------------------------
|
||||
procedure BtnWfAGCClick(Sender: TObject);
|
||||
procedure BtnWfNFClick(Sender: TObject);
|
||||
procedure BtnHidePanelClick(Sender: TObject);
|
||||
@@ -974,6 +1020,15 @@ begin
|
||||
// Audio device names
|
||||
Result.AudioOutDevice := FAudioOutDevName;
|
||||
Result.AudioInDevice := FAudioInDevName;
|
||||
// CAT settings — carried from the last loaded/saved device config
|
||||
Result.CATSerialEnabled := FCATLastGlobal.CATSerialEnabled;
|
||||
Result.CATSerialPort := FCATLastGlobal.CATSerialPort;
|
||||
Result.CATSerialBaud := FCATLastGlobal.CATSerialBaud;
|
||||
Result.CATSerialDataBits := FCATLastGlobal.CATSerialDataBits;
|
||||
Result.CATSerialStopBits := FCATLastGlobal.CATSerialStopBits;
|
||||
Result.CATSerialParity := FCATLastGlobal.CATSerialParity;
|
||||
Result.CATTcpEnabled := FCATLastGlobal.CATTcpEnabled;
|
||||
Result.CATTcpPort := FCATLastGlobal.CATTcpPort;
|
||||
end;
|
||||
|
||||
procedure TMainForm.SaveCurrentBand;
|
||||
@@ -1159,6 +1214,8 @@ begin
|
||||
FWebServer.OnMOX := WebOnMOX;
|
||||
FWebServer.OnDrive := WebOnDrive;
|
||||
FWebServer.Start;
|
||||
FillChar(FCATLastGlobal, SizeOf(FCATLastGlobal), 0);
|
||||
InitCATEngine;
|
||||
FSMeterPeak := -130;
|
||||
FSMeterMin := -130;
|
||||
FSMeterAvg := -130;
|
||||
@@ -1298,6 +1355,9 @@ begin
|
||||
FSettings.Free;
|
||||
FWebServer.Stop;
|
||||
FWebServer.Free;
|
||||
if Assigned(FCATTcp) then begin FCATTcp.Stop; FreeAndNil(FCATTcp); end;
|
||||
if Assigned(FCATSerial) then begin FCATSerial.StopAll; FreeAndNil(FCATSerial); end;
|
||||
FreeAndNil(FCATEngine);
|
||||
end;
|
||||
|
||||
procedure TMainForm.FormClose(Sender: TObject; var CloseAction: TCloseAction);
|
||||
@@ -3909,6 +3969,8 @@ begin
|
||||
Move(FNetwork.Device.MAC[0], FDevMAC[0], 6);
|
||||
FDevConnected := True;
|
||||
FSettings.LoadDevice(FDevMAC, G_Settings, FBandCache);
|
||||
FCATLastGlobal := G_Settings;
|
||||
CATApplySettings(G_Settings);
|
||||
FVolume := G_Settings.Volume;
|
||||
FActiveVfo := G_Settings.ActiveVfo;
|
||||
// PA settings
|
||||
@@ -5790,9 +5852,19 @@ begin
|
||||
SF.OnVisibilityChange := ApplyVisibility;
|
||||
SF.OnFPSChange := ApplyFPS;
|
||||
SF.OnPAChange := OnPASettingsChange;
|
||||
SF.OnCATChange := OnCATSettingsChange;
|
||||
end;
|
||||
SF := TSettingsForm(FSettingsForm);
|
||||
SF.LoadPASettings(FPAMaxPower, FPABandCal);
|
||||
SF.LoadCATSettings(
|
||||
FCATLastGlobal.CATSerialEnabled,
|
||||
FCATLastGlobal.CATSerialPort,
|
||||
FCATLastGlobal.CATSerialBaud,
|
||||
FCATLastGlobal.CATSerialDataBits,
|
||||
FCATLastGlobal.CATSerialStopBits,
|
||||
FCATLastGlobal.CATSerialParity,
|
||||
FCATLastGlobal.CATTcpEnabled,
|
||||
FCATLastGlobal.CATTcpPort);
|
||||
// Перечисляем PA устройства
|
||||
SF.RefreshAudioDevices(FAudioOut, FAudioIn);
|
||||
SF.LoadVisibility(FShowSpectrum, FShowWaterfall);
|
||||
@@ -5841,5 +5913,240 @@ begin
|
||||
EnsureWDSPWisdom;
|
||||
end;
|
||||
|
||||
// ===========================================================================
|
||||
// CAT subsystem
|
||||
// ===========================================================================
|
||||
|
||||
procedure TMainForm.InitCATEngine;
|
||||
var
|
||||
Ctx: TCATContext;
|
||||
begin
|
||||
FillChar(Ctx, SizeOf(Ctx), 0);
|
||||
Ctx.GetVfoA := CATGetVfoA;
|
||||
Ctx.GetVfoB := CATGetVfoB;
|
||||
Ctx.GetMode := CATGetMode;
|
||||
Ctx.GetActiveVfo := CATGetActiveVfo;
|
||||
Ctx.GetAGCMode := CATGetAGCMode;
|
||||
Ctx.GetVolume := CATGetVolume;
|
||||
Ctx.GetDriveLevel := CATGetDriveLevel;
|
||||
Ctx.GetFilterIdx := CATGetFilterIdx;
|
||||
Ctx.GetFilterBW := CATGetFilterBW;
|
||||
Ctx.GetNRMode := CATGetNRMode;
|
||||
Ctx.GetNBMode := CATGetNBMode;
|
||||
Ctx.GetSNBEnabled := CATGetSNB;
|
||||
Ctx.GetANFEnabled := CATGetANF;
|
||||
Ctx.GetTransmitting := CATGetTX;
|
||||
Ctx.GetRunning := CATGetRunning;
|
||||
Ctx.GetSMeter := CATGetSMeter;
|
||||
Ctx.GetCurrentBand := CATGetBand;
|
||||
Ctx.SetVfoA := CATSetVfoA;
|
||||
Ctx.SetVfoB := CATSetVfoB;
|
||||
Ctx.SetMode := WebOnMode;
|
||||
Ctx.SetActiveVfo := WebOnActiveVfo;
|
||||
Ctx.SetAGCMode := WebOnAGC;
|
||||
Ctx.SetVolume := WebOnVolume;
|
||||
Ctx.SetDriveLevel := WebOnDrive;
|
||||
Ctx.SetFilterIdx := CATSetFilterIdx;
|
||||
Ctx.SetNRMode := WebOnNR;
|
||||
Ctx.SetNBMode := WebOnNB;
|
||||
Ctx.SetSNBEnabled := WebOnSNB;
|
||||
Ctx.SetANFEnabled := WebOnANF;
|
||||
Ctx.SetTransmitting := WebOnMOX;
|
||||
Ctx.DoBandUp := CATDoBandUp;
|
||||
Ctx.DoBandDown := CATDoBandDown;
|
||||
Ctx.DoTuneUp := CATDoTuneUp;
|
||||
Ctx.DoTuneDown := CATDoTuneDown;
|
||||
Ctx.DoBandByIndex := WebOnBand;
|
||||
FCATEngine := TCATEngine.Create(Ctx);
|
||||
FCATSerial := TCATSerialManager.Create(FCATEngine);
|
||||
FCATTcp := TCATTcpServer.Create(FCATEngine);
|
||||
end;
|
||||
|
||||
procedure TMainForm.CATApplySettings(const G: TGlobalSettings);
|
||||
var
|
||||
Cfgs: array[0..3] of TCATSerialConfig;
|
||||
i: Integer;
|
||||
begin
|
||||
for i := 0 to 3 do
|
||||
begin
|
||||
Cfgs[i].Enabled := G.CATSerialEnabled[i];
|
||||
Cfgs[i].PortName := G.CATSerialPort[i];
|
||||
Cfgs[i].BaudRate := G.CATSerialBaud[i];
|
||||
Cfgs[i].DataBits := G.CATSerialDataBits[i];
|
||||
Cfgs[i].StopBits := G.CATSerialStopBits[i];
|
||||
case G.CATSerialParity[i] of
|
||||
1: Cfgs[i].Parity := cspOdd;
|
||||
2: Cfgs[i].Parity := cspEven;
|
||||
else Cfgs[i].Parity := cspNone;
|
||||
end;
|
||||
end;
|
||||
FCATSerial.ApplyConfig(Cfgs);
|
||||
FCATTcp.Stop;
|
||||
if G.CATTcpEnabled then
|
||||
begin
|
||||
FCATTcp.Port := G.CATTcpPort;
|
||||
FCATTcp.Start;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMainForm.OnCATSettingsChange(
|
||||
const SerEnabled: array of Boolean;
|
||||
const SerPort: array of string;
|
||||
const SerBaud, SerDataBits, SerStopBits, SerParity: array of Integer;
|
||||
TcpEnabled: Boolean; TcpPort: Integer);
|
||||
var i: Integer;
|
||||
begin
|
||||
for i := 0 to 3 do
|
||||
begin
|
||||
if i <= High(SerEnabled) then FCATLastGlobal.CATSerialEnabled[i] := SerEnabled[i];
|
||||
if i <= High(SerPort) then FCATLastGlobal.CATSerialPort[i] := SerPort[i];
|
||||
if i <= High(SerBaud) then FCATLastGlobal.CATSerialBaud[i] := SerBaud[i];
|
||||
if i <= High(SerDataBits) then FCATLastGlobal.CATSerialDataBits[i] := SerDataBits[i];
|
||||
if i <= High(SerStopBits) then FCATLastGlobal.CATSerialStopBits[i] := SerStopBits[i];
|
||||
if i <= High(SerParity) then FCATLastGlobal.CATSerialParity[i] := SerParity[i];
|
||||
end;
|
||||
FCATLastGlobal.CATTcpEnabled := TcpEnabled;
|
||||
FCATLastGlobal.CATTcpPort := TcpPort;
|
||||
CATApplySettings(FCATLastGlobal);
|
||||
if FDevConnected then begin
|
||||
FSettings.SaveGlobal(FDevMAC, MakeGlobalSettings);
|
||||
FSettings.Save;
|
||||
end;
|
||||
end;
|
||||
|
||||
// --- Getters (called from CAT thread — read only, no sync needed) -----------
|
||||
|
||||
function TMainForm.CATGetVfoA: Double; begin Result := FVfoA; end;
|
||||
function TMainForm.CATGetVfoB: Double; begin Result := FVfoB; end;
|
||||
function TMainForm.CATGetMode: Integer; begin Result := FMode; end;
|
||||
function TMainForm.CATGetActiveVfo: Integer; begin Result := FActiveVfo; end;
|
||||
function TMainForm.CATGetAGCMode: Integer; begin Result := FAGCMode; end;
|
||||
function TMainForm.CATGetVolume: Integer; begin Result := FVolume; end;
|
||||
function TMainForm.CATGetDriveLevel: Integer;begin Result := TrkDrive.Position; end;
|
||||
function TMainForm.CATGetFilterIdx: Integer; begin Result := FFilter; end;
|
||||
function TMainForm.CATGetFilterBW: Integer; begin Result := FFilterBW; end;
|
||||
function TMainForm.CATGetNRMode: Integer; begin Result := BtnNR.Tag; end;
|
||||
function TMainForm.CATGetNBMode: Integer; begin Result := BtnNB.Tag; end;
|
||||
function TMainForm.CATGetSNB: Boolean; begin Result := BtnSNB.Tag <> 0; end;
|
||||
function TMainForm.CATGetANF: Boolean; begin Result := BtnANF.Tag <> 0; end;
|
||||
function TMainForm.CATGetTX: Boolean; begin Result := FTransmitting; end;
|
||||
function TMainForm.CATGetRunning: Boolean; begin Result := FRunning; end;
|
||||
function TMainForm.CATGetSMeter: Double; begin Result := FLastSMeter; end;
|
||||
function TMainForm.CATGetBand: Integer; begin Result := FCurrentBand; end;
|
||||
|
||||
// --- Setters ----------------------------------------------------------------
|
||||
|
||||
procedure TMainForm.CATSetVfoA(V: Double);
|
||||
begin
|
||||
FCATSyncFreq := V;
|
||||
TThread.Synchronize(nil, SyncCATVfoA);
|
||||
end;
|
||||
|
||||
procedure TMainForm.CATSetVfoB(V: Double);
|
||||
begin
|
||||
FCATSyncFreq := V;
|
||||
TThread.Synchronize(nil, SyncCATVfoB);
|
||||
end;
|
||||
|
||||
procedure TMainForm.CATSetFilterIdx(V: Integer);
|
||||
begin
|
||||
// WebOnFilter: negative value encodes 0-based index as -(idx+1)
|
||||
WebOnFilter(-(V + 1));
|
||||
end;
|
||||
|
||||
procedure TMainForm.CATDoBandUp;
|
||||
begin TThread.Synchronize(nil, SyncCATBandUp); end;
|
||||
|
||||
procedure TMainForm.CATDoBandDown;
|
||||
begin TThread.Synchronize(nil, SyncCATBandDown); end;
|
||||
|
||||
procedure TMainForm.CATDoTuneUp;
|
||||
begin TThread.Synchronize(nil, SyncCATTuneUp); end;
|
||||
|
||||
procedure TMainForm.CATDoTuneDown;
|
||||
begin TThread.Synchronize(nil, SyncCATTuneDown); end;
|
||||
|
||||
// --- Sync methods (run in main thread) --------------------------------------
|
||||
|
||||
procedure TMainForm.SyncCATVfoA;
|
||||
var BandIdx: Integer;
|
||||
begin
|
||||
FVfoA := FCATSyncFreq;
|
||||
if FActiveVfo = 0 then
|
||||
begin
|
||||
ApplyVfoA(Round(FVfoA));
|
||||
end
|
||||
else
|
||||
begin
|
||||
// VFO A is not active — just update display and band indicator
|
||||
FreqDispA.Frequency := Round(FVfoA);
|
||||
BandIdx := FreqToBandIdx(FVfoA);
|
||||
if (BandIdx >= 0) and (BandIdx <> FCurrentBand) then
|
||||
begin
|
||||
StyleButton(BtnBand[FCurrentBand], False);
|
||||
FCurrentBand := BandIdx;
|
||||
StyleButton(BtnBand[FCurrentBand], True);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMainForm.SyncCATVfoB;
|
||||
var BandIdx: Integer;
|
||||
begin
|
||||
FVfoB := FCATSyncFreq;
|
||||
FreqDispB.Frequency := Round(FVfoB);
|
||||
if FActiveVfo = 1 then
|
||||
begin
|
||||
FCenterFreq := FVfoB;
|
||||
if FWDSPReady then FDSPEngine.SetShift(0.0);
|
||||
if FRunning then
|
||||
FNetwork.SetRunAndFreq(True, FCenterFreq, FCenterFreq, FDriveLevel);
|
||||
BandIdx := FreqToBandIdx(FVfoB);
|
||||
if (BandIdx >= 0) and (BandIdx <> FCurrentBand) then
|
||||
begin
|
||||
StyleButton(BtnBand[FCurrentBand], False);
|
||||
FCurrentBand := BandIdx;
|
||||
StyleButton(BtnBand[FCurrentBand], True);
|
||||
end;
|
||||
FRulerLastFreq := -1.0; FRulerLastVfo := -1.0;
|
||||
DrawSpectrum; PbSpectrum.Invalidate;
|
||||
if PbRuler <> nil then PbRuler.Invalidate;
|
||||
UpdateVfoDisplay;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMainForm.SyncCATBandUp;
|
||||
begin
|
||||
if FCurrentBand < BAND_COUNT - 1 then
|
||||
WebOnBand(FCurrentBand + 1);
|
||||
end;
|
||||
|
||||
procedure TMainForm.SyncCATBandDown;
|
||||
begin
|
||||
if FCurrentBand > 0 then
|
||||
WebOnBand(FCurrentBand - 1);
|
||||
end;
|
||||
|
||||
procedure TMainForm.SyncCATTuneUp;
|
||||
begin
|
||||
if FActiveVfo = 0 then
|
||||
ApplyVfoA(Round(FVfoA) + 10)
|
||||
else
|
||||
begin
|
||||
FCATSyncFreq := FVfoB + 10;
|
||||
SyncCATVfoB;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMainForm.SyncCATTuneDown;
|
||||
begin
|
||||
if FActiveVfo = 0 then
|
||||
ApplyVfoA(Round(FVfoA) - 10)
|
||||
else
|
||||
begin
|
||||
FCATSyncFreq := FVfoB - 10;
|
||||
SyncCATVfoB;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
Reference in New Issue
Block a user