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
- Choose a PLL output or crystal for the USBPHYC reference that is exactly 16, 19.2, 20, 24, 26 or 32 MHz.
- Adjust upstream PLL dividers so the derived reference lands exactly on one of the supported values.
- 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
- Pick crystals/PLL outputs for the PHY reference from the supported 6-value list only.
- Compute upstream dividers so the derived frequency lands exactly on a supported value (integer match, not approximately).
- Leave the source unset to accept the 24 MHz default when flexibility exists.
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
- cannot select OTG_HS reference clock with source frequency…
- cannot select OTG_HS reference clock with source frequency…
- Failed to configure PLL_USB
- The LCD driver needs the RTC/LCD clock to be running
- if PLL source is HSI, PLL prediv must be 2.
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)