mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
feat: Pluto/AD936x SDR backend (discovery, RX, VHF band plan)
Add ADALM-Pluto / AD9361 support as a second hardware backend alongside openHPSDR, sharing the WDSP DSP pipeline and the existing controller API (UI stays decoupled from logic). - RadioBackend.pas: abstract TRadioBackend + TBackendCaps + TRadioDevice (Kind/URI/Serial). THPSDRNetwork now derives from it (state via virtual getters); TRadioController.FNetwork is the base type. - IIOBindings.pas: dynamic libiio loader (runs without libiio present). - PlutoBackend.pas: scan/probe-by-URI, connect, LO/rate/bandwidth/gain control, RX streaming thread (int16->24bit BE -> OnDDCIQ), Q conjugated to match WDSP IQ convention. Verified on LibreSDR (AD9361) over network. - Unified discovery: TDiscoverThread scans both backends; network Plutos found via direct ProbeURI (no mDNS needed). ConnectDevice dispatches by Dev.Kind (EnsureBackend swaps backend, preserving callbacks). - DeviceStore/DeviceForm: persist Kind/URI/Serial; save Pluto via AddSavedPluto so saved/autostart devices reconnect across restarts. - VHF/UHF band plan (BoardUtils, kind-aware): 6m..ADS-B for Pluto; fixes HF clamps (band detect, mouse-wheel 60 MHz cap, freq-display max). - SampleRateOverlay: configurable presets (Pluto 576k..5760k, >520 ksps), auto-width to fit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+41
-3
@@ -11,7 +11,7 @@ unit DeviceStore;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, IniFiles, BoardUtils, PlatformUtils;
|
||||
Classes, SysUtils, IniFiles, BoardUtils, PlatformUtils, RadioBackend;
|
||||
|
||||
const
|
||||
DEVICE_CFG_NAME = 'hpsdr_devices.ini';
|
||||
@@ -23,6 +23,9 @@ type
|
||||
IPAddress: string;
|
||||
BoardType: Integer;
|
||||
AutoStart: Boolean; // запускать автоматически при старте
|
||||
Kind: TBackendKind; // bkHPSDR / bkPluto
|
||||
URI: string; // Pluto: 'ip:..' / 'usb:..'
|
||||
Serial: string; // Pluto serial
|
||||
end;
|
||||
|
||||
// Найденное устройство (результат discovery)
|
||||
@@ -31,6 +34,9 @@ type
|
||||
DisplayName: string;
|
||||
BoardType: Integer;
|
||||
MAC: array[0..5] of Byte; // нужен для preload-rate lookup (LoadDevice по MAC)
|
||||
Kind: TBackendKind; // bkHPSDR / bkPluto
|
||||
URI: string; // Pluto: context URI
|
||||
Serial: string; // Pluto serial
|
||||
end;
|
||||
|
||||
{ TDeviceStore }
|
||||
@@ -50,6 +56,8 @@ type
|
||||
function Saved(Idx: Integer): TSavedDevice;
|
||||
// Добавляет запись (Name пустое → 'HPSDR'); возвращает индекс новой записи.
|
||||
function AddSaved(const AName, IP: string; BoardType: Integer): Integer;
|
||||
// Добавляет Pluto-устройство (Kind=bkPluto) с URI/Serial.
|
||||
function AddSavedPluto(const AName, AURI, ASerial: string): Integer;
|
||||
procedure RemoveSaved(Idx: Integer);
|
||||
procedure SetAutoStart(Idx: Integer); // эксклюзивно: только одно autostart
|
||||
function AutoStartIP: string;
|
||||
@@ -60,7 +68,9 @@ type
|
||||
// ---- Найденные (discovery) ----
|
||||
procedure ClearDiscovered;
|
||||
procedure AddDiscovered(const IP, DisplayName: string; BoardType: Integer;
|
||||
const MAC: array of Byte);
|
||||
const MAC: array of Byte;
|
||||
Kind: TBackendKind = bkHPSDR;
|
||||
const URI: string = ''; const Serial: string = '');
|
||||
function DiscoveredCount: Integer;
|
||||
function Discovered(Idx: Integer): TDiscoveredDevice;
|
||||
// IP найденного устройства по IP (для preload-rate lookup и т.п.)
|
||||
@@ -100,6 +110,9 @@ begin
|
||||
FSaved[I].IPAddress := Ini.ReadString (Section, 'IP', '');
|
||||
FSaved[I].BoardType := Ini.ReadInteger(Section, 'BoardType', 0);
|
||||
FSaved[I].AutoStart := Ini.ReadBool (Section, 'AutoStart', False);
|
||||
FSaved[I].Kind := TBackendKind(Ini.ReadInteger(Section, 'Kind', 0));
|
||||
FSaved[I].URI := Ini.ReadString (Section, 'URI', '');
|
||||
FSaved[I].Serial := Ini.ReadString (Section, 'Serial', '');
|
||||
Inc(FSavedCount);
|
||||
end;
|
||||
finally
|
||||
@@ -123,6 +136,9 @@ begin
|
||||
Ini.WriteString (Section, 'IP', FSaved[I].IPAddress);
|
||||
Ini.WriteInteger(Section, 'BoardType', FSaved[I].BoardType);
|
||||
Ini.WriteBool (Section, 'AutoStart', FSaved[I].AutoStart);
|
||||
Ini.WriteInteger(Section, 'Kind', Ord(FSaved[I].Kind));
|
||||
Ini.WriteString (Section, 'URI', FSaved[I].URI);
|
||||
Ini.WriteString (Section, 'Serial', FSaved[I].Serial);
|
||||
end;
|
||||
finally
|
||||
Ini.Free;
|
||||
@@ -155,6 +171,25 @@ begin
|
||||
FSaved[Result].IPAddress := Trim(IP);
|
||||
FSaved[Result].BoardType := BoardType;
|
||||
FSaved[Result].AutoStart := False;
|
||||
FSaved[Result].Kind := bkHPSDR;
|
||||
FSaved[Result].URI := '';
|
||||
FSaved[Result].Serial := '';
|
||||
SaveSaved;
|
||||
end;
|
||||
|
||||
function TDeviceStore.AddSavedPluto(const AName, AURI, ASerial: string): Integer;
|
||||
begin
|
||||
Result := FSavedCount;
|
||||
Inc(FSavedCount);
|
||||
SetLength(FSaved, FSavedCount);
|
||||
if Trim(AName) <> '' then FSaved[Result].Name := Trim(AName)
|
||||
else FSaved[Result].Name := 'PlutoSDR';
|
||||
FSaved[Result].IPAddress := Trim(AURI); // в списке показываем URI
|
||||
FSaved[Result].BoardType := 0;
|
||||
FSaved[Result].AutoStart := False;
|
||||
FSaved[Result].Kind := bkPluto;
|
||||
FSaved[Result].URI := Trim(AURI);
|
||||
FSaved[Result].Serial := Trim(ASerial);
|
||||
SaveSaved;
|
||||
end;
|
||||
|
||||
@@ -233,7 +268,7 @@ begin
|
||||
end;
|
||||
|
||||
procedure TDeviceStore.AddDiscovered(const IP, DisplayName: string; BoardType: Integer;
|
||||
const MAC: array of Byte);
|
||||
const MAC: array of Byte; Kind: TBackendKind; const URI: string; const Serial: string);
|
||||
var
|
||||
Idx, J: Integer;
|
||||
begin
|
||||
@@ -243,6 +278,9 @@ begin
|
||||
FDiscovered[Idx].IPAddress := IP;
|
||||
FDiscovered[Idx].DisplayName := DisplayName;
|
||||
FDiscovered[Idx].BoardType := BoardType;
|
||||
FDiscovered[Idx].Kind := Kind;
|
||||
FDiscovered[Idx].URI := URI;
|
||||
FDiscovered[Idx].Serial := Serial;
|
||||
FillChar(FDiscovered[Idx].MAC, SizeOf(FDiscovered[Idx].MAC), 0);
|
||||
for J := 0 to High(MAC) do
|
||||
if J <= 5 then FDiscovered[Idx].MAC[J] := MAC[J];
|
||||
|
||||
Reference in New Issue
Block a user