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

On STM32WBA, the OTG_HS USB reference clock selector only accepts sources of 16, 19.2, 20, 24, 26, or 32 MHz (Usbrefcksel field). embassy-stm32's RCC init panics when config.usb_refck names a source whose frequency falls outside this set, because no hardware selector value exists for it.

Solutions

  1. Retune the PLL (Q/dividers) so the usb_refck source is exactly 16, 19.2, 20, 24, 26, or 32 MHz
  2. Or omit usb_refck (None), which selects the default 24 MHz option
  3. Pick a different configured clock source that already runs at a supported frequency

Example fix

// before
config.usb_refck = Some(UsbRefCkConfig { source: UsbRefCkSource::Pll1Q }); // PLL1.Q = 40 MHz -> panic
// after
// adjust PLL1 dividers so PLL1.Q = 32 MHz, then:
config.usb_refck = Some(UsbRefCkConfig { source: UsbRefCkSource::Pll1Q });
Defensive patterns

Strategy: validation

Validate before calling

const 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 = resolve_freq(refck.source); // your clock tree resolution
    assert!(SUPPORTED.contains(&f), "OTG_HS refck source {} Hz unsupported", f);
}

Type guard

fn is_valid_usb_refck_freq(hz: u32) -> bool {
    matches!(hz, 16_000_000 | 19_200_000 | 20_000_000 | 24_000_000 | 26_000_000 | 32_000_000)
}

Prevention

When it happens

Trigger: rcc init with config.usb_refck = Some(...) where the selected source clock (PLL output, HSE-derived, etc.) is not exactly one of the six supported frequencies.

Common situations: Pointing usb_refck at a PLL Q output of e.g. 48 or 60 MHz; porting a U5 clock tree to WBA with different PLL settings; external oscillator frequencies not in the supported list.

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/57bf433cb8d46d47. Report an issue: GitHub.

Appendix: source

Thrown at embassy-stm32/src/rcc/wba.rs:408

    let hclk5 = sys_clk / config.ahb5_pre;

    #[cfg(all(stm32wba, 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(stm32wba, 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(stm32wba, peri_usb_otg_hs))]
    SYSCFG.otghsphycr().modify(|w| {
        w.set_clksel(usb_refck_sel);
    });

    #[cfg(sai_v4_2pdm)]
    let audioclk = match config.mux.sai1sel {
        Sai1sel::Hsi => Some(HSI_FREQ),
        Sai1sel::Pll1Q => Some(pll1.q.expect("PLL1.Q not configured")),
        Sai1sel::Pll1P => Some(pll1.p.expect("PLL1.P not configured")),
        Sai1sel::Sys => panic!("SYS not supported yet"),
        Sai1sel::Audioclk => panic!("AUDIOCLK not supported yet"),

View on GitHub (pinned to 463a07b963)