Помехоустойчивое кодирование DMR: BPTC, Trellis, Golay и Reed-Solomon
В DMR почти половина эфирного времени тратится не на голос, а на защиту от ошибок. Именно поэтому цифровая связь держится там, где аналог уже шипит, и обрывается резко, а не постепенно. Разберём, какие коды где стоят, зачем биты перемешивают по формуле и почему без масок CRC приёмник отбрасывает правильные кадры.
Из чего состоит бёрст
Единица передачи — бёрст длиной 264 бита (33 байта), это 27,5 мс эфира в своём таймслоте. Внутри он выглядит так:
- первая половина полезных данных — 98 бит;
- 10 бит Slot Type;
- 48 бит синхронизации либо встроенная сигнализация (EMB плюс фрагмент Link Control);
- ещё 10 бит Slot Type;
- вторая половина данных — 98 бит.
Для голоса две половины по 108 бит несут три кадра AMBE+2 по 72 бита. Для данных обе половины склеиваются в одно кодовое слово на 196 бит — то самое BPTC.
BPTC(196,96): матрица, которую перемешивают по формуле
Block Product Turbo Code — основной код для данных и сигнализации. Работает он так:
- 96 информационных бит раскладываются в матрицу 9 строк на 11 столбцов, добавляются три нулевых резервных бита — получается 99.
- Каждая строка защищается кодом Хэмминга (15,11,3), каждый столбец — Хэмминга (13,9,3). Один и тот же бит оказывается прикрыт дважды, с двух направлений.
- Биты нумеруются слева направо и сверху вниз, добавляется ещё один нулевой бит — итого ровно 196.
- Всё это перемешивается по формуле новый индекс = старый × 181 mod 196.
Смысл перемешивания в том, что помеха в эфире почти всегда групповая: замирание бьёт подряд идущие биты. После интерливинга соседние по времени биты оказываются в разных строках и столбцах матрицы, и каждый из кодов Хэмминга видит одну-две ошибки вместо пачки — а с этим он справляется.
Trellis 3/4: код для скоростных данных
Для режима rate ¾ применяется решётчатый (trellis) код: на вход идут 48 трибитов (144 бита) плюс один нулевой трибит на «промывку» регистра, на выходе — 98 дибитов. Кодер — автомат на восемь состояний, у которого есть удобное свойство: текущий вход сразу становится следующим состоянием. Дибиты отображаются в четыре уровня ±1 и ±3, после чего тоже перемешиваются по своей таблице.
При деинтерливинге важна одна тонкость: индексы после 98-го смещаются на 68 — ровно на длину середины бёрста, где живёт синхронизация. Забыли смещение — получите мусор на второй половине.
Golay(20,8): как рация узнаёт тип бёрста
Slot Type — это всего 8 информационных бит: 4 бита Color Code и 4 бита типа данных. Но именно от них зависит, как трактовать весь остальной кадр, поэтому защищены они сильно: код Голея, укороченный из классического (23,12,7) до (20,8). Восемь бит превращаются в двадцать.
Про Color Code и то, что бывает при несовпадении, есть отдельная статья — Color Code на пальцах.
Reed-Solomon(12,9) и Link Control
Полный Link Control — 72 бита (9 октетов): кто говорит, кому, групповой вызов или приватный. Он защищён кодом Рида-Соломона (12,9,4) над полем GF(2⁸): к девяти октетам добавляются три октета проверки.
И вот здесь начинается то, что ломает большинство самодельных декодеров.
Маски CRC: зачем портить правильную сумму
После вычисления контрольной суммы её складывают по модулю два с маской, зависящей от типа данных. На приёме — то же самое в обратную сторону. Маски такие:
| Тип данных | Маска |
|---|---|
| Voice LC Header | 0x969696 |
| Terminator with LC | 0x999999 |
| PI Header | 0x6969 |
| CSBK | 0xA5A5 |
| MBC Header | 0xAAAA |
| Data Header | 0xCCCC |
| Unified Single Block Data | 0x3333 |
| Rate ½ Data Continuation | 0x0F0 |
| Rate ¾ Data Continuation | 0x1FF |
| Rate 1 Data Continuation | 0x10F |
| Reverse Channel | 0x7A |
Зачем так? Маска работает как «подпись типа». Приёмник, ожидающий заголовок голосового вызова, снимает маску 0x969696 — и если пришёл на самом деле терминатор, сумма не сойдётся, и кадр будет отброшен вместо ошибочной интерпретации. Дешёвая защита от рассинхрона: проверка типа получается бесплатно, поверх уже существующего CRC.
Сводная таблица: где какой код
| Поле | Размер | Защита |
|---|---|---|
| Синхронизация | 48 бит | шаблон, коррекции нет |
| Slot Type | 8 → 20 бит | Голей (20,8) |
| EMB | 7 → 16 бит | квадратичных вычетов (16,7,6) |
| Встроенный Link Control | 72 → 128 бит | BPTC переменной длины + CRC |
| Полный Link Control | 72 бита + 3 октета | Reed-Solomon (12,9,4) |
| Данные и CSBK | 96 → 196 бит | BPTC(196,96) |
| Данные rate ¾ | 144 → 196 бит | Trellis 3/4 |
| Реверсивный канал | 11 → 32 бита | BPTC(32,11) |
| Голос | 3 × 72 бита | FEC внутри самого AMBE+2 |
Что это значит на практике
Понимание кодирования объясняет три вещи, с которыми сталкивается любой владелец хотспота.
Почему цифра «обрывается», а не шуршит. Пока ошибок мало, коды их правят полностью — звук идеальный. Когда порог перейдён, декодер перестаёт справляться сразу и целыми кадрами. Отсюда знаменитый эффект «или отлично, или никак».
Что показывает BER. Это доля ошибочных бит до исправления. Значения до процента коды съедают незаметно, поэтому связь при BER 1% ещё уверенная. Подробнее — в статье про норму BER.
Почему сигнализация выживает лучше голоса. Служебные поля защищены сильнее голосовых кадров, поэтому в тяжёлых условиях вы видите позывной вызывающего, но не слышите его самого.
Проверьте, что у вас с ошибками
В панели DMRhub видно BER и потери кадров по каждому вашему устройству — не в теории, а по живому эфиру. Если цифра выше процента, начните с калибровки, а не с покупки новой антенны.
Источники
- ETSI TS 102 361-1 V2.6.1 (2023-05), приложение B: коды, генераторные матрицы, интерливинг, таблица масок CRC — dmrassociation.org
- MMDVMHost, эталонные реализации BPTC, Trellis, Golay, RS(12,9) и CRC — github.com/g4klx/MMDVMHost
- ok-dmrlib: кодирование и декодирование всех перечисленных кодов на Python — github.com/OK-DMR/ok-dmrlib
- Разбор раскладки бёрста по дибитам и замечание о полярности синхронизации — gophertrunk.org
- dsd-fme, практическая реализация декодера DMR — github.com/lwvmobile/dsd-fme
Настроили рацию — заходите в эфир: свой мастер, хотспоты и приложение с DMR прямо в телефоне.
Войти в портал