diff options
| author | Dario Nieuwenhuis <[email protected]> | 2025-09-16 09:47:51 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-09-16 09:47:51 +0000 |
| commit | ec117e3b08e329c0d713dcd493822fbb547eb5aa (patch) | |
| tree | af2897ffcc9331d92ffa00046a103bb65271d575 | |
| parent | fe95e338617d28116e38af6b8c5a5be37c6c24a0 (diff) | |
| parent | 9ae76cbad6fc2bf4d00c731d98df0563241b1de8 (diff) | |
Merge pull request #4670 from tonarino/handle-ospi-errors
embassy-stm32: Handle OSPI address errors
| -rw-r--r-- | embassy-stm32/CHANGELOG.md | 1 | ||||
| -rw-r--r-- | embassy-stm32/src/ospi/mod.rs | 21 |
2 files changed, 19 insertions, 3 deletions
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 | |||
| 19 | - fix: stm32/(ospi/hspi/xspi): Fix the alternate bytes register config sticking around for subsequent writes | 19 | - fix: stm32/(ospi/hspi/xspi): Fix the alternate bytes register config sticking around for subsequent writes |
| 20 | - feat: Configurable gpio speed for QSPI | 20 | - feat: Configurable gpio speed for QSPI |
| 21 | - feat: derive Clone, Copy and defmt::Format for all *SPI-related configs | 21 | - feat: derive Clone, Copy and defmt::Format for all *SPI-related configs |
| 22 | - fix: handle address and data-length errors in OSPI | ||
| 22 | 23 | ||
| 23 | ## 0.4.0 - 2025-08-26 | 24 | ## 0.4.0 - 2025-08-26 |
| 24 | 25 | ||
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 { | |||
| 31 | /// Indicates the type of external device connected | 31 | /// Indicates the type of external device connected |
| 32 | pub memory_type: MemoryType, // Need to add an additional enum to provide this public interface | 32 | pub memory_type: MemoryType, // Need to add an additional enum to provide this public interface |
| 33 | /// Defines the size of the external device connected to the OSPI corresponding | 33 | /// Defines the size of the external device connected to the OSPI corresponding |
| 34 | /// to the number of address bits required to access the device | 34 | /// to the number of address bits required to access the device. |
| 35 | /// When using indirect mode, [`TransferConfig::address`] + the length of the data being read | ||
| 36 | /// or written must fit within the configured `device_size`, otherwise an error is returned. | ||
| 35 | pub device_size: MemorySize, | 37 | pub device_size: MemorySize, |
| 36 | /// Sets the minimum number of clock cycles that the chip select signal must be held high | 38 | /// Sets the minimum number of clock cycles that the chip select signal must be held high |
| 37 | /// between commands | 39 | /// between commands |
| @@ -95,10 +97,11 @@ pub struct TransferConfig { | |||
| 95 | pub isize: AddressSize, | 97 | pub isize: AddressSize, |
| 96 | /// Instruction Double Transfer rate enable | 98 | /// Instruction Double Transfer rate enable |
| 97 | pub idtr: bool, | 99 | pub idtr: bool, |
| 98 | |||
| 99 | /// Address width (ADMODE) | 100 | /// Address width (ADMODE) |
| 100 | pub adwidth: OspiWidth, | 101 | pub adwidth: OspiWidth, |
| 101 | /// Device memory address | 102 | /// Device memory address. |
| 103 | /// In indirect mode, this value + the length of the data being read or written must be within | ||
| 104 | /// configured [`Config::device_size`], otherwise the transfer returns an error. | ||
| 102 | pub address: Option<u32>, | 105 | pub address: Option<u32>, |
| 103 | /// Number of Address Bytes | 106 | /// Number of Address Bytes |
| 104 | pub adsize: AddressSize, | 107 | pub adsize: AddressSize, |
| @@ -528,6 +531,18 @@ impl<'d, T: Instance, M: PeriMode> Ospi<'d, T, M> { | |||
| 528 | } | 531 | } |
| 529 | } | 532 | } |
| 530 | 533 | ||
| 534 | // The following errors set the TEF flag in OCTOSPI_SR register: | ||
| 535 | // - in indirect or automatic status-polling mode, when a wrong address has been programmed | ||
| 536 | // in OCTOSPI_AR (according to the device size defined by DEVSIZE[4:0]) | ||
| 537 | // - in indirect mode, if the address plus the data length exceed the device size: TEF is | ||
| 538 | // set as soon as the access is triggered. | ||
| 539 | if T::REGS.sr().read().tef() { | ||
| 540 | // Clear the TEF register to make it ready for the next transfer. | ||
| 541 | T::REGS.fcr().write(|w| w.set_ctef(true)); | ||
| 542 | |||
| 543 | return Err(OspiError::InvalidCommand); | ||
| 544 | } | ||
| 545 | |||
| 531 | Ok(()) | 546 | Ok(()) |
| 532 | } | 547 | } |
| 533 | 548 | ||
