embassy-rs/embassy · error

QSPI address is not set, so the address width should be NONE

Error message

QSPI address is not set, so the address width should be NONE

What it means

The transaction carries no address (None) but its address width is not NONE, i.e. lanes are allocated to transmit an address that does not exist. The library enforces the pairing: no address implies QspiWidth::NONE.

Solutions

  1. Set awidth = QspiWidth::NONE when address is None.
  2. Use a command-only constructor/template that leaves both address None and awidth NONE.

Example fix

// before
let t = TransferConfig::new(0x06, QspiWidth::SING, None, QspiWidth::SING, QspiWidth::NONE);
// after
let t = TransferConfig::new(0x06, QspiWidth::SING, None, QspiWidth::NONE, QspiWidth::NONE);
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 = None and awidth of SING/DUAL/FOUR into setup_transaction via blocking_read, blocking_write, setup_auto_poll, or setup_command.

Common situations: Command-only transactions (e.g. write-enable 0x06) copied from a template that still sets awidth; config structs with default width values that aren't reset when the address is dropped.

Related errors


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

Appendix: source

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

        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"),
        }

        T::REGS.fcr().modify(|v| {
            v.set_csmf(true);
            v.set_ctcf(true);
            v.set_ctef(true);
            v.set_ctof(true);
        });

        while T::REGS.sr().read().busy() {}

View on GitHub (pinned to 463a07b963)