embassy-rs/embassy · error

must not select PLL source as DISABLE

Error message

must not select PLL source as DISABLE

What it means

embassy-stm32's STM32U5 init_pll panics if the PLL configuration's source is PllSource::Disable. init_pll is only reached when a PLL config is actually present; selecting Disable as the source is contradictory — to disable the PLL you must pass None for the whole PLL config, not a PLL config with a Disabled source.

Solutions

  1. Set pll.source to PllSource::Hse, PllSource::Hsi, or PllSource::Msis (and ensure that clock is configured so input.hse/hsi/msi is Some)
  2. If you intend no PLL, pass None for the PLL config instead of a config with a Disable source

Example fix

// before
let pll = Some(PllConfig { source: PllSource::Disable, m: 1, n: 40, divp: ..., ... });
// after
let pll = Some(PllConfig { source: PllSource::Hsi, m: 1, n: 40, divp: ..., ... });
// or to disable the PLL entirely:
let pll = None;
Defensive patterns

Strategy: validation

Validate before calling

if let Some(pll) = &config.pll1 {
    assert!(pll.source != PllSource::Disable, "set a real PLL source or pass None");
}

Type guard

fn pll_configured(pll: &Option<PllConfig>) -> bool {
    matches!(pll, Some(p) if p.source != PllSource::Disable)
}

Prevention

When it happens

Trigger: Setting pll.source = PllSource::Disable while still supplying the Some(pll_config) to init_pll via rcc init (e.g. leaving a copied config's source field at its Disable default).

Common situations: Copying an RCC config where only source was reset to Disable; scaffolding a new PLL config from an enum and forgetting to pick Hse/Hsi/Msis; refactoring code and nulling the source instead of the whole PLL option.

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/6f75aa496af8f213. Report an issue: GitHub.

Appendix: source

Thrown at embassy-stm32/src/rcc/u5.rs:617

enum PllInstance {
    Pll1 = 0,
    Pll2 = 1,
    Pll3 = 2,
}

fn pll_enable(instance: PllInstance, enabled: bool) {
    RCC.cr().modify(|w| w.set_pllon(instance as _, enabled));
    while RCC.cr().read().pllrdy(instance as _) != enabled {}
}

fn init_pll(instance: PllInstance, config: Option<Pll>, input: &PllInput, voltage_range: VoltageScale) -> PllOutput {
    // Disable PLL
    pll_enable(instance, false);

    let Some(pll) = config else { return PllOutput::default() };

    let src_freq = match pll.source {
        PllSource::Disable => panic!("must not select PLL source as DISABLE"),
        PllSource::Hse => unwrap!(input.hse),
        PllSource::Hsi => unwrap!(input.hsi),
        PllSource::Msis => unwrap!(input.msi),
    };

    // Calculate the reference clock, which is the source divided by m
    let ref_freq = src_freq / pll.prediv;
    // Check limits per RM0456 § 11.4.6
    assert!(Hertz::mhz(4) <= ref_freq && ref_freq <= Hertz::mhz(16));

    // Check PLL clocks per RM0456 § 11.4.10
    let (vco_min, vco_max, out_max) = match voltage_range {
        VoltageScale::Range1 => (Hertz::mhz(128), Hertz::mhz(544), Hertz::mhz(208)),
        VoltageScale::Range2 => (Hertz::mhz(128), Hertz::mhz(544), Hertz::mhz(110)),
        VoltageScale::Range3 => (Hertz::mhz(128), Hertz::mhz(330), Hertz::mhz(55)),
        VoltageScale::Range4 => panic!("PLL is unavailable in voltage range 4"),
    };

View on GitHub (pinned to 463a07b963)