{"record":{"id":"dff17c6c032b6201","repo":"embassy-rs/embassy","slug":"ahb-frequency-is-too-low-dff17c","errorCode":null,"errorMessage":"AHB frequency is too low","messagePattern":"AHB frequency is too low","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-stm32/src/usb/otg.rs","lineNumber":1044,"sourceCode":"\n        async fn bus_reset(&mut self) {\n            self.inner.bus_reset().await\n        }\n    }\n}\n\n#[cfg(feature = \"usb-host\")]\npub use host_impl::*;\n\nfn calculate_trdt<T: Instance>(speed: Dspd) -> u8 {\n    let ahb_freq = T::bus_frequency().0;\n    match speed {\n        Dspd::HIGH_SPEED => {\n            // From RM0431 (F72xx), RM0090 (F429), RM0390 (F446)\n            if ahb_freq >= 30_000_000 || cfg!(stm32h7rs) {\n                0x9\n            } else {\n                panic!(\"AHB frequency is too low\")\n            }\n        }\n        Dspd::FULL_SPEED_EXTERNAL | Dspd::FULL_SPEED_INTERNAL => {\n            // From RM0431 (F72xx), RM0090 (F429)\n            match ahb_freq {\n                0..=14_199_999 => panic!(\"AHB frequency is too low\"),\n                14_200_000..=14_999_999 => 0xF,\n                15_000_000..=15_999_999 => 0xE,\n                16_000_000..=17_199_999 => 0xD,\n                17_200_000..=18_499_999 => 0xC,\n                18_500_000..=19_999_999 => 0xB,\n                20_000_000..=21_799_999 => 0xA,\n                21_800_000..=23_999_999 => 0x9,\n                24_000_000..=27_499_999 => 0x8,\n                27_500_000..=31_999_999 => 0x7, // 27.7..32 in code from CubeIDE\n                32_000_000..=u32::MAX => 0x6,\n            }\n        }","sourceCodeStart":1026,"sourceCodeEnd":1062,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-stm32/src/usb/otg.rs#L1026-L1062","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nconfig.ahb_pre = AHBPrescaler::DIV4; // ahb = 24 MHz, HS USB panics\n// after\nconfig.ahb_pre = AHBPrescaler::DIV2; // ahb = 48 MHz","handlingStrategy":"validation","validationCode":"let ahb = rcc.ahb1().frequency();\nassert!(ahb.0 >= 30_000_000, \"AHB {} Hz too low for high-speed USB\", ahb.0);","typeGuard":"fn ahb_ok_for_hs(hz: u32) -> bool { hz >= 30_000_000 }","tryCatchPattern":null,"preventionTips":["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"],"tags":["embedded","stm32","usb","clock-config","high-speed","panic"],"backgroundTag":"invalid-config-value","analyzedSha":"463a07b963419a1bfe61d5d597c44acb810afb8b","analyzedAt":"2026-09-10T13:38:26.660Z","contentChangedAt":"2026-09-10T13:38:26.660Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}