diff options
| author | Dario Nieuwenhuis <[email protected]> | 2025-09-16 13:54:44 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-09-16 13:54:44 +0000 |
| commit | 5ad56290ffba202fe1ccd69d33452cc18d3575ea (patch) | |
| tree | 3c7943059a4e97959753fb228d9ba7b30a6bfc44 | |
| parent | ec117e3b08e329c0d713dcd493822fbb547eb5aa (diff) | |
| parent | 97462c07ce3d5797dfcefb15dd4b50383a850638 (diff) | |
Merge pull request #4671 from tonarino/chunk-ospi-dma-write
embasy-stm32: Allow large OSPI DMA writes with chunking
| -rw-r--r-- | embassy-stm32/CHANGELOG.md | 1 | ||||
| -rw-r--r-- | embassy-stm32/src/ospi/mod.rs | 42 |
2 files changed, 25 insertions, 18 deletions
diff --git a/embassy-stm32/CHANGELOG.md b/embassy-stm32/CHANGELOG.md index e3f18ca0d..253b4796d 100644 --- a/embassy-stm32/CHANGELOG.md +++ b/embassy-stm32/CHANGELOG.md | |||
| @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 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 | - fix: handle address and data-length errors in OSPI |
| 23 | - feat: Allow OSPI DMA writes larger than 64kB using chunking | ||
| 23 | 24 | ||
| 24 | ## 0.4.0 - 2025-08-26 | 25 | ## 0.4.0 - 2025-08-26 |
| 25 | 26 | ||
diff --git a/embassy-stm32/src/ospi/mod.rs b/embassy-stm32/src/ospi/mod.rs index c291a311d..d93cecb69 100644 --- a/embassy-stm32/src/ospi/mod.rs +++ b/embassy-stm32/src/ospi/mod.rs | |||
| @@ -1198,16 +1198,19 @@ impl<'d, T: Instance> Ospi<'d, T, Async> { | |||
| 1198 | .cr() | 1198 | .cr() |
| 1199 | .modify(|v| v.set_fmode(vals::FunctionalMode::INDIRECT_WRITE)); | 1199 | .modify(|v| v.set_fmode(vals::FunctionalMode::INDIRECT_WRITE)); |
| 1200 | 1200 | ||
| 1201 | let transfer = unsafe { | 1201 | // TODO: implement this using a LinkedList DMA to offload the whole transfer off the CPU. |
| 1202 | self.dma | 1202 | for chunk in buf.chunks(0xFFFF) { |
| 1203 | .as_mut() | 1203 | let transfer = unsafe { |
| 1204 | .unwrap() | 1204 | self.dma |
| 1205 | .write(buf, T::REGS.dr().as_ptr() as *mut W, Default::default()) | 1205 | .as_mut() |
| 1206 | }; | 1206 | .unwrap() |
| 1207 | 1207 | .write(chunk, T::REGS.dr().as_ptr() as *mut W, Default::default()) | |
| 1208 | T::REGS.cr().modify(|w| w.set_dmaen(true)); | 1208 | }; |
| 1209 | 1209 | ||
| 1210 | transfer.blocking_wait(); | 1210 | T::REGS.cr().modify(|w| w.set_dmaen(true)); |
| 1211 | |||
| 1212 | transfer.blocking_wait(); | ||
| 1213 | } | ||
| 1211 | 1214 | ||
| 1212 | finish_dma(T::REGS); | 1215 | finish_dma(T::REGS); |
| 1213 | 1216 | ||
| @@ -1268,16 +1271,19 @@ impl<'d, T: Instance> Ospi<'d, T, Async> { | |||
| 1268 | .cr() | 1271 | .cr() |
| 1269 | .modify(|v| v.set_fmode(vals::FunctionalMode::INDIRECT_WRITE)); | 1272 | .modify(|v| v.set_fmode(vals::FunctionalMode::INDIRECT_WRITE)); |
| 1270 | 1273 | ||
| 1271 | let transfer = unsafe { | 1274 | // TODO: implement this using a LinkedList DMA to offload the whole transfer off the CPU. |
| 1272 | self.dma | 1275 | for chunk in buf.chunks(0xFFFF) { |
| 1273 | .as_mut() | 1276 | let transfer = unsafe { |
| 1274 | .unwrap() | 1277 | self.dma |
| 1275 | .write(buf, T::REGS.dr().as_ptr() as *mut W, Default::default()) | 1278 | .as_mut() |
| 1276 | }; | 1279 | .unwrap() |
| 1280 | .write(chunk, T::REGS.dr().as_ptr() as *mut W, Default::default()) | ||
| 1281 | }; | ||
| 1277 | 1282 | ||
| 1278 | T::REGS.cr().modify(|w| w.set_dmaen(true)); | 1283 | T::REGS.cr().modify(|w| w.set_dmaen(true)); |
| 1279 | 1284 | ||
| 1280 | transfer.await; | 1285 | transfer.await; |
| 1286 | } | ||
| 1281 | 1287 | ||
| 1282 | finish_dma(T::REGS); | 1288 | finish_dma(T::REGS); |
| 1283 | 1289 | ||
