From 8ed1e796bad7b3dbf6e78ea5e5d89b7257571d06 Mon Sep 17 00:00:00 2001 From: goodhoko Date: Mon, 15 Sep 2025 15:34:07 +0200 Subject: [PATCH 1/2] Handle OSPI address errors We were using OSPI in indirect mode via DMA and noticed that the transfer future would never resolve. It was forever busy-looping in `finish_dma()` on the `while !regs.sr().read().tcf() {}` line. After some debugging we noticed that the the `TEF` flag is set. The data sheet says the following about this flag: > The following errors set the TEF flag in OCTOSPI_SR and generates an interrupt if enabled (TEIE = 1 in OCTOSPI_CR): > - in indirect or automatic status-polling mode, when a wrong address has been programmed in OCTOSPI_AR (according to the device size defined by DEVSIZE[4:0]). > - in indirect mode, if the address plus the data length exceed the device size: TEF is set as soon as the access is triggered. Indeed we were configuring our device size to 0 while specifying a non-zero address. Detect this condition and return an error early - as soon as we configure the registers (which, according to the data sheet, should be enough to raise the flag) Also document this behavior on the respective TransferConfig and Config fields. Testing ------- See https://github.com/goodhoko/spi-error-test/blob/main/src/main.rs --- embassy-stm32/src/ospi/mod.rs | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/embassy-stm32/src/ospi/mod.rs b/embassy-stm32/src/ospi/mod.rs index eebaf5573..c291a311d 100644 --- a/embassy-stm32/src/ospi/mod.rs +++ b/embassy-stm32/src/ospi/mod.rs @@ -31,7 +31,9 @@ pub struct Config { /// Indicates the type of external device connected pub memory_type: MemoryType, // Need to add an additional enum to provide this public interface /// Defines the size of the external device connected to the OSPI corresponding - /// to the number of address bits required to access the device + /// to the number of address bits required to access the device. + /// When using indirect mode, [`TransferConfig::address`] + the length of the data being read + /// or written must fit within the configured `device_size`, otherwise an error is returned. pub device_size: MemorySize, /// Sets the minimum number of clock cycles that the chip select signal must be held high /// between commands @@ -95,10 +97,11 @@ pub struct TransferConfig { pub isize: AddressSize, /// Instruction Double Transfer rate enable pub idtr: bool, - /// Address width (ADMODE) pub adwidth: OspiWidth, - /// Device memory address + /// Device memory address. + /// In indirect mode, this value + the length of the data being read or written must be within + /// configured [`Config::device_size`], otherwise the transfer returns an error. pub address: Option, /// Number of Address Bytes pub adsize: AddressSize, @@ -528,6 +531,18 @@ impl<'d, T: Instance, M: PeriMode> Ospi<'d, T, M> { } } + // The following errors set the TEF flag in OCTOSPI_SR register: + // - in indirect or automatic status-polling mode, when a wrong address has been programmed + // in OCTOSPI_AR (according to the device size defined by DEVSIZE[4:0]) + // - in indirect mode, if the address plus the data length exceed the device size: TEF is + // set as soon as the access is triggered. + if T::REGS.sr().read().tef() { + // Clear the TEF register to make it ready for the next transfer. + T::REGS.fcr().write(|w| w.set_ctef(true)); + + return Err(OspiError::InvalidCommand); + } + Ok(()) } From 9ae76cbad6fc2bf4d00c731d98df0563241b1de8 Mon Sep 17 00:00:00 2001 From: goodhoko Date: Tue, 16 Sep 2025 09:49:01 +0200 Subject: [PATCH 2/2] Don't forget to update the changelog (again) --- embassy-stm32/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/embassy-stm32/CHANGELOG.md b/embassy-stm32/CHANGELOG.md index 624845b3a..e3f18ca0d 100644 --- a/embassy-stm32/CHANGELOG.md +++ b/embassy-stm32/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - fix: stm32/(ospi/hspi/xspi): Fix the alternate bytes register config sticking around for subsequent writes - feat: Configurable gpio speed for QSPI - feat: derive Clone, Copy and defmt::Format for all *SPI-related configs +- fix: handle address and data-length errors in OSPI ## 0.4.0 - 2025-08-26