buildGateRuns/buildPhysicalGateRuns крутили автомат передачи по одному такту (пинг 10 байт =
8728 тактов) — на 12 МГц это ~30 мс между вызовом send и стартом DMA, на каждой передаче
(задний ~20 мс). Обход по границам (txWalkRuns: ран = toggleCounter+1 тактов уровня state)
даёт ту же последовательность за число шагов = число ранов (225). Эквивалентность проверена на
хосте: 12480 случаев, len 1..38, множитель 2..8, логические и физические раны совпадают
бит-в-бит (len=39 — чтение за буфером в sync-фазе автомата у обеих версий, на эфире ≤31).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AeA1K5dBUKrnoXVwyoVjzq
Для гейта заднего у машинки (Даша 04.09): держать задний по СОСТОЯНИЮ приёма, но
не дольше airtime кадра — а если объявленный в 1-м байте размер МЕНЬШЕ протокольного
максимума, то ровно до его конца (усиление надёжности). rxDeclaredPackSize() =
packSize из 1-го байта, если валиден (не битый) и идёт приём, иначе 0 (потребитель
берёт rxMaxPackSize() — до CRC значение недоверенное). packAirtimeMs() — публичная
обёртка над calculateSendTime (чистая функция протокольных констант, годна и для RX).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J3Ca6J2JJ1NrptqQjKs8BK