# 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-контроллер не изменены.