embassy-rs/embassy · error

time-driver-any requested, but the chip doesn't have a TIM…

Error message

time-driver-any requested, but the chip doesn't have a TIM with at least 2 capture/compare channels.

What it means

When the 'time-driver-any' feature is enabled, embassy-stm32's build script scans the chip's TIM peripherals for one with at least 2 capture/compare channels to back the internal time driver. If no such timer exists in the chip metadata, the build script panics. This is a compile-time error meaning the selected chip cannot supply a default time driver.

Solutions

  1. Pick an explicit time-driver timer feature (e.g. time-driver-tim2) matching a timer the chip actually has.
  2. Verify the selected chip's timer inventory in the datasheet / stm32-metapac.
  3. Use a chip variant with a standard TIM2/TIM3 if the application needs the built-in time driver.
  4. Provide your own time driver via embassy-time-driver instead of time-driver-any.

Example fix

# before
embassy-stm32 = { features = ["stm32wba52cg", "time-driver-any"] }

# after
embassy-stm32 = { features = ["stm32wba52cg", "time-driver-tim2"] }
Defensive patterns

Strategy: validation

Validate before calling

# Verify the chip has a TIM with >=2 CC channels (e.g. TIM2/TIM3) and use an explicit driver:
# embassy-stm32 = { features = ["<chip>", "time-driver-tim2"] }

Prevention

When it happens

Trigger: Building with features embassy-stm32/time-driver-any on a chip whose TIM list contains no timer with >=2 CC channels (very small parts), or on a chip whose timers aren't named TIM*.

Common situations: Selecting a tiny/odd STM32 variant for a library default target; typos in the chip feature name resolving to an unsupported metapac entry; adding time-driver-any to a shared base feature set used by all targets in a workspace.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at embassy-stm32/build.rs:391

                .filter_map(|p| {
                    let regs = p.registers.as_ref()?;
                    if regs.kind != "timer" {
                        return None;
                    }
                    let category = match regs.block {
                        "TIM_GP32" => 0,
                        "TIM_2CH" => 1,
                        "TIM_2CH_CMP" => 2,
                        "TIM_GP16" => 3,
                        "TIM_ADV" => 4,
                        _ => return None,
                    };
                    let number: u32 = p.name.strip_prefix("TIM")?.parse().ok()?;
                    Some(((category, std::cmp::Reverse(number)), p.name))
                })
                .min_by_key(|(rank, _)| *rank)
                .map(|(_, name)| name.to_string())
                .expect("time-driver-any requested, but the chip doesn't have a TIM with at least 2 capture/compare channels.")
        }
        Some(x) => x.to_ascii_uppercase(),
    };

    let time_driver_irq_decl = if !time_driver_singleton.is_empty() {
        cfgs.set(format!("time_driver_{}", time_driver_singleton.to_lowercase()), true);

        let Some((p, regs)) = peripheral_map.get(time_driver_singleton.as_str()) else {
            panic!("Tried to select {time_driver_singleton}, which is not available on this device");
        };

        // Tell the time driver how wide the timer's counter is.
        if regs.kind == "timer" {
            cfgs.enable(if regs.block == "TIM_GP32" {
                "time_driver_32bit"
            } else {
                "time_driver_16bit"
            });

View on GitHub (pinned to 463a07b963)