embassy-rs/embassy · error

HSI is not ready to be selected as CPU clock source

Error message

HSI is not ready to be selected as CPU clock source

What it means

On STM32N6, before switching the CPU clock to HSI, embassy-stm32 verifies the HSI ready flag (`RCC.sr().hsirdy()`). If HSI is not running/stable, selecting it as the CPU clock source would hang or clock-fault, so the library panics.

Solutions

  1. Enable HSI in the rcc config (`hsi: true`) so it is started and ready before selection.
  2. Or pick a CPU clock source that is currently ready (Hse/Msi/Ic1 with proper config).
  3. Check earlier errors/logs: if the intention was a different source, fix `config.cpu`.

Example fix

// before
rcc: RccConfig { cpu: CpuClk::Hsi, ..Default::default() }, // hsi not enabled
// after
rcc: RccConfig { hsi: true, cpu: CpuClk::Hsi, ..Default::default() },
Defensive patterns

Strategy: validation

Validate before calling

if config.rcc.cpu == CpuClk::Hsi && !config.rcc.hsi {
    panic!("CpuClk::Hsi requires hsi: true in rcc config");
}

Type guard

fn cpu_source_configured(cpu: CpuClk, rcc: &RccConfig) -> bool {
    match cpu {
        CpuClk::Hsi => rcc.hsi,
        CpuClk::Hse => rcc.hse.is_some(),
        CpuClk::Msi => rcc.msi.is_some(),
        CpuClk::Ic1 => rcc.ics.first().map_or(false, |ic| ic.is_some()),
    }
}

Prevention

When it happens

Trigger: Setting `config.cpu = CpuClk::Hsi` while `hsirdy()` is false at init time — HSI was never enabled, was disabled in config (`hsi: false`), or has not stabilized.

Common situations: Selecting HSI as CPU clock without enabling it in the rcc config; previous init turned HSI off; very early reinit where HSI enable hadn't completed.

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


AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10). Data as JSON: /api/errors/788bad27500af742. Report an issue: GitHub.

Appendix: source

Thrown at embassy-stm32/src/rcc/n6.rs:355

            w.set_ppre2(config.apb2);
        }
        if config.apb4 > w.ppre4() {
            debug!("  - APB4");
            w.set_ppre4(config.apb4);
        }
        if config.apb5 > w.ppre5() {
            debug!("  - APB5");
            w.set_ppre5(config.apb5);
        }
        if config.ahb > w.hpre() {
            debug!("  - AHB");
            w.set_hpre(config.ahb);
        }
    });
    // cpuclk
    debug!("configuring cpuclk");
    match config.cpu {
        CpuClk::Hsi if !RCC.sr().read().hsirdy() => panic!("HSI is not ready to be selected as CPU clock source"),
        CpuClk::Msi if !RCC.sr().read().msirdy() => panic!("MSI is not ready to be selected as CPU clock source"),
        CpuClk::Hse if !RCC.sr().read().hserdy() => panic!("HSE is not ready to be selected as CPU clock source"),
        CpuClk::Ic1 if !ic_enabled(1) => panic!("IC1 is not ready to be selected as CPU clock source"),
        _ => {}
    }
    // set source
    let cpusw = Cpusw::from_bits(config.cpu.to_bits());
    RCC.cfgr().modify(|w| w.set_cpusw(cpusw));
    // wait for changes to take effect
    while RCC.cfgr().read().cpusws() != Cpusws::from_bits(config.cpu.to_bits()) {}

    // sysclk
    debug!("configuring sysclk");
    match config.sys {
        SysClk::Hsi if !RCC.sr().read().hsirdy() => panic!("HSI is not ready to be selected as system clock source"),
        SysClk::Msi if !RCC.sr().read().msirdy() => panic!("MSI is not ready to be selected as system clock source"),
        SysClk::Hse if !RCC.sr().read().hserdy() => panic!("HSE is not ready to be selected as system clock source"),
        SysClk::Ic2 if !ic_enabled(2) || !ic_enabled(6) || !ic_enabled(11) => panic!(

View on GitHub (pinned to 463a07b963)