switch controller: separate pin per switch, gap histogram

PB2 now drives the switch on master port 1 and PB6 the one on port 2, both
updated in a single BSRR write so they move in the same cycle. The CDC report
gained a gap histogram, which showed the point boundary sits at 70-79 us against
62 us between stages, so the resync threshold only fires on the longer
inter-sweep pauses; the misleading "stages per point" counter is renamed to
match what it actually counts.
This commit is contained in:
Ayzen
2026-09-15 14:41:21 +03:00
parent caac6561c2
commit 3f6cfc9108
2 changed files with 140 additions and 32 deletions
+56 -7
View File
@@ -8,7 +8,8 @@
```text
мастер TRIGGER_OUT ──► PB0 [STM32] PB1 ──► слейв 1 TRIGGER_IN
PB2 ──► управление обоими СВЧ-ключами
PB2 ──► ключ выходного порта 1
PB6 ──► ключ выходного порта 2
PB5 ──► отладочный выход
```
@@ -17,10 +18,24 @@
`Mode::Trigger` прошивка LibreVNA уводит собственный STM32 прибора в Hi-Z на обеих
триггерных линиях, так что и вход слейва, и выход мастера свободны.
Одна нога PB2 управляет **обоими** ключами (на порту 1 и на порту 2) — они ходят
синхронно, и этого достаточно: нужное положение зависит только от номера стадии,
а не от того, какой порт сейчас излучает. Если у ключа больше двух состояний,
лишние входы замыкаются джампером.
**У каждого ключа своя нога:** PB2 — ключ выходного порта 1, PB6 — ключ порта 2.
В штатном режиме оба идут в одно и то же положение, потому что положение зависит
только от номера стадии, а не от того, какой порт сейчас излучает. Раздельные
линии нужны по двум причинам: не вешать два входа параллельно на один вывод и
иметь возможность развести ключи независимо.
Оба вывода лежат на порту B, и это существенно: положение меняется **одной
записью в `BSRR`** (младшая половина слова ставит биты, старшая сбрасывает),
поэтому ноги переключаются в одном такте, без взаимного сдвига. Если менять
распиновку, оставляйте оба вывода на одном порту.
Если у конкретного ключа положению A соответствует логическая единица, инверсию
можно включить **отдельно для каждого** — константы `kSwitchPort1ActiveLow` и
`kSwitchPort2ActiveLow`. Если у ключа больше двух состояний, лишние входы
замыкаются джампером.
PB6 выбран как свободный вывод порта B без отладочной функции. **PB3 (SWO) и
PB4 (NJTRST) занимать не стоит** — они мешают отладчику.
> Прошивка рассчитана **ровно на два положения** ключа
> (`stimulus_switch_positions: 2` на хосте). Хост технически допускает и 4
@@ -68,6 +83,38 @@
умноженный на `kBoundaryFactorNum / kBoundaryFactorDen` (по умолчанию 1.5). Пока
минимум не набран, восстановление молчит — чередование корректно и без него.
### Измерено на железе 2026-09-11: коэффициент 1.5 мал
Первый прогон с замкнутой петлёй (мастер + 2 слейва, `dwell_us = 2`, IFBW 50 кГц,
201 точка, 4 стадии на точку) дал по CDC:
```text
trigger cycles : 6432
point boundaries : 96 <- ожидалось бы 6432 / 4 = 1608
parity corrections : 0 (ok)
stages per point : 124 (ожидается 4), отклонений: 80
gap min/max, us : 62 / 14364445
inter-stage gap, us : 62
boundary above, us : 94
```
Межстадийная пауза **62 мкс** — точно как считалось (`dwell 2` + задержка PLL 60).
А границы точек распознаются примерно раз в 67 стадий вместо каждых четырёх.
Значит **пауза на границе точки обычно не дотягивает до 1.5×**, то есть до 94 мкс:
перезагрузка регистров PLL и ожидание захвата добавляют к успокоению меньше
половины от него.
**На работу это не влияет**, и `parity corrections : 0` тому подтверждение.
Переключение идёт на каждом спаде безусловно, а стадий на точку чётное число (4),
поэтому чередование `A B A B` само собой возвращается к A на новой точке.
Распознавание границы — только страховка от уже случившегося сбоя чётности.
Но страховка сейчас почти не работает: пропущенный фронт исправится не через
четыре стадии, а через несколько десятков. И диагностика `stages per point`
бесполезна. Чтобы починить, нужно измерить осциллографом фактическое
распределение пауз на PB0 и выбрать коэффициент по нему, а не по догадке. До тех
пор значения `stages per point` и `point boundaries` в отчёте читать нельзя.
### Надо ли перекалибровывать паузу под каждую настройку
Нет, порог подстраивается сам, и вот что на него влияет, а что нет.
@@ -113,8 +160,10 @@
положение на границе точки. Постоянные импульсы означают, что фронты теряются
или порог распознавания границы занижен.
**PB2** — само положение ключа, смотрится осциллографом вместе с триггером: на
одной частоте должно быть ровно 4 стадии и два полных периода `A B A B`.
**PB2 и PB6** — положение ключей, смотрятся осциллографом вместе с триггером: на
одной частоте должно быть ровно 4 стадии и два полных периода `A B A B`. Оба
вывода обязаны меняться одновременно и в одну сторону — расхождение между ними
означает ошибку в распиновке или в константах инверсии.
**USB CDC (115200)** — отчёт печатается один раз, когда на линии триггера
тишина дольше 200 мс, то есть когда развёртка остановлена. Во время работы