embassy-rs/embassy · error

cannot select USBPHYC reference clock with source frequency…

Error message

cannot select USBPHYC reference clock with source frequency of {}, must be one of 16, 19.2, 20, 24, 26, 32 MHz

What it means

On H7RS (USBPHYC), the USB PHY reference clock selection register can only encode a fixed set of input frequencies: 16, 19.2, 20, 24, 26 or 32 MHz. init panics if the selected USBPHYC reference source frequency (clk_val) is anything else; when no source is configured the driver defaults to Mhz24.

Solutions

  1. Choose a PLL output or crystal for the USBPHYC reference that is exactly 16, 19.2, 20, 24, 26 or 32 MHz.
  2. Adjust upstream PLL dividers so the derived reference lands exactly on one of the supported values.
  3. If no explicit source is needed, leave it unset to use the default 24 MHz selection.

Example fix

// before
// usb refck source = 25 MHz crystal -> panic
// after
// derive 20 MHz from PLL via divider and use it as usb refck source:
// Usbrefcksel::Mhz20 (freq = 20_000_000.Hz())
Defensive patterns

Strategy: validation

Validate before calling

const USBPHYC_REF: [u32; 6] = [16_000_000, 19_200_000, 20_000_000, 24_000_000, 26_000_000, 32_000_000];
if let Some(f) = usb_refck_source {
    assert!(USBPHYC_REF.contains(&f.0), "USBPHYC ref {} Hz not supported", f.0);
}

Prevention

When it happens

Trigger: Configuring the USB PHY reference clock on stm32h7rs with a source crystal/PLL output whose frequency is not exactly one of 16, 19.2, 20, 24, 26 or 32 MHz (e.g. 8 MHz, 25 MHz, 48 MHz), so the match arm falls through to the panic.

Common situations: Board crystals that do not match the PHY's supported list; reusing an H7 (non-RS) clock config on H7RS; assuming any frequency can be divided down automatically — the driver does not add extra dividers.

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/83d9e76cbd3586d9. Report an issue: GitHub.

Appendix: source

Thrown at embassy-stm32/src/rcc/h.rs:659

    let rtc = config.ls.init();

    #[cfg(all(stm32h7rs, peri_usb_otg_hs))]
    let usb_refck = match config.mux.usbphycsel {
        Usbphycsel::Hse => hse,
        Usbphycsel::HseDiv2 => hse.map(|hse_val| hse_val / 2u8),
        Usbphycsel::Pll3Q => pll3.q,
        _ => None,
    };
    #[cfg(all(stm32h7rs, peri_usb_otg_hs))]
    let usb_refck_sel = match usb_refck {
        Some(clk_val) => match clk_val {
            Hertz(16_000_000) => Usbrefcksel::Mhz16,
            Hertz(19_200_000) => Usbrefcksel::Mhz192,
            Hertz(20_000_000) => Usbrefcksel::Mhz20,
            Hertz(24_000_000) => Usbrefcksel::Mhz24,
            Hertz(26_000_000) => Usbrefcksel::Mhz26,
            Hertz(32_000_000) => Usbrefcksel::Mhz32,
            _ => panic!(
                "cannot select USBPHYC reference clock with source frequency of {}, must be one of 16, 19.2, 20, 24, 26, 32 MHz",
                clk_val
            ),
        },
        None => Usbrefcksel::Mhz24,
    };

    #[cfg(stm32h7)]
    {
        RCC.d1cfgr().modify(|w| {
            w.set_d1cpre(config.d1c_pre);
            w.set_d1ppre(config.apb3_pre);
            w.set_hpre(config.ahb_pre);
        });
        // Ensure core prescaler value is valid before future lower core voltage
        while RCC.d1cfgr().read().d1cpre() != config.d1c_pre {}

        RCC.d2cfgr().modify(|w| {

View on GitHub (pinned to 463a07b963)