diff --git a/IR_config.h b/IR_config.h index afdfff5..31f439e 100644 --- a/IR_config.h +++ b/IR_config.h @@ -6,6 +6,13 @@ /** Число потоков DMA-TX задаётся шаблоном: IrDmaTxStm32<2>, см. IrDmaTxStm32.h и irproto::kDefaultDmaTxMaxStreams. */ namespace irproto { constexpr size_t kDefaultDmaTxMaxStreams = 4U; +/** NVIC-приоритет IRQ DMA-каналов TX (refill кольца BSRR-слов). Refill длинный (полубуфер + * 2048 слов = миллисекунды на небыстрых SYSCLK), а его дедлайн мягкий (~9 мс при 38кГц×6), + * поэтому он обязан сидеть НИЖЕ SysTick (0) и EXTI приёмника (6): с приоритетом по умолчанию + * (0, HAL_NVIC_EnableIRQ без SetPriority) он не вытеснялся SysTick'ом, тики слипались и + * millis() замедлялся в 1.6×/2.2× (один/два потока) на всё время передачи — мерено на стенде + * TofSickHunt 2026-08-11. Меньше число = выше приоритет; 8 = ниже EXTI, выше самого дна. */ +constexpr uint32_t kDmaTxIrqPriority = 8U; /** Кольцевой буфер BSRR-слов для ISR-TX (как у DMA: два полублока). Чётное число. */ constexpr uint16_t kIsrTxBsrrWordCount = 256U; /** Максимум RLE-сегментов для buildGateRuns при ISR-TX. */ diff --git a/IrDmaTxStm32.h b/IrDmaTxStm32.h index 2e71fe2..3ef0549 100644 --- a/IrDmaTxStm32.h +++ b/IrDmaTxStm32.h @@ -87,6 +87,10 @@ public: s_instance = this; for (uint8_t i = 0; i < streamCount_; i++) { + // Приоритет ЯВНО и ДО включения: без SetPriority канал остаётся на 0 (уровень + // SysTick), длинный refill не вытесняется и глотает тики millis. Обоснование + // и измерения — у irproto::kDmaTxIrqPriority (IR_config.h). + HAL_NVIC_SetPriority(streams_[i].dmaIrq, irproto::kDmaTxIrqPriority, 0); HAL_NVIC_EnableIRQ(streams_[i].dmaIrq); }