embassy-rs/embassy · error
Invalid HCLK frequency - should be at least 25 MHz.
Error message
Invalid HCLK frequency - should be at least 25 MHz.
What it means
The v1 Ethernet Station Management block derives MDC from HCLK. To keep MDC in the 1–2.5 MHz window, HCLK must be at least 25 MHz so the smallest divider is valid; below that no clock-range value exists and the driver panics.
Solutions
- Raise HCLK1 to at least 25 MHz in the RCC config before creating the Ethernet driver.
- Verify rcc::get_freqs().hclk1 is nonzero and correct after RCC init.
- Use a board RCC default meeting Ethernet clocking requirements.
Example fix
// before config.sys = Sysclk::HSI; // ~16 MHz // after config.sys = Sysclk::PLL1_R; // 80 MHz PLL -> hclk >= 25 MHz
Defensive patterns
Strategy: validation
Validate before calling
let hclk = embassy_stm32::rcc::get_freqs().hclk1.0;
assert!(hclk >= 25_000_000, "Ethernet requires HCLK1 >= 25 MHz, got {}", hclk); Prevention
- Size the RCC PLL so HCLK1 >= 25 MHz whenever Ethernet is used.
- Check get_freqs().hclk1 right after RCC init.
When it happens
Trigger: Constructing the v1 StationManagement while rcc hclk1 is < 25 MHz (hclk_mhz in 0..=24).
Common situations: Low-power/HSI-only clock configs; hclk1 unassigned or very small; early bring-up before RCC is fully configured.
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
- HCLK results in MDC clock > 2.5MHz even for the highest CSR…
- HCLK results in MDC clock > 2.5MHz even for the highest CSR…
- Maximal allowed frequency for ADC4 is
- Maximal allowed frequency for the ADC is
- Maximal allowed frequency for the ADC is
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/c485f9db5b2c92c8.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-stm32/src/eth/sma/v1.rs:46
critical_section::with(|_| {
#[cfg(eth_v1a)]
let reg = crate::pac::RCC.ahbenr();
#[cfg(any(eth_v1b, eth_v1c))]
let reg = crate::pac::RCC.ahb1enr();
reg.modify(|w| {
w.set_ethen(true);
})
});
let hclk = unsafe { crate::rcc::get_freqs().hclk1.to_hertz() };
let hclk = unwrap!(hclk, "SMA requires HCLK to be enabled, but it was not.");
let hclk_mhz = hclk.0 / 1_000_000;
// Set the MDC clock frequency in the range 1MHz - 2.5MHz
let clock_range = match hclk_mhz {
0..=24 => panic!("Invalid HCLK frequency - should be at least 25 MHz."),
25..=34 => Cr::Cr2035, // Divide by 16
35..=59 => Cr::Cr3560, // Divide by 26
60..=99 => Cr::Cr60100, // Divide by 42
100..=149 => Cr::Cr100150, // Divide by 62
150..=216 => Cr::Cr150168, // Divide by 102
_ => {
panic!("HCLK results in MDC clock > 2.5MHz even for the highest CSR clock divider")
}
};
Self {
_peri: peri,
clock_range,
_pins: [
new_pin!(mdio, AfType::output(OutputType::PushPull, Speed::VeryHigh)).unwrap(),
new_pin!(mdc, AfType::output(OutputType::PushPull, Speed::VeryHigh)).unwrap(),
],
}View on GitHub (pinned to 463a07b963)