embassy-rs/embassy · error

bad dma channel kind

Error message

bad dma channel kind {}

What it means

build.rs generates `DmaInfo` tokens per DMA channel based on the channel block's `kind` (dma, bdma, gpdma, mdma, lpdma). An unknown kind means the chip metadata tagged a DMA channel with a type embassy-stm32's generator doesn't handle, so the script panics naming the kind. It is a build-time consistency check between chip metadata and supported DMA engines.

Solutions

  1. Update embassy-stm32 to a version that supports the DMA kind present in your chip's metadata.
  2. Fix the chip metadata so the channel kind is one of dma/bdma/gpdma/mdma/lpdma.
  3. Add a match arm in build.rs for the new kind, mapping it to a corresponding DmaInfo variant.

Example fix

// before
let dma_info = match bi.kind {
    "dma" => ..., 
    _ => panic!("bad dma channel kind {}", bi.kind),
};
// after (support new kind)
"newdma" => quote!(crate::dma::DmaInfo::Dma(crate::pac::#dma)),
_ => panic!("bad dma channel kind {}", bi.kind),
Defensive patterns

Strategy: validation

Validate before calling

// metadata sanity check
const VALID: [&str; 5] = ["dma", "bdma", "gpdma", "mdma", "lpdma"];
assert!(VALID.contains(&bi.kind), "bad dma channel kind {}", bi.kind);

Prevention

When it happens

Trigger: Building DMA support for a chip whose metadata has a channel with `bi.kind` outside the five known values — typically from new/unsupported DMA engine types in freshly added chip data.

Common situations: Adding a new STM32 family with a DMA variant not yet handled by the generator; typos or renames in chip metadata kind strings.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at embassy-stm32/build.rs:2711

        if ch.supports_2d.unwrap_or(false) {
            g.extend(quote!(dma_channel_2d_impl!(#name);));
        }

        let dma = format_ident!("{}", ch.dma);
        let ch_num = ch.channel as usize;
        let bi = dma_peri.registers.as_ref().unwrap();

        if ch.supports_2d.unwrap_or(false) && bi.kind == "gpdma" {
            has_gpdma_2d = true;
        }

        let dma_info = match bi.kind {
            "dma" => quote!(crate::dma::DmaInfo::Dma(crate::pac::#dma)),
            "bdma" => quote!(crate::dma::DmaInfo::Bdma(crate::pac::#dma)),
            "gpdma" => quote!(crate::dma::DmaInfo::Gpdma(crate::pac::#dma)),
            "mdma" => quote!(crate::dma::DmaInfo::Mdma(crate::pac::#dma)),
            "lpdma" => quote!(crate::dma::DmaInfo::Lpdma(crate::pac::#dma)),
            _ => panic!("bad dma channel kind {}", bi.kind),
        };

        let dmamux = if has_dmamux {
            match &ch.dmamux {
                Some(dmamux) => {
                    let dmamux = format_ident!("{}", dmamux);
                    let num = ch.dmamux_channel.unwrap() as usize;
                    quote! {
                        dmamux: Some(crate::dma::DmamuxInfo {
                            mux: crate::pac::#dmamux,
                            num: #num,
                        }),
                    }
                }
                None => quote!(dmamux: None),
            }
        } else {
            quote!()

View on GitHub (pinned to 463a07b963)