embassy-rs/embassy · critical
DMA data error
Error message
DMA data error
What it means
The DMA interrupt handler reads the masked interrupt status of control event 0 and panics if the DATAERR bit is set, indicating the DMA controller reported a data error (e.g. invalid burst/increment configuration or bus data issue). Since the driver cannot determine which channel caused it, it panics instead of silently continuing, per the TODO in the source.
Solutions
- Review the DMA channel configuration (data width, burst size, address increment) against the peripheral's DMA requirements in the device datasheet.
- Reduce transfer complexity (single transfers instead of bursts) to isolate which peripheral/channel raises DATAERR.
- Check for FIFO overrun/underrun on the servicing peripheral and fix the peripheral-side error handling.
- Update embassy-mspm0 — the TODO notes DATAERR handling is incomplete, so newer versions may report the channel instead of panicking.
Example fix
// before: width/burst mismatch with peripheral FIFO let cfg = ChannelConfig::default().burst(BurstSize::X4).width(Width::WORD); // after: match peripheral FIFO width (e.g. UART is byte-wide, no burst) let cfg = ChannelConfig::default().width(Width::BYTE);
Defensive patterns
Strategy: validation
Validate before calling
// Sanity-check channel config before starting a transfer: assert!(width_matches_peripheral_fifo(peripheral, cfg.width)); assert!(cfg.burst.is_supported_by(peripheral));
Prevention
- Match DMA width/burst to the peripheral's FIFO width exactly (UART=byte, etc.).
- Bring up DMA transfers with small test buffers first.
- Keep embassy-mspm0 updated; DATAERR/ADDRERR handling is marked TODO and may improve.
- Monitor peripheral error flags when debugging DMA panics.
When it happens
Trigger: A DMA transfer completes/aborts with the controller raising a data error interrupt: typically a misconfigured channel (bad transfer width/burst vs peripheral requirements) or FIFO overrun/underrun feeding the DMA, triggering `mis.dataerr()` in `on_irq`.
Common situations: Configuring a DMA channel for a peripheral with an incompatible data width or address increment; running transfers against a peripheral that signals errors (SPI/UART FIFO issues); firmware bugs corrupting the channel descriptor mid-transfer.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- DMA: error on DMA_0 channel
- DMA: error on DMA_0 channel
- DMA: error on DMA@ channel
- DMA: error on BDMA@ channel
- DMA: error on MDMA@ channel
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/42bf02885a0738be.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-mspm0/src/dma.rs:645
// C1104 has no full DMA channels.
#[allow(unused_macros)]
macro_rules! impl_full_dma_channel {
($instance: ident, $num: expr) => {
impl_dma_channel!($instance, $num);
impl crate::dma::FullChannelInstance for crate::peripherals::$instance {}
};
}
fn on_irq(dma: pac::dma::Dma) {
use crate::BitIter;
let events = dma.int_event(0);
let mis = events.mis().read();
// TODO: Handle DATAERR and ADDRERR? However we do not know which channel causes an error.
if mis.dataerr() {
panic!("DMA data error");
} else if mis.addrerr() {
panic!("DMA address error")
}
// Ignore preirq interrupts (values greater than 16).
for i in BitIter(mis.0 & 0x0000_FFFF) {
if let Some(state) = STATE.get(i as usize) {
state.waker.wake();
// Notify the future that the counter size hit zero
events.imask().modify(|w| {
w.set_ch(i as usize, false);
});
}
}
}
View on GitHub (pinned to 463a07b963)