Files
ewsdr/AndromedaMap.pas
T

197 lines
8.3 KiB
ObjectPascal

{
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.
Таблицы соответствуют нумерации команд аппаратной панели. Для LED-индикаторов
используются номера 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
abVFOBtoA, // копировать VFO B → A
abVFOLock, // блокировка перестройки VFO
abStartStop, // старт/стоп SDR
abShift); // модификатор band-keypad — обрабатывается в панели
// Параметр, управляемый поворотным энкодером панели.
TAndEncoder = (
aeNone, aeAFGain, aeAGCLevel, aeDrive, aeSquelch,
aeFilterWidth, aeFilterHigh, aeFilterLow, aeMulti);
// Индикатор (LED) панели в порядке протокольной нумерации.
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), значение = действие.
// Внутренний индекс 0-based на единицу меньше номера кнопки в протоколе.
// Нумерация проверена на реальной панели
// (см. 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), значение = параметр.
// Внутренний индекс на единицу меньше номера энкодера в протоколе.
// Энкодер #1 управляет AGC Level, поэтому используется 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
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 — базовая раскладка панели; 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.