Добавить протокол Altera Logic и общие клиенты прошивки

This commit is contained in:
2026-09-19 07:12:09 +03:00
parent def3eb08f3
commit 80ba17d77d
38 changed files with 3271 additions and 10 deletions

View File

@@ -0,0 +1,189 @@
# Altera Logic — ONLINE через SETCAN / GAS / UART
Версия профиля: **1**. Реализация, порты и тесты принадлежат `templates`.
Это профиль существующего classic SETCAN/ProtoCAN с 29-битным ID;
он не подменяется кадром SETP v2 и не использует старые команды `A5 CMD` FPGA.
## Адрес и носители
| Поле | Значение |
|---|---|
| Priority | 1, стандартный |
| Route | 1, от устройства |
| DeviceType | `0x6` |
| DeviceID | `0xE` |
| Device Name | `Altera Logic` |
| MsgType | `0x3`, GAS |
| CAN | Extended ID, data frame, DLC=8 |
CAN доставляет ID + 8 байт непосредственно. UART доставляет ровно тот же ID
и те же данные в существующем контейнере `pcan_frame`:
```text
AA 55 | LEN | SEQ | FLAGS | CAN_ID u32 LE | DATA | CRC16 u16 LE
```
Для этого профиля LEN=14, FLAGS=1 (IDE), DIR/RTR/ERR сброшены,
итоговая длина 19 байтов. CRC-16/CCITT-FALSE считается существующим кодеком
по LEN…DATA. SEQ — транспортный 8-битный счётчик; порядок выборок определяется
полем SampleIndex, поэтому независимые CAN/UART потоки дают одинаковый результат.
Предоставленные простые C-билдеры устанавливают SEQ=0; устройство может вести
его самостоятельно, используя `pcan_frame_encode`.
Настройки прямого UART-порта GUI: **921600, 8N1, без flow control**.
## GAS: метаданные потока
**CAN ID `0x1EE3FE00`, MsgBody/GAS address `0xFE00`, DLC=8.**
| Регистры GAS | Байты DATA | Поле |
|---|---|---|
| FE00 | 0…1 | Tag/version = `0x4C01` |
| FE01 | 2…3 | SessionID u16 |
| FE02…FE03 | 4…7 | SamplePeriodNs u32, строго больше 0 |
Порядок байтов little-endian. Число каналов профиля фиксировано: 16.
Частота выборок = `1e9 / SamplePeriodNs`.
Пример сессии 1 с частотой 1000 выборок/с:
```text
ID: 1EE3FE00
DATA: 01 4C 01 00 40 42 0F 00
```
Источник отправляет метаданные перед первой выборкой и повторяет примерно
раз в секунду, чтобы подключившийся GUI мог присоединиться к потоку.
Повтор с теми же SessionID/периодом историю не очищает.
При перезапуске потока или изменении периода источник увеличивает SessionID
по модулю 65536. Новый SessionID очищает историю; задержанные метаданные
предыдущей сессии игнорируются. Разница менее 32768 считается движением вперёд.
Если после аппаратного сброса устройство начало счётчик с меньшего значения,
нужно остановить и снова включить приём в GUI (либо сохранять счётчик сессий
на устройстве). Без полученных метаданных отсчёты не отображаются.
## GAS: одна выборка всех 16 каналов
**CAN ID `0x1EE3FF00`, MsgBody/GAS address `0xFF00`, DLC=8.**
| Регистры GAS | Байты DATA | Поле |
|---|---|---|
| FF00 | 0…1 | SessionID u16, должен совпадать с метаданными |
| FF01 | 2…3 | Sample u16: бит n = уровень канала Dn |
| FF02…FF03 | 4…7 | SampleIndex u32 |
Пример: сессия 1, выборка 0, D0 и D15 равны 1:
```text
ID: 1EE3FF00
DATA: 01 00 01 80 00 00 00 00
```
SampleIndex увеличивается на каждой аппаратной выборке, в том числе если
пакет не удалось передать. GUI замечает скачок индекса, учитывает потерянные
выборки и рисует разрыв, не соединяя его выдуманными состояниями.
Время получается из индекса и периода устройства, а не из времени прихода UART.
Переполнение индекса u32 разворачивается в u64 на приёмнике. Однозначное
восстановление порядка требует разрыва меньше 2^31 выборок. При более долгом
перерыве следует начать новую сессию. При подключении после полного оборота
индекса GUI не знает число оборотов до первой принятой выборки.
Одновременный CAN+UART приём объединяет один поток: одинаковые или запоздалые
индексы в одной сессии не добавляются повторно. Их число показывается как
«дубли/старые». Поздние данные старой сессии игнорируются по SessionID.
Если два источника прислали разные значения с одинаковыми SessionID/индексом,
остаётся первый принятый пакет: это не механизм голосования или сверки каналов.
## Нагрузка и история
Профиль передаёт одну 16-битную выборку на CAN-кадр. Это осознанный обмен
пропускной способности на независимую проверку сессии, потерь и дублей.
Начальный профиль для устройства — 1000 выборок/с.
На UART при 921600 бод и 19 байтах × 10 бит на пакет теоретический потолок
составляет около 4850 выборок/с, без учёта метаданных и пауз. Для непрерывной
передачи 50 Мвыб/с этот транспорт не подходит. Высокоскоростной буферный
захват остаётся отдельным режимом.
Общая C-история ограничена 8192 последними принятыми выборками. Старые данные
вытесняются; полный длительный архив в этом режиме не ведётся. GUI обновляет
экран не чаще 20 раз в секунду. Пауза фиксирует показанное окно, но приём
продолжается. CSV сохраняет текущее окно с индексами, временем и признаками разрывов.
## API для прошивки / порта
### Маркеры в ONLINE GUI
Колесо внутри графика прокручивает его по X (влево/вправо), Ctrl + колесо —
по Y (вверх/вниз), не меняя масштаб. Когда вся ось помещается в окно,
прокрутка этой оси не требуется. После ручной прокрутки X автоматический
переход к концу потока отключается до сброса масштаба.
Qt-порт этой обработки: `python/altera_logic/plot_scroll.py`.
Масштабирование внутри графика: зажать ЛКМ и двигать вправо/влево для X;
Ctrl + ЛКМ и движение вверх/вниз — для Y. Начальная точка остаётся на месте
в видимой области. Масштаб X: 1…16, Y: 1…8. «Сброс масштаба» возвращает
обе оси к 1. ЛКМ за линию маркера перемещает маркер; Ctrl отдаёт приоритет
масштабу Y. Обычный клик устанавливает выбранный маркер, если он включён.
При увеличении Y растягиваются дорожки цифровых каналов, не изменяются
измеренные значения. Прокрутка позволяет просматривать увеличенную область.
Две пары X1/X2 и X3/X4 включаются независимо и показывают время каждого
маркера, знаковый интервал Δt = X2 X1 (либо X4 X3) и f = 1/|Δt|.
При совпадении маркеров частота отображается как «—». Это обратный интервал,
а не автоматическое определение частоты сигнала.
Две пары Y1/Y2 и Y3/Y4 включаются независимо, показывают оба положения и
знаковую ΔY в процентах высоты графика (это не измерение напряжения).
Панель измерений построена по примеру AndroidGUI: отдельная строка для каждой
пары и ползунок выбранного маркера. dB для цифровых дорожек не вычисляются.
Разности вычисляет общий C-код `set_plot.c` через `protocan.plot.PlotMath`,
тот же код используется Android-портом.
Линии можно перетаскивать мышью; список «Установить кликом» выбирает маркер
для установки в любой точке. Режим «Курсор» возвращает обычный просмотр выборок.
Снятие галочки скрывает линии, сохраняя их позиции. «Маркеры в окно» возвращает
их в текущую область. Для измерения неподвижного фрагмента включите паузу.
X сохраняет положение во времени при обновлении истории и может уйти за окно;
новая сессия устанавливает начальные позиции. Визуальная модель находится
в `python/altera_logic/markers.py`, обработка мыши и рисование — в SETGUI.
`c/set-protocol/include/altera_stream.h` экспортирует:
- `las_metadata` — общий билдер метаданных для CAN либо UART;
- `las_data` — общий билдер выборки для CAN либо UART;
- `las_can` / `las_uart` — два входа одного декодера и истории;
- `las_snapshot` — хронологический снимок с индексами и разрывами;
- `las_get` — диагностика: потери, дубли, неправильные кадры, CRC.
Пример формирования одной выборки для CAN, без HAL-зависимостей:
```c
#include "altera_stream.h"
uint8_t bytes[32];
uint32_t id;
size_t size;
/* SessionID=1, период=1 мс. CAN-драйверу передаются id и size байт. */
size = las_metadata(LAS_DEVICE_ID, 1, 1000000, 0, &id, bytes, sizeof(bytes));
/* board_can_send_extended(id, bytes, size); */
size = las_data(LAS_DEVICE_ID, 1, 0, 0x8001, 0, &id, bytes, sizeof(bytes));
/* board_can_send_extended(id, bytes, size); */
/* Для UART последний флаг носителя заменить с 0 на 1:
билдер вернёт полный пакет AA55, который передаётся в UART без изменений. */
```
Драйвер платы должен передавать каждый пакет полностью и сохранять порядок,
периодически публиковать метаданные и увеличивать SampleIndex даже при потере
пакета в своей очереди. CAN-контроллер и трансивер остаются аппаратным портом.
## Размещение реализации и границы
- `templates/c/set-protocol/src/altera_stream.c`: протокол и кольцевая история.
- `templates/python/altera_logic/stream.py`: тонкий ctypes-порт и CSV-модель.
- `templates/python/altera_logic/stream_port.py`: Qt UART/CAN-приём и жизненный цикл.
- SETGUI: только визуальная вкладка и подключение к существующему CAN-источнику.
Текущий FPGA RTL с протоколом `A5 CMD` не становится SETCAN-источником от
обновления GUI. Нужен передатчик этого профиля в прошивке/RTL либо внешний
мост, который получает реальные выборки и публикует их в описанном формате.
В этой версии реализованы GUI-приёмник, общие C-билдеры для устройства и
демопроизводитель; FPGA RTL и физический CAN-контроллер не изменены.

View File

@@ -0,0 +1,21 @@
# Реестр адресов SETCAN
Дополнения к исходной таблице `Протокол CAN и ОАП.xlsx` фиксируются здесь.
Числовая раскладка CAN ID не меняется: DeviceType — 3 бита, DeviceID — 4 бита.
Device Name — отображаемое имя адреса, а не дополнительное поле CAN ID.
| DeviceType | DeviceID | Device Name | Назначение |
|---|---|---|---|
| `0x0` | существующие | Верхний уровень | Существующие адреса исходной таблицы |
| `0x6` | `0xE` | **Altera Logic** | Онлайн-анализатор 16 цифровых каналов |
| `0x7` | `0xD` | configurator | Существующий конфигуратор |
| `0x7` | `0xF` | KONOR / SETTINGS | Существующий профиль SETCAN и привязка датчиков |
Для Altera Logic выбран предпоследний тип `0x6` и предпоследний экземпляр `0xE`:
эта пара не была назначена в проверенных локальных таблицах и исходниках.
Тип `0x7` уже используется. Наличие другого физического узла с тем же адресом
на конкретной шине нужно исключить при вводе в эксплуатацию.
Числовые константы устройства: `c/set-protocol/include/altera_stream.h`.
Отображаемые имена: `python/protocan/protocan.py`.
Контракт потока: [ALTERA_LOGIC_STREAM.md](ALTERA_LOGIC_STREAM.md).

View File

@@ -32,3 +32,7 @@
Для пересборки HTML запустите `doc/setcan/build-html.bat` из корня
репозитория `templates`.
# Расширение Altera Logic
- [Реестр устройств SETCAN](DEVICE_REGISTRY.md).
- [ONLINE-поток Altera Logic через GAS и UART](ALTERA_LOGIC_STREAM.md).