embassy-rs/embassy · error
cannot select OTG_HS reference clock with source frequency…
Error message
cannot select OTG_HS reference clock with source frequency of {}, must be one of 16, 19.2, 20, 24, 26, 32 MHz What it means
In embassy-stm32's STM32U5 RCC init, the OTG_HS USB reference clock selector only supports source frequencies of 16, 19.2, 20, 24, 26, or 32 MHz (Usbrefcksel register field). When config.usb_refck source is set to Some with a frequency outside this set, the driver panics because no hardware divider/selector value exists for it.
Solutions
- Choose a usb_refck source whose frequency is exactly 16, 19.2, 20, 24, 26, or 32 MHz (tune the PLL Q divider accordingly)
- Or leave usb_refck as None, which defaults to the 24 MHz selection
- Add/adjust a prescaler upstream so the source presented to OTG_HS is one of the supported frequencies
Example fix
// before
config.usb_refck = Some(UsbRefCkConfig { source: UsbRefCkSource::Pll1Q }); // PLL1.Q = 48 MHz -> panic
// after
// retune PLL1 so Q = 32 MHz, or pick a supported source
config.usb_refck = Some(UsbRefCkConfig { source: UsbRefCkSource::Pll1Q }); // PLL1.Q now 32 MHz Defensive patterns
Strategy: validation
Validate before calling
const USB_REFCK_SUPPORTED: [u32; 6] = [16_000_000, 19_200_000, 20_000_000, 24_000_000, 26_000_000, 32_000_000];
if let Some(refck) = &config.usb_refck {
let f = source_frequency(refck.source); // your resolved source freq
assert!(USB_REFCK_SUPPORTED.contains(&f), "usb_refck source {} MHz unsupported", f / 1_000_000);
} Type guard
fn usb_refck_supported(freq_hz: u32) -> bool {
matches!(freq_hz, 16_000_000 | 19_200_000 | 20_000_000 | 24_000_000 | 26_000_000 | 32_000_000)
} Prevention
- Tune PLL Q outputs to one of the six supported frequencies
- Leave usb_refck as None to get the 24 MHz default when unsure
- Compute your full clock tree frequencies before writing the RCC config
- Check embassy-stm32 docs/examples for known-good USB clock setups
When it happens
Trigger: rcc init with config.usb_refck = Some(...) whose source clock frequency (e.g. HSI 16 MHz is fine, but PLL outputs like 40 MHz, 48 MHz, 64 MHz) is not one of the six supported values.
Common situations: Feeding a PLL Q output at a nonstandard frequency into usb_refck; assuming any clock can be selected; upgrading embassy-stm32 and hitting the stricter validation; board designs using an external oscillator with an unsupported frequency.
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
- The LCD driver needs the RTC/LCD clock to be running
- LSE frequency more than 5% off from 32.768 kHz, cannot use…
- MSIx auto-calibration is enabled for a source that has not…
- LSE frequency more than 5% off from 32.768 kHz, cannot use…
- Invalid ahb5_pre for HSI/HSE sysclk: only DIV1 and DIV2 are…
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/574c2d6eb53a4457.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-stm32/src/rcc/u5.rs:499
let rtc = config.ls.init();
#[cfg(all(stm32u5, peri_usb_otg_hs))]
let usb_refck = match config.mux.otghssel {
Otghssel::Hse => hse,
Otghssel::HseDiv2 => hse.map(|hse_val| hse_val / 2u8),
Otghssel::Pll1P => pll1.p,
Otghssel::Pll1PDiv2 => pll1.p.map(|pll1p_val| pll1p_val / 2u8),
};
#[cfg(all(stm32u5, 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 OTG_HS reference clock with source frequency of {}, must be one of 16, 19.2, 20, 24, 26, 32 MHz",
clk_val
),
},
None => Usbrefcksel::Mhz24,
};
#[cfg(all(stm32u5, peri_usb_otg_hs))]
SYSCFG.otghsphycr().modify(|w| {
w.set_clksel(usb_refck_sel);
});
let lse = config.ls.lse.map(|l| l.frequency);
let lsi = config.ls.lsi.then_some(LSI_FREQ);
// Disable HSI if not used
if !config.hsi {
RCC.cr().modify(|w| w.set_hsion(false));
}View on GitHub (pinned to 463a07b963)