mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 17:27:32 +00:00
feat(cat): Andromeda/G2 front panel support (serial, LED indicators)
Bidirectional Apache Labs Andromeda/G2 front-panel protocol on top of CAT. Panel logic lives in dedicated units; existing files get only thin hooks. New units: - AndromedaMap.pas — data only: action enums + default button/encoder layout tables and LED (ZZZI) numbers (mirroring the Thetis defaults) - AndromedaPanel.pas — TAndromedaPanel: inbound panel events -> controller actions (marshalled via Invoke), state subscription -> ZZZI push via SendProc Hooks: - CATEngine: parse ZZZD/ZZZU/ZZZE/ZZZP/ZZZS into generic TCATContext callbacks - CATAdapter: creates the panel, routes engine callbacks to it, supplies the SendProc to the Andromeda port, AddStateListener, ZZZS handshake - CATSerial: Andromeda flag in port config + HasAndromeda/SendToAndromeda - RadioController: AddStateListener (multicast, does not steal MainForm's OnStateChanged) - Settings/SettingsForm/MainForm: CATSerialAndromeda[0..3] + persistence + checkbox First version: serial transport, hardcoded default mapping, LED indicators (MOX/Tune/CTUN/VFO A-B/Split/NB/NR/SNB/ANF/Squelch). Doc: doc/ANDROMEDA.md. TODO: default button mapping does not match the physical panel (hardcoded) — to be fixed later; also ZZMF/LCD text, TCP G2V2 transport, configurable mapping. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
# Поддержка передней панели Andromeda / G2 в EWSDR
|
||||
|
||||
Ветка разработки: `feature/cat-commands-expansion`.
|
||||
Дата последнего обновления: 2026-06-26.
|
||||
|
||||
Документ описывает поддержку аппаратной передней панели Apache Labs
|
||||
**Andromeda / ANAN-G2** (поворотные энкодеры, кнопки, LED-индикаторы, LCD).
|
||||
За эталон протокола взят Thetis (`Andromeda/Andromeda.cs`, `CAT/CATCommands.cs`).
|
||||
|
||||
См. также [CAT_STATUS.md](CAT_STATUS.md) — общий статус CAT-подсистемы.
|
||||
|
||||
---
|
||||
|
||||
## 1. Что такое Andromeda и чем отличается от обычного CAT
|
||||
|
||||
Andromeda — это **не отдельный набор команд**, а двунаправленный протокол панели
|
||||
поверх CAT-фрейминга. В отличие от обычного CAT (реактивный «запрос → ответ»),
|
||||
панель требует, чтобы хост **сам инициативно отправлял** обновления подсветки.
|
||||
|
||||
```
|
||||
ZZZD/ZZZU/ZZZE/ZZZP/ZZZS (панель → хост: ввод)
|
||||
┌─────────┐ ───────────────────────────► ┌──────────┐
|
||||
│ Панель │ │ EWSDR │
|
||||
│ G2 / │ ◄─────────────────────────── │ (хост) │
|
||||
│Andromeda│ ZZZI / ZZMF / ZZZS; └──────────┘
|
||||
└─────────┘ (хост → панель: подсветка, LCD, рукопожатие)
|
||||
```
|
||||
|
||||
| Направление | Команды | Назначение |
|
||||
|---|---|---|
|
||||
| **Панель → хост** | `ZZZS<v>` | панель сообщает версию HW/SW (рукопожатие) |
|
||||
| | `ZZZU<nn>` / `ZZZD<nn>` | энкодер VFO повёрнут вверх/вниз на nn шагов |
|
||||
| | `ZZZE<eees>` | энкодер #ee повёрнут (01–20 = +шаг, 51–70 = −шаг) |
|
||||
| | `ZZZP<bbs>` | кнопка #bb: s=1 нажата, 2 long-press, 0 отпущена |
|
||||
| **Хост → панель** | `ZZZI<nn><s>` | LED-индикатор #nn (00–19) вкл (1)/выкл (0) |
|
||||
| | `ZZMF<30 цифр>` | текст мультифункц. энкодера на LCD (пока **не реализован**) |
|
||||
| | `ZZZS;` | запрос версии у панели |
|
||||
|
||||
---
|
||||
|
||||
## 2. Архитектура реализации
|
||||
|
||||
Логика панели вынесена в отдельные юниты; в существующих файлах — только тонкие
|
||||
хуки. Зависимости однонаправленные, без циклов.
|
||||
|
||||
```
|
||||
┌────────────────────┐
|
||||
serial-порт ──────► │ TCATEngine │ разбор ZZZ* → generic callbacks
|
||||
(Andromeda) │ (CATEngine.pas) │ (OnPanelVfoStep/Encoder/Button/Version)
|
||||
└─────────┬──────────┘
|
||||
│ callbacks
|
||||
┌─────────▼──────────┐ создаёт/связывает
|
||||
│ TCATAdapter │ ◄───────────────────┐
|
||||
│ (CATAdapter.pas) │ │
|
||||
└─────────┬──────────┘ │
|
||||
SendProc (ZZZI/ZZZS;) │ ▲ AddStateListener │
|
||||
на Andromeda-порт ▼ │ (push индикаторов) │
|
||||
┌────────────────────┐ ┌────────────┴───────┐
|
||||
│ TAndromedaPanel │ ───────►│ TRadioController │
|
||||
│ (AndromedaPanel.pas)│ Invoke │ (ядро) │
|
||||
│ использует ▼ │ действия└────────────────────┘
|
||||
│ AndromedaMap.pas │ (таблицы раскладки — только данные)
|
||||
└────────────────────┘
|
||||
```
|
||||
|
||||
| Файл | Роль |
|
||||
|---|---|
|
||||
| **`AndromedaMap.pas`** | Только данные: enum'ы `TAndButton` / `TAndEncoder` / `TAndIndicator`, дефолтные таблицы раскладки кнопок/энкодеров и номера LED (`ZZZI`). Без логики и зависимостей. |
|
||||
| **`AndromedaPanel.pas`** | `TAndromedaPanel` — «мозг»: входящие события → действия контроллера (свой маршалинг через `FController.Invoke`); подписка на состояние контроллера → построение `ZZZI` → отправка через callback `SendProc`. Зависит только от `RadioController` + `AndromedaMap`. |
|
||||
| `CATEngine.pas` | Разбор входящих `ZZZD/ZZZU/ZZZE/ZZZP/ZZZS` в 4 generic-callback'а `TCATContext`. Движок остаётся чистым парсером, про Andromeda «не знает». |
|
||||
| `CATAdapter.pas` | Тонкий клей: создаёт панель, маршрутизирует callback'и движка в неё, даёт `SendProc` на Andromeda-порт, регистрирует панель как слушателя состояния, инициирует рукопожатие. |
|
||||
| `CATSerial.pas` | Флаг `Andromeda` в конфиге порта + `HasAndromeda` / `SendToAndromeda`. |
|
||||
| `RadioController.pas` | `AddStateListener` — multicast-наблюдатель состояния (push не «ворует» единственный `OnStateChanged`, занятый MainForm). |
|
||||
| `Settings.pas` / `SettingsForm.pas` / `MainForm.pas` | Поле `CATSerialAndromeda[0..3]`, персист, чекбокс на каждом serial-порту. |
|
||||
|
||||
### Потоки
|
||||
- Входящие хэндлеры (`HandleVfoStep/Encoder/Button/Version`) зовутся из потока
|
||||
CAT-транспорта и маршалят действия в поток контроллера через `FController.Invoke`
|
||||
(GUI = `TThread.Synchronize`).
|
||||
- Слушатель состояния и `SendProc` работают из потока, вызвавшего `Changed()`;
|
||||
отправка в порт потокобезопасна (serial `SendStr` под своим локом).
|
||||
|
||||
---
|
||||
|
||||
## 3. Раскладка по умолчанию (AndromedaMap.pas)
|
||||
|
||||
Раскладка **зашита в коде** (первая версия). Правится в `AndromedaMap.pas`.
|
||||
|
||||
### Кнопки (`ZZZP`, индекс 0-based после разбора)
|
||||
| # | Действие | # | Действие |
|
||||
|---|---|---|---|
|
||||
| 0 | MOX | 9 | SNB |
|
||||
| 1 | Tune (TUN) | 10 | Split (TX VFO-B) |
|
||||
| 2 | Band Up | 11 | VFO Swap (актив. A/B) |
|
||||
| 3 | Band Down | 12 | CTUN |
|
||||
| 4 | Mode Up | 13 | Mute |
|
||||
| 5 | Mode Down | 14 | CTCSS |
|
||||
| 6 | NB | 15 | Squelch on/off |
|
||||
| 7 | NR | 16 | Filter Up |
|
||||
| 8 | ANF | 17 | Filter Down |
|
||||
|
||||
### Энкодеры (`ZZZE`, индекс 0-based)
|
||||
| # | Параметр | Шаг |
|
||||
|---|---|---|
|
||||
| 0 | AF Gain (громкость) | ±1 |
|
||||
| 1 | AGC-T | ±1 dB |
|
||||
| 2 | Drive (мощность) | ±1 % |
|
||||
| 3 | Squelch level | ±1 |
|
||||
| 4 | Filter width | ±50 Гц (`AND_BW_STEP_HZ`) |
|
||||
| VFO | энкодер VFO (`ZZZU/ZZZD`) | ±10 Гц/шаг (`AND_VFO_STEP_HZ`) |
|
||||
|
||||
### Индикаторы (`ZZZI`, номера зеркалят дефолт Thetis)
|
||||
| LED # | Индикатор | LED # | Индикатор |
|
||||
|---|---|---|---|
|
||||
| 1 | MOX | 12 | Split |
|
||||
| 2 | ATU Ready *(нет в ewsdr)* | 13 | NB |
|
||||
| 3 | Tune | 14 | NR |
|
||||
| 6 | Shift *(нет)* | 15 | SNB |
|
||||
| 7 | CTUN | 16 | ANF |
|
||||
| 8/9 | RIT/XIT *(нет)* | 17 | Squelch |
|
||||
| 10 | VFO A/B | | |
|
||||
| 11 | VFO Lock *(нет)* | | |
|
||||
|
||||
Драйвятся реально: **MOX, Tune, CTUN, VFO A/B, Split, NB, NR, SNB, ANF, Squelch**.
|
||||
Остальные слоты дефолтной таблицы Thetis (ATU/Shift/RIT/XIT/VFOLock) в ewsdr
|
||||
функций не имеют и не зажигаются.
|
||||
|
||||
---
|
||||
|
||||
## 4. Как включить
|
||||
|
||||
1. Подключить панель как обычный serial CAT-порт (USB).
|
||||
2. Settings → CAT → выбрать нужный Serial Port, поставить **Enable** и параметры
|
||||
порта (скорость и т.д. — как требует панель).
|
||||
3. Поставить галку **«Andromeda / G2 front panel»** на этом порту.
|
||||
4. При применении настроек EWSDR пошлёт `ZZZS;`; панель ответит версией — после
|
||||
этого включается push индикаторов и панель управляет радио.
|
||||
|
||||
Только **один** порт может быть Andromeda-портом (первый помеченный).
|
||||
|
||||
Настройки сохраняются ключами `cat_serial_androm_N` / `ser_androm_N`
|
||||
(N = 0..3) в JSON-конфиге.
|
||||
|
||||
---
|
||||
|
||||
## 5. Что сделано / что осталось
|
||||
|
||||
### Сделано (первая версия)
|
||||
- Транспорт: **serial** (USB CAT).
|
||||
- Вход: `ZZZD/ZZZU` (VFO), `ZZZE` (энкодеры), `ZZZP` (кнопки), `ZZZS` (рукопожатие).
|
||||
- Выход: **`ZZZI`** — LED-индикаторы (push от `OnStateChanged`, дедуп повторов).
|
||||
- Раскладка — зашитый дефолт.
|
||||
- UI-чекбокс на каждый serial-порт + персист.
|
||||
|
||||
### Осталось / возможные улучшения
|
||||
| Задача | Заметки |
|
||||
|---|---|
|
||||
| **`ZZMF`** — текст на LCD мультифункц. энкодера | кодировка: 15 ASCII-символов парами цифр (код−32) |
|
||||
| **TCP-транспорт (G2 V2 panel)** | сейчас только serial; нужен режим в `CATTcp` |
|
||||
| **Настраиваемая раскладка** | сейчас зашита; вынести в конфиг/UI (как `AndromedaEditForm` в Thetis) |
|
||||
| **Long-press кнопок** | принимается (`ZZZP` state=2), но действий пока нет — обрабатывается только нажатие (state=1) |
|
||||
| **Индикаторы RIT/XIT/PureSignal/Diversity/ATU** | нет соответствующих функций в `TRadioController` |
|
||||
| **Мультифункц. энкодер (`aeMulti`)** | назначение не задано |
|
||||
|
||||
---
|
||||
|
||||
## 6. Точки расширения (чек-лист)
|
||||
|
||||
- **Добавить действие кнопки/энкодера:** новый элемент в `TAndButton`/`TAndEncoder`
|
||||
(AndromedaMap.pas) + ветка в `TAndromedaPanel.SyncButton`/`SyncEncoder`
|
||||
(AndromedaPanel.pas) + правка таблицы `AND_BUTTON_MAP`/`AND_ENCODER_MAP`.
|
||||
- **Добавить индикатор:** элемент `TAndIndicator` + номер в `AND_INDICATOR_NUM` +
|
||||
push в `SyncAllIndicators` и в `OnControllerState` (по нужному `rf*`-полю).
|
||||
- **Изменить раскладку:** только `AndromedaMap.pas` (таблицы-константы).
|
||||
- Сверяться с форматами Thetis: `Andromeda/Andromeda.cs` (логика панели,
|
||||
`EIndicatorActions`/`EButtonBarActions`/`EEncoderActions`) и
|
||||
`CAT/CATCommands.cs` (`ZZZ*`).
|
||||
Reference in New Issue
Block a user