embassy-rs/embassy · error

LSE must be configured for MSI auto-calibration

Error message

LSE must be configured for MSI auto-calibration

What it means

On STM32 U3 series, enabling MSI auto-calibration (MSIRC calibration against LSE) requires a configured LSE clock. The rcc `init` unwraps `config.ls.lse` with `.expect`, panicking if it is `None`. Auto-calibration works by measuring MSI against the 32.768 kHz LSE, so LSE must exist and be routed to peripherals.

Solutions

  1. Add an LSE configuration to the RCC config, e.g. `ls: DefaultLse { lse: Some(LseConfig { frequency: Hertz(32_768), peripherals_clocked: true, .. }) }`
  2. Or explicitly disable auto-calibration: `auto_calibration: MsiAutoCalibration::Disabled`
  3. Ensure `peripherals_clocked` is true on the LSE config so calibration has an active clock

Example fix

// before
rcc::init(rcc::Config { auto_calibration: MsiAutoCalibration::Lse, ..Default::default() });
// after
rcc::init(rcc::Config {
    auto_calibration: MsiAutoCalibration::Lse,
    ls: rcc::LsConfig::default_lse(Some(rcc::LseConfig { peripherals_clocked: true, ..Default::default() })),
    ..Default::default()
});
Defensive patterns

Strategy: validation

Validate before calling

assert!(
    config.auto_calibration == MsiAutoCalibration::Disabled
        || config.ls.lse.is_some(),
    "MSI auto-calibration requires an LSE config"
);

Prevention

When it happens

Trigger: Calling `rcc::init` with a `Config` where `auto_calibration` is not `MsiAutoCalibration::Disabled` but `ls.lse` is `None`.

Common situations: Enabling MSI auto-calibration on a chip/board without an LSE crystal (or with LSE not configured in RCC config); forgetting that LSE must also have `peripherals_clocked: true` (enforced by the following assert).

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

Appendix: source

Thrown at embassy-stm32/src/rcc/u3.rs:219

        VoltageScale::RANGE2 => {
            if PWR.vosr().read().r1en() {
                while !PWR.vosr().read().r1rdy() {}
            }
            PWR.vosr().modify(|w| {
                w.set_r2en(true);
                w.set_r1en(false);
            });
            while !PWR.vosr().read().r2rdy() {}
        }
    }

    let lse_calibration_freq = if config.auto_calibration != MsiAutoCalibration::Disabled {
        // LSE must be configured and peripherals clocked for MSI auto-calibration
        let lse_config = config
            .ls
            .lse
            .clone()
            .expect("LSE must be configured for MSI auto-calibration");
        assert!(lse_config.peripherals_clocked);

        // Expect less than +/- 5% deviation for LSE frequency
        if (31_100..=34_400).contains(&lse_config.frequency.0) {
            // Check that the calibration is applied to an active clock
            match (
                config.auto_calibration.base_mode(),
                config.msis.is_some(),
                config.msik.is_some(),
            ) {
                (MsiAutoCalibration::MSIS, true, _) => {
                    // MSIS is active and using LSE for auto-calibration
                    Some(lse_config.frequency)
                }
                (MsiAutoCalibration::MSIK, _, true) => {
                    // MSIK is active and using LSE for auto-calibration
                    Some(lse_config.frequency)
                }

View on GitHub (pinned to 463a07b963)