embassy-rs/embassy · error
AHB frequency is too low
Error message
AHB frequency is too low
What it means
calculate_trdt computes the USB turnaround time (TRDT) from the AHB bus clock; at high speed the OTG core requires AHB >= 30 MHz (or an H7RS part, which the driver treats as exempt) to produce a valid TRDT encoding per RM0431/RM0090/RM0390. Below that threshold no correct TRDT value exists, so the driver panics.
Solutions
- Raise the AHB/HCLK frequency to at least 30 MHz in the RCC configuration
- If low AHB is mandatory, configure the peripheral as full speed (Dspd::FULL_SPEED_EXTERNAL/INTERNAL) instead of high speed
- Use an H7RS part, where the driver permits high speed regardless of the 30 MHz rule, if hardware allows
- Compute and print ahb_freq before USB init and assert it meets the 30 MHz floor
Example fix
// before config.ahb_pre = AHBPrescaler::DIV4; // ahb = 24 MHz, HS USB panics // after config.ahb_pre = AHBPrescaler::DIV2; // ahb = 48 MHz
Defensive patterns
Strategy: validation
Validate before calling
let ahb = rcc.ahb1().frequency();
assert!(ahb.0 >= 30_000_000, "AHB {} Hz too low for high-speed USB", ahb.0); Type guard
fn ahb_ok_for_hs(hz: u32) -> bool { hz >= 30_000_000 } Prevention
- Keep AHB >= 30 MHz whenever Dspd::HIGH_SPEED is used on non-H7RS parts
- Assert AHB frequency in board init before USB setup
- Choose full speed if the product's clock tree cannot reach 30 MHz
When it happens
Trigger: Initializing the OTG peripheral in Dspd::HIGH_SPEED mode while the AHB clock is below 30 MHz on a non-H7RS target (calculate_trdt called during common_init).
Common situations: Low-power clock trees (e.g. 24 MHz AHB) combined with a high-speed USB configuration; forgetting to raise AHB after lowering it for power experiments; copying an FS clock tree into an HS application.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- USB clock should be one of 16, 19.2, 20, 24, 26, 32Mhz but…
- USB clock should be 48Mhz but is
- USB HS PHY reference clock should be 19.2, 20 or 24 MHz but…
- AHB frequency is too low
- LSE frequency more than 5% off from 32.768 kHz, cannot use…
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/dff17c6c032b6201.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-stm32/src/usb/otg.rs:1044
async fn bus_reset(&mut self) {
self.inner.bus_reset().await
}
}
}
#[cfg(feature = "usb-host")]
pub use host_impl::*;
fn calculate_trdt<T: Instance>(speed: Dspd) -> u8 {
let ahb_freq = T::bus_frequency().0;
match speed {
Dspd::HIGH_SPEED => {
// From RM0431 (F72xx), RM0090 (F429), RM0390 (F446)
if ahb_freq >= 30_000_000 || cfg!(stm32h7rs) {
0x9
} else {
panic!("AHB frequency is too low")
}
}
Dspd::FULL_SPEED_EXTERNAL | Dspd::FULL_SPEED_INTERNAL => {
// From RM0431 (F72xx), RM0090 (F429)
match ahb_freq {
0..=14_199_999 => panic!("AHB frequency is too low"),
14_200_000..=14_999_999 => 0xF,
15_000_000..=15_999_999 => 0xE,
16_000_000..=17_199_999 => 0xD,
17_200_000..=18_499_999 => 0xC,
18_500_000..=19_999_999 => 0xB,
20_000_000..=21_799_999 => 0xA,
21_800_000..=23_999_999 => 0x9,
24_000_000..=27_499_999 => 0x8,
27_500_000..=31_999_999 => 0x7, // 27.7..32 in code from CubeIDE
32_000_000..=u32::MAX => 0x6,
}
}View on GitHub (pinned to 463a07b963)