INAV: возможности конкретных плат — справочник для board-aware (AD-705)
Статус: research / discovery + фактическая база данных, используемая кодом
(web/static/js/tools/inav_boards.js). Документ обосновывает, откуда взяты
байтовые/пиновые факты справочника, и фиксирует, что именно НЕ реализовано и
почему (честность важнее охвата).
0. Зачем это нужно
Фаза 1 (AD-705) — план: тула /tools/inav-connect должна знать возможности
КОНКРЕТНОГО подключённого борта (LED-пад, выделенный видео/камера-свитч,
реально обнаруженные сенсоры) и ненавязчиво подсказывать, как их применить.
Модель разрешения — 3 яруса: живой MSP-сигнал → статический справочник
плат → честный null («не знаем»). Этот документ — источник фактов для яруса
2 (справочник) и обоснование, почему часть яруса 1 (живые MSP-каналы)
отложена.
1. Источники и clean-room
Исходники INAV (github.com/iNavFlight/inav, ветка master, 9.1.0-dev,
получено 2026-07-20) читались ТОЛЬКО ради фактов: номера пинов
(PINIO*_PIN, WS2811_PIN), короткий идентификатор платы
(TARGET_BOARD_IDENTIFIER), наличие фич компиляции (USE_LED_STRIP,
USE_SDCARD), дефолтный box PINIO (pinioBoxConfigMutable()->permanentId[N]
в config.c каждого таргета). Это данные протокола/аппаратной конфигурации,
не творческий код — GPLv3-исходники INAV/INAV Configurator в наш репозиторий
не копировались; сами записи справочника и код lookupBoard/
resolveCapability написаны заново.
2. MSP2_INAV_STATUS (0x2000) — байтовый макет
Источники: src/main/fc/fc_msp.c (case MSP2_INAV_STATUS, сериализация
ответа) и src/main/fc/fc_msp_box.c (packSensorStatus() — раскладка
битовой маски сенсоров, используется И MSP_STATUS/MSP_STATUS_EX, И
MSP2_INAV_STATUS).
Поля ответа по порядку (наш кодек читает только первые три u16):
| Смещение | Поле | Тип | Комментарий |
|---|---|---|---|
| 0 | cycleTime |
u16 LE | не используется тулой |
| 2 | i2cErrorCounter |
u16 LE | не используется тулой |
| 4 | sensorStatus |
u16 LE | читаем — маска обнаруженных сенсоров |
| 6 | averageSystemLoadPercent |
u16 LE | не используется |
| 8 | profileByte |
u8 | (batteryProfile<<4)\|profile, не используется |
| 9 | armingFlags |
u32 LE | не используется |
| 13.. | boxModeFlags |
переменной длины (растёт между версиями) | не используется, поэтому mixerProfile в самом хвосте НЕ читаем — его смещение зависит от длины этого поля |
packSensorStatus() (fc_msp_box.c):
bit0 = ACC, bit1 = BARO, bit2 = MAG, bit3 = GPS, bit4 = RANGEFINDER,
bit5 = OPFLOW, bit6 = PITOT, bit7 = TEMP, bit15 = аппаратный сбой (!isHardwareHealthy())
Gyro отдельным битом НЕ кодируется — по конвенции протокола считается всегда
присутствующим (SENSOR_GYRO = 1 << 0, // always present в sensors.h,
внутренний enum, не совпадает с битами packSensorStatus()).
Реализация: parseInavStatus() в web/static/js/tools/inav_msp.js —
короче 6 байт (3×u16) → null (честная деградация, не «сенсоров нет»).
3. MSP2_INAV_OUTPUT_MAPPING_EXT2 (0x210D) — ОТЛОЖЕНО
Канал обещал бы ярус 1 (живой сигнал) для «физический LED-пад по
timer-слоту pinLabel==PIN_LABEL_LED» — board-agnostic сигнал вместо
справочника. Не реализован в Фазе 2: byte-layout serialize-функции для
этой команды не удалось вывести с уверенностью из публичного fc_msp.c без
риска угадывания (в отличие от MSP2_INAV_STATUS, где packSensorStatus()
цитируется в самом файле fc_msp_box.c). Гадать по битам — то же самое, что
уже сознательно отвергнуто для LED legacy MSP_LED_STRIP_CONFIG (AD-703,
см. docs/tools/inav-connect.md § LED). Честность важнее охвата: пока канал
не проверен на реальном источнике/железе, ярус 1 для ledPad/vsw пуст,
разрешение падает на ярус 2 (справочник).
4. Справочник плат — таблица фактов
Для каждой платы: TARGET_BOARD_IDENTIFIER (короткий код MSP), WS2811_PIN
(LED-пад), PINIO*_PIN + дефолтный permanentId (видео/камера-свитч),
USE_SDCARD. Источник каждой строки — файл target.h/config.c таргета в
src/main/target/<TARGET>/ (ссылки — в самом справочнике,
web/static/js/tools/inav_boards.js, поле source).
| Плата (key) | boardId | WS2811 (LED-пад) | PINIO1 (VSW) | PINIO2 (camera) | SD | Заметка |
|---|---|---|---|---|---|---|
MATEKH743 |
H743 |
PA8 |
PD10, box USER1 |
PD11, box USER2 |
да | — |
MATEKF405SE (aka F405-WING) |
MF4S |
PA15 |
PC6, box USER1 |
PC7, box USER2 |
да | PINIO собран ТОЛЬКО в firmware-варианте MATEKF405SE_PINIO (#ifdef); базовая прошивка держит те же пины как обычный UART6 TX/RX. TARGET_BOARD_IDENTIFIER/USBD_PRODUCT_STRING у ОБОИХ вариантов одинаковые — MSP не различает |
MATEKF405TE |
MF4T |
PB1 |
PA4, box USER1 |
PB5, box USER2 |
нет (SD — отдельный firmware-вариант MATEKF405TE_SD, не моделируем) |
— |
MATEKF722SE (aka F722-WING) |
MF7S (MINI-вариант — MF7M) |
PA8 |
PC8, box USER1 |
PC9, box USER2 |
нет в записи (не проверяли отдельно) | PINIO собран безусловно — общий для SE/MINI |
SPEEDYBEEF405WING |
SP4W |
PA8 |
PC13, box USER1 |
— (один PINIO) | да | — |
SPEEDYBEEF405V3 |
SB43 |
PC9 |
PC3, box USER1 (свободен) |
— | да | — |
SPEEDYBEEF405V4 |
SB44 |
PA8 |
PB11, box BOXARM по умолчанию |
— | не проверяли | ⚠ В отличие от V3, config.c V4 назначает permanentId[0] = BOXARM — пин физически тот же (video-switch по схеме), но не свободен под USER1. Справочник НЕ заявляет vsw доступным на V4 (см. caveats) |
5. Решение про vsw на SPEEDYBEEF405V4
Пин PB11 физически совпадает с назначением VSW на V3, но targetConfiguration()
в config.c V4 явно ставит pinioBoxConfigMutable()->permanentId[0] = BOXARM
(не BOX_PERMANENT_ID_USER1, как у всех остальных 6 плат справочника). Если бы
справочник заявил static.vsw доступным, движок рекомендаций посоветовал бы
использовать пин как видео-свитч — а по факту переключение этого пина
арм/дизармит борт. Решение: static.vsw для V4 не задан (запись не
проходит правило vsw-available), физика и предупреждение — в caveats[].
6. Что дальше (вне Фазы 2)
- Проверить
MSP2_INAV_OUTPUT_MAPPING_EXT2(0x210D) на реальном источнике
(например, собрав INAV из исходников и залогировав фактический ответ) —
тогда можно включить ярус 1 дляledPad/vswбез справочника. - Добавить недостающие популярные платы (Matek F411-й ряд, iFlight, Mamba) —
тот же процесс:target.h/config.cконкретного таргета → факты → запись
сsource/verified/confidence.