DMR-данные (SMS) на TYT MD-UV380 под OpenGD77
Восстановлено из транскрипта сессии после потери рабочего дерева на сервере сборки. Что внутри: - четыре новых модуля прошивки (приём, сборка исходящего, меню Messages); - правки существующих файлов в виде скриптов, с порядком применения; - инструменты стенда: снятие экрана рации по USB, дамп кадров, эталонная сборка пакета; - NOTES.md: что проверено в эфире, что не доделано, где грабли. Работало в эфире в августе 2026: данные ходят в обе стороны в режиме хотспота, рация принимает SMS и показывает на экране. Отправка собрана и сверена с эталоном сервера побайтово, но в эфире не проверялась. Claude-Session: https://claude.ai/code/session_01GJtvG5WwqYNe1b7s9LLtgy
Этот коммит содержится в:
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env python3
|
||||
"""SMS step 1: capture data bursts in normal radio mode too, and route them to an
|
||||
assembler module. In hotspot mode nothing changes - bursts still go to the host."""
|
||||
W = "/home/viktor/ogd77rel/uv_src/OpenGD77_MDUV380_DM1701_20260130/MDUV380_firmware/application"
|
||||
|
||||
p = W + "/source/hardware/HR-C6000.c"
|
||||
s = open(p).read()
|
||||
|
||||
if "smsRxHandleBurst" in s:
|
||||
print("HR-C6000.c already routed to the SMS assembler")
|
||||
else:
|
||||
old = """ if ((settingsUsbMode == USB_MODE_HOTSPOT) && hrc6000CrcIsValid() && (rxSyncClass == SYNC_CLASS_DATA) &&
|
||||
((rxDataType == DT_CSBK) || (rxDataType == DT_DATA_HEADER) || (rxDataType == DT_RATE_12_DATA)) &&
|
||||
hrc6000CheckColourCodeFilter())
|
||||
{
|
||||
if (SPI0ReadPageRegByteArray(0x02, 0x00, (uint8_t *)DMR_frame_buffer, LC_DATA_LENGTH) == kStatus_Success)
|
||||
{
|
||||
DMR_frame_buffer[AMBE_AUDIO_LENGTH + LC_DATA_LENGTH] = HOTSPOT_RX_DATA_FRAME;
|
||||
DMR_frame_buffer[AMBE_AUDIO_LENGTH + LC_DATA_LENGTH + 1] = rxDataType;
|
||||
hrc.hotspotDMRRxFrameBufferAvailable = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
"""
|
||||
assert old in s, "existing capture block not found"
|
||||
|
||||
new = """ if (hrc6000CrcIsValid() && (rxSyncClass == SYNC_CLASS_DATA) &&
|
||||
((rxDataType == DT_CSBK) || (rxDataType == DT_DATA_HEADER) || (rxDataType == DT_RATE_12_DATA)) &&
|
||||
hrc6000CheckColourCodeFilter())
|
||||
{
|
||||
uint8_t dataBurst[LC_DATA_LENGTH];
|
||||
|
||||
if (SPI0ReadPageRegByteArray(0x02, 0x00, dataBurst, LC_DATA_LENGTH) == kStatus_Success)
|
||||
{
|
||||
if (settingsUsbMode == USB_MODE_HOTSPOT)
|
||||
{
|
||||
// Acting as a modem: hand the burst to the host untouched.
|
||||
memcpy((uint8_t *)DMR_frame_buffer, dataBurst, LC_DATA_LENGTH);
|
||||
DMR_frame_buffer[AMBE_AUDIO_LENGTH + LC_DATA_LENGTH] = HOTSPOT_RX_DATA_FRAME;
|
||||
DMR_frame_buffer[AMBE_AUDIO_LENGTH + LC_DATA_LENGTH + 1] = rxDataType;
|
||||
hrc.hotspotDMRRxFrameBufferAvailable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normal radio operation: collect the bursts into a message.
|
||||
smsRxHandleBurst(dataBurst, rxDataType);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
"""
|
||||
s = s.replace(old, new, 1)
|
||||
|
||||
# include the new module
|
||||
anchor = '#include "functions/hotspot.h"\n'
|
||||
assert anchor in s, "include anchor missing"
|
||||
s = s.replace(anchor, anchor + '#include "functions/sms.h"\n', 1)
|
||||
|
||||
open(p, "w").write(s)
|
||||
print("HR-C6000.c: data bursts now captured in normal mode too")
|
||||
Ссылка в новой задаче
Block a user