embassy-rs/embassy · error
QSPI data can't be sent with a data width of NONE
Error message
QSPI data can't be sent with a data width of NONE
What it means
A data phase was requested (data_len = Some(n>0)) but the data width is QspiWidth::NONE, so no lanes exist to move the data bytes. The library enforces that any data transfer uses an actual width and panics on the mismatch.
Solutions
- Set dwidth to SING, DUAL, or FOUR whenever data is transferred.
- If no data is involved, pass data_len = None together with dwidth = QspiWidth::NONE.
Example fix
// before let t = TransferConfig::new(cmd, QspiWidth::SING, Some(addr), QspiWidth::SING, QspiWidth::NONE); t.data_len = Some(4); qspi.blocking_read(t); // after let t = TransferConfig::new(cmd, QspiWidth::SING, Some(addr), QspiWidth::SING, QspiWidth::SING); qspi.blocking_read(t);
Defensive patterns
Strategy: validation
Validate before calling
fn data_width_ok(len: Option<usize>, w: QspiWidth) -> bool {
!(len.is_some() && w == QspiWidth::NONE)
} Prevention
- Set dwidth whenever data_len is set; bundle them in a constructor.
- Check existing template configs for default NONE widths before adding data phases.
When it happens
Trigger: Passing a TransferConfig with data_len = Some(len) and dwidth = QspiWidth::NONE into setup_transaction via blocking_read, blocking_write, setup_auto_poll, or setup_command.
Common situations: Setting only the data length in a config struct whose dwidth defaulted to NONE; command templates reused for data-bearing operations without updating dwidth.
Related errors
- QSPI transfer width exceeds configured IO lanes
- QSPI address can't be sent with an address width of NONE
- QSPI address too large to be represented with the given…
- QSPI address is not set, so the address width should be NONE
- QSPI data must be at least one byte
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/ffa07232249b35d0.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-stm32/src/qspi/mod.rs:384
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() {}
if let Some(len) = data_len {
T::REGS.dlr().write(|v| v.set_dl(len as u32 - 1));
}
View on GitHub (pinned to 463a07b963)