embassy-rs/embassy · error
DSI PHY clock must be enabled before init
Error message
DSI PHY clock must be enabled before init
What it means
phy_init for dsihost_v1 reads the RCC Frequencies and converts clocks.dsi_phy to Hertz with an expect. The panic asserts the DSI PHY clock was programmed and enabled before the PHY is initialized (needed to compute the UIX4 timing value). Without it the PHY timing registers cannot be set correctly.
Solutions
- Add `rcc.dsi_phy = Some(PllSel::PllN)` (and configure that PLL) in the RCC config before starting the panel.
- Enable the PLL that feeds the DSI PHY (PLLDSI) and check it appears in the computed Frequencies.
- Ensure start_panel is called after Rcc::new/config application, not before.
- Compare with the embassy-stm32 dsihost example for your exact chip.
Example fix
// before
config.rcc.dsihost = Some(...) // only kernel clock
// after
config.rcc.pll3 = Some(Pll { source: PllSource::HSE, ... });
config.rcc.dsi_phy = Some(PllSel::Pll3); // PHY clock must be set
config.rcc.dsihost = Some(...); Defensive patterns
Strategy: validation
Validate before calling
// Guard before starting the panel:
// RCC config must include the DSI PHY clock
let mut config = Config::default();
config.rcc.pll3 = Some(Pll { .. });
config.rcc.dsi_phy = Some(PllSel::Pll3);
// then: Rcc::new, DsiHost::new, start_panel Type guard
fn phy_clock_enabled(freqs: &Frequencies) -> bool {
freqs.dsi_phy.to_hertz().is_ok()
} Prevention
- Enable the DSI PHY PLL (PLLDSI) plus the DSIHOST kernel clock in RCC.
- Call start_panel only after full RCC initialization.
- Diff your clock config against the official example when changing chips.
When it happens
Trigger: Calling start_panel (which calls phy_init) when the RCC config has no dsi_phy clock set; enabling DSIHOST peripheral clock but not the DSI PHY clock source (PLLDSI); running phy_init before RCC init commits frequencies.
Common situations: STM32F469/DSI projects where only DSIHOST kernel clock was configured; switching chip families (F4 -> H7/U5) where the clock field name/PLL changed; order-of-init mistakes where panel start happens before set-up of PLLDSI.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- DSI lane byte clock
- DSI TX escape clock
- AHB frequency is too low
- cannot select OTG_HS reference clock with source frequency…
- DTS PCLK frequency must be less than 127 MHz.
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/c4feee52054578f1.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-stm32/src/dsihost/phy.rs:124
});
T::regs().pconfr().modify(|w| {
w.set_nl(config.lanes as u8);
w.set_sw_time(config.stop_wait_time);
});
T::regs().ccr().modify(|w| {
w.set_tockdiv(timeout_div);
w.set_txeckdiv(escape_div);
});
#[cfg(dsihost_v1)]
{
let clocks = unsafe { get_freqs() };
let phy_clock = clocks
.dsi_phy
.to_hertz()
.expect("DSI PHY clock must be enabled before init");
// Calculate UIX4
let uix4 = (4_000_000_000u64) / phy_clock.0 as u64;
let uix4 = uix4.max(1).min(63) as u8;
T::regs().wpcr0().modify(|w| {
w.set_uix4(uix4);
});
}
T::regs().pcr().modify(|w| {
w.set_crcrxe(config.crc_rx);
w.set_eccrxe(config.ecc_rx);
w.set_etrxe(config.eotp_rx);
w.set_ettxe(config.eotp_tx);
w.set_btae(config.bta);
});
T::regs().cltcr().modify(|w| {View on GitHub (pinned to 463a07b963)