embassy-rs/embassy · error

Tried to select , which is not available on this device

Error message

Tried to select {time_driver_singleton}, which is not available on this device

What it means

embassy-stm32's build script validates the time-driver feature selection (e.g. time-driver-tim2) against the peripheral map generated for the selected chip. If the chosen timer does not exist on that chip, the build script panics at compile time. It is an intentional early failure so users get a clear message instead of generated code referencing a nonexistent peripheral.

Solutions

  1. Use the `time-driver-any` feature instead of a specific timer so the build script picks an available timer.
  2. Pick a timer that actually exists on your chip: check the chip's generated peripheral list (embassy-stm32 per-chip metadata or the reference manual).
  3. If you must pin a timer, switch to a chip variant that includes that timer.

Example fix

# before
embassy-stm32 = { version = "...", features = ["stm32g071rb", "time-driver-tim2"] }
# after
embassy-stm32 = { version = "...", features = ["stm32g071rb", "time-driver-any"] }
Defensive patterns

Strategy: validation

Validate before calling

// Cargo.toml check before build
// ensure the timer exists on your chip, or just use time-driver-any:
// features = ["stm32g071rb", "time-driver-any"]

Prevention

When it happens

Trigger: Enabling a specific time-driver cargo feature such as `time-driver-tim2` while building for a chip that has no TIM2 (or forgetting `time-driver-any`), so `peripheral_map.get(time_driver_singleton)` returns None.

Common situations: Porting an example between STM32 families (e.g. an F4 example built for an F0/G0 chip with fewer timers); typos in feature names; chip variants where the timer exists under a different name.

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


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

Appendix: source

Thrown at embassy-stm32/build.rs:400

                        "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"
            });
        }

        if regs.kind == "lptim" && regs.version == "n6" {
            panic!(
                "{time_driver_singleton} does not support use as a time driver on this chip yet: N6's LPTIM \
                 register layout (split isr_output/dier_output/icr_output registers) and RCC clock-mux \
                 selection are not yet implemented for the time driver. Select a TIM-based time driver \
                 (e.g. time-driver-any) instead."
            );

View on GitHub (pinned to 463a07b963)