chore: refine project documentation

This commit is contained in:
2026-08-25 22:44:36 +03:00
parent 8237f03930
commit 98d90e1e5a
45 changed files with 457 additions and 516 deletions
+42 -45
View File
@@ -428,7 +428,7 @@ type
FPSEnabled: Boolean; // авто-калибровка PS включена (кнопка PS)
FPSSingleCal: Boolean; // запрошена одиночная калибровка
FPSResetReq: Boolean; // запрошен сброс коррекции (OFF)
FPSCmdState: Integer; // eCMDState Thetis (см. PureSignalTick)
FPSCmdState: Integer; // состояние автомата команд PureSignal
FPSAAState: Integer; // auto-attenuate state (0=monitor,1=set,2=restore)
FPSAASaveAuto: Integer; // сохранённый automode на время смены атт.
FPSAASaveSingle: Integer;
@@ -497,7 +497,7 @@ type
FSpecRefLevel: Double;
FSpecRange: Double;
FSpecGridStep: Double;
FTXSpecRefLevel: Double; // TX-сетка (Thetis-style): применяется при FTransmitting
FTXSpecRefLevel: Double; // опорный уровень TX-сетки при FTransmitting
FTXSpecRange: Double;
FTXSpecGridStep: Double;
@@ -718,7 +718,7 @@ type
// FM-девиация, squelch). Вызывается командами и UI-путями смены режима.
procedure ApplyModeFilter;
// Вычисляет hardware drive-байт (Thetis-формула) из текущего состояния
// Вычисляет аппаратный drive-байт из текущего состояния мощности.
// (band/xvtr cal, TUN/drive%, PA max). Чистая функция над состоянием.
function CalcDriveByte: Byte;
@@ -1152,8 +1152,8 @@ type
function CWSettings: TCWSettings;
procedure SetCWSettings(const C: TCWSettings);
// Программная передача текста: PC сам выдерживает тайминги и дёргает бит
// CWX в High Priority — точки/тире рисует прошивка по этому биту (эталон
// Thetis cwx.cs). Занят ли передатчик — CWXBusy; ЛЮБОЕ касание
// CWX в High Priority — точки/тире рисует прошивка по этому биту.
// Занят ли передатчик — CWXBusy; ЛЮБОЕ касание
// манипулятора или снятие MOX обрывает передачу (CWXAbort).
procedure CWXSend(const Text: string);
// Чужая манипуляция: один готовый интервал (посылка или пауза) заданной
@@ -1192,8 +1192,8 @@ type
procedure SetPureSignal(On_: Boolean);
procedure PSSingleCal; // одиночная калибровка
procedure PSReset; // выключить и сбросить коррекцию
// Тик PS (~10 Гц, из UI-таймера): state machine команд (порт Thetis
// PSForm timer1/timer2), опрос GetPSInfo, auto-attenuate через AttOnTX.
// Тик PS (~10 Гц, из UI-таймера): автомат команд, опрос GetPSInfo и
// автоматическая регулировка AttOnTX по уровню обратной связи.
procedure PureSignalTick;
procedure ApplyPSSettingsToDSP; // FTXSettings.PS* → WDSP calcc
// Вооружение/снятие feedback-тракта (сеть + движок), идемпотентно.
@@ -1202,7 +1202,7 @@ type
function PSFeedbackLevel: Integer; // info[4], оптимум ~PSFBTarget
// Эффективная цель уровня feedback: настройка ps_fb_target, либо авто по
// плате (Orion MkII/ANAN-7000/8000 → 22 — выше перегружается вход ADC,
// замеры eu2av на Anvelina PRO3; остальные → 152, классика Thetis).
// замеры на Anvelina PRO3; для остальных используется значение 152.
function PSFBTarget: Integer;
function PSCalCount: Integer; // info[5]
function PSCorrecting: Boolean; // info[14]=1 — коррекция применяется
@@ -1337,8 +1337,8 @@ const
// (TUNLevel), падение уровня IQ ~1.6дБ компенсируется калибровкой TUNLevel.
TUN_TONE_MAG = 0.83;
// Состояния командной state machine PureSignal (порт Thetis eCMDState;
// Restore-ветка (7) не реализована — Save/Restore коррекции нет).
// Состояния автомата команд PureSignal. Восстановление сохранённой
// коррекции не реализовано.
PS_ST_OFF = 0;
PS_ST_TURNON_AUTO = 1;
PS_ST_AUTOCAL = 2;
@@ -1827,7 +1827,7 @@ begin
SupplyV := -1.0;
SupplyA := -1.0;
// Board 5 (Orion MkII): напряжение на UserADC0, ток на UserADC1 (как Thetis).
// Board 5 (Orion MkII): напряжение на UserADC0, ток на UserADC1.
// Прочие платы — в SupplyVolts-байтах, без тока.
if BoardSupportsSupplyVoltage(FNetwork.Device.BoardType) then
begin
@@ -1849,7 +1849,7 @@ begin
end;
// Детектор Alex-моста: константы по модели (вкладка Calibration) + per-band
// множитель. Множитель общий для FWD/REV, поэтому КСВ от него не зависит
// (как Thetis PABandCalMult).
// и используется только для калибровки показаний мощности.
Bi := TxBandIdx;
Is6m := Bi = BAND_6M;
DetK := 1.0;
@@ -1859,7 +1859,7 @@ begin
RevW := AlexDetToWatts(RevPwr, FCal.PwrDetModel, True, Is6m) * DetK;
// FTransmitting — программный флаг; HPS_PTT — вход HW-PTT (footswitch/mic).
IsTx := FTransmitting or ((Status.StatusBits and HPS_PTT) <> 0);
// SWR = (1+ρ)/(1-ρ), ρ = sqrt(RevW/FwdW) (Thetis); только при значимой
// SWR = (1+ρ)/(1-ρ), ρ = sqrt(RevW/FwdW); только при значимой
// fwd-мощности.
if IsTx and (FwdW >= SWR_MIN_FWD_W) then
begin
@@ -1884,8 +1884,8 @@ begin
FHPpHWPTT := (Status.StatusBits and HPS_PTT) <> 0;
FHPpOverload := Status.ADCOverload;
// Состояние ключа/манипулятора в разъёме трансивера (сетевой поток).
// Касание обрывает программную передачу — как в Thetis/pihpsdr («key hit»
// останавливает CAT CW), иначе оператор не может вклиниться. ★Обрываем по
// Касание обрывает программную передачу, чтобы оператор мог вклиниться.
// ★Обрываем по
// ФРОНТУ, а не по уровню: на плате без подключённого ключа входы могут стоять
// в единице, и проверка уровня убивала бы передачу на первом же HP-статусе.
KeyDot := (Status.StatusBits and HPS_DOT) <> 0;
@@ -2989,7 +2989,7 @@ function TRadioController.FrontEndCalDB: Double;
// Поправка на регулируемое усиление входного тракта — то, что меняется ручкой
// или само и не должно двигать абсолютную шкалу dBm.
// openHPSDR: шаговый аттенюатор ADC режет вход → его дБ возвращаем в
// показания (так же делают Thetis и piHPSDR).
// показания.
// AD936x: hardwaregain поднимает уровень (а в режимах AGC железо крутит
// его само) → вычитаем текущее значение.
// Постоянная часть тракта (LNB, кабель, конвертер) остаётся за таблицами
@@ -3356,8 +3356,8 @@ end;
procedure TRadioController.RequestSliceTx(SliceId: Integer; On_: Boolean;
Tune: Boolean = False);
// PTT, пришедшая по CAT-порту слайса или по TCI с номером приёмника. Аналог
// «Auto Switch TX Slice» в SmartSDR CAT: с Auto TX слайс сам становится
// PTT, пришедшая по CAT-порту слайса или по TCI с номером приёмника. При
// включённом Auto TX слайс сам становится
// TX-источником, без него — передаёт, только если оператор уже выбрал его
// источником (бейдж TX на флаге).
// Выполняется в потоке контроллера (CAT и TCI маршалят через Invoke), поэтому
@@ -4049,7 +4049,7 @@ begin
Hi := FFilterHi;
if FWDSPReady and Assigned(FDSPEngine) then
begin
// Только RX. TX-полоса НЕ следует за RX-фильтром (модель Thetis) — её
// Только RX. TX-полоса НЕ следует за RX-фильтром — её
// единственный источник TX-фильтр из настроек (SetTXFilterFull/ApplyTXChain
// через TXSignedEdges). Иначе широкий RX раздувал бы излучаемый сигнал.
FDSPEngine.SetFilter(Lo, Hi);
@@ -4148,7 +4148,7 @@ end;
// =====================================================================
function TRadioController.CalcDriveByte: Byte;
// Thetis-совместимая формула:
// Преобразование целевой мощности в аппаратный байт drive:
// drive_byte = int( min(target_volts/0.8, 1.0) * 1.02 * 255 )
// target_volts = sqrt( 10^(target_dBm/10) * 0.05 )
// target_dBm = 10*log10(pwr_W*1000) - Cal ; pwr_W = Pos/100 * FPAMaxPower
@@ -4385,9 +4385,9 @@ begin
if Assigned(FDMRDec) then FDMRDec.SetEnabled(FMode = MODE_DMR);
if FWDSPReady and Assigned(FDSPEngine) then FDSPEngine.SetMode(FMode);
// --- Фильтр (санитизация FM до применения к DSP — как в оригинале) ---
// --- Фильтр: санитизация FM до применения к DSP ----------------------
// Банд помнит ТОЛЬКО выбранный слот; кромки живут в таблице фильтров
// (по режиму, как в Thetis). Иначе у VAR было бы два источника истины —
// отдельно по режимам. Иначе у VAR было бы два источника истины —
// ровно та болезнь, от которой уходили.
ApplyFilterSlot(B.FilterIdx);
ApplyModeFilter;
@@ -5814,7 +5814,7 @@ end;
function TRadioController.CWTXActive: Boolean;
// «Передачей в телеграфе владеет не MOX»: режим ИСТОЧНИКА передачи — CW и
// манипуляция кому-то поручена (прошивке или локальному генератору). В этом
// состоянии голосовой TXA не запускается вовсе (эталон Thetis, console.cs:29570),
// состоянии голосовой TXA не запускается вовсе,
// а несущую даёт кейер / бит CWX / тон TUN.
begin
Result := (ActiveTXMode in [MODE_CWL, MODE_CWU])
@@ -5851,10 +5851,9 @@ begin
end;
function TRadioController.CWOptionsByte: Byte;
// DUC Specific байт 5. Порт pihpsdr new_protocol.c:1353-1383 (там же
// объяснение, почему iambic-бит выставляется и для Mode B).
// Формирует DUC Specific byte 5; iambic-бит выставляется и для Mode B.
// ★Вне телеграфа байт ОБЯЗАН быть нулевым: иначе прошивка сама поднимет PTT
// на замыкание ключа посреди SSB (Thetis, console.cs:27394).
// на замыкание ключа посреди SSB.
begin
Result := 0;
// ★Байт обязан быть нулевым не только вне телеграфа, но и когда манипуляцию
@@ -5913,10 +5912,10 @@ begin
DUCPkt.DUC0RateLo := Lo(RateKsps);
DUCPkt.DUC0Bits := 24;
DUCPkt.MicLineSelect := BuildMicLineSelectByte;
// Line In Gain (byte 51): 0=-34.5dB .. 31=+12dB (шаг 1.5 dB, формула Thetis).
// Line In Gain (byte 51): 0=-34.5dB .. 31=+12dB с шагом 1.5 dB.
// При Mic In значение игнорируется железом, но шлём корректное для Line In.
DUCPkt.LineInGain := Byte(EnsureRange(Round((FTXSettings.LineInGainDB + 34.5) / 1.5), 0, 31));
// ATT on TX — RX-ADC step attenuator во время передачи (Thetis-style protection).
// ATT on TX — ступенчатый аттенюатор RX-ADC во время передачи.
// Дублируем значение во все три ADC-байта: на однопотоковых платах активен только
// ADC0, на Saturn/Hermes Lite 2 — могут использоваться ADC1/ADC2.
DUCPkt.StepAtten0 := Byte(EnsureRange(FTXSettings.AttOnTX, 0, 31));
@@ -6269,7 +6268,7 @@ end;
procedure TRadioController.ApplyTXSettingsToDSP;
begin
if not FWDSPReady then Exit;
// Thetis держит CFIR постоянно включённым для openHPSDR Protocol 2:
// Для openHPSDR Protocol 2 CFIR постоянно включён:
// он компенсирует АЧХ FPGA CIC-интерполятора TX. Pluto этого фильтра не
// имеет, поэтому при смене бэкенда явно выключаем его.
FDSPEngine.SetTXCFIR(BackendCaps.Kind = bkHPSDR);
@@ -6418,8 +6417,8 @@ begin
if FTransmitting then FDSPEngine.SetTXMode(ActiveTXMode);
// PureSignal: mox-флаг calcc (гейтит сбор данных калибровки в pscc).
FDSPEngine.PSSetMox(FTransmitting);
// ★Телеграф: голосовой TXA не запускается ВООБЩЕ (эталон Thetis,
// console.cs:29570). В WDSP режим TXA_CWL — буквально ветка SSB, поэтому
// ★Телеграф: голосовой TXA не запускается ВООБЩЕ. В WDSP режим TXA_CWL —
// буквально ветка SSB, поэтому
// без этого гарда MOX в CW отправлял бы в эфир микрофон на 2.9 кГц.
// Несущую в телеграфе даёт прошивка: кейер, бит CWX или тон TUN.
// Гард по РЕЖИМУ, а не по CWTXActive: даже с выключенным кейером прошивки
@@ -6476,8 +6475,7 @@ begin
begin
// Тон включаем ДО запуска TX-аудио, чтобы первые сэмплы уже шли с тоном.
// В телеграфе тон = pitch: TX-частота уезжает на CWLOOffset (ActiveTXFreqHz),
// и несущая настройки встаёт РОВНО на VFO, а не на VFO±тон. Так же в Thetis
// (console.cs:31757, ветка cw_fw_keyer && chkTUN).
// и несущая настройки встаёт РОВНО на VFO, а не на VFO±тон.
if FWDSPReady and Assigned(FDSPEngine) then
begin
if ActiveTXMode in [MODE_CWL, MODE_CWU] then
@@ -6902,7 +6900,7 @@ procedure TRadioController.CWKeyboardKey(Dot, Dash: Boolean);
// Манипулятор с клавиатуры. У локального генератора это те же лепестки, что с
// COM-порта — включая иамбик. У кейера прошивки лепестков нет: их читает FPGA
// со своего разъёма, а из программы доступен только бит CWX, то есть прямой
// ключ (это же ограничение у Thetis).
// ключ; это ограничение удалённого управления телеграфом.
begin
if not CWTXActive then
begin
@@ -7071,7 +7069,7 @@ begin
end;
// ===========================================================================
// PureSignal — оркестрация (порт state machine Thetis PSForm timer1/timer2)
// PureSignal — оркестрация автомата калибровки и обратной связи.
// ===========================================================================
function TRadioController.PSAvailable: Boolean;
@@ -7097,7 +7095,7 @@ begin
end;
procedure TRadioController.SetPureSignal(On_: Boolean);
// Кнопка PS = режим авто-калибровки (Thetis AutoCalEnabled). Выключение —
// Кнопка PS включает режим автоматической калибровки. Выключение —
// через запрос сброса: state machine выполнит reset коррекции и погасит тракт.
begin
if On_ = FPSEnabled then Exit;
@@ -7114,7 +7112,7 @@ begin
end;
procedure TRadioController.PSSingleCal;
// Одиночная калибровка (Thetis btnPSCalibrate): авто-режим выключается.
// Одиночная калибровка выключает автоматический режим.
begin
if not PSAvailable then Exit;
if FPSSingleCal then begin FPSSingleCal := False; Exit; end; // отмена
@@ -7140,7 +7138,7 @@ begin
if FDevConnected and (FNetwork <> nil) and (FNetwork.Device.BoardType = 5) then
Result := 22 // Orion MkII: замеры eu2av — при 152 фидбек-АЦП сам даёт IMD
else
Result := 152; // классическая цель Thetis
Result := 152; // стандартный целевой уровень
end;
end;
@@ -7150,7 +7148,7 @@ begin
if Result < 0 then
begin
if FDevConnected and (FNetwork <> nil) and (FNetwork.Device.BoardType = 5) then
Result := 5.0 // Orion MkII: дефолт Thetis-Enhanced eu2av
Result := 5.0 // Orion MkII: значение по умолчанию
else
Result := 0.0; // выключен
end;
@@ -7203,9 +7201,8 @@ begin
end;
procedure TRadioController.PureSignalTick;
// Вызывается из UI-таймера (~10 Гц). Командная state machine — порт Thetis
// PSForm timer1code (без Restore-ветки: Save/Restore коррекции не реализованы)
// + auto-attenuate (timer2code): подстройка AttOnTX по уровню feedback.
// Вызывается из UI-таймера (~10 Гц). Автомат управляет калибровкой без
// восстановления сохранённой коррекции и подстраивает AttOnTX по feedback.
var
NewAtt: Integer;
FBTarget: Integer;
@@ -7287,7 +7284,7 @@ begin
PS_ST_TURNOFF:
begin
// Reset исполняется внутри pscc — держим feedback-тракт, пока calcc
// не дойдёт до LRESET (как Thetis: PSEnabled=true в состоянии TurnOFF).
// не дойдёт до LRESET при PSEnabled=true в состоянии TurnOFF.
FDSPEngine.PSControl(1, 0, 0, 0);
PSSetFeedbackPath(True);
FPSResetReq := False;
@@ -7300,7 +7297,7 @@ begin
end;
end;
// --- Auto-attenuate (Thetis-Enhanced eu2av timer2code) ---
// --- Автоматическая регулировка аттенюатора обратной связи ----------
// По завершении очередной попытки калибровки: если feedback слишком горячий
// (>1.5×цели) или слабый при ненулевом атт. (<0.7×цели), подстроить AttOnTX
// так, чтобы уровень лёг к цели PSFBTarget (22 на Orion MkII — выше вход
@@ -7350,7 +7347,7 @@ begin
end;
procedure TRadioController.SetTwoTone(On_: Boolean);
// 2TON: двухтональник PostGen + MOX (как Thetis chkTestIMD). Уровень — обычный
// 2TON: двухтональник PostGen + MOX. Уровень — обычный
// Drive; тона PSTTFreq1/2 (700/1900 по умолчанию).
begin
if On_ = FTwoTone then Exit;