embassy-rs/embassy · error
Invalid ahb5_pre for HSI/HSE sysclk: only DIV1 and DIV2 are…
Error message
Invalid ahb5_pre for HSI/HSE sysclk: only DIV1 and DIV2 are allowed
What it means
On STM32WBA, when the system clock source is HSI or HSE, the AHB5 prescaler can only be Div1 or Div2, implemented via the single HDIV5 bit. embassy-stm32's RCC init panics if config.ahb5_pre is set to any HPRE-style divider (Div4, Div8, ...) in this configuration, since the hardware has no encoding for it.
Solutions
- Set config.ahb5_pre to AHB5Prescaler::Div1 or AHB5Prescaler::Div2 while using HSI/HSE sysclk
- If you need deeper AHB5 division, switch sysclk to Sysclk::Pll1R so the full HPRE5 bits are used
- Pre-divide via PLL1 (feed HSI/HSE through PLL1 with a suitable divider) and clock from PLL1R instead
Example fix
// before config.sysclk = Some(Sysclk::Hsi); config.ahb5_pre = AHB5Prescaler::Div4; // panic // after config.sysclk = Some(Sysclk::Hsi); config.ahb5_pre = AHB5Prescaler::Div1; // or Div2 only
Defensive patterns
Strategy: validation
Validate before calling
if matches!(config.sysclk, Some(Sysclk::Hsi) | Some(Sysclk::Hse)) {
assert!(matches!(config.ahb5_pre, AHB5Prescaler::Div1 | AHB5Prescaler::Div2),
"HSI/HSE sysclk allows only Div1/Div2 for AHB5");
} Type guard
fn ahb5_pre_valid_for_hsi_hse(pre: &AHB5Prescaler) -> bool {
matches!(pre, AHB5Prescaler::Div1 | AHB5Prescaler::Div2)
} Prevention
- When switching sysclk source, re-check ahb5_pre constraints for the new source
- Use Div1/Div2 with HSI/HSE; deep dividers require PLL1R sysclk
- Update ahb5_pre whenever porting configs between sysclk sources
- Read the WBA RCC chapter on HDIV5 vs HPRE5 encodings
When it happens
Trigger: rcc init with config.sysclk = Sysclk::Hsi or Sysclk::Hse and config.ahb5_pre = AHB5Prescaler::Div4 (or any divider other than Div1/Div2).
Common situations: Copying an AHB5 prescaler value from a PLL1R-based config and then switching sysclk to HSI/HSE; wanting a large AHB5 divide from the raw oscillator, which the hardware simply does not support.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- The LCD driver needs the RTC/LCD clock to be running
- LSE frequency more than 5% off from 32.768 kHz, cannot use…
- MSIx auto-calibration is enabled for a source that has not…
- LSE frequency more than 5% off from 32.768 kHz, cannot use…
- cannot select OTG_HS reference clock with source frequency…
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/ad70ea3488ff756d.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-stm32/src/rcc/wba.rs:380
w.set_sw(config.sys);
});
while RCC.cfgr1().read().sws() != config.sys {}
RCC.cfgr2().modify(|w| {
w.set_hpre(config.ahb_pre);
w.set_ppre1(config.apb1_pre);
w.set_ppre2(config.apb2_pre);
});
// Set AHB5 prescaler depending on sysclk source
RCC.cfgr4().modify(|w| match config.sys {
// When using HSI or HSE, use HDIV5 bit (0 = div1, 1 = div2)
Sysclk::Hsi | Sysclk::Hse => {
// Only Div1 and Div2 are valid for HDIV5, enforce this
match config.ahb5_pre {
AHB5Prescaler::Div1 => w.set_hdiv5(Hdiv5::Div1),
AHB5Prescaler::Div2 => w.set_hdiv5(Hdiv5::Div2),
_ => panic!("Invalid ahb5_pre for HSI/HSE sysclk: only DIV1 and DIV2 are allowed"),
};
}
// When using PLL1, use HPRE5 bits [2:0]
Sysclk::Pll1R => {
w.set_hpre5(config.ahb5_pre);
}
_ => {}
});
let hclk5 = sys_clk / config.ahb5_pre;
#[cfg(all(stm32wba, peri_usb_otg_hs))]
let usb_refck = match config.mux.otghssel {
Otghssel::Hse => hse,
Otghssel::HseDiv2 => hse.map(|hse_val| hse_val / 2u8),
Otghssel::Pll1P => pll1.p,
Otghssel::Pll1PDiv2 => pll1.p.map(|pll1p_val| pll1p_val / 2u8),
};View on GitHub (pinned to 463a07b963)