383 lines
31 KiB
Markdown
383 lines
31 KiB
Markdown
# Оборудование
|
||
|
||
Тип радара задаёт поле `radar.model` профиля, а `radar.driver_mode` — работать с
|
||
настоящим железом (`"native"`) или с симулятором (`"mock"`). Ключи профиля описаны
|
||
в главе [Файл конфигурации](configuration.md), принцип измерения — в главе
|
||
[Как работает радар](principles.md), термины — в [словаре](glossary.md).
|
||
|
||
| Радар | `radar.model` | Что подключается | Процесс сбора |
|
||
| --- | --- | --- | --- |
|
||
| Одиночный LibreVNA | `librevna` | один LibreVNA по USB, два ВЧ-ключа на GPIO | `python_app.scripts.matrix_raw_producer` |
|
||
| Многоприборная схема | `librevna_multi` | три LibreVNA по USB, петля триггера; в режиме переключения стимула — контроллер STM32 и ключи на портах мастера | `python_app.scripts.matrix_raw_producer` |
|
||
| Радиофотонный радар с АЦП | `rph_radar`, `radar.rph_radar.source: "e502"` | АЦП L-Card E-502 по USB, плата лазеров по последовательному порту, два ВЧ-ключа на GPIO | `python_app.scripts.rph_radar_raw_producer` и программа `rph_radar_collector` |
|
||
| Радиофотонный радар с платой RFG | `rph_radar`, `radar.rph_radar.source: "rfg_udp"` | плата RFG по Ethernet, плата лазеров по последовательному порту; одна пара антенн | `python_app.scripts.rph_radar_raw_producer` |
|
||
| Симулятор | `librevna` или `librevna_multi` с `driver_mode: "mock"` | ничего | `python_app.scripts.matrix_raw_producer` |
|
||
|
||
Для радиофотонного радара симулятора нет: он работает только с `driver_mode: "native"`.
|
||
|
||
Процесс сбора открывает приборы и при неудаче повторяет попытки бесконечно, с паузой
|
||
от 1 до 10 с: прибор можно подключить и после запуска. Его сообщения пишутся в
|
||
`python_app/runtime/logs/acquisition.err.log`, а в журнал окна попадают, только если
|
||
процесс завершился. Ошибки сбора и их признаки собраны в главе
|
||
[Неполадки](troubleshooting.md).
|
||
|
||
## LibreVNA
|
||
|
||
LibreVNA — двухпортовый векторный анализатор цепей (ВАЦ) с USB. В системе используются платы
|
||
ревизии B. Прошивки — изменённая версия 1.6.5, протокол версии 14 (программа
|
||
проверяет версию при подключении одиночного прибора).
|
||
|
||
| Предел | Значение |
|
||
| --- | --- |
|
||
| Частота | 0–6 ГГц |
|
||
| Полоса ПЧ | 6 Гц–50 кГц |
|
||
| Число точек | до 4501 |
|
||
| Мощность | от −40 до 0 дБм |
|
||
| Задержка на стадии `dwell_us` | до 10 239 мкс |
|
||
|
||
Ниже 25 МГц генератор прибора переключается на другую микросхему, и развёртка идёт
|
||
с неравномерными длинными паузами: если развёртка должна быть быстрой, начинайте её не
|
||
ниже 30 МГц (так сделано в `run_config_librevna_multi_per_point_lowband.example.json`).
|
||
|
||
С `driver_mode: "native"` программа при запуске окна, загрузке профиля и нажатии
|
||
**Apply Radar** читает пределы прибора и подрезает поля секции **Radar** под них
|
||
(`Radar fields were adjusted to satisfy device limits.` в журнале). У многоприборной
|
||
схемы пределы читаются с мастера. Если прибор с `driver_mode: "native"` не
|
||
подключён, окно программы не открывается: чтение пределов при старте завершается
|
||
ошибкой.
|
||
|
||
USB-доступ к прибору даёт правило udev `/etc/udev/rules.d/99-radar-librevna.rules`
|
||
(группа `plugdev`). Его ставит `./start.sh` при обычном запуске с профилем LibreVNA;
|
||
при запуске без экрана (`--headless`) правило не ставится.
|
||
|
||
## Одиночный LibreVNA
|
||
|
||
Прибор подключается по USB; если `radar.serial` пуст, берётся первый найденный.
|
||
Порт 1 излучает, порт 2 принимает. Выходной ВЧ-ключ (`switches.port1`) подключает
|
||
порт 1 к одной из передающих антенн, входной (`switches.port2`) — порт 2 к одной из
|
||
приёмных. Ключами управляет компьютер через GPIO.
|
||
|
||
Сбор одной коллекции:
|
||
|
||
1. Для каждой пары из списка сбора программа выставляет выходной ключ, затем входной,
|
||
и ждёт время установления `run.settling_ms`.
|
||
2. Запускает развёртку и принимает все точки. Если какая-то точка не пришла,
|
||
коллекция не публикуется, а прибор открывается заново.
|
||
3. Публикует коллекцию в кольцо `raw` и начинает следующую.
|
||
|
||
S21 одиночного прибора — отношение сигнала порта 2 к сигналу опорного приёмника.
|
||
**Apply Radar** открывает прибор, отправляет настройки развёртки и закрывает его.
|
||
|
||
## Многоприборная схема
|
||
|
||
Три LibreVNA: мастер (`radar.serial`) и два ведомых
|
||
(`radar.multi_device.slave_serials`, ровно два). Мастер на каждой частоте излучает по
|
||
очереди с порта 1 и порта 2, ведомые не излучают и принимают каждый на оба порта.
|
||
S21 — сигнал приёмника ведомого, делённый на сигнал опорного приёмника мастера на той
|
||
же стадии.
|
||
|
||
| Номер | Что это |
|
||
| --- | --- |
|
||
| вход 0, 1 | первый ведомый из `slave_serials`, порт 1 и порт 2 |
|
||
| вход 2, 3 | второй ведомый, порт 1 и порт 2 |
|
||
| выход 0, 1 (без переключения стимула) | мастер, порт 1 и порт 2 |
|
||
| выход 0, 1, 2, 3 (переключение стимула, два положения) | порт 1 положение A, порт 1 положение B, порт 2 положение A, порт 2 положение B |
|
||
|
||
Номер выхода совпадает с номером стадии прибора. Многоприборная схема всегда снимает
|
||
полную матрицу: список пар `run.combos` у неё заменяется всеми парами, и в окне он не
|
||
редактируется.
|
||
|
||
Приборы синхронизированы аппаратным сигналом запуска. Петля триггера:
|
||
`TRIGGER_OUT` мастера → первый ведомый → второй ведомый → `TRIGGER_IN` мастера.
|
||
Вернувшийся сигнал означает «все готовы». Мастер измеряет по вернувшемуся сигналу,
|
||
поэтому задержки в петле одинаковы для всех приборов и в отношении «приёмник/опорный»
|
||
сокращаются.
|
||
|
||
Опорная частота: поле `radar.multi_device.force_external_reference` включает внешнюю
|
||
опору 10 МГц сразу на всех трёх приборах (раздельно задать нельзя). Во всех профилях
|
||
оно выключено. Включайте его, только если опора 10 МГц действительно подана на все
|
||
приборы. Признак отсутствующей опоры при включённом поле — мастер не отдаёт точки:
|
||
`Packet not received from <серийный номер> within 1.0 s`.
|
||
|
||
Сбор: перед первой коллекцией программа настраивает опору на всех приборах,
|
||
затем отправляет настройки развёртки сначала ведомым, потом мастеру, чтобы приёмники
|
||
были готовы раньше, чем мастер выдаст запуск. Развёртка идёт непрерывно. Каждый
|
||
прибор передаёт свои точки по отдельному USB; программа ждёт начала развёртки на всех
|
||
трёх и принимает цикл, только если начала совпали по времени. Если пропало не больше
|
||
5 % точек трассы, они заменяются нулями (`Zero-filled dropped sweep point(s) to keep the cycle…`),
|
||
иначе цикл отбрасывается.
|
||
|
||
| Сбой | Предел |
|
||
| --- | --- |
|
||
| от прибора нет ни одной точки | 1,5 с |
|
||
| нет начала развёртки | 6 с |
|
||
| цикл не закончился | 8 с |
|
||
| повторные попытки без переподключения | 2 |
|
||
| переподключение всех приборов | `radar.multi_device.recovery_attempts` раз (по умолчанию 3), не дольше 10 с |
|
||
|
||
После этого процесс сбора пересоздаёт подключение и ждёт приборы бесконечно. Если
|
||
не пришло ни одной точки ни от одного прибора, в журнале процесса сбора будет
|
||
`No datapoints received from at least one device; hardware trigger sync did not start. Check Trigger Out/In loop and 10 MHz reference wiring.`
|
||
|
||
**Apply Radar** в этой схеме приборы не трогает: их настраивает процесс сбора
|
||
(`Multi-device raw producer will configure all LibreVNA devices`), кнопка только
|
||
перечитывает пределы мастера.
|
||
|
||
Прошивки: мастер работает с образом `combined.vnafw` (обычная раскладка стадий с
|
||
аппаратным триггером) или `combined_per_point_switching.vnafw` (переключение стимула),
|
||
ведомые — с `combined_external_lo_slave.vnafw`. Образы и правила их сборки — в
|
||
разделе «Прошивки» ниже.
|
||
|
||
## Переключение стимула внутри частотной точки
|
||
|
||
В этом режиме одна развёртка даёт матрицу 4 × 4 вместо 2 × 4: на каждом порту
|
||
мастера стоит ВЧ-ключ, и на каждой частоте каждый порт излучает дважды, через оба
|
||
положения ключа. Все 16 пар одной частоты измеряются за доли миллисекунды, поэтому
|
||
движение радара между ними пренебрежимо мало. Полное описание —
|
||
[per_point_switching.md](../device_firmware/per_point_switching.md).
|
||
|
||
Что нужно:
|
||
|
||
- прошить мастер образом `combined_per_point_switching.vnafw`; ведомые не трогать;
|
||
- поставить контроллер ключей (плата WeAct STM32G431CB с прошивкой
|
||
`device_firmware/switch_controller`) в разрыв петли триггера между
|
||
`TRIGGER_OUT` мастера и `TRIGGER_IN` первого ведомого;
|
||
- в профиле задать `radar.multi_device.stimulus_switch_positions: 2` и
|
||
`radar.sweep.dwell_us: 2`. Ключами на портах мастера управляет контроллер, а не
|
||
компьютер; разделы `switches` у многоприборной схемы программа сама ставит в `mock`.
|
||
|
||
| Вывод STM32 | Куда |
|
||
| --- | --- |
|
||
| PB0 (вход) | `TRIGGER_OUT` мастера |
|
||
| PB1 (выход, повторяет PB0) | `TRIGGER_IN` первого ведомого |
|
||
| PB2 | ключ порта 1 мастера |
|
||
| PB6 | ключ порта 2 мастера |
|
||
| PB5 | отладка: импульс 2 мкс на каждую поправку чётности |
|
||
|
||
Контроллер переключает оба ключа по каждому спаду сигнала запуска (положение A —
|
||
логический 0, B — 1). Если пауза между стадиями в 1,5 раза длиннее наименьшей из
|
||
последних 16 пауз, то есть на границе развёртки, он принудительно возвращает положение
|
||
A и считает это поправкой чётности. Задержка, которую он вносит в петлю (около 50 нс),
|
||
одинакова для всех
|
||
приборов и на фазу не влияет. Через 200 мс простоя триггера контроллер печатает
|
||
отчёт по USB (115 200 бод): `trigger cycles`, `resyncs (sweep ends)`, `parity corrections`
|
||
(должно быть `0 (ok)`), `stages per resync` (ожидается число точек × число стадий),
|
||
паузы и их гистограмма.
|
||
|
||
Проверка на железе — `python_app/scripts/per_point_switching_check.py --config <профиль>`:
|
||
она отказывает, если медиана модуля S21 какого-то выхода ниже −80 дБ (признак старой
|
||
прошивки мастера) или если два положения одного порта без подключённого ключа
|
||
различаются больше чем на 6 дБ. С ключом нужен флаг `--switch-connected`.
|
||
|
||
> **Внимание.** Полоса ПЧ 1 кГц в этом режиме воспроизводимо роняет приборы
|
||
> (`LIBUSB_ERROR_IO`). Работают 5, 10, 20 и 50 кГц; рабочее значение — 50 кГц.
|
||
|
||
## ВЧ-ключи H7992
|
||
|
||
Ключ подключает порт прибора к одной из до четырёх антенн. Положение задают две
|
||
линии GPIO, A (`pin_a`) и B (`pin_b`); линии нужны обе даже при двух положениях.
|
||
|
||
| Положение | A | B |
|
||
| --- | --- | --- |
|
||
| 0 | 0 | 0 |
|
||
| 1 | 0 | 1 |
|
||
| 2 | 1 | 0 |
|
||
| 3 | 1 | 1 |
|
||
|
||
Номера линий в профилях — номера линий GPIO-чипа (`gpio_chip`, обычно
|
||
`/dev/gpiochip0`), а не номера контактов разъёма. Во всех профилях-примерах, кроме
|
||
примера с платой RFG (там ключей нет), выходной ключ на линиях 17 (A) и 27 (B),
|
||
входной — на 22 (A) и 23 (B). При открытии программа
|
||
выставляет ключ в `default_position`. Ключ с `driver_mode: "mock"` никуда не
|
||
переключается, программа только помнит его положение.
|
||
|
||
Кто управляет ключами:
|
||
|
||
| Радар | Кто переключает |
|
||
| --- | --- |
|
||
| одиночный LibreVNA | процесс сбора на Python |
|
||
| многоприборная схема | процесс сбора, только если `multi_device.output_switch_positions` или `input_switch_positions` больше 1; в режиме переключения стимула — контроллер STM32 |
|
||
| радиофотонный с E-502 | программа `rph_radar_collector`, если оба ключа `native`; иначе процесс сбора |
|
||
|
||
> **Внимание.** На Raspberry Pi 5 номер GPIO-чипа 40-контактного разъёма менялся от
|
||
> версии ядра к версии. Перед работой проверьте его на самой машине: `gpiodetect` и
|
||
> `gpioinfo -c gpiochip0`. Неверный чип означает ключи, которые молча не
|
||
> переключаются.
|
||
|
||
## Радиофотонный радар
|
||
|
||
Плата лазеров меняет ток лазера LD1 ступенями, при этом ток второго лазера и
|
||
температуры обоих постоянны. На каждой ступени оцифровываются основной сигнал и
|
||
опорный. Опорное плечо имеет постоянную задержку, поэтому его фаза растёт с частотой
|
||
линейно; по двум опорным точкам `phase_calibration` (фаза — частота) программа
|
||
определяет частоту каждой ступени. S21 — основной сигнал, делённый на модуль
|
||
опорного. Развёртки, которые не покрывают выходную полосу `radar.rph_radar.band`,
|
||
отбрасываются, остальные пересчитываются на её равномерную сетку (по умолчанию
|
||
2,1–5,5 ГГц, 2048 точек). Поля `radar.sweep` для этого радара не используются, в
|
||
окне вместо секции LibreVNA показывается секция RPH.
|
||
|
||
### Плата лазеров
|
||
|
||
Плата подключается по последовательному порту (115 200 бод) и программируется
|
||
кнопкой **Apply Radar**, если в профиле `laser_control.enabled: true`. Программа
|
||
проверяет все значения до отправки первого байта, затем сбрасывает плату и отправляет
|
||
постоянные токи и температуры, а в режиме `variation` — ещё задачу развёртки тока
|
||
LD1. Каждая команда должна получить ответ «состояние 0»; иначе
|
||
`Device rejected command: STATE 0x…`. После закрытия порта развёртка лазера
|
||
продолжается.
|
||
|
||
| Величина | Пределы | По умолчанию |
|
||
| --- | --- | --- |
|
||
| температура лазеров | 15–40 °C | 24,0 и 24,9 °C |
|
||
| ток лазеров | 15–110 мА | 97,3 и 102,0 мА |
|
||
| развёртка тока LD1 | 15–110 мА, начало меньше конца | 97,3 → 107,0 мА |
|
||
| шаг тока | 0,002–0,5 мА | 0,05 мА |
|
||
| длительность ступени | 20–100 мкс | 50 мкс |
|
||
| пауза между развёртками | 3–10 мс | 10 мс |
|
||
|
||
При запуске без экрана **Apply Radar** выполняется автоматически через 0,5 с после
|
||
старта, а через 1 с после него — **Start**, даже если **Apply Radar** не удался.
|
||
В веб-интерфейсе **Apply Radar** нет.
|
||
|
||
### АЦП L-Card E-502
|
||
|
||
Данные с АЦП читает отдельная программа `build/bin/rph_radar_collector` (собирается
|
||
командой `make rph_radar_collector`, в обычный `make` не входит). Её запускает и
|
||
останавливает процесс сбора; программа живёт, только пока жив её запустивший
|
||
процесс. Библиотеки L-Card `libx502api.so` и `libe502api.so` она загружает при
|
||
запуске, по умолчанию из `~/.local/lib`. Развёртки она передаёт процессу сбора через
|
||
псевдотерминал `rph_radar.tty_path` (в примере `/tmp/ttyADC_data`). Устройство
|
||
выбирается первое найденное. Подробности — в
|
||
[README коллектора](../data_acq_and_processing/rph_radar_collector/README.md).
|
||
|
||
Параметры коллектора задаются списком `radar.rph_radar.args`:
|
||
|
||
| Параметр | Что задаёт | По умолчанию |
|
||
| --- | --- | --- |
|
||
| `range:<В>` | диапазон входа ±В: `10`, `5`, `2`, `1`, `0.5` или `0.2` | ±2 В |
|
||
| `internal_ref_hz:<Гц>` | внутренняя опорная частота, она же наибольшая частота АЦП: `2000000` или `1500000` | 2 МГц |
|
||
| `duration_ms:<мс>` | наибольшая длительность развёртки, больше 0 и не больше 60 000 мс; более длинная считается испорченной | 100 мс |
|
||
| `do8_cycle_period:<n>` | период выхода DO8 в словах цифрового вывода, 4–262144, причём НОК(4, n) не больше 262144 (нечётные n больше 65 536 не подходят) | 8 |
|
||
|
||
Остальные слова в `args` (`profile:phase`, `clock:internal`, `start:di_syn2_rise`,
|
||
`stop:di_syn2_fall`, `sample_clock_hz:max`, `packet_limit:0`, `do1_toggle_per_frame`,
|
||
`do1_pair_subtract_avg`, `do8_freq_ref`) только подтверждают единственный
|
||
поддерживаемый режим; любое другое слово отвергается.
|
||
|
||
Как коллектор использует цифровые линии АЦП:
|
||
|
||
| Линия | Что делает коллектор |
|
||
| --- | --- |
|
||
| DI_SYN2 | фронт открывает развёртку, спад закрывает |
|
||
| DI1 | смена уровня отмечает новую ступень |
|
||
| DI2 | делит отсчёты ступени на две группы; значение ступени — среднее разности групп |
|
||
| DI8 | отсчёты с высоким DI8 идут в опорный канал |
|
||
| DO1 | меняется на каждом кадре |
|
||
| DO2 | высокий, пока идёт поток |
|
||
| DO8 | высокий на двух последних словах каждого периода `do8_cycle_period` |
|
||
|
||
Если ключами управляет коллектор, он переключает их сам между развёртками, ждёт
|
||
`run.settling_ms` (не меньше 1 мс) и открывает новый сеанс АЦП; первая развёртка
|
||
после переключения отбрасывается.
|
||
|
||
### Плата RFG
|
||
|
||
Плата RFG шлёт по UDP точки развёртки на адрес `radar.rph_radar.udp_bind`. В примере
|
||
это проводной адрес компьютера `192.168.2.1:5000`: привязка к проводному интерфейсу
|
||
отсекает чужие широковещательные пакеты (например, из Wi-Fi), а любой непонятный пакет
|
||
программа считает ошибкой. В каждой точке три канала; основной сигнал — разность
|
||
каналов 0 и 1 (синхронный детектор), опорный — канал 2.
|
||
|
||
Требования профиля:
|
||
|
||
- `laser_control.mode: "variation"` — даже если лазер запускают из другой программы:
|
||
по его настройкам вычисляется длина развёртки;
|
||
- у обоих ключей одно положение, то есть одна пара антенн: без метки от источника
|
||
нельзя доказать, что развёртка после переключения свежая.
|
||
|
||
Длина развёртки — ⌈(конец − начало) / шаг⌉ ступеней в кодах ЦАП тока; при настройках
|
||
по умолчанию 199 ступеней по 50 мкс. Развёртка принимается, только если пришли все
|
||
ступени подряд. Плата теряет несколько процентов точек, такие развёртки
|
||
отбрасываются. Время каждой точки — метка ядра о приёме пакета.
|
||
|
||
### Фазовая калибровка
|
||
|
||
Фазовые якоря `radar.rph_radar.phase_calibration` измеряются программой
|
||
`python_app/scripts/rph_radar_calibrate.py`. Перед ней примените настройки лазера
|
||
кнопкой **Apply Radar** и остановите сбор.
|
||
|
||
```sh
|
||
.venv/bin/python -m python_app.scripts.rph_radar_calibrate --config run_config.json --sweeps 200
|
||
.venv/bin/python -m python_app.scripts.rph_radar_calibrate --config run_config.json --sweeps 200 --apply
|
||
```
|
||
|
||
Первая команда снимает развёртки и печатает измеренные фазы начала и конца, вторая
|
||
снимает заново и записывает в профиль только `phase0_rad` и `phase1_rad`, не трогая
|
||
остальные байты файла. Частотные якоря `freq0_hz` и `freq1_hz` должны заранее
|
||
описывать известные концы развёртки. `--warmup` задаёт, сколько первых развёрток
|
||
отбросить (по умолчанию 10). Команды лазеру программа не отправляет. Если профиль
|
||
изменился во время съёма, она его не перезаписывает.
|
||
|
||
## Симулятор
|
||
|
||
С `driver_mode: "mock"` процесс сбора не трогает железо и моделирует один точечный
|
||
отражатель. Отражатель движется по восьмисекундному циклу: вдоль ряда антенн — вокруг
|
||
его середины (размах — половина ширины ряда плюс 0,25 м, но не меньше 0,75 м), по
|
||
дальности — между 3,25 и 4,25 м, на высоте 0,25 м. S21 каждой пары
|
||
считается по настоящим расстояниям от антенн из профиля; коллекции идут не чаще чем
|
||
раз в 50 мс. Шума, помех, переключения ключей и движения радара симулятор не
|
||
моделирует; скорость радара при работе с ним должна быть нулевой. Предобработке
|
||
по-прежнему нужны наборы; для симулятора подходят нейтральные (глава
|
||
[Калибровка и предобработка](preprocessing.md)).
|
||
|
||
## GPIO-кнопка
|
||
|
||
К компьютеру можно подключить кнопку, которая снимает временный референс — то же,
|
||
что **Capture Temporary Reference**. По умолчанию она выключена (раздел
|
||
`control_button` профиля, ни в одном примере не включена). Схема, на которую
|
||
рассчитаны умолчания: кнопка между линией GPIO и землёй, внутренняя подтяжка к
|
||
питанию, нажатие — спад уровня. Дребезг подавляет ядро (`debounce_ms`, по умолчанию
|
||
50 мс). Настройки кнопки читаются при запуске окна; после загрузки другого профиля
|
||
нужно перезапустить программу.
|
||
|
||
## Тележка
|
||
|
||
`device_firmware/cart_firmware` — прошивка платы WeAct STM32G431CB, которая заменяет
|
||
пульт тележки: читает джойстик и выдаёт команды движения в формате SBUS. С
|
||
программой радара она не связана. Скорость для поправки на движение радар получает
|
||
от клиента TCP-локатора (глава [Веб-интерфейс, кнопка и локатор](web.md)).
|
||
Протокол пульта — [protocol.md](../device_firmware/cart_firmware/docs/protocol.md).
|
||
|
||
## Прошивки
|
||
|
||
| Где | Что | На чём работает |
|
||
| --- | --- | --- |
|
||
| `device_firmware/multi_libreVNA_firmware/combined.vnafw` | образ мастера: обычные стадии и аппаратный триггер | LibreVNA-мастер |
|
||
| `device_firmware/multi_libreVNA_firmware/combined_per_point_switching.vnafw` | образ мастера с переключением стимула | LibreVNA-мастер |
|
||
| `device_firmware/multi_libreVNA_firmware/combined_external_lo_slave.vnafw` | образ ведомого | LibreVNA-ведомые |
|
||
| `device_firmware/multi_libreVNA_firmware/reproduce/` | полное дерево LibreVNA 1.6.5 с доработками и комплект воспроизводимой сборки | ПК разработчика |
|
||
| `device_firmware/switch_controller/` | контроллер ключей для переключения стимула | WeAct STM32G431CB |
|
||
| `device_firmware/cart_firmware/` | пульт тележки | WeAct STM32G431CB |
|
||
|
||
Образ `.vnafw` заливается в LibreVNA программой LibreVNA-GUI (Device → Firmware
|
||
Update). Платы STM32 прошиваются через PlatformIO и ST-Link: `pio run -t upload`.
|
||
|
||
> **Внимание.** `top_master.bin` и `combined.vnafw` — единственные копии рабочего
|
||
> битстрима мастера и рабочего образа прошивки, битстрим заново не воспроизводится.
|
||
> Никогда их не перезаписывайте; новые сборки сохраняйте под новыми именами.
|
||
|
||
Подробно:
|
||
|
||
- [reproduce/README.md](../device_firmware/multi_libreVNA_firmware/reproduce/README.md) — как
|
||
устроен комплект сборки, отличия от LibreVNA 1.6.5, что воспроизводится побайтово;
|
||
- [install_windows/README.txt](../device_firmware/multi_libreVNA_firmware/reproduce/install_windows/README.txt)
|
||
—
|
||
сборка мастера с переключением стимула на Windows;
|
||
- [per_point_switching.md](../device_firmware/per_point_switching.md) — переключение
|
||
стимула: раскладка стадий, изменения FPGA и микроконтроллера, порядок ввода в
|
||
строй;
|
||
- [switch_controller/README.md](../device_firmware/switch_controller/README.md) —
|
||
контроллер ключей: разводка, отчёт, отладка;
|
||
- [librevna_protocol.md](../device_firmware/librevna_protocol.md) — USB-протокол
|
||
LibreVNA и форматы кадров между процессами программы.
|