embassy-rs/embassy · error
Maximal allowed frequency for ADC4 is
Error message
Maximal allowed frequency for ADC4 is {} MHz and it varies with different packages, refer to ST docs for more information. What it means
The ADC4 driver on STM32C0-family parts clocks the ADC from a kernel clock divided by a prescaler. If, even after applying the largest supported prescaler, the resulting ADC4 clock exceeds MAX_ADC_CLK_FREQ, the constructor panics because the ADC would run outside its datasheet limits, where conversions are inaccurate or unreliable. The limit depends on package/voltage, hence the pointer to ST docs.
Solutions
- Lower the ADC4 kernel clock in your RCC config (choose a slower clock source, e.g. a divided HCLK or a low-speed oscillator)
- Reduce overall system frequency so the derived ADC4 clock fits under MAX_ADC_CLK_FREQ
- Check ST's datasheet/reference manual for the exact MHz limit for your specific package and voltage range
Example fix
// before let config = Config::default(); // ADC4 clock derived from fast HCLK // after: select a slower ADC4 kernel clock in rcc config.rcc.adc4_clock_source = Some(Adc4ClockSource::HCLK / 4); // or a slow oscillator
Defensive patterns
Strategy: validation
Validate before calling
// check before constructing ADC4
let adc_freq = adc4_kernel_clock_hz; // from your RCC config
let max_presc = 128u32; // largest supported prescaler
assert!(adc_freq / max_presc <= MAX_ADC_CLK_FREQ_HZ, "ADC4 clock too high: {}", adc_freq); Prevention
- Compute the ADC4 kernel clock from your RCC tree before writing init code
- Prefer slow clock sources (LSI/HSI/divided HCLK) for ADC kernels
- Check the datasheet limit for your exact package/voltage range
- Add an early debug print of the ADC frequency in bring-up
When it happens
Trigger: Calling `Adc4::new_adc4(...)` (or whatever constructs ADC4 in adc4.rs) while the ADC4 kernel clock frequency divided by the best achievable prescaler still exceeds MAX_ADC_CLK_FREQ — i.e., the peripheral clock source feeding ADC4 is configured too fast in RCC.
Common situations: Running the MCU at a high sysclk/PLL frequency and mapping ADC4's kernel clock from a fast bus clock without lowering it; forgetting to configure ADC4's clock source to a slower oscillator (e.g. HCLK vs. sync/ASYNC slow clock); copying RCC init code from a lower-frequency board.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Maximal allowed frequency for the ADC is
- Maximal allowed frequency for the ADC is
- Selected PCLK2 frequency is too high for ADC with largest…
- Maximal allowed frequency for the ADC is
- not implemented
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/a3c9526dbbbbe731.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-stm32/src/adc/adc4.rs:389
fn wait_done(&self) -> bool {
self.isr().read().eos()
}
}
impl<'d, T: Instance<Regs = crate::pac::adc::Adc4>> super::Adc<'d, T> {
/// Create a new ADC driver.
pub fn new_adc4(adc: Peri<'d, T>) -> Self {
rcc::enable_and_reset::<T>();
let prescaler = from_ker_ck(T::frequency());
T::regs().ccr().modify(|w| w.set_presc(prescaler));
let frequency = T::frequency() / prescaler;
info!("ADC4 frequency set to {}", frequency);
if frequency > MAX_ADC_CLK_FREQ {
panic!(
"Maximal allowed frequency for ADC4 is {} MHz and it varies with different packages, refer to ST docs for more information.",
MAX_ADC_CLK_FREQ.0 / 1_000_000
);
}
T::regs().isr().modify(|w| {
w.set_ldordy(true);
});
T::regs().cr().modify(|w| {
w.set_advregen(true);
});
while !T::regs().isr().read().ldordy() {}
T::regs().isr().modify(|w| {
w.set_ldordy(true);
});
T::regs().cr().modify(|w| w.set_adcal(true));View on GitHub (pinned to 463a07b963)