diff --git a/src/main/drivers/timer_impl_hal.c b/src/main/drivers/timer_impl_hal.c index 8df0f7024d3..93ebec5de86 100644 --- a/src/main/drivers/timer_impl_hal.c +++ b/src/main/drivers/timer_impl_hal.c @@ -528,6 +528,20 @@ void impl_timerPWMPrepareDMA(TCH_t * tch, uint32_t dmaBufferElementCount) DMA_CLEAR_FLAG(tch->dma, DMA_IT_TCIF); } + // Wait for EN bit to actually clear before reconfiguring DMA registers. + // Per STM32F7 RM: writes to DMA_SxNDTR and DMA_SxM0AR are ignored while EN=1. + // The EN bit does not clear synchronously - hardware may still be completing an + // in-progress burst when software writes 0 to EN. + for (uint32_t timeout = 10000; timeout && LL_DMA_IsEnabledStream(dmaBase, streamLL); timeout--) { + __NOP(); + } + if (LL_DMA_IsEnabledStream(dmaBase, streamLL)) { + // EN did not clear - cannot reconfigure this cycle. Skip frame (ESC holds + // last command); EN should clear before the next call. + tch->dmaState = TCH_DMA_IDLE; + return; + } + LL_DMA_SetDataLength(dmaBase, streamLL, dmaBufferElementCount); LL_DMA_ConfigAddresses(dmaBase, streamLL, (uint32_t)tch->dmaBuffer, (uint32_t)impl_timerCCR(tch), LL_DMA_DIRECTION_MEMORY_TO_PERIPH); LL_DMA_EnableIT_TC(dmaBase, streamLL);