embassy-rs/embassy · error
PLL source is not ready
Error message
PLL source is not ready
What it means
When enabling or reconfiguring a PLL on STM32N6, embassy-stm32 first verifies the chosen PLL input source (via pll_source_ready, which reads the source oscillator's ready flag in RCC.sr) is actually running. If the source oscillator is not ready it panics rather than waiting forever on a PLL that can never lock.
Solutions
- Enable and configure the PLL's source oscillator in the same rcc config (e.g. config.hse = Some(Hse...)) so it is started before the PLL
- Or choose a different, already-enabled PLL source (HSI/MSI)
- Check the board actually has the oscillator (HSE crystal) the config references
Example fix
// before
config.pll1 = Some(Pll::DivP { source: Pllsel::Hse, .. }); // HSE not enabled
// after
config.hse = Some(Hse { freq: Megahertz::new(48), mode: HseMode::Oscillator });
config.pll1 = Some(Pll::DivP { source: Pllsel::Hse, .. }); Defensive patterns
Strategy: validation
Validate before calling
// before enabling a PLL on HSE, confirm HSE is on and ready
let sr = unsafe { (*stm32_metapac::RCC::ptr()).sr().read() };
assert!(sr.hserdy(), "enable HSE in rcc config before using it as PLL source"); Prevention
- Always configure the PLL's source oscillator in the same rcc config
- Verify the board physically has the HSE crystal if your config uses HSE
- Check pll_source_ready semantics: the source must already be running, init will not start it for the PLL
When it happens
Trigger: init_config with a Pll::DivP or Pll::Bypass whose source oscillator (HSI/MSI/HSE) has not been enabled or has not stabilized when the PLL is configured — e.g. HSE given in config but its crystal/enable bits not set, or PLL::Bypass { source: Hse } while HSE is disabled.
Common situations: Requesting a PLL fed by HSE while the board has no HSE crystal or the HSE config was omitted; MSI/HSI turned off in the same config while still used as PLL input; very early init before oscillator startup.
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
- IC source was set to PLL , but it is not currently enabled
- IC2 is not ready to be selected as system clock source…
- reserved PLL source not allowed
- When the HSE is used as cpu/system bus clock or clock…
- When the HSI is used as cpu/system bus clock or clock…
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/4dfaf0da55ca6d40.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-stm32/src/rcc/n6.rs:845
// enable pll post divider output
cfgr3.modify(|w| {
w.set_pllmodssrst(true);
w.set_pllpdiven(true);
});
// enable the pll
debug!("PLL{}: enabling", pll_index + 1);
RCC.csr().write(|w| w.set_pllons(pll_index, true));
// wait until ready
debug!("PLL{}: waiting for ready", pll_index + 1);
while !RCC.sr().read().pllrdy(pll_index) {}
debug!("PLL{}: ready", pll_index + 1);
pll_output(pll_config, input)
}
Some(Pll::Bypass { source }) => {
// check if source is ready
if !pll_source_ready(source.to_bits()) {
panic!("PLL source is not ready")
}
// ensure pll is disabled
RCC.ccr().write(|w| w.set_pllonc(pll_index, true));
while RCC.sr().read().pllrdy(pll_index) {}
cfgr1.modify(|w| {
w.set_pllbyp(true);
w.set_pllsel(source);
});
pll_output(pll_config, input)
}
None => {
disable_pll(pll_index);
PllOutput::default()
}View on GitHub (pinned to 463a07b963)