embassy-rs/embassy · error

DSI requires configured HSE

Error message

DSI requires configured HSE

What it means

`configure_pll` in embassy-stm32's DSI host driver requires a hardware high-speed external oscillator (HSE) as the PLL input. The `hse` parameter is `Option<Hertz>`; when it is `None`, the code panics via `.expect("DSI requires configured HSE")`. The library throws this because the DSIHOST PLL can only be derived from the HSE clock, so it cannot proceed without it.

Solutions

  1. Configure HSE in the RCC config before initializing DSI, e.g. `Config { hse: Some(Hertz(8_000_000)), .. }`
  2. Verify the board actually has an HSE crystal and pass its exact frequency
  3. Check board-support crate examples for the correct HSE value for your hardware

Example fix

// before
let config = rcc::Config { ..Default::default() };
// after
let config = rcc::Config {
    hse: Some(Hertz(25_000_000)),
    ..Default::default()
};
Defensive patterns

Strategy: validation

Validate before calling

if rcc_config.hse.is_none() {
    panic!("DSI display init requires HSE; set hse: Some(Hertz(crystal_hz)) in rcc::Config");
}

Prevention

When it happens

Trigger: Calling `dsi::configure_pll(None, config)` — i.e. the RCC config did not enable or yield an HSE frequency — while initializing a DSI display panel.

Common situations: Board support or user RCC config lacks `hse: Some(frequency)`; running on a board that boots from HSI/MSI and never configures the external crystal; copying display init code between boards where one has no HSE crystal.

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


AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10). Data as JSON: /api/errors/0e8ff230ae3e7027. Report an issue: GitHub.

Appendix: source

Thrown at embassy-stm32/src/rcc/dsi.rs:116

        #[cfg(dsihost_v1)]
        assert!(
            ndiv >= 10 && ndiv <= 125,
            "DSI PLL loop divisor must be 10 <= ndiv <= 125"
        );

        #[cfg(dsihost_u5)]
        assert!(
            ndiv >= 1 && ndiv <= 511,
            "DSI PLL loop divisor must be 1 <= ndiv <= 511"
        );

        Self { ndiv, idf, odf }
    }
}

/// Enable the DSIHOST PLL
pub fn configure_pll(hse: Option<Hertz>, config: DsiHostPllConfig) -> Hertz {
    let pll_vco = hse.expect("DSI requires configured HSE") * config.idf * config.ndiv * 2u32;

    #[cfg(feature = "defmt")]
    {
        debug!("DSI PLL VCO: {} MHz", pll_vco / Hertz::mhz(1));
    }

    assert!(
        pll_vco >= Hertz::mhz(1000) && pll_vco <= Hertz::mhz(2000),
        "DSI PLL VCO must be >= 1GHz and <= 2GHz"
    );

    #[cfg(dsihost_u5)]
    {
        assert!(config.idf <= 511, "DSI PLL input division factor must be <= 511");
        assert!(config.odf <= 511, "DSI PLL output division factor must be <= 511");
    }

    let pll_freq = pll_vco / 2u32 * config.odf;

View on GitHub (pinned to 463a07b963)