Esc Protocols Am32

Обновлено: 2026-11-12
На этой странице

ESC-протоколы: 4-way interface, EEPROM AM32 и BLHeli_S/Bluejay — факты для тулы

Статус: research / discovery + фактическая база, используемая кодом (web/static/js/tools/esc_fourway.js + web/static/js/tools/esc_blheli.js, AD-1066). Документ фиксирует, откуда взяты протокольные факты, где проходит граница уверенности и что НЕ реализовано (честность важнее охвата). Лицензионный анализ и решение — в ADR docs/adr/ad-856-esc-clean-room.md.

1. Clean-room и источники

Код кодека написан с нуля по открытым описаниям (без копирования GPL/AGPL):

  • 4-way interface — спецификация интерфейса BLHeliSuite (описание кадров, команд, ACK-кодов; опубликована в дистрибутиве BLHeliSuite, https://github.com/bitdump/BLHeli) и вики Betaflight «4 way interface».
  • MSP-вход в passthrough — открытые таблицы MSP INAV/Betaflight: MSP_SET_4WAY_IF / MSP_SET_PASSTHROUGH = 245; без payload = переход в 4-way, ответ — 1 байт (число выходов ESC), после ответа порт полётного контроллера говорит на протоколе 4-way до команды InterfaceExit.
  • BLHeli_S/Bluejay EEPROM — опубликованные исходники самих прошивок как первоисточник формата данных; поимённый список файлов и что из каждого взято — § 5.1 (AD-1070).
  • AM32 — открытая документация проекта (https://github.com/am32-firmware/AM32, https://am32.ca): раскладка блока настроек, адреса блока по таргетам, формулы производных величин.

2. Протокол 4-way interface (реализовано)

запрос : 0x2F cmd addr_hi addr_lo len params[len] crc_hi crc_lo
ответ  : 0x2E cmd addr_hi addr_lo len params[len] ack crc_hi crc_lo
  • len == 0 означает 256 байт параметров; «без параметров» не бывает — кодируется один dummy-байт 0x00 (len=1);
  • CRC — CRC16/XMODEM (poly 0x1021, init 0), от стартового байта включительно; в ответе ack входит в CRC; на проводе — big-endian;
  • device info (ответ DeviceInitFlash) — 4 байта: [sig_lo, sig_hi, метка bootloader-сообщения, режим интерфейса];
  • режимы интерфейса: 0 SiLabs C2, 1 SiLabs BLB (BLHeli_S), 2 Atmel BLB, 3 Atmel SK, 4 ARM BLB (AM32).

Реализованное подмножество команд (v1 read-only): InterfaceTestAlive 0x30, ProtocolGetVersion 0x31, InterfaceGetName 0x32, InterfaceGetVersion 0x33, InterfaceExit 0x34, DeviceReset 0x35, DeviceInitFlash 0x37, DeviceRead 0x3A. Команды записи/стирания (0x38, 0x39, 0x3B, 0x3E и др.) сознательно не реализованы — инвариант v1, закреплён тестом.

3. EEPROM AM32 (реализовано, с границей уверенности)

  • Блок настроек лежит во флеше по фиксированному смещению таргета: 0x7C00 (классические 32К-таргеты: STM32F051, AT32F421 и др.) или 0xF800 (таргеты с большим флешем, например G071). Оба адреса влезают в 16-битное поле адреса кадра. Тула пробует адреса по порядку и принимает блок только после валидации формы (looksLikeAm32Eeprom: правдоподобная версия прошивки + читаемое имя таргета; иначе — только сырой дамп).
  • Читается 48 байт — документированная зона настроек.
  • Разбираемая раскладка (байты): 0 boot byte, 1 версия EEPROM-раскладки, 2 версия загрузчика, 3/4 версия прошивки (major/minor), 5–16 имя таргета (12 ASCII), 17–45 — настройки (полный список с идентификаторами — в AM32_SETTINGS_LAYOUT, web/static/js/tools/esc_fourway.js).
  • Производные величины показываются только там, где формула документирована: timing advance = байт × 7.5°, KV = байт × 40 + 20, порог ячейки = (байт + 250)/100 В, лимит тока = байт × 2 А, серво-пороги (×2+750 / ×2+1750 / +1374 мкс). Сырой байт показывается всегда.
  • Байты 46+ и любые поля вне списка не разбираются — видны только в HEX-дампе (принцип «не выдумываем»).

4. Телеметрия (реализовано частично)

  • RPM через полётный контроллер: MSP2 INAV_ESC_RPM = 0x2040 (INAV с esc-sensor), ответ — по u32 LE RPM на мотор. Прошивка без esc-sensor отвечает MSP-ошибкой → тула честно показывает «недоступно».
  • KISS/AM32-телеметрия по сигнальному проводу (температура/напряжение/ток) в режиме passthrough недоступна (регулятор в загрузчике, не в рабочей прошивке) — кандидат на v2 через MSP-каналы полётного контроллера (Betaflight MSP_ESC_SENSOR_DATA = 134, INAV MSP2_INAV_ESC_TELEM).

5. BLHeli_S/Bluejay — детект и чтение настроек

web/static/js/tools/esc_blheli.js классифицирует регулятор по ОТВЕТУ DeviceInitFlash (те же факты, что в § 2 — режим интерфейса 0..4):

  • режим интерфейса 1 (SiLabs BLB) покрывает и BLHeli_S, и Bluejay — обе прошивки используют один и тот же бутлоадер/интерфейс на SiLabs EFM8-микроконтроллерах;
  • режимы 2/3 (Atmel BLB/SK) — легаси 8-бит BLHeli на AVR;
  • режим 0 (SiLabs C2) — отладочный интерфейс, не BLHeli-бутлоадер.

Легаси Atmel и SiLabs C2 по-прежнему только ОПОЗНАЮТСЯ: открытого описания их блока настроек у нас нет. SiLabs BLB (BLHeli_S/Bluejay) с AD-1070 читается полностью.

5.1. Источники раскладки

Раскладка EEPROM — это ФОРМАТ ДАННЫХ, и первоисточник формата у BLHeli_S и Bluejay один: их собственные опубликованные исходники прошивки. Решение основателя по AD-1070 — брать факты формата оттуда и ссылаться на источник в коде; clean-room-дисциплина ADR ad-856-esc-clean-room.md при этом не меняется: КОД пишется с нуля, из GPL/AGPL-проектов не копируется ни строки, и конфигураторы (esc-configurator.com — AGPL-3.0, BLHeliSuite) не используются как источник вовсе. Точные места процитированы в шапке esc_blheli.js:

Метка Файл Что взято
[S1] BLHeli_S SiLabs/BLHeli_S.asm (github.com/bitdump/BLHeli) порядок меток Eep_* = смещения; комментарии к DEFAULT_PGM_* = перечисления и формулы; EEPROM_LAYOUT_REVISION EQU 33
[S2] src/Bluejay.asm (github.com/bird-sanctuary/bluejay) своя последовательность Eep_*; EEPROM_LAYOUT_REVISION EQU 208
[S3] src/Settings/BluejaySettings.asm (там же) комментарии к DEFAULT_PGM_* Bluejay: диапазоны и формулы
[S4] src/Modules/Codespace.asm (там же) CSEG_EEPROM/CSEG_NAME по типам МК: 0x1A00 (EFM8BB1/BB21) и 0x3000 (EFM8BB51), имя — по +0x60

5.2. Что разбирается и что нет

  • Адрес блока настроек подбирается перебором [0x1A00, 0x3000] с валидацией формы — тот же приём, что у AM32 (§ 3). Читается 0x70 байт: блок настроек (0x00..0x2A) и зона имени (+0x60), одним DEVICE_READ.
  • Валидация формы — сигнатура «EEPROM инициализирован» (0x55 по 0x0D, 0xAA по 0x0E, [S1]/[S2]) плюс известная ревизия раскладки в байте 0x02.
  • Ревизия раскладки — гейт разбора, а не подсказка. 33 → таблица BLHeli_S, 208 → таблица Bluejay, любая другая → разбор НЕ выполняется, UI показывает ревизию и сырой дамп. Раскладка отличается между версиями прошивки, и «похоже подходит» здесь означает молча наврать; неверно распарсенная настройка выглядит достовернее, чем её отсутствие.
  • Bluejay — отдельная таблица, не «BLHeli_S плюс поля». Он занял байты, свободные в BLHeli_S (0x04 STARTUP_POWER_MIN, 0x05 STARTUP_BEEP, 0x07 STARTUP_POWER_MAX, 0x0A PWM_FREQUENCY, 0x10 BRAKING_STRENGTH), и освободил занятые им (0x19/0x1A MIN/MAX_THROTTLE, 0x21 CENTER_THROTTLE, 0x24 LOW_RPM_POWER_PROTECTION). Инвариант держит tests/test_esc_blheli.js.
  • НЕ разбирается намеренно: байты, объявленные в первоисточниках неиспользуемыми (_Eep_* = 0FFh); зоны +0x40 (layout tag) и +0x50 (MCU tag) — адреса документированы [S4], но содержимое пишет инструмент прошивки, открытого описания формата нет; точная формула Bluejay STARTUP_POWER_MAX — [S3] задаёт только диапазон, поэтому поле показывается сырым числом; назначение бит LED_CONTROL и SAFETY_ARM — только HEX. Значение, которого нет в документированном перечислении, показывается ЧИСЛОМ, а не ближайшим по смыслу вариантом.
  • Запись по-прежнему невозможна (инвариант AD-856): парсер только читает, функции обратной сериализации настроек в байты нет и заводить её нельзя — ошибка парсера при записи выводит регулятор из строя.

6. Не реализовано / отложено (v2+)

  • запись настроек AM32 и прошивка (write/erase/verify) — отдельное решение основателя, новый класс риска;
  • запись настроек BLHeli_S/Bluejay — тот же класс риска, отдельное решение;
  • легаси BLHeli на Atmel (BLB/SK) и SiLabs C2: блок настроек не разбирается — открытого описания их раскладки у нас нет (детект есть, см. § 5);
  • BLHeli_32 — NO-GO навсегда (закрытый протокол, лицензионная программа остановлена);
  • карта «сигнатура MCU → таргет/размер флеша»: в открытых источниках есть таблицы соответствий, но мы их не проверяли на железе — v1 показывает сигнатуру hex как есть и подбирает адрес EEPROM (для AM32) перебором с валидацией;
  • прямое подключение USB-UART к сигнальному проводу (без полётного контроллера) — осознанно вне v1 (дефолт основателя: только passthrough).

7. Проверка на железе

Кодек и разбор покрыты юнит-тестами (tests/test_esc_fourway.js — CRC-вектор, кадры, синтетический EEPROM AM32; tests/test_esc_blheli.js — классификация семейства прошивки по всем 5 режимам интерфейса (AD-1066) и разбор синтетического блока настроек BLHeli_S/Bluejay: обе ревизии раскладки, отказы too_short/not_initialized/unsupported_layout, формулы по трём точкам каждая (AD-1070)), но на реальном AM32- или BLHeli_S-регуляторе ещё не прогонялся — тула помечена «предальфа». Синтетический тест доказывает, что код читает ТЕ байты, которые описаны в источнике, но не то, что источник описывает конкретный экземпляр регулятора: первый прогон на железе остаётся обязательным. С AD-1066 инструмент включён по умолчанию фича-флагом esc_tools (решение основателя, /admin/flags может выключить конкретное окружение). Первый прогон на реальном железе (обеих семейств) остаётся обязательным шагом перед снятием пометки «предальфа».