{"record":{"id":"34e96bc2f3cbb08a","repo":"embassy-rs/embassy","slug":"when-the-hsi-is-used-as-cpu-system-bus-clock-or-cl","errorCode":null,"errorMessage":"When the HSI is used as cpu/system bus clock or clock source for any PLL, it is not allowed to be disabled","messagePattern":"When the HSI is used as cpu/system bus clock or clock source for any PLL, it is not allowed to be disabled","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-stm32/src/rcc/n6.rs","lineNumber":996,"sourceCode":"    let (hsi, hsi_div) = if let Some(hsi) = config.hsi {\n        RCC.csr().write(|w| w.set_hsions(true));\n        while !RCC.sr().read().hsirdy() {}\n\n        // set divider and calibration\n        RCC.hsicfgr().modify(|w| {\n            w.set_hsidiv(hsi.pre);\n            w.set_hsitrim(hsi.trim);\n        });\n\n        (Some(HSI_FREQ), Some(HSI_FREQ / hsi.pre))\n    } else if cpu_src == Cpusws::Hsi\n        || sys_src == Syssws::Hsi\n        || (pll1_src == Pllsel::Hsi && rcc_sr.pllrdy(0))\n        || (pll2_src == Pllsel::Hsi && rcc_sr.pllrdy(1))\n        || (pll3_src == Pllsel::Hsi && rcc_sr.pllrdy(2))\n        || (pll4_src == Pllsel::Hsi && rcc_sr.pllrdy(3))\n    {\n        panic!(\n            \"When the HSI is used as cpu/system bus clock or clock source for any PLL, it is not allowed to be disabled\"\n        );\n    } else {\n        debug!(\"HSI off\");\n\n        RCC.ccr().write(|w| w.set_hsionc(true));\n        while RCC.sr().read().hsirdy() {}\n\n        (None, None)\n    };\n\n    // msi configuration\n    debug!(\"configuring MSI\");\n    let msi = if let Some(msi) = config.msi {\n        RCC.msicfgr().modify(|w| w.set_msifreqsel(msi.freq));\n        RCC.csr().write(|w| w.set_msions(true));\n        while !RCC.sr().read().msirdy() {}\n        RCC.msicfgr().modify(|w| w.set_msitrim(msi.trim));","sourceCodeStart":978,"sourceCodeEnd":1014,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-stm32/src/rcc/n6.rs#L978-L1014","documentation":"Same in-use guard as error 254 but for HSI: the driver refuses to disable HSI when it is the current cpu/system bus clock or the ready source of any running PLL (PLL1-PLL4), because the STM32N6 hardware does not allow disabling an oscillator that clocks the system or PLLs.","triggerScenarios":"Invoking the HSI-off path while sys source is HSI, or any PLL with pllrdy set uses Pllsel::Hsi as its input.","commonSituations":"Low-power entry or rcc re-init that blindly turns HSI off while HSI still feeds sysclk or a PLL; switching sysclk to a PLL that itself is fed by HSI (so HSI is still in use); partially migrated clock-tree code from another chip.","solutions":["Move sysclk to a source not depending on HSI and stop all HSI-fed PLLs before disabling HSI","Skip disabling HSI if it must remain the backup/active source","Reorder: disable PLL1-4 first, then switch sysclk, then HSI off"],"exampleFix":"// before\nconfig.hsi = None; // HSI still feeds sysclk\nconfig.sys = SysClk::Hsi;\n// after\nconfig.hsi = Some(Hsi { .. });\nconfig.sys = SysClk::Pll1; // PLL1 fed by HSE\nconfig.hsi = None;","handlingStrategy":"validation","validationCode":"fn hsi_in_use() -> bool {\n    sysclk_is(Syssws::Hsi) || (0..4).any(|n| pll_ready(n) && pll_source(n) == Pllsel::Hsi)\n}\nassert!(!hsi_in_use(), \"HSI still clocks sys or a PLL\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember a PLL fed by HSI keeps HSI 'in use' even after sysclk moves elsewhere","Keep HSI enabled as a fallback unless you are sure nothing depends on it","Re-check usage after every runtime clock-tree change"],"tags":["rust","embedded","rcc","hsi","stm32n6","clock-config"],"backgroundTag":"conflicting-config-options","analyzedSha":"463a07b963419a1bfe61d5d597c44acb810afb8b","analyzedAt":"2026-09-10T13:38:26.660Z","contentChangedAt":"2026-09-10T13:38:26.660Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}