embassy-rs/embassy · error
PLL should not be disabled / reconfigured if used for IC2…
Error message
PLL should not be disabled / reconfigured if used for IC2, IC6 or IC11 (sysclksrc)
What it means
Companion guard to error 257 on the system-clock side: when reconfiguring a PLL, if the system clock switch is on IC2 and any of IC2/IC6/IC11 currently select this PLL, disabling it would collapse the system clock, so the driver panics before the disable/reconfigure.
Solutions
- Switch sysclk to a temporary independent source (e.g. HSI via a direct Syssw) before reconfiguring the PLL
- Reconfigure a PLL that is not in the active IC2/IC6/IC11 chain, then retarget the ICs
- Design the final clock tree up front and avoid re-running init_config on a live PLL-fed sysclk
Example fix
// before config.pll2 = Some(new_pll2_cfg); // IC2 chain runs on PLL2 init(config); // after // step 1: switch sysclk off the PLL chain config.sys = SysClk::Hsi; init(config); // step 2: apply new PLL2 and switch back to SysClk::Ic2
Defensive patterns
Strategy: validation
Validate before calling
let sys_src = current_sys_sws();
let chain = [current_ic2_sel(), current_ic6_sel(), current_ic11_sel()];
assert!(!(sys_src == Syssws::Ic2 && chain.contains(&Icsel::from_bits(n as u8))),
"switch sysclk off the IC2 chain before reconfiguring this PLL"); Prevention
- Stage PLL changes while sysclk runs on HSI/MSI directly
- Map your IC2/IC6/IC11 chain on paper before runtime PLL retuning
- Treat any PLL in the active sysclk chain as read-only at runtime
When it happens
Trigger: is_new_pll_config detects a changed PLL n; sys_src == Syssws::Ic2 and ic2_src, ic6_src, or ic11_src equals Icsel::from_bits(n) — the PLL being torn down is part of the active sysclk chain.
Common situations: Runtime retuning of a PLL that feeds the sysclk via IC2/IC6/IC11; re-running init with tweaked PLL dividers on a live system; bootloaders re-entering clock init after switching to a PLL-derived sysclk.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- reserved PLL source not allowed
- PLL source is not ready
- PLL should not be disabled / reconfigured if used for IC1…
- if PLL source is HSI, PLL prediv must be 2.
- if PLL source is PLL2, Config::pll2 must also be set.
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/763775e0ed01f54f.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-stm32/src/rcc/n6.rs:1104
// Return the new sys source
RCC.cfgr().read().syssws()
} else {
sys_src
};
for (n, (&pll, out)) in pll_configs.iter().zip(pll_outputs.iter_mut()).enumerate() {
debug!("configuring PLL{}", n + 1);
let pll_ready = RCC.sr().read().pllrdy(n);
if is_new_pll_config(pll, n) {
let this_pll = Icsel::from_bits(n as u8);
if cpu_src == Cpusws::Ic1 && ic1_src == this_pll {
panic!("PLL should not be disabled / reconfigured if used for IC1 (cpuclksrc)")
}
if sys_src == Syssws::Ic2 && (ic2_src == this_pll || ic6_src == this_pll || ic11_src == this_pll) {
panic!("PLL should not be disabled / reconfigured if used for IC2, IC6 or IC11 (sysclksrc)")
}
*out = pll.map_or_else(
|| {
disable_pll(n);
PllOutput::default()
},
|c| init_pll(Some(c), n, &pll_input),
);
} else if pll.is_some() {
// Config matches current register state.
*out = pll_output(pll, &pll_input);
if !pll_ready {
RCC.csr().write(|w| w.set_pllons(n, true));
while !RCC.sr().read().pllrdy(n) {}
}
}
}View on GitHub (pinned to 463a07b963)