embassy-rs/embassy · error
invalid word size
Error message
invalid word size
What it means
In bDMA channel configuration, the NDTR (number of data to transfer) computation panics when either the memory or peripheral side uses WordSize::EightBytes, which this hardware path does not implement. The library throws it early in configure() rather than programming a wrong word-size field. It signals the requested transfer width is invalid for this DMA instance.
Solutions
- Reconfigure the transfer with OneByte, TwoBytes or FourBytes word sizes on both sides
- Convert the u64 buffer to a u32 (or smaller) buffer before the transfer
- Verify the mem_len alignment assertion matches the chosen word size (mem_len % word_bytes == 0)
- Update the driver's match arms if the target chip's bDMA actually supports 64-bit sizes
Example fix
// before let wsize = WordSize::EightBytes; ch.configure(None, peri_addr, &mem_buf, ..., wsize, ...); // after let wsize = WordSize::FourBytes; ch.configure(None, peri_addr, &mem_buf32, ..., wsize, ...);
Defensive patterns
Strategy: validation
Validate before calling
fn check_transfer(mem: &[u32], peri_ws: WordSize) {
assert!(!matches!(peri_ws, WordSize::EightBytes));
assert!(mem.len() > 0 && mem.len() <= 0xFFFF);
} Type guard
fn is_valid_word_size(ws: WordSize) -> bool {
!matches!(ws, WordSize::EightBytes)
} Try / catch
if !is_valid_word_size(ws) {
return Err(Err::WordSizeUnsupported);
}
ch.configure(..., ws, ...); Prevention
- Never configure EightBytes on bDMA channels
- Ensure buffer length is a multiple of the word size and <= 0xFFFF
- Assert word sizes at config wrapper level
- Document word-size limits in your driver wrappers
When it happens
Trigger: Calling channel.configure()/start with mem or peri word size of EightBytes (e.g. &[u64] buffer); the match arm (WordSize::EightBytes, _) | (_, WordSize::EightBytes) is hit.
Common situations: DMA-ing arrays of f64/u64 samples; generic driver code instantiated with a 64-bit word type; buffer alignment mistakes leading a caller to pick the largest word size.
Related errors
- not implemented
- invalid burst size
- Invalid word size
- DMA: data transfer error on DMA@
- DMA: user settings error on DMA@
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/5bc5b3f72e1edc73.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-stm32/src/dma/dma_bdma.rs:559
};
// NDTR is the number of transfers in the *peripheral* word size.
// ex: if mem_size=1, peri_size=4 and ndtr=3 it'll do 12 mem transfers, 3 peri transfers.
let ndtr = match (mem_size, peri_size) {
(WordSize::FourBytes, WordSize::OneByte) => mem_len * 4,
(WordSize::FourBytes, WordSize::TwoBytes) | (WordSize::TwoBytes, WordSize::OneByte) => mem_len * 2,
(WordSize::FourBytes, WordSize::FourBytes)
| (WordSize::TwoBytes, WordSize::TwoBytes)
| (WordSize::OneByte, WordSize::OneByte) => mem_len,
(WordSize::TwoBytes, WordSize::FourBytes) | (WordSize::OneByte, WordSize::TwoBytes) => {
assert!(mem_len % 2 == 0);
mem_len / 2
}
(WordSize::OneByte, WordSize::FourBytes) => {
assert!(mem_len % 4 == 0);
mem_len / 4
}
(WordSize::EightBytes, _) | (_, WordSize::EightBytes) => unimplemented!("invalid word size"),
};
assert!(ndtr > 0 && ndtr <= 0xFFFF);
ch.par().write_value(peri_addr as u32);
ch.m0ar().write_value(mem_addr as u32);
ch.ndtr().write_value(pac::dma::regs::Ndtr(ndtr as _));
ch.fcr().write(|w| {
if let Some(fth) = options.fifo_threshold {
// FIFO mode
w.set_dmdis(pac::dma::vals::Dmdis::Disabled);
w.set_fth(fth.into());
} else if mem_size != peri_size {
// force FIFO mode if msize != psize
// packing/unpacking doesn't work in direct mode.
w.set_dmdis(pac::dma::vals::Dmdis::Disabled);
w.set_fth(FifoThreshold::Half.into());
} else {View on GitHub (pinned to 463a07b963)