Баузбенд FM100B: - найден прозрачный мост ПК<->модуль (включение с зажатой МЕНЮ), проверен живьём - расшифрована контрольная сумма кадров (one's complement, BE), сверена с ответом рации - инструмент tools/fm100b.py (ping/send/raw/scan) - cmd 0x25 = запрос версии, модуль отвечает V1.2.0.32 (совпало с офиц. образом) - разобран диспетчер входящих кадров: 193 записи, реальный код у 10 команд - cmd 0x59 = индикация приёма, она же управляет гейтом звука PA14 - исправлено: boot-handshake это cmd 0x84, а не 0x64 (research/re/dmr.md) Спектроанализатор REFV DualTachyon (docs/refw-spectrum.md): - вызывается как функция горячей клавиши №22 Analog Spectrum - вход 0x08009CAA -> обычный 0x080139E4 / по зоне 0x08015318 - спектр это экран №11; тик 0x08013BA4 (автомат на 4 состояния), клавиши 0x08013BFC Декомпозиция (docs/firmware-parts.md): - два процессора + внешний SPI = три канала внедрения - карта ресурсов SPI: шрифты, пиньинь, голос, таблица Unicode - найден штатный загрузчик ресурсов FontVoicePicture (шрифты/голос/картинки) - дерево меню целиком: MIC/SPK Gain, RX/TX Limit, SMS Format уже в стоке - аудио двухступенчатое: PA2 питание УНЧ, PA14 гейт от DMR-модуля Прочее: - везде исправлен режим прошивки: тангента PTT вместо клавиши "*" - устаревший Ru-4D_Flasher.exe удалён из репозитория - добавлены инструменты реверса: xref, refs, gpiomap, gpioscan, schem
135 строки
8.2 KiB
Markdown
135 строки
8.2 KiB
Markdown
# Спектроанализатор REFV (DualTachyon) — где он лежит
|
|
|
|
Разбор по образу `refw/rt-4d-refw-beta42.bin`
|
|
(251 904 Б, md5 `c6ab8306b5512b21b1f49fda8df2b1f5`, база загрузки `0x08002800`).
|
|
|
|
Именно эту реализацию хвалят пользователи. Ниже — как до неё добраться и из чего она состоит.
|
|
|
|
---
|
|
|
|
## 1. Как спектр вызывается
|
|
|
|
Спектр **не является пунктом меню**. Это **функция назначаемой клавиши № 22** —
|
|
`Analog Spectrum` в списке функций горячих клавиш (`0x080213A9`, записи по 16 байт).
|
|
|
|
> В стоке та же функция есть под номером **21** — REFV сдвинул нумерацию, вставив
|
|
> `Bandwidth Toggle` на позицию 15.
|
|
|
|
Диспетчер функций клавиш: **`TBH @0x080094EC`**, 45 ветвей (`cmp #44` перед таблицей),
|
|
таблица с `0x080094F0`. Ветка 22 → **`0x08009CAA`**.
|
|
|
|
## 2. Точка входа `0x08009CAA`
|
|
|
|
```c
|
|
if (mode == 3 || mode == 4) return; // в этих режимах спектр запрещён
|
|
bl 0x08010ADC; // подготовка
|
|
// [area*5 + 0x84] — режим области:
|
|
// 0=Frequency, 1=Channel, 2=Zone
|
|
if (area_mode == 2) bl 0x08015318; // ← спектр ПО ЗОНЕ
|
|
else bl 0x080139E4; // ← ОБЫЧНЫЙ спектр
|
|
goto 0x08009BC0; // общий выход
|
|
```
|
|
|
|
Это ровно совпадает с официальным описанием REFV: «переключитесь в режим VFO или канала,
|
|
если нужен обычный спектр; из зоны он сканирует эту зону».
|
|
|
|
## 3. Обычный спектр — `0x080139E4` (инициализация)
|
|
|
|
```
|
|
0x080139E4 push {r4-r8,lr}
|
|
0x080139E8 bl 0x08014888 ; подготовка подсистемы
|
|
... ; сброс флагов состояния
|
|
0x08013A2C mla r2, #0x30, chan, r3 ; запись канала = 48 байт
|
|
0x08013A30 ldr [r2+5] -> [r4+5] ; копирование частоты RX/TX
|
|
0x08013A38 ldr [r2+9] -> [r4+9] ; в рабочий VFO
|
|
... ; полоса/режим: bfi в [r4], [r4+4], [r4+0xe]
|
|
0x08013A86 bl 0x08011164 ; применить настройки ВЧ-тракта
|
|
0x08013AA6 bl 0x080136EC ; подготовка экрана
|
|
0x08013ABA bl 0x08013944 ; отрисовка шапки
|
|
0x08013AC8 bl 0x08015978 ; печать числа (r1=2 разряда)
|
|
0x08013AF8 ite eq / 'W' : 'N' ; метка полосы Wide/Narrow
|
|
0x08013B1C bl 0x0801C62C ; запуск
|
|
0x08013B22 movs r2,#0x0B
|
|
0x08013B24 strb r2,[0x200009B0] ; ← ЭКРАН = 11
|
|
0x08013B26 pop
|
|
```
|
|
|
|
**Ключевой вывод: спектр — это экран № 11.** Архитектура та же, что в стоке
|
|
(`g_screen`, значения 0…11), только переменная в REFV живёт по адресу **`0x200009B0`**.
|
|
|
|
## 4. Модуль спектра целиком
|
|
|
|
| Адрес | Роль |
|
|
|---|---|
|
|
| `0x08009CAA` | точка входа с горячей клавиши, выбор обычный/зонный |
|
|
| **`0x080139E4`** | **инициализация обычного спектра**, ставит `экран = 11` |
|
|
| **`0x08013BA4`** | **тик**: автомат на 4 состояния, счётчик `[база+0x3E] & 3` |
|
|
| **`0x08013BFC`** | **обработчик клавиш** спектра, `cmp r0,#0x10` + `TBH @0x08013C20` (17 клавиш) |
|
|
| `0x08013598` | шаг развёртки (состояние 1) |
|
|
| `0x08012FA0` | рабочий обработчик (состояния 2 и 3) |
|
|
| `0x0801307C` | ветка при `состояние > 1` |
|
|
| `0x080135E8` | помощник (вызывается из `0x0801449C`) |
|
|
| `0x080136EC`, `0x08013944`, `0x08015978` | подготовка экрана, шапка, печать чисел |
|
|
| `0x08014888` | инициализация подсистемы |
|
|
| **`0x08015318`** | **спектр по зоне** — отдельная реализация |
|
|
|
|
### Автомат тика `0x08013BA4`
|
|
```c
|
|
state = (state + 1) & 3; // [база+0x3E]
|
|
switch (state) {
|
|
case 1: flags[1]=flags[2]=0; bl 0x08013598; break; // шаг развёртки
|
|
case 2: flag=0; goto 0x08012FA0; // обработка
|
|
case 3: flag=1; goto 0x08012FA0;
|
|
default: goto 0x0800A57C; // пометить перерисовку
|
|
}
|
|
```
|
|
Развёртка размазана по тикам главного цикла — экран не блокируется, поэтому спектр
|
|
и ощущается отзывчивым.
|
|
|
|
### Спектр по зоне `0x08015318`
|
|
Перебирает **200 каналов** зоны (`cmp r6,#0xC8`), запись зоны — **0x1BD байт**:
|
|
```c
|
|
for (i = 0; i < 200; i++) {
|
|
ch = zone[i].channel; // halfword, отбрасывается если >= 0x400
|
|
if (!(zone.scanlist_bitmap[i>>3] >> (i&7) & 1)) continue; // битовая карта scan-list
|
|
read_channel(sp, 0x30*ch + 0x4000); // запись канала 48 байт из SPI
|
|
// разбор полей: частота ubfx(…,8,12), CTCSS, полоса, режим
|
|
// укладка в массив с шагом 28 байт
|
|
}
|
|
```
|
|
Отсюда и фича «зонный спектр показывает живую информацию о субтонах».
|
|
|
|
## 5. Прочие детали
|
|
|
|
- **Перерисовка**: `0x0800A5FC` — `TBB` на 12 экранов (`cmp #0x0B`), каждая ветка делает
|
|
`memset(флаги_экрана, 1, N)`. Для экрана 11 — 16 элементов по адресу `0x200000A9`.
|
|
- **Идиом связки экранов** встречается в 6 местах:
|
|
`if (screen == 11 || (prev == 11 && (screen & ~4) == 8))` — экраны 8 и 12
|
|
накладываются поверх спектра (меню/подсказки).
|
|
|
|
## 6. Что даёт REFV сверх стока (полная таблица UI, 338 записей)
|
|
|
|
Новые функции горячих клавиш: `Bandwidth Toggle`, `Talker Alias`, `RX AM/FM/**SSB** SW`,
|
|
`DMR DCDM Switch`, `DMR TS/CC Switch`, `DMR Key Select`, `Next Zone`, `DTMF List`,
|
|
`Freq Monitor`, `Last Call Info`, `Address Book`, `Contacts List`.
|
|
|
|
Новое в меню: верхнеуровневое **`Extra`**, `Extra hotkey` + `0…9 Hotkey`,
|
|
`Edit Scan List` в зонах, `SMS Templates`, `Time Calibrate`, `AM/FM/SSB RX` в канале,
|
|
`Last Channel`, `Skip Scan`, `Radio Info`, `Flash Type`.
|
|
|
|
## 7. Как это перенести к нам
|
|
|
|
Прямой перенос бинарного кода невозможен — REFV написан с нуля, у него своя карта
|
|
памяти и свои структуры (запись канала 48 Б, запись зоны 0x1BD Б, экран в `0x200009B0`).
|
|
Переносится **архитектура**:
|
|
|
|
1. Спектр — отдельный экран в общей диспетчеризации, а не модальный цикл.
|
|
2. Развёртка разбита на состояния по тикам, поэтому UI не подвисает.
|
|
3. Вход — функция горячей клавиши, а не пункт меню.
|
|
4. Отрисовка перерисовывает только помеченные элементы (массив флагов).
|
|
|
|
В нашей прошивке всё это ложится на уже найденные точки: хук `0x080207E6` (отрисовка) и
|
|
`0x08020816` (клавиши) в `ui_tick_normal @0x080207DC`, диспетчеризация по
|
|
`g_screen @0x200008B3`. Обязательно **вызывая оригинальный обработчик** — см.
|
|
`docs/firmware-parts.md`.
|