Files
viktor b5a8e92e45 DMR-данные (SMS) на TYT MD-UV380 под OpenGD77
Восстановлено из транскрипта сессии после потери рабочего дерева на сервере сборки.

Что внутри:
- четыре новых модуля прошивки (приём, сборка исходящего, меню Messages);
- правки существующих файлов в виде скриптов, с порядком применения;
- инструменты стенда: снятие экрана рации по USB, дамп кадров, эталонная сборка пакета;
- NOTES.md: что проверено в эфире, что не доделано, где грабли.

Работало в эфире в августе 2026: данные ходят в обе стороны в режиме хотспота,
рация принимает SMS и показывает на экране. Отправка собрана и сверена с эталоном
сервера побайтово, но в эфире не проверялась.

Claude-Session: https://claude.ai/code/session_01GJtvG5WwqYNe1b7s9LLtgy
2026-09-11 02:39:24 +09:00

3.0 KiB

name, description, metadata
name description metadata
uv390-dmr-data-path Почему OpenGD77 в режиме хотспота не передаёт SMS/данные и где в коде это чинится
type
project

Задача (с августа 2026): научить OpenGD77 на MD-UV380 в режиме хотспота проводить пакетные ДАННЫЕ (SMS, координаты), а не только голос. Рация досталась Виктору уже с прошивкой OpenGD77_HS v0.1.18 — он её не собирал.

Диагноз (дерево R20260131, MDUV380_firmware/application/source/):

  • functions/hotspot.c:2071 hotspotModeReceiveNetFrame декодирует кадр ТОЛЬКО как голосовой LC. Всё нераспознанное (включая SMS) уходит в else → storeNetFrame (2026) → копируется в аудиобуфер как звук. Отсюда симптом «модем ACK'ает кадры, в эфире ничего».
  • В hotspot.h определены только DT_VOICE_LC_HEADER и DT_TERMINATOR_WITH_LC — типов данных нет как класса. В старой MK22-ветке был закомментированный switch по DT_*, в актуальной STM32-ветке он удалён совсем.
  • На приёме hrc6000SysReceivedDataInt (HR-C6000.c:939) классифицирует кадр по reg_0x51 (rxSyncClass 2=data, rxDataType), но payload данных с чипа не читает вообще (для голоса читает 27 байт AMBE с page 0x03).

Ключ к решению — механизм передачи данных В ПРОШИВКЕ УЖЕ РАБОТАЕТ: HR-C6000.c:1889 DMR_STATE_REPEATER_WAKE_1 шлёт настоящий CSBK-burst:

SPI0WritePageRegByteArray(0x02, 0x00, payload, LC_DATA_LENGTH); // 12 байт на page 0x02
SPI0WritePageRegByte(0x04, 0x50, 0x30);  // reg 0x50 = селектор типа burst'а (DT<<4), 0x30 = CSBK
SPI0WritePageRegByte(0x04, 0x41, 0x80);  // передать в следующем слоте

Другие типы: Voice LC Header 0x10, Terminator 0x20, Data Header 0x60, rate 1/2 0x70, rate 3/4 0x90. Размерность сходится: CSBK, Data Header и rate 1/2 — все 96 бит = 12 байт = LC_DATA_LENGTH. Чип сам накладывает CRC/FEC.

Мост к MMDVM тоже уже есть: BPTCencode/BPTCdecode в hotspot.c (545/551). MMDVMHost шлёт полный 33-байтный burst, чипу нужны 12 байт:

  • TX: burst хоста → BPTCdecode → 12 байт → page 0x02 + reg 0x50
  • RX: 12 байт с чипа → BPTCencode → + slot type + sync → MMDVM_DMR_DATA2 хосту

Главный нерешённый вопрос: с какой страницы/регистра C6000 читать ПРИНЯТЫЙ data-payload.

Связано: opengd77-sources-location, uv390-test-bench