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
- Set pll.source to PllSource::Hse, PllSource::Hsi, or PllSource::Msis (and ensure that clock is configured so input.hse/hsi/msi is Some)
- 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
- To disable a PLL, pass None for its config, never PllSource::Disable inside Some
- Pick Hse/Hsi/Msis explicitly and ensure that clock is initialized
- Avoid leaving scaffolding enum variants in shipped configs
- Copy complete PLL configs, not partially reset ones
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
- if PLL source is HSI, PLL prediv must be 2.
- if PLL source is PLL2, Config::pll2 must also be set.
- must not set PllSource::Disable
- LSE frequency more than 5% off from 32.768 kHz, cannot use…
- MSIx auto-calibration is enabled for a source that has not…
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)