HAL_DMA_ERROR_BUSY embedded resource_error ai_generated true

DMA: stream already enabled, cannot reconfigure while busy

ID: embedded/dma-configuration-busy-flag

Also available as: JSON · Markdown · 中文
88%Fix Rate
87%Confidence
1Evidence
2023-09-12First Seen

Root Cause

A DMA stream or channel is being reconfigured (e.g., changing source/destination address or transfer size) while the DMA peripheral is still active (EN bit set), causing a write to read-only registers or a bus error.

generic

中文

在DMA外设仍处于活动状态(EN位已置位)时重新配置DMA流或通道(如更改源/目标地址或传输大小),导致对只读寄存器的写入或总线错误。

Official Documentation

https://www.st.com/resource/en/reference_manual/dm00031020-stm32f405xx-stm32f407xx-stm32f415xx-stm32f417xx-reference-manual.pdf

Workarounds

  1. 90% success Disable the DMA stream before reconfiguration. Example: hdma->Instance->CCR &= ~DMA_CCR_EN; while (hdma->Instance->CCR & DMA_CCR_EN); // Wait for disable confirmation
    Disable the DMA stream before reconfiguration. Example: hdma->Instance->CCR &= ~DMA_CCR_EN; while (hdma->Instance->CCR & DMA_CCR_EN); // Wait for disable confirmation
  2. 85% success Use a state machine to ensure DMA is only reconfigured after transfer completion interrupt. Check the Transfer Complete flag before calling HAL_DMA_Start_IT again.
    Use a state machine to ensure DMA is only reconfigured after transfer completion interrupt. Check the Transfer Complete flag before calling HAL_DMA_Start_IT again.

中文步骤

  1. Disable the DMA stream before reconfiguration. Example: hdma->Instance->CCR &= ~DMA_CCR_EN; while (hdma->Instance->CCR & DMA_CCR_EN); // Wait for disable confirmation
  2. Use a state machine to ensure DMA is only reconfigured after transfer completion interrupt. Check the Transfer Complete flag before calling HAL_DMA_Start_IT again.

Dead Ends

Common approaches that don't work:

  1. 75% fail

    Calling HAL_DMA_Abort() and then immediately reconfiguring without waiting for the abort completion flag results in the same busy state.

  2. 50% fail

    Resetting the DMA peripheral via RCC reset does clear the busy flag but also loses all configuration, requiring full re-initialization.