{"record":{"id":"eb36b8e4aaf86a26","repo":"embassy-rs/embassy","slug":"selected-pclk2-frequency-is-too-high-for-adc-with","errorCode":null,"errorMessage":"Selected PCLK2 frequency is too high for ADC with largest possible prescaler.","messagePattern":"Selected PCLK2 frequency is too high for ADC with largest possible prescaler\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-stm32/src/adc/v2.rs","lineNumber":98,"sourceCode":"    pub fn start_time_us() -> u32 {\n        10\n    }\n}\n\nfn from_pclk2(freq: Hertz) -> Adcpre {\n    // Datasheet for F2 specifies min frequency 0.6 MHz, and max 30 MHz (with VDDA 2.4-3.6V).\n    #[cfg(stm32f2)]\n    const MAX_FREQUENCY: Hertz = Hertz(30_000_000);\n    // Datasheet for both F4 and F7 specifies min frequency 0.6 MHz, typ freq. 30 MHz and max 36 MHz.\n    #[cfg(not(stm32f2))]\n    const MAX_FREQUENCY: Hertz = Hertz(36_000_000);\n    let raw_div = rcc::raw_prescaler(freq.0, MAX_FREQUENCY.0);\n    match raw_div {\n        0..=1 => Adcpre::Div2,\n        2..=3 => Adcpre::Div4,\n        4..=5 => Adcpre::Div6,\n        6..=7 => Adcpre::Div8,\n        _ => panic!(\"Selected PCLK2 frequency is too high for ADC with largest possible prescaler.\"),\n    }\n}\n\n/// ADC configuration\n#[derive(Default)]\npub struct AdcConfig {\n    pub resolution: Option<Resolution>,\n}\n\nimpl AdcRegs for crate::pac::adc::Adc {\n    fn data(&self) -> *mut u16 {\n        crate::pac::adc::Adc::dr(*self).as_ptr() as *mut u16\n    }\n\n    fn enable(&self) {\n        self.cr2().modify(|reg| {\n            reg.set_adon(true);\n        });","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-stm32/src/adc/v2.rs#L80-L116","documentation":"The F1-style ADC (v2) derives its prescaler from PCLK2 using only Div2/4/6/8. The helper `from_pclk2` computes the required division; if even the maximum divide-by-8 leaves the ADC clock over MAX_FREQUENCY, there is no valid ADCCPRE value and the code panics at construction time.","triggerScenarios":"Calling `Adc::new_with_config(...)` (which calls from_pclk2) on an F1 target where PCLK2/8 > MAX_FREQUENCY — i.e., PCLK2 above roughly 8x the ADC clock limit (e.g. PCLK2 > 56 MHz if ADC max is 14 MHz).","commonSituations":"Overclocked or aggressively tuned RCC setups (PCLK2 at 64/72 MHz without ADC-aware clocking); copying a 72 MHz HSE config where APB2 is not divided; older codebases built before ADC clock checks existed.","solutions":["Lower PCLK2 in the RCC config (set APB2 prescaler so PCLK2/8 <= MAX_FREQUENCY, e.g. <=14 MHz)","Reduce SYSCLK/HSE-driven PLL output","Verify PCLK2 frequency with embassy rcc trace output and recalculate the required prescaler"],"exampleFix":"// before\nconfig.rcc.apb2_pre = APB2Prescaler::Div1; // PCLK2 = 72MHz, ADC too fast\n// after\nconfig.rcc.apb2_pre = APB2Prescaler::Div2; // PCLK2 = 36MHz -> ADC = 4.5..9MHz OK","handlingStrategy":"validation","validationCode":"let pclk2_hz = pclk2_frequency();\nlet max_adc_hz = MAX_FREQUENCY.0; // e.g. 14 MHz on F1\nassert!(pclk2_hz / 8 <= max_adc_hz, \"PCLK2 {} too high for ADC\", pclk2_hz);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure APB2 prescaler divides PCLK2 to at most 8x the ADC limit","For F1 at 72 MHz sysclk, keep PCLK2 <= 56 MHz or use a divided ADC clock","Simulate the prescaler table (2/4/6/8) against your PCLK2 in code review","Keep overclocking experiments separate from ADC-using builds"],"tags":["embedded","stm32","adc","clock-config","rust"],"backgroundTag":"value-out-of-range","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"}