mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
Fix IQ data flow: send HP Run=1 before DDC/DUC Specific packets
The emulator (and real hardware) creates ddc_specific_thread (port 1025), duc_specific_thread (port 1026), and rx_thread[0..3] (ports 1035+) only after receiving HP Run=1. Previously ConfigureDDCs and SendDUCSpecific were sent before SetRunAndFreq(True), so both packets arrived at closed ports and were silently dropped — ddcenable remained -1, rx_thread slept forever, no IQ data ever arrived, and the 5-second timeout fired Run=0. Fix: reorder DoConnectDevice to send Run=1 first, then DDC/DUC Specific. Also add keepalive resend of the cached DDC Specific packet every 500 ms for the first 5 seconds after start, to handle thread-startup races on real hardware over the network. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -121,6 +121,11 @@ type
|
|||||||
FPortDUCIQ: Word;
|
FPortDUCIQ: Word;
|
||||||
FDirectIP: string; // для unicast discovery
|
FDirectIP: string; // для unicast discovery
|
||||||
|
|
||||||
|
// Кэш DDC Specific — keepalive повторно шлёт первые 5 сек после старта
|
||||||
|
FCachedDDCSpec: TDDCSpecificPacket;
|
||||||
|
FCachedDDCValid: Boolean;
|
||||||
|
FResendCount: Integer;
|
||||||
|
|
||||||
// Текущее состояние для построения HP пакетов
|
// Текущее состояние для построения HP пакетов
|
||||||
FCurrentRXFreq: Double;
|
FCurrentRXFreq: Double;
|
||||||
FCurrentTXFreq: Double;
|
FCurrentTXFreq: Double;
|
||||||
@@ -398,6 +403,15 @@ begin
|
|||||||
if not FNet.FConnected then Continue;
|
if not FNet.FConnected then Continue;
|
||||||
// Отправляем полный HP с частотами и ALEX — как piHPSDR
|
// Отправляем полный HP с частотами и ALEX — как piHPSDR
|
||||||
FNet.SendFullHP;
|
FNet.SendFullHP;
|
||||||
|
// Повторно отправляем DDC Specific первые 5 сек после Run=1 (каждые 500 мс).
|
||||||
|
// ddc_specific_thread на эмуляторе/железе стартует ПОСЛЕ получения Run=1,
|
||||||
|
// поэтому первый ConfigureDDCs может прийти раньше чем порт 1025 откроется.
|
||||||
|
if FNet.FRunning and FNet.FCachedDDCValid then
|
||||||
|
begin
|
||||||
|
Inc(FNet.FResendCount);
|
||||||
|
if (FNet.FResendCount <= 100) and (FNet.FResendCount mod 10 = 2) then
|
||||||
|
FNet.SendDDCSpecific(FNet.FCachedDDCSpec);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -914,6 +928,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
SendDDCSpecific(Pkt);
|
SendDDCSpecific(Pkt);
|
||||||
|
FCachedDDCSpec := Pkt;
|
||||||
|
FCachedDDCValid := True;
|
||||||
|
FResendCount := 0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure THPSDRNetwork.SendDUCSpecific(const Pkt: TDUCSpecificPacket);
|
procedure THPSDRNetwork.SendDUCSpecific(const Pkt: TDUCSpecificPacket);
|
||||||
|
|||||||
+8
-4
@@ -2827,8 +2827,6 @@ begin
|
|||||||
else
|
else
|
||||||
FActiveDDC := 0;
|
FActiveDDC := 0;
|
||||||
|
|
||||||
FNetwork.ConfigureDDCs(1, FSampleRate div 1000, 0);
|
|
||||||
|
|
||||||
// Синхронизируем samplerate WDSP если нужно
|
// Синхронизируем samplerate WDSP если нужно
|
||||||
if FWDSPReady and (FDSPEngine.SampleRate <> FSampleRate) then
|
if FWDSPReady and (FDSPEngine.SampleRate <> FSampleRate) then
|
||||||
begin
|
begin
|
||||||
@@ -2849,7 +2847,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
FSpecView.AGCTop := FAGCTop;
|
FSpecView.AGCTop := FAGCTop;
|
||||||
|
|
||||||
// DUC specific
|
// DUC specific packet (строим здесь, отправляем после Run=1)
|
||||||
FillChar(DUCPkt, SizeOf(DUCPkt), 0);
|
FillChar(DUCPkt, SizeOf(DUCPkt), 0);
|
||||||
DUCPkt.NumDACs := 1;
|
DUCPkt.NumDACs := 1;
|
||||||
DUCPkt.SidetoneLevel := 50;
|
DUCPkt.SidetoneLevel := 50;
|
||||||
@@ -2860,14 +2858,20 @@ begin
|
|||||||
DUCPkt.DUC0RateHi := Hi(192);
|
DUCPkt.DUC0RateHi := Hi(192);
|
||||||
DUCPkt.DUC0RateLo := Lo(192);
|
DUCPkt.DUC0RateLo := Lo(192);
|
||||||
DUCPkt.DUC0Bits := 24;
|
DUCPkt.DUC0Bits := 24;
|
||||||
FNetwork.SendDUCSpecific(DUCPkt);
|
|
||||||
|
|
||||||
|
// Сначала отправляем Run=1 — эмулятор/железо создают ddc_specific_thread
|
||||||
|
// (порт 1025) и rx_thread (порт 1035+) только после получения HP Run=1.
|
||||||
|
// DDC Specific и DUC Specific отправляем ПОСЛЕ, иначе порты ещё не открыты.
|
||||||
FNetwork.UpdateState(FCenterFreq, FCenterFreq, FDriveLevel, False, True, True);
|
FNetwork.UpdateState(FCenterFreq, FCenterFreq, FDriveLevel, False, True, True);
|
||||||
FNetwork.SetRunAndFreq(True, FCenterFreq, FCenterFreq, FDriveLevel);
|
FNetwork.SetRunAndFreq(True, FCenterFreq, FCenterFreq, FDriveLevel);
|
||||||
FRunning := True;
|
FRunning := True;
|
||||||
FRXStartTime := GetTickCount64;
|
FRXStartTime := GetTickCount64;
|
||||||
FRXLastPktTime := 0;
|
FRXLastPktTime := 0;
|
||||||
|
|
||||||
|
// DDC и DUC Specific — теперь потоки эмулятора слушают на своих портах
|
||||||
|
FNetwork.ConfigureDDCs(1, FSampleRate div 1000, 0);
|
||||||
|
FNetwork.SendDUCSpecific(DUCPkt);
|
||||||
|
|
||||||
// Принудительно обновляем AGC линии — гарантированно после всех SetAGC вызовов
|
// Принудительно обновляем AGC линии — гарантированно после всех SetAGC вызовов
|
||||||
if FWDSPReady then
|
if FWDSPReady then
|
||||||
FDSPEngine.UpdateAGCLines(FSpectrumWidth); // ещё не получили ни одного пакета
|
FDSPEngine.UpdateAGCLines(FSpectrumWidth); // ещё не получили ни одного пакета
|
||||||
|
|||||||
Reference in New Issue
Block a user