embassy-rs/embassy · error
Maximal allowed frequency for the ADC is
Error message
Maximal allowed frequency for the ADC is {} MHz and it varies with different packages, refer to ST docs for more information. What it means
The C0-series ADC driver applies a prescaler on the ADC common clock (CCR.PRESC) and picks the largest one it supports. If the ADC clock frequency still exceeds MAX_ADC_CLK_FREQ, the constructor panics, because exceeding the ADC clock limit violates ST's electrical specification and corrupts conversion accuracy. The limit varies per package/voltage, so ST's docs are referenced.
Solutions
- Set the ADC kernel clock source in RCC config to a slower clock (e.g. PCLK/HSI16 with proper division)
- Lower SYSCLK so the derived ADC clock is within the datasheet limit
- Verify the exact MAX_ADC_CLK_FREQ for your package in the ST datasheet and adjust clocking accordingly
Example fix
// before let config = Config::default(); // ADC clock too fast // after config.rcc.adc_clock_source = AdcClockSource::SysClkDiv...; // choose a divided source so adc_clk <= MAX_ADC_CLK_FREQ
Defensive patterns
Strategy: validation
Validate before calling
let adc_clk_hz = adc_kernel_clock_hz(); // from RCC config
assert!(adc_clk_hz <= MAX_ADC_CLK_FREQ_HZ, "ADC clock {} Hz exceeds limit", adc_clk_hz); Prevention
- Design the clock tree with the ADC limit in mind from the start
- Use a dedicated slow kernel-clock source for the ADC
- Verify limits in the C0 datasheet for your package and voltage
- Log ADC frequency at startup during bring-up
When it happens
Trigger: Calling `Adc::new(...)` for an STM32C0 target when T::frequency() (the ADC kernel clock) divided by the maximum prescaler still exceeds MAX_ADC_CLK_FREQ.
Common situations: High system clock (e.g. 48 MHz HSI at max PLL) feeding the ADC with no slow kernel-clock source selected; reusing RCC config from another board; upgrading embassy-stm32 and hitting stricter frequency checks.
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 ADC4 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/3e79593f69ad75c6.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-stm32/src/adc/c0.rs:199
self.isr().read().eoc()
}
}
impl<'d, T: Instance<Regs = crate::pac::adc::Adc>> Adc<'d, T> {
/// Create a new ADC driver.
pub fn new(adc: Peri<'d, T>, resolution: Resolution) -> Self {
rcc::enable_and_reset::<T>();
T::regs().cfgr2().modify(|w| w.set_ckmode(Ckmode::Sysclk));
let prescaler = from_ker_ck(T::frequency());
T::common_regs().ccr().modify(|w| w.set_presc(prescaler));
let frequency = T::frequency() / prescaler;
debug!("ADC frequency set to {}", frequency);
if frequency > MAX_ADC_CLK_FREQ {
panic!(
"Maximal allowed frequency for the ADC 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().cr().modify(|reg| {
reg.set_advregen(true);
});
// "The software must wait for the ADC voltage regulator startup time."
// See datasheet for the value.
block_for_us(TIME_ADC_VOLTAGE_REGUALTOR_STARTUP_US as u64 + 1);
T::regs().cfgr1().modify(|reg| reg.set_res(resolution));
// We have to make sure AUTOFF is OFF, but keep its value after calibration.
let autoff_value = T::regs().cfgr1().read().autoff();
T::regs().cfgr1().modify(|w| w.set_autoff(false));View on GitHub (pinned to 463a07b963)