{"record":{"id":"2148cb350149abd4","repo":"embassy-rs/embassy","slug":"pll-should-not-be-disabled-reconfigured-if-used","errorCode":null,"errorMessage":"PLL should not be disabled / reconfigured if used for IC1 (cpuclksrc)","messagePattern":"PLL should not be disabled / reconfigured if used for IC1 \\(cpuclksrc\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-stm32/src/rcc/n6.rs","lineNumber":1100,"sourceCode":"        debug!(\"switching sys clock away from IC2 before PLL reconfiguration\");\n        let syssw = Syssw::from_bits(config.sys.to_bits());\n        RCC.cfgr().modify(|w| w.set_syssw(syssw));\n        while RCC.cfgr().read().syssws() != Syssws::from_bits(config.sys.to_bits()) {}\n        // Return the new sys source\n        RCC.cfgr().read().syssws()\n    } else {\n        sys_src\n    };\n\n    for (n, (&pll, out)) in pll_configs.iter().zip(pll_outputs.iter_mut()).enumerate() {\n        debug!(\"configuring PLL{}\", n + 1);\n        let pll_ready = RCC.sr().read().pllrdy(n);\n\n        if is_new_pll_config(pll, n) {\n            let this_pll = Icsel::from_bits(n as u8);\n\n            if cpu_src == Cpusws::Ic1 && ic1_src == this_pll {\n                panic!(\"PLL should not be disabled / reconfigured if used for IC1 (cpuclksrc)\")\n            }\n\n            if sys_src == Syssws::Ic2 && (ic2_src == this_pll || ic6_src == this_pll || ic11_src == this_pll) {\n                panic!(\"PLL should not be disabled / reconfigured if used for IC2, IC6 or IC11 (sysclksrc)\")\n            }\n\n            *out = pll.map_or_else(\n                || {\n                    disable_pll(n);\n                    PllOutput::default()\n                },\n                |c| init_pll(Some(c), n, &pll_input),\n            );\n        } else if pll.is_some() {\n            // Config matches current register state.\n            *out = pll_output(pll, &pll_input);\n            if !pll_ready {\n                RCC.csr().write(|w| w.set_pllons(n, true));","sourceCodeStart":1082,"sourceCodeEnd":1118,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-stm32/src/rcc/n6.rs#L1082-L1118","documentation":"During PLL reconfiguration on STM32N6, is_new_pll_config triggers a disable/reconfigure cycle; before doing so the driver checks whether the PLL (as Icsel n) currently feeds IC1, the CPU clock source. If the CPU is switching on IC1 whose source is this very PLL, disabling the PLL would kill the CPU clock, so it panics.","triggerScenarios":"Applying a new rcc config where cpu_src == Cpusws::Ic1 and ic1_src equals the PLL being reconfigured (Icsel::from_bits(n)), i.e. the same PLL is both being torn down and still feeding the CPU clock.","commonSituations":"Changing PLL1's dividers at runtime while PLL1 is the CPU clock via IC1; re-running init_config with a modified PLL without first moving the CPU clock to a temporary source (like HSI).","solutions":["Temporarily switch the CPU clock (Cpusw to IC1 from HSI, or a different IC source) before reconfiguring the PLL","Reconfigure a different PLL and only then retarget IC1 to it","Avoid re-running init_config for a PLL that is the active cpuclksrc; plan the clock tree statically"],"exampleFix":"// before\nconfig.pll1 = Some(new_pll1_cfg); // IC1/PLL1 is current CPU clock\ninit(config);\n// after\n// first: switch CPU to HSI via IC1\nconfig.ic1 = Some(Ic1Config::from(hsi_ck));\nconfig.cpu_source = CpuClkSource::IC1;\n// then apply new PLL1 and switch IC1 back to PLL1","handlingStrategy":"validation","validationCode":"// before re-running init_config with a changed PLL n\nlet cpu_src = current_cpu_sws();\nlet ic1_src = current_ic1_sel();\nassert!(!(cpu_src == Cpusws::Ic1 && ic1_src == Icsel::from_bits(n as u8)),\n        \"move the CPU clock off this PLL before reconfiguring it\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never re-tune the PLL that is the live cpuclksrc; stage the change via a temporary source","Do all clock-tree setup once at boot from a static config","Read back Cpusws/IC selection before mutating PLL configs"],"tags":["rust","embedded","rcc","pll","stm32n6","cpu-clock"],"backgroundTag":"invalid-state-transition","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"}