embassy-rs/embassy · error

When the MSI is used as cpu/system bus clock or clock…

Error message

When the MSI is used as cpu/system bus clock or clock source for any PLL, it is not allowed to be disabled

What it means

Mirror of errors 254/255 for MSI: on STM32N6 the driver panics if an MSI-disable request arrives while MSI is the cpu/system bus clock or the ready input of any running PLL. Disabling would immediately break the active system clock, so the library treats it as a configuration bug.

Solutions

  1. Switch sysclk and stop all MSI-fed PLLs before disabling MSI
  2. Omit the MSI-disable step if MSI is still needed (e.g. for LSE-backed auto-calibration or as a wake clock)
  3. Order the shutdown: PLLs off, sysclk switched, then MSI off

Example fix

// before
disable_msi(); // PLL2 still running off MSI
// after
stop_pll(1);
switch_sysclk_to_hsi();
disable_msi();
Defensive patterns

Strategy: validation

Validate before calling

fn msi_in_use() -> bool {
    sysclk_is(Syssws::Msi) || (0..4).any(|n| pll_ready(n) && pll_source(n) == Pllsel::Msi)
}
assert!(!msi_in_use(), "MSI still clocks sys or a PLL");

Prevention

When it happens

Trigger: Calling the MSI-off path while sys source is MSI, or PLL1-PLL4 running (pllrdy set) with Pllsel::Msi input.

Common situations: Low-power sequences that disable MSI unconditionally; switching sysclk away but forgetting a PLL still uses MSI; MSI-based configs (common on L-series-style code) ported to N6 with a PLL also on MSI.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

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

    debug!("configuring MSI");
    let msi = if let Some(msi) = config.msi {
        RCC.msicfgr().modify(|w| w.set_msifreqsel(msi.freq));
        RCC.csr().write(|w| w.set_msions(true));
        while !RCC.sr().read().msirdy() {}
        RCC.msicfgr().modify(|w| w.set_msitrim(msi.trim));

        Some(match msi.freq {
            Msifreqsel::_4mhz => Hertz::mhz(4),
            Msifreqsel::_16mhz => Hertz::mhz(16),
        })
    } else if cpu_src == Cpusws::Msi
        || sys_src == Syssws::Msi
        || (pll1_src == Pllsel::Msi && rcc_sr.pllrdy(0))
        || (pll2_src == Pllsel::Msi && rcc_sr.pllrdy(1))
        || (pll3_src == Pllsel::Msi && rcc_sr.pllrdy(2))
        || (pll4_src == Pllsel::Msi && rcc_sr.pllrdy(3))
    {
        panic!(
            "When the MSI is used as cpu/system bus clock or clock source for any PLL, it is not allowed to be disabled"
        );
    } else {
        RCC.ccr().write(|w| w.set_msionc(true));
        while RCC.sr().read().msirdy() {}

        None
    };

    // rtc configuration
    let rtc = config.ls.init();
    // lse configuration
    debug!("configuring LSE");
    let lse = config.ls.lse.map(|l| l.frequency);
    // lsi configuration
    debug!("configuring LSI");
    let lsi = config.ls.lsi.then_some(LSI_FREQ);

View on GitHub (pinned to 463a07b963)