embassy-rs/embassy · error

SAI failed to enable. Check that config is valid (frame…

Error message

SAI failed to enable. Check that config is valid (frame length, slot count, etc)

What it means

After setting SAIEN in CR1, the driver reads the bit back to confirm the peripheral actually enabled. Hardware refuses to enable when the SAI configuration is inconsistent (e.g. invalid frame length, slot count, or mode mismatch), so the driver panics instead of returning a silently dead peripheral.

Solutions

  1. Validate frame length (FRCR) equals slot_count * slot_size (e.g. 8 slots x 16 bits = 128) and matches the mode.
  2. Check slot count and slot enable mask in SLOTR are nonzero and consistent with the frame.
  3. Verify CR1 settings: mode (master/slave), sync selection, and clock strobing are legal for your topology.
  4. Cross-check the configuration against the reference manual's valid combinations for your SAI block.

Example fix

// before
frame_length: 0,
slot_count: 0,
// after
frame_length: 128, // e.g. 8 slots * 16 bits
slot_count: 8,
Defensive patterns

Strategy: validation

Validate before calling

fn sai_config_is_consistent(cfg: &SaiConfig) -> bool {
    cfg.frame_length > 0
        && cfg.slot_count > 0
        && cfg.frame_length == cfg.slot_count * cfg.slot_size
        && cfg.slot_enable_mask != 0
}

Try / catch

// Panics cannot be caught in embedded; validate config before constructing:
assert!(sai_config_is_consistent(&config), "invalid SAI config");
let sai = Sai::new(...);

Prevention

When it happens

Trigger: Creating a Sai new / sub-block with a SaiConfig whose frame length (FRCR), slot count (SLOTR), protocol, or synchronization settings are invalid for the selected mode, causing SAIEN to not stick.

Common situations: Frame length not matching the data/slot configuration; slot count of 0 or incompatible with frame sync; copying an I2S config that doesn't fit the chosen protocol; wrong master clock division.

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


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

Appendix: source

Thrown at embassy-stm32/src/sai/mod.rs:702

                    w.set_syncout(syncout);
                });
            }
        }

        let tx_rx = if Self::is_transmitter(&ring_buffer) {
            TxRx::Transmitter
        } else {
            TxRx::Receiver
        };
        regs::configure_cr1(ch, &config, tx_rx);
        regs::configure_cr2(ch, &config);
        regs::configure_frcr(ch, &config);
        regs::configure_slotr(ch, &config);

        ch.cr1().modify(|w| w.set_saien(true));

        if !ch.cr1().read().saien() {
            panic!("SAI failed to enable. Check that config is valid (frame length, slot count, etc)");
        }

        Self {
            sub_block,
            _sck: sck,
            _mclk: mclk,
            _sd: sd,
            _fs: fs,
            ring_buffer,
            info: T::info(),
            state: T::state(),
        }
    }

    /// Start the SAI driver.
    ///
    /// Only receivers can be started. Transmitters are started on the first writing operation.
    pub fn start(&mut self) -> Result<(), Error> {

View on GitHub (pinned to 463a07b963)