embassy-rs/embassy · error
reserved PLL source not allowed
Error message
reserved PLL source not allowed
What it means
During PLL frequency computation for STM32N6, embassy-stm32 matches on the selected PLL source (Pllsel). Only HSI, MSI, HSE and I2S_CKIN are valid; any other Pllsel discriminant (a reserved value, reached via from_bits on raw register/config bits) hits the wildcard arm and panics. It guards against computing frequencies from an undefined clock source.
Solutions
- Set the PLL source to Pllsel::Hsi, Pllsel::Msi, Pllsel::Hse or Pllsel::I2sCkin explicitly
- Ensure the input.hsi/msi/hse/i2s_ckin Option is populated in the RccInput for the chosen source (unwrap! would otherwise panic too)
- Avoid constructing Pllsel from raw bits; use the enum variants
Example fix
// before
let pll = Pll::DivP { source: unsafe { Pllsel::from_bits(0x7) }, divm, divn, divp1, divp2 };
// after
let pll = Pll::DivP { source: Pllsel::Hse, divm, divn, divp1, divp2 }; Defensive patterns
Strategy: validation
Validate before calling
fn pll_source_is_real(s: Pllsel) -> bool {
matches!(s, Pllsel::Hsi | Pllsel::Msi | Pllsel::Hse | Pllsel::I2sCkin)
}
assert!(pll_source_is_real(my_pll.source)); Type guard
fn as_valid_pll_source(bits: u8) -> Option<Pllsel> {
Pllsel::from_bits(bits).filter(|s| !matches!(s, Pllsel::_RESERVED_5 | Pllsel::_RESERVED_6 | Pllsel::_RESERVED_7))
} Prevention
- Never build Pllsel from raw integers; use enum variants
- Only enable the PLL source variants your chip/package supports
- Validate generated/HAL-converted clock configs against the enum before init
When it happens
Trigger: pll_output called with Pll::DivP (non-bypass) config whose `source` field holds a reserved Pllsel value — i.e. a Pllsel constructed from raw bits not corresponding to Hsi/Msi/Hse/I2sCkin.
Common situations: Casting arbitrary integers into Pllsel via from_bits/transmute; a config generated from device-tree or HAL registers containing a reserved encoding; corrupt or vendor-tool-generated clock configs.
Related errors
- PLL source is not ready
- PLL should not be disabled / reconfigured if used for IC1…
- 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/1252942f2a3ad7b6.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-stm32/src/rcc/n6.rs:747
cfgr1.modify(|w| w.set_pllbyp(false));
}
fn pll_output(pll_config: Option<Pll>, input: &PllInput) -> PllOutput {
match pll_config {
Some(Pll::Oscillator {
source,
divm,
fractional: _,
divn,
divp1,
divp2,
}) => {
let in_clk = match source {
Pllsel::Hsi => unwrap!(input.hsi),
Pllsel::Msi => unwrap!(input.msi),
Pllsel::Hse => unwrap!(input.hse),
Pllsel::I2sCkin => unwrap!(input.i2s_ckin),
_ => panic!("reserved PLL source not allowed"),
};
let m = divm.to_bits() as u32;
let n = divn as u32;
let p1 = divp1.to_bits() as u32;
let p2 = divp2.to_bits() as u32;
PllOutput {
divm: Some(Hertz(m)),
divn: Some(Hertz(n)),
divp1: Some(Hertz(p1)),
divp2: Some(Hertz(p2)),
output: Some(Hertz(in_clk.0 / m * n / p1 / p2)),
}
}
Some(Pll::Bypass { source }) => {
let in_clk = match source {
Pllsel::Hsi => unwrap!(input.hsi),
Pllsel::Msi => unwrap!(input.msi),View on GitHub (pinned to 463a07b963)