embassy-rs/embassy · error
if PLL source is HSI, PLL prediv must be 2.
Error message
if PLL source is HSI, PLL prediv must be 2.
What it means
On certain STM32 F0/F1/F3 parts (not rcc_f0v3/f0v4/f3v3 silicon), the RCC hardware hardwires the HSI path into the PLL to a fixed divide-by-2, so the configurable prediv is ignored. embassy-stm32 panics at init if you specify PllSource::HSI with a PllPreDiv other than Div2, since the requested prediv cannot actually be applied.
Solutions
- Set pll.prediv to PllPreDiv::Div2 when using PllSource::HSI on these parts.
- If you need a different prediv, switch the PLL source to HSE, which honors the configurable prediv.
- Adjust the pll.mul value to compensate so the target PLL output frequency is still achieved with /2.
Example fix
// before
let config = Config {
pll: Some(Pll { source: PllSource::HSI, prediv: PllPreDiv::Div1, mul: Mul::Mul6 }),
..Default::default()
};
// after
let config = Config {
pll: Some(Pll { source: PllSource::HSI, prediv: PllPreDiv::Div2, mul: Mul::Mul12 }),
..Default::default()
}; Defensive patterns
Strategy: validation
Validate before calling
if pll.source == PllSource::HSI {
assert!(pll.prediv == PllPreDiv::Div2, "HSI PLL source requires prediv = Div2 on this chip");
} Prevention
- HSI is hardwired to /2 on most F0/F1/F3 (except F0v3/F0v4/F3v3).
- Compensate frequency changes via pll.mul, not prediv, when using HSI.
- Check the cfg feature gates for your exact chip before reusing PLL configs across boards.
When it happens
Trigger: Calling embassy_stm32::rcc init with Config containing pll configured as PllSource::HSI and prediv set to Div1, Div3, Div4, etc., on a target where cfg(not(any(rcc_f0v3, rcc_f0v4, rcc_f3v3))) applies.
Common situations: Porting an RCC config from an F0 v3 or F3 v3 board to a different F0/F3 chip that hardwires HSI/2; copying PLL setups between chip families; assuming prediv is a general-purpose knob on HSI source.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- if PLL source is PLL2, Config::pll2 must also be set.
- must not select PLL source as DISABLE
- PLL is unavailable in voltage range 4
- The LCD driver needs the RTC/LCD clock to be running
- Source must be equal across all enabled PLLs.
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/3866620769f383a0.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-stm32/src/rcc/f013.rs:254
}
// Configure PLL3
if let Some(pll3) = config.pll3 {
RCC.cfgr2().modify(|w| w.set_pll3mul(pll3.mul));
RCC.cr().modify(|w| w.set_pll3on(true));
while !RCC.cr().read().pll3rdy() {}
}
}
// Enable PLL
let pll = config.pll.map(|pll| {
let (src_val, src_freq) = match pll.src {
#[cfg(any(rcc_f0v3, rcc_f0v4, rcc_f3v3))]
PllSource::HSI => (Pllsrc::HsiDivPrediv, unwrap!(hsi)),
#[cfg(not(any(rcc_f0v3, rcc_f0v4, rcc_f3v3)))]
PllSource::HSI => {
if pll.prediv != PllPreDiv::Div2 {
panic!("if PLL source is HSI, PLL prediv must be 2.");
}
(Pllsrc::HsiDiv2, unwrap!(hsi))
}
PllSource::HSE => {
#[cfg(any(stm32f105, stm32f107))]
RCC.cfgr2().modify(|w| w.set_prediv1src(Prediv1src::Hse));
(Pllsrc::HseDivPrediv, unwrap!(hse))
}
#[cfg(rcc_f0v4)]
PllSource::HSI48 => (Pllsrc::Hsi48DivPrediv, unwrap!(hsi48)),
#[cfg(any(stm32f105, stm32f107))]
PllSource::PLL2 => {
if config.pll2.is_none() {
panic!("if PLL source is PLL2, Config::pll2 must also be set.");
}
RCC.cfgr2().modify(|w| w.set_prediv1src(Prediv1src::Pll2));
View on GitHub (pinned to 463a07b963)