embassy-rs/embassy · error

QSPI address can't be sent with an address width of NONE

Error message

QSPI address can't be sent with an address width of NONE

What it means

An address was supplied in the transaction while its address width was QspiWidth::NONE, meaning no lanes are allocated to transmit it. The controller cannot send the address, so the library panics rather than silently dropping it.

Solutions

  1. Set awidth to a real width (SING, DUAL, or FOUR) whenever an address is provided.
  2. If no address is needed, set transaction.address to None together with awidth = QspiWidth::NONE.

Example fix

// before
let t = TransferConfig::new(cmd, QspiWidth::SING, Some(0x1000), QspiWidth::NONE, QspiWidth::SING);
// after
let t = TransferConfig::new(cmd, QspiWidth::SING, Some(0x1000), QspiWidth::SING, QspiWidth::SING);
Defensive patterns

Strategy: validation

Validate before calling

fn address_pairing_ok(t: &TransferConfig) -> bool {
    !(t.address.is_some() && t.awidth == QspiWidth::NONE)
}

Prevention

When it happens

Trigger: Passing a TransferConfig with address = Some(addr) and awidth = QspiWidth::NONE into setup_transaction (via blocking_read, blocking_write, setup_auto_poll, or setup_command).

Common situations: Building the config conditionally and defaulting awidth to NONE while still filling in the address; copying a config template that uses NONE widths and only updating the address field.

Related errors


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

Appendix: source

Thrown at embassy-stm32/src/qspi/mod.rs:370

        T::REGS.psmkr().write(|w| w.set_mask(mask));
        T::REGS.psmar().write(|w| w.set_match_(match_value));
        T::REGS.pir().write(|w| w.set_interval(interval));

        self.setup_transaction(QspiMode::AutoPolling, &transaction, Some(data_len));
    }

    fn setup_command(&mut self, transaction: TransferConfig) {
        #[cfg(not(stm32h7))]
        T::REGS.cr().modify(|v| v.set_dmaen(false));

        self.setup_transaction(QspiMode::IndirectWrite, &transaction, None);
    }

    fn setup_transaction(&mut self, fmode: QspiMode, transaction: &TransferConfig, data_len: Option<usize>) {
        self.assert_transfer_widths(transaction);

        match (transaction.address, transaction.awidth) {
            (Some(_), QspiWidth::NONE) => panic!("QSPI address can't be sent with an address width of NONE"),
            (Some(address), _) => {
                // u32::bit_width was only stabilized in 1.97
                let address_bit_width = u32::BITS - address.leading_zeros();
                if address_bit_width > transaction.address_size.bit_width() as u32 {
                    panic!("QSPI address too large to be represented with the given address size");
                }
            }
            (None, QspiWidth::NONE) => {}
            (None, _) => panic!("QSPI address is not set, so the address width should be NONE"),
        }

        match (data_len, transaction.dwidth) {
            (Some(0), _) => panic!("QSPI data must be at least one byte"),
            (Some(_), QspiWidth::NONE) => panic!("QSPI data can't be sent with a data width of NONE"),
            (Some(_), _) => {}
            (None, QspiWidth::NONE) => {}
            (None, _) => panic!("QSPI data is empty, so the data width should be NONE"),
        }

View on GitHub (pinned to 463a07b963)