dma fix priority and debug

This commit is contained in:
2026-04-02 17:25:10 +03:00
parent af3e012aac
commit e7d7c0e1c1
18 changed files with 89260 additions and 142 deletions

View File

@ -24,6 +24,19 @@
Идея `buildGateRuns`: **эмулировать** шаги FSM, которые в ISR выполняются при **`toggleCounter == 0`** (см. комментарий в `IR_Encoder.cpp` рядом с внутренним `while`).
### 2.1. Приоритеты NVIC: приём ИК выше, чем DMA передачи (STM32)
Пока активна **внешняя** передача по DMA (`IrDmaBackend` и т.п.), таймер крутит поток запросов к DMA — срабатывают **`DMA1_Channelx_IRQn`** (половина/конец буфера и т.д.). Если их приоритет **выше**, чем у **EXTI** линии пина приёмника, обработка фронтов на входе ИК **откладывается** → растёт джиттер `micros()` и страдает заполнение `subBuffer` / журнал `@IRF1v1`, хотя алгоритм `tick`/`writeToBuffer` не менялся.
**Требование:** числовой приоритет **приёма (EXTI)** должен быть **выше приоритета DMA передачи** (в терминах Cortex-M / STM32 HAL: **меньше** значение preempt priority у EXTI, чем у канала DMA ИК).
**В репозитории:**
- **`IR_Decoder`**: библиотека **не** задаёт приоритет EXTI по умолчанию. На Arduino STM32 пользователь вызывает **`setReceiveExtiPreemptPriority(preempt)`** (до или после `enable()`); после `attachInterrupt` применяется поверх приоритета ядра. Семейства с укороченной картой EXTI (C0/F0/G0/L0) — без изменения NVIC из этой функции.
- **DMA ИК-TX** (например **`Car/src/IR/IrDmaBackend.cpp`**): preempt задаётся в прошивке носителя (**`CarIrq::kIrTxDmaPreempt`** и т.д.) и должен быть **больше** (ниже срочность), чем у приёма.
Свой проект: пользователь обязан согласовать приоритеты; **ни один** канал DMA ИК-TX не должен вытеснять EXTI приёма (меньший preempt у DMA = ошибка).
---
## 3. Ключевое наблюдение: `runLenTicks = toggleCounter + 1`
@ -107,6 +120,7 @@ python docs/scripts/ir_protocol_gate_runs_sim.py
1. **Байты в RAM** на передаче формируются корректно библиотекой; проблема «после DMA» укладывается в **расхождение тайминговой развёртки** (`buildGateRuns` + DMA) со **старой** развёрткой ISR, а не в «другой CRC на машинке» при неизменённой библиотеке.
2. **Подозрение №1:** `runLenTicks = toggleCounter + 1` в **`buildGateRuns`** не совпадает с числом тиков ISR между шагами FSM (**`N`** vs **`N+1`**). Требуется сверка с эталонной трассой ISR или логическим анализатором.
3. **Проверка на будущее:** сравнить побитово выходы ISR и DMA на **одном** буфере (8 и 31 байт); при необходимости поправить формулу длины run в **`IR-protocol`** и пересобрать Car и пульт.
4. При **DMA-режиме передачи** на STM32 соблюдать **приоритеты NVIC** (раздел **2.1**): приём EXTI **выше**, чем DMA ИК-TX.
---
@ -115,9 +129,11 @@ python docs/scripts/ir_protocol_gate_runs_sim.py
| Файл | Назначение |
|------|------------|
| `Documents/Arduino/libraries/IR-protocol/IR_Encoder.cpp` | `buildGateRuns`, `_isr`, `rawSend` |
| `Documents/Arduino/libraries/IR-protocol/IR_Decoder.cpp` | `setReceiveExtiPreemptPriority` / `enable`: опциональный `NVIC_SetPriority` для EXTI (Arduino STM32) |
| `Documents/Arduino/libraries/IR-protocol/IR_config.cpp` | `crc8` |
| `Car/src/IR/IR.cpp` | `setExternalTxBackend`, `txStart` |
| `Car/src/IR/IrDmaBackend.cpp` | `startStream`, `totalTicks`, `nextWord` |
| `Car/src/IR/IrDmaBackend.cpp` | `startStream`, `totalTicks`, `nextWord`, NVIC DMA из `CarIrq` |
| `Car/src/IR/IR.cpp` | `setReceiveExtiPreemptPriority` + `enable` декодера |
| `ControlPointUnion/Plan_B/TestPoints/CustomCmd.h` | `sendResp` / `version_query` для тестовых слотов |
---