{"record":{"id":"289f89603867e98b","repo":"embassy-rs/embassy","slug":"must-not-set-pllsource-disable","errorCode":null,"errorMessage":"must not set PllSource::Disable","messagePattern":"must not set PllSource::Disable","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-stm32/src/rcc/h.rs","lineNumber":963,"sourceCode":"    #[allow(dead_code)]\n    t: Option<Hertz>,\n}\n\nfn disable_pll(num: usize) {\n    // Stop PLL\n    RCC.cr().modify(|w| w.set_pllon(num, false));\n    while RCC.cr().read().pllrdy(num) {}\n\n    // \"To save power when PLL1 is not used, the value of PLL1M must be set to 0.\"\"\n    #[cfg(any(stm32h7, stm32h7rs))]\n    RCC.pllckselr().write(|w| w.set_divm(num, PllPreDiv::from_bits(0)));\n    #[cfg(stm32h5)]\n    RCC.pllcfgr(num).write(|w| w.set_divm(PllPreDiv::from_bits(0)));\n}\n\nfn init_pll(num: usize, config: Pll, input: &PllInput) -> PllOutput {\n    let in_clk = match config.source {\n        PllSource::Disable => panic!(\"must not set PllSource::Disable\"),\n        PllSource::Hsi => unwrap!(input.hsi),\n        PllSource::Hse => unwrap!(input.hse),\n        PllSource::Csi => unwrap!(input.csi),\n    };\n\n    let ref_clk = in_clk / config.prediv as u32;\n\n    let ref_range = match ref_clk.0 {\n        ..=1_999_999 => Pllrge::Range1,\n        ..=3_999_999 => Pllrge::Range2,\n        ..=7_999_999 => Pllrge::Range4,\n        ..=16_000_000 => Pllrge::Range8,\n        x => panic!(\"pll ref_clk out of range: {} hz\", x),\n    };\n\n    // The smaller range (150 to 420 MHz) must\n    // be chosen when the reference clock frequency is lower than 2 MHz.\n    let wide_allowed = ref_range != Pllrge::Range1;","sourceCodeStart":945,"sourceCodeEnd":981,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-stm32/src/rcc/h.rs#L945-L981","documentation":"init_pll is only called for PLLs the user actually configured, and PllSource::Disable means 'this PLL is off'. Passing Disable inside a Pll config is contradictory — there is no input clock to divide — so init_pll panics immediately. Every configured PLL must give a real source: Hsi, Hse or Csi.","triggerScenarios":"Constructing a Pll { source: PllSource::Disable, .. } and putting it into config.pll1/pll2/pll3 on H7/H5/WL-family targets, so init -> init_pll receives Disable.","commonSituations":"Building PLL configs programmatically where a default() starts with Disable and was never replaced; copy-pasting a 'disabled' placeholder struct into the config; generic code that fills Config pll fields unconditionally.","solutions":["Remove the PLL from the Config (set the field to None) if it should be disabled — do not configure it with PllSource::Disable.","Set source to PllSource::Hsi, Hse or Csi (whichever the board provides) in the Pll struct.","Check constructors/builders for a default source of Disable being left in place."],"exampleFix":"// before\nlet config = Config {\n    pll1: Some(Pll { source: PllSource::Disable, prediv: PllPreDiv::Div1, ..Default::default() }),\n    ..Default::default()\n};\n// after\nlet config = Config {\n    pll1: Some(Pll { source: PllSource::Hse, prediv: PllPreDiv::Div1, ..Default::default() }),\n    ..Default::default()\n};","handlingStrategy":"validation","validationCode":"fn configured(pll: &Option<Pll>) -> bool {\n    pll.as_ref().map_or(true, |p| p.source != PllSource::Disable)\n}\nassert!(configured(&config.pll1) && configured(&config.pll2) && configured(&config.pll3));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use None (not PllSource::Disable) to express 'PLL off'.","Audit builders/default() paths that may seed source: Disable into configured PLLs.","Search your config-construction code for PllSource::Disable and remove those entries."],"tags":["rust","embedded","rcc","pll","panic"],"backgroundTag":"invalid-enum-value","analyzedSha":"463a07b963419a1bfe61d5d597c44acb810afb8b","analyzedAt":"2026-09-10T13:38:26.660Z","contentChangedAt":"2026-09-10T13:38:26.660Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}