Files
ewsdr/AndromedaMap.pas
T

199 lines
8.5 KiB
ObjectPascal
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
Copyright (C)
2026 - Uladzimir Karpenka, EW8BAK
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
}
unit AndromedaMap;
{
AndromedaMap.pas — таблицы раскладки передней панели Apache Labs Andromeda / G2.
Только ДАННЫЕ: перечисления действий и дефолтные таблицы
«номер кнопки → действие», «номер энкодера → параметр»,
«индикатор → номер LED (ZZZI)». Без логики и без зависимостей от
контроллера — этим занимается AndromedaPanel.pas.
Соответствие протоколу Thetis:
• действия кнопок/энкодеров — подмножество EButtonBarActions / EEncoderActions;
• номера LED-индикаторов (ZZZI nn) зеркалят дефолтную таблицу Thetis
(MakeNewAndromedaDataset): 1=MOX, 3=Tune, 7=CTUN и т.д. Свободные слоты
12..17 заняты функциями ewsdr (Split/NB/NR/SNB/ANF/Squelch).
}
{$mode objfpc}{$H+}
interface
type
// Действие кнопки панели (подмножество, поддержанное ewsdr).
TAndButton = (
abNone, abMOX, abTune, abBandUp, abBandDown, abModeUp, abModeDown,
abMute, abNB, abNR, abSNB, abANF, abVFOSplit, abVFOSwap, abCTUN,
abCTCSS, abSquelch, abFilterUp, abFilterDown,
abVFOAtoB, // копировать VFO A → B (Thetis eBBVFOAtoB)
abVFOBtoA, // копировать VFO B → A (Thetis eBBVFOBtoA)
abVFOLock, // блокировка перестройки VFO (Thetis eBBVFOLockOnOff)
abStartStop, // старт/стоп SDR (Thetis eBBStartStop)
abShift); // модификатор band-keypad (Thetis eBBShift) — обрабатывается в панели
// Параметр, управляемый поворотным энкодером панели.
TAndEncoder = (
aeNone, aeAFGain, aeAGCLevel, aeDrive, aeSquelch,
aeFilterWidth, aeFilterHigh, aeFilterLow, aeMulti);
// Индикатор (LED) панели. Порядок зеркалит EIndicatorActions Thetis.
TAndIndicator = (
aiNone, aiMOX, aiTune, aiRIT, aiXIT, aiSplit, aiCTune, aiVFOSync,
aiVFOAB, aiVFOLock, aiNB, aiNR, aiSNB, aiANF, aiSquelch,
aiCompander, aiPuresignal, aiDiversity, aiATUReady, aiShift);
const
// Размеры дефолтных таблиц (кнопки/энкодеры нумеруются с 0 после разбора ZZZP/ZZZE).
AND_MAX_BUTTONS = 48;
AND_MAX_ENCODERS = 20;
// Раскладка кнопок: индекс = номер кнопки (0-based), значение = действие.
// Нумерация совпадает с дефолтом Thetis (MakeNewAndromedaDataset): наш 0-based
// индекс = «Pushbutton Number» Thetis 1. Проверено на реальной панели
// (см. andromeda_test/AndDecode.pas). Неназначенные / отсутствующий тракт → abNone.
AND_BUTTON_MAP: array[0..AND_MAX_BUTTONS-1] of TAndButton = (
abMute, // 0 RX1 Mute
abNone, // 1
abNone, // 2 RX2 Mute — нет второго приёмника
abNone, // 3
abNone, // 4
abNone, // 5
abNone, // 6
abNone, // 7
abNone, // 8
abNone, // 9
abNone, // 10
abNone, // 11
abNone, // 12
abNone, // 13
abNone, // 14
abNone, // 15
abNone, // 16
abNone, // 17
abNone, // 18
abNone, // 19
abNone, // 20
abNone, // 21
abNone, // 22
abNone, // 23
abNone, // 24
abNone, // 25
abNone, // 26
abNone, // 27
abShift, // 28 Shift (band-keypad модификатор)
abBandUp, // 29 Band + (под shift → 160m)
abModeUp, // 30 Mode + (под shift → 80m)
abFilterUp, // 31 Filter + (под shift → 60m)
abBandDown, // 32 Band - (под shift → 40m)
abModeDown, // 33 Mode - (под shift → 30m)
abFilterDown, // 34 Filter - (под shift → 20m)
abVFOAtoB, // 35 A>B (под shift → 17m)
abVFOBtoA, // 36 B>A (под shift → 15m)
abVFOSplit, // 37 Split (под shift → 12m)
abNone, // 38 (под shift → 10m)
abNone, // 39 (под shift → 6m)
abNone, // 40 (под shift → GEN, нет в ewsdr)
abNone, // 41 RIT/XIT toggle — нет RIT/XIT
abVFOSwap, // 42 Toggle A/B
abVFOLock, // 43 VFO Lock
abCTUN, // 44 CTUNE
abStartStop, // 45 SDR ON (start/stop)
abMOX, // 46 MOX
abTune); // 47 TUN
// Раскладка энкодеров: индекс = номер энкодера (0-based), значение = параметр.
// Нумерация = «Encoder Number» Thetis 1 (дефолт MakeNewAndromedaDataset).
// Энкодер #1 в Thetis — AGC Level (слайдер RF), поэтому aeAGCLevel.
// #4/#5 — Filter High/Low: настоящие независимые края (как на железе G2).
// aeFilterWidth оставлен в перечислении для раскладок, где нужен один
// энкодер «ширина» — в дефолтной раскладке не используется.
AND_ENCODER_MAP: array[0..AND_MAX_ENCODERS-1] of TAndEncoder = (
aeAFGain, // 0 RX1 AF Gain
aeAGCLevel, // 1 RX1 AGC Level (Thetis «RF»)
aeNone, // 2 RX2 AF — нет второго приёмника
aeNone, // 3 RX2 AGC
aeFilterHigh, // 4 Filter High — верхний край
aeFilterLow, // 5 Filter Low — нижний край
aeNone, // 6 Diversity gain
aeNone, // 7 Diversity phase
aeNone, // 8 RIT
aeNone, // 9 XIT
aeMulti, // 10 Multifunction
aeDrive, // 11 TX Drive
aeNone, aeNone, aeNone, aeNone, aeNone, aeNone, aeNone, aeNone);
// Номер LED (ZZZI nn) для каждого индикатора; 0 = панель этот индикатор не имеет.
// 1..11 — дефолт Thetis; 12..17 — функции ewsdr на свободных слотах.
AND_INDICATOR_NUM: array[TAndIndicator] of Integer = (
{aiNone} 0,
{aiMOX} 1,
{aiTune} 3,
{aiRIT} 8,
{aiXIT} 9,
{aiSplit} 12,
{aiCTune} 7,
{aiVFOSync} 0,
{aiVFOAB} 10,
{aiVFOLock} 11,
{aiNB} 13,
{aiNR} 14,
{aiSNB} 15,
{aiANF} 16,
{aiSquelch} 17,
{aiCompander} 0,
{aiPuresignal} 0,
{aiDiversity} 0,
{aiATUReady} 2,
{aiShift} 6);
{ Возвращает действие для номера кнопки (0-based); abNone вне диапазона. }
function ButtonAction(BtnIndex: Integer): TAndButton;
{ Возвращает параметр для номера энкодера (0-based); aeNone вне диапазона. }
function EncoderParam(EncIndex: Integer): TAndEncoder;
{ Номер ZZZI для индикатора; 0 если панель его не отображает. }
function IndicatorNum(Ind: TAndIndicator): Integer;
implementation
function ButtonAction(BtnIndex: Integer): TAndButton;
begin
if (BtnIndex >= 0) and (BtnIndex < AND_MAX_BUTTONS) then
Result := AND_BUTTON_MAP[BtnIndex]
else
Result := abNone;
end;
function EncoderParam(EncIndex: Integer): TAndEncoder;
begin
if (EncIndex >= 0) and (EncIndex < AND_MAX_ENCODERS) then
Result := AND_ENCODER_MAP[EncIndex]
else
Result := aeNone;
end;
function IndicatorNum(Ind: TAndIndicator): Integer;
begin
Result := AND_INDICATOR_NUM[Ind];
end;
end.