embassy-rs/embassy · error
PLL should not be disabled / reconfigured if used for IC1…
Error message
PLL should not be disabled / reconfigured if used for IC1 (cpuclksrc)
What it means
During PLL reconfiguration on STM32N6, is_new_pll_config triggers a disable/reconfigure cycle; before doing so the driver checks whether the PLL (as Icsel n) currently feeds IC1, the CPU clock source. If the CPU is switching on IC1 whose source is this very PLL, disabling the PLL would kill the CPU clock, so it panics.
Solutions
- Temporarily switch the CPU clock (Cpusw to IC1 from HSI, or a different IC source) before reconfiguring the PLL
- Reconfigure a different PLL and only then retarget IC1 to it
- Avoid re-running init_config for a PLL that is the active cpuclksrc; plan the clock tree statically
Example fix
// before config.pll1 = Some(new_pll1_cfg); // IC1/PLL1 is current CPU clock init(config); // after // first: switch CPU to HSI via IC1 config.ic1 = Some(Ic1Config::from(hsi_ck)); config.cpu_source = CpuClkSource::IC1; // then apply new PLL1 and switch IC1 back to PLL1
Defensive patterns
Strategy: validation
Validate before calling
// before re-running init_config with a changed PLL n
let cpu_src = current_cpu_sws();
let ic1_src = current_ic1_sel();
assert!(!(cpu_src == Cpusws::Ic1 && ic1_src == Icsel::from_bits(n as u8)),
"move the CPU clock off this PLL before reconfiguring it"); Prevention
- Never re-tune the PLL that is the live cpuclksrc; stage the change via a temporary source
- Do all clock-tree setup once at boot from a static config
- Read back Cpusws/IC selection before mutating PLL configs
When it happens
Trigger: Applying a new rcc config where cpu_src == Cpusws::Ic1 and ic1_src equals the PLL being reconfigured (Icsel::from_bits(n)), i.e. the same PLL is both being torn down and still feeding the CPU clock.
Common situations: Changing PLL1's dividers at runtime while PLL1 is the CPU clock via IC1; re-running init_config with a modified PLL without first moving the CPU clock to a temporary source (like HSI).
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 IC2…
- 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/2148cb350149abd4.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-stm32/src/rcc/n6.rs:1100
debug!("switching sys clock away from IC2 before PLL reconfiguration");
let syssw = Syssw::from_bits(config.sys.to_bits());
RCC.cfgr().modify(|w| w.set_syssw(syssw));
while RCC.cfgr().read().syssws() != Syssws::from_bits(config.sys.to_bits()) {}
// 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));View on GitHub (pinned to 463a07b963)