embassy-rs/embassy · critical

DMA: data transfer error on DMA@

Error message

DMA: data transfer error on DMA@{:08x} channel {}

What it means

The GPDMA channel interrupt handler read the data transfer error flag (DTEF) in the channel status register, meaning a bus error occurred during the transfer: bad address, illegal access, or aborted transaction. The driver panics because a data transfer error leaves the DMA state undefined and the peripheral access was invalid.

Solutions

  1. Ensure the buffer is in RAM accessible by the DMA (use DMA-capable memory, avoid DTCM/ITCM on parts where GPDMA can't reach it)
  2. Check that buffer addresses are properly aligned for the transfer word size
  3. Verify the buffer outlives the transfer (no scope exit or move while DMA is active)
  4. Re-check the peripheral request line / address configuration (e.g. correct data register address)

Example fix

// before
#[link_section = ".dtcm"]
static mut BUF: [u8; 64] = [0; 64]; // unreachable by GPDMA
// after
static mut BUF: [u8; 64] = [0; 64]; // in normal SRAM reachable by DMA
Defensive patterns

Strategy: validation

Validate before calling

fn dma_accessible(buf_addr: u32, len: u32) -> bool {
    // GPDMA typically reaches SRAM1-4/AHB SRAM, not DTCM/ITCM on many parts
    (0x2000_0000..0x2004_0000).contains(&buf_addr)
        && buf_addr % 4 == 0 // alignment for max word size used
}

Prevention

When it happens

Trigger: DMA programmed with an invalid source/destination address (e.g. unmapped memory, unaligned address for the required width); peripheral FIFO underrun/overrun on the AHB/AXI bus; buffer invalidated or stack memory moved after configuration.

Common situations: Passing a buffer in flash or core-coupled memory (DTCM) that the GPDMA bus master cannot reach; buffer freed/stack-unwound while DMA still running; wrong word size making the end address unaligned.

Related errors


AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10). Data as JSON: /api/errors/3c1f210a5c31da9e. Report an issue: GitHub.

Appendix: source

Thrown at embassy-stm32/src/dma/gpdma/mod.rs:562

    crate::_generated::init_gpdma();
    crate::_generated::init_lpdma();
}

pub(crate) unsafe fn on_irq(channel: DmaChannel) {
    let info = super::info(channel);
    #[cfg(feature = "_dual-core")]
    {
        use embassy_hal_internal::interrupt::InterruptExt as _;
        info.irq.enable();
    }

    let state = &STATE[channel as usize];

    let ch = info.dma.ch(info.num);
    let sr = ch.sr().read();

    if sr.dtef() {
        panic!(
            "DMA: data transfer error on DMA@{:08x} channel {}",
            info.dma.cast().as_ptr() as u32,
            info.num
        );
    }
    if sr.usef() {
        panic!(
            "DMA: user settings error on DMA@{:08x} channel {}",
            info.dma.cast().as_ptr() as u32,
            info.num
        );
    }
    if sr.ulef() {
        panic!(
            "DMA: link transfer error on DMA@{:08x} channel {}",
            info.dma.cast().as_ptr() as u32,
            info.num
        );

View on GitHub (pinned to 463a07b963)