embassy-rs/embassy · error

HCLK results in MDC clock > 2.5MHz even for the highest CSR…

Error message

HCLK results in MDC clock > 2.5MHz even for the highest CSR clock divider

What it means

Same family as v1: the v2 StationManagement picks an MDC CSR clock range from HCLK. If hclk_mhz exceeds 310 MHz (largest table entry, divide by 124), no valid clock range exists and the driver panics.

Solutions

  1. Lower HCLK to <= 310 MHz in the RCC config.
  2. If the target MAC is eth_v2a, ensure the cfg path is active so the extended divider table is used.
  3. Pick the highest divider arm appropriate for the actual HCLK.

Example fix

// before
config.pll = Pll { freq: 400.MHz(), .. };
// after
config.pll = Pll { freq: 240.MHz(), .. }; // 150..=249 -> divide by 102
Defensive patterns

Strategy: validation

Validate before calling

let hclk_mhz = embassy_stm32::rcc::get_freqs().hclk1.0 / 1_000_000;
assert!(hclk_mhz <= 310, "v2 Ethernet requires HCLK1 <= 310 MHz, got {} MHz", hclk_mhz);

Prevention

When it happens

Trigger: Constructing the v2 StationManagement on an eth_v2 (non-v2a) part with hclk_mhz > 310.

Common situations: Very high HCLK RCC configs on v2 Ethernet parts; forgetting that the eth_v2a extended divider table applies only to specific MACs.

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


AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10). Data as JSON: /api/errors/ca82dc6900ccc8a8. Report an issue: GitHub.

Appendix: source

Thrown at embassy-stm32/src/eth/sma/v2.rs:53

                w.set_eth1macen(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
        #[cfg(not(eth_v2a))]
        let clock_range = match hclk_mhz {
            0..=34 => 2,    // Divide by 16
            35..=59 => 3,   // Divide by 26
            60..=99 => 0,   // Divide by 42
            100..=149 => 1, // Divide by 62
            150..=249 => 4, // Divide by 102
            250..=310 => 5, // Divide by 124
            _ => {
                panic!("HCLK results in MDC clock > 2.5MHz even for the highest CSR clock divider")
            }
        };
        // The eth_v2a MAC supports two extra dividers for higher HCLK
        // frequencies. Boundaries match the ST HAL (HAL_ETH_SetMDIOClockRange).
        #[cfg(eth_v2a)]
        let clock_range = match hclk_mhz {
            0..=34 => 2,    // Divide by 16
            35..=59 => 3,   // Divide by 26
            60..=99 => 0,   // Divide by 42
            100..=149 => 1, // Divide by 62
            150..=249 => 4, // Divide by 102
            250..=299 => 5, // Divide by 124
            300..=499 => 6, // Divide by 204
            _ => 7,         // Divide by 324
        };

        Self {
            _peri: peri,

View on GitHub (pinned to 463a07b963)