mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
fix(cw): реле T/R и антенна за ключом прошивки + залипание HW-PTT
Отвязав FTransmitting от телеграфа, я оставил в приёмной конфигурации всё, что бэкенд считает от состояния передачи: CalcAlex0 бит 27 (реле T/R), выбор антенны (TxAnt вместо RxAnt), bypass/Ext1 и CalcOCBits, которым ключуется внешний усилитель. Прошивка гнала несущую, пока плата фильтров стояла на приём, и приёмник видел собственный передатчик — на водопаде это широкополосные полосы в моменты манипуляции. PushNetworkState отдаёт в UpdateState RadioKeyed, и он же вызывается на фронтах ключа. PTT в кадре этим не поднимается (он живёт в SendPTT), так что манипуляцией по-прежнему владеет FPGA. Выдержка RadioKeyed поднята до hang + 250 мс: по ней теперь щёлкает реле, и щёлкать оно обязано раз на передачу, а не на каждую посылку. FTuning из RadioKeyed убран — при TUN и так взведён FTransmitting, а в разборе SetTune флаги гаснут не разом. Второе: телеграфная ветка разбора статуса заканчивается Exit, и падающий фронт HW-PTT обработать было некому. Если в эфир увёл именно HW-PTT, пока источником передачи был не телеграф, а телеграф включился уже после, то передача залипала навсегда — FTransmitting взведён, Alex в TX, PTT не снимается. Подтверждено на железе: всплески появлялись после переключения передачи на слайс и оставались после возврата на главный. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+27
-2
@@ -1324,8 +1324,11 @@ procedure TRadioController.PushNetworkState;
|
|||||||
begin
|
begin
|
||||||
if Assigned(FNetwork) and FNetwork.Connected and FNetwork.Running then
|
if Assigned(FNetwork) and FNetwork.Connected and FNetwork.Running then
|
||||||
begin
|
begin
|
||||||
|
// Состояние передачи для ЖЕЛЕЗА — RadioKeyed, а не FTransmitting: в
|
||||||
|
// телеграфе ключ замыкает прошивка, и реле T/R с антенной и OC обязаны
|
||||||
|
// ехать за ней. PTT в кадре этим не поднимается (он живёт в SendPTT).
|
||||||
FNetwork.UpdateState(XvtrTranslate(FCenterFreq), XvtrTranslateTX(ActiveTXFreqHz),
|
FNetwork.UpdateState(XvtrTranslate(FCenterFreq), XvtrTranslateTX(ActiveTXFreqHz),
|
||||||
FDriveLevel, FTransmitting, True, True, FTuning, FTwoTone);
|
FDriveLevel, RadioKeyed, True, True, FTuning, FTwoTone);
|
||||||
FNetwork.SendFullHP;
|
FNetwork.SendFullHP;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@@ -1578,6 +1581,17 @@ begin
|
|||||||
// модуляции, — но передачей по нему не управляем.
|
// модуляции, — но передачей по нему не управляем.
|
||||||
if CWTXActive then
|
if CWTXActive then
|
||||||
begin
|
begin
|
||||||
|
// ★Ниже стоит Exit, поэтому падающий фронт HWPTT здесь обработать НЕКОМУ.
|
||||||
|
// Если в эфир нас увёл именно HWPTT, пока источником передачи был не
|
||||||
|
// телеграф (например слайс в голосовом режиме), а телеграф включился уже
|
||||||
|
// после — передача залипала бы НАВСЕГДА: FTransmitting остаётся взведённым,
|
||||||
|
// Alex стоит в TX, PTT не снимается, и приёмник всю дорогу видит свой же
|
||||||
|
// передатчик. Снимаем такую передачу здесь.
|
||||||
|
if FHWPTTStartedTX and (not FHPpHWPTT) then
|
||||||
|
begin
|
||||||
|
FHWPTTStartedTX := False;
|
||||||
|
SetMOX(False);
|
||||||
|
end;
|
||||||
FHWPTTActive := FHPpHWPTT;
|
FHWPTTActive := FHPpHWPTT;
|
||||||
if FHPpHWPTT then FCWKeyedAt := GetTickCount64;
|
if FHPpHWPTT then FCWKeyedAt := GetTickCount64;
|
||||||
// UI про телеграфную передачу иначе не узнает вовсе: SetMOX здесь не
|
// UI про телеграфную передачу иначе не узнает вовсе: SetMOX здесь не
|
||||||
@@ -1586,6 +1600,11 @@ begin
|
|||||||
if FCWKeyedShown <> RadioKeyed then
|
if FCWKeyedShown <> RadioKeyed then
|
||||||
begin
|
begin
|
||||||
FCWKeyedShown := RadioKeyed;
|
FCWKeyedShown := RadioKeyed;
|
||||||
|
// ★Железная обвязка обязана идти за фактическим ключом: реле T/R (Alex
|
||||||
|
// bit 27), TX-антенна, bypass/Ext1 и выходы OC (ими ключуется усилитель)
|
||||||
|
// считаются в бэкенде от состояния передачи. Без этого пути прошивка
|
||||||
|
// гнала бы несущую, пока Alex стоит в ПРИЁМНОЙ конфигурации.
|
||||||
|
PushNetworkState;
|
||||||
Changed(rfTransmitting);
|
Changed(rfTransmitting);
|
||||||
end;
|
end;
|
||||||
Exit;
|
Exit;
|
||||||
@@ -1594,6 +1613,7 @@ begin
|
|||||||
if FCWKeyedShown then
|
if FCWKeyedShown then
|
||||||
begin
|
begin
|
||||||
FCWKeyedShown := False;
|
FCWKeyedShown := False;
|
||||||
|
PushNetworkState;
|
||||||
Changed(rfTransmitting);
|
Changed(rfTransmitting);
|
||||||
end;
|
end;
|
||||||
// Hardware PTT (footswitch / mic PTT): фронт на rate HP Status — не пропустить
|
// Hardware PTT (footswitch / mic PTT): фронт на rate HP Status — не пропустить
|
||||||
@@ -5683,11 +5703,16 @@ function TRadioController.RadioKeyed: Boolean;
|
|||||||
// выдержка гасила бы индикацию между словами.
|
// выдержка гасила бы индикацию между словами.
|
||||||
var Hold: QWord;
|
var Hold: QWord;
|
||||||
begin
|
begin
|
||||||
Result := FTransmitting or FTuning;
|
Result := FTransmitting;
|
||||||
if Result then Exit;
|
if Result then Exit;
|
||||||
if not CWTXActive then Exit(False);
|
if not CWTXActive then Exit(False);
|
||||||
if FCWKeyedAt = 0 then Exit(False);
|
if FCWKeyedAt = 0 then Exit(False);
|
||||||
|
// Выдержка = hang прошивки + запас, но не меньше 8 точек: полурывок semi-QSK.
|
||||||
|
// По ней же переключается реле T/R, поэтому щёлкать оно обязано РАЗ на
|
||||||
|
// передачу, а не на каждую посылку.
|
||||||
Hold := 8 * (1200 div EnsureRange(FCWSettings.Speed, 5, 60));
|
Hold := 8 * (1200 div EnsureRange(FCWSettings.Speed, 5, 60));
|
||||||
|
if Hold < QWord(FCWSettings.HangTimeMS) + 250 then
|
||||||
|
Hold := QWord(FCWSettings.HangTimeMS) + 250;
|
||||||
if Hold < 500 then Hold := 500;
|
if Hold < 500 then Hold := 500;
|
||||||
Result := (GetTickCount64 - FCWKeyedAt) < Hold;
|
Result := (GetTickCount64 - FCWKeyedAt) < Hold;
|
||||||
end;
|
end;
|
||||||
|
|||||||
Reference in New Issue
Block a user