diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-05-21 22:27:15 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-05-21 22:27:15 +0000 |
| commit | 608c953fc8bf782d73b3e2a22ae06150a6259bb6 (patch) | |
| tree | d1b1a6ed5f443aa19b198277894d504569a2e7b2 | |
| parent | 6fa608f516cf21f38a5592eaf1d176c683a7b6dd (diff) | |
| parent | e7161aa085bb145df6607eff5b2c2d0ed06acda1 (diff) | |
Merge pull request #2982 from embassy-rs/qspi-nodma
stm32/qspi: remove DMA generic param.
| -rw-r--r-- | embassy-stm32/src/qspi/mod.rs | 305 | ||||
| -rw-r--r-- | examples/stm32f7/src/bin/qspi.rs | 13 |
2 files changed, 167 insertions, 151 deletions
diff --git a/embassy-stm32/src/qspi/mod.rs b/embassy-stm32/src/qspi/mod.rs index 0a4b4f074..a82e93b5b 100644 --- a/embassy-stm32/src/qspi/mod.rs +++ b/embassy-stm32/src/qspi/mod.rs | |||
| @@ -4,11 +4,14 @@ | |||
| 4 | 4 | ||
| 5 | pub mod enums; | 5 | pub mod enums; |
| 6 | 6 | ||
| 7 | use core::marker::PhantomData; | ||
| 8 | |||
| 7 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 9 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 8 | use enums::*; | 10 | use enums::*; |
| 9 | 11 | ||
| 10 | use crate::dma::Transfer; | 12 | use crate::dma::ChannelAndRequest; |
| 11 | use crate::gpio::{AFType, AnyPin, Pull}; | 13 | use crate::gpio::{AFType, AnyPin, Pull, Speed}; |
| 14 | use crate::mode::{Async, Blocking, Mode as PeriMode}; | ||
| 12 | use crate::pac::quadspi::Quadspi as Regs; | 15 | use crate::pac::quadspi::Quadspi as Regs; |
| 13 | use crate::rcc::RccPeripheral; | 16 | use crate::rcc::RccPeripheral; |
| 14 | use crate::{peripherals, Peripheral}; | 17 | use crate::{peripherals, Peripheral}; |
| @@ -71,7 +74,7 @@ impl Default for Config { | |||
| 71 | 74 | ||
| 72 | /// QSPI driver. | 75 | /// QSPI driver. |
| 73 | #[allow(dead_code)] | 76 | #[allow(dead_code)] |
| 74 | pub struct Qspi<'d, T: Instance, Dma> { | 77 | pub struct Qspi<'d, T: Instance, M: PeriMode> { |
| 75 | _peri: PeripheralRef<'d, T>, | 78 | _peri: PeripheralRef<'d, T>, |
| 76 | sck: Option<PeripheralRef<'d, AnyPin>>, | 79 | sck: Option<PeripheralRef<'d, AnyPin>>, |
| 77 | d0: Option<PeripheralRef<'d, AnyPin>>, | 80 | d0: Option<PeripheralRef<'d, AnyPin>>, |
| @@ -79,93 +82,12 @@ pub struct Qspi<'d, T: Instance, Dma> { | |||
| 79 | d2: Option<PeripheralRef<'d, AnyPin>>, | 82 | d2: Option<PeripheralRef<'d, AnyPin>>, |
| 80 | d3: Option<PeripheralRef<'d, AnyPin>>, | 83 | d3: Option<PeripheralRef<'d, AnyPin>>, |
| 81 | nss: Option<PeripheralRef<'d, AnyPin>>, | 84 | nss: Option<PeripheralRef<'d, AnyPin>>, |
| 82 | dma: PeripheralRef<'d, Dma>, | 85 | dma: Option<ChannelAndRequest<'d>>, |
| 86 | _phantom: PhantomData<M>, | ||
| 83 | config: Config, | 87 | config: Config, |
| 84 | } | 88 | } |
| 85 | 89 | ||
| 86 | impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { | 90 | impl<'d, T: Instance, M: PeriMode> Qspi<'d, T, M> { |
| 87 | /// Create a new QSPI driver for bank 1. | ||
| 88 | pub fn new_bk1( | ||
| 89 | peri: impl Peripheral<P = T> + 'd, | ||
| 90 | d0: impl Peripheral<P = impl BK1D0Pin<T>> + 'd, | ||
| 91 | d1: impl Peripheral<P = impl BK1D1Pin<T>> + 'd, | ||
| 92 | d2: impl Peripheral<P = impl BK1D2Pin<T>> + 'd, | ||
| 93 | d3: impl Peripheral<P = impl BK1D3Pin<T>> + 'd, | ||
| 94 | sck: impl Peripheral<P = impl SckPin<T>> + 'd, | ||
| 95 | nss: impl Peripheral<P = impl BK1NSSPin<T>> + 'd, | ||
| 96 | dma: impl Peripheral<P = Dma> + 'd, | ||
| 97 | config: Config, | ||
| 98 | ) -> Self { | ||
| 99 | into_ref!(peri, d0, d1, d2, d3, sck, nss); | ||
| 100 | |||
| 101 | sck.set_as_af_pull(sck.af_num(), AFType::OutputPushPull, Pull::None); | ||
| 102 | sck.set_speed(crate::gpio::Speed::VeryHigh); | ||
| 103 | nss.set_as_af_pull(nss.af_num(), AFType::OutputPushPull, Pull::Up); | ||
| 104 | nss.set_speed(crate::gpio::Speed::VeryHigh); | ||
| 105 | d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::None); | ||
| 106 | d0.set_speed(crate::gpio::Speed::VeryHigh); | ||
| 107 | d1.set_as_af_pull(d1.af_num(), AFType::OutputPushPull, Pull::None); | ||
| 108 | d1.set_speed(crate::gpio::Speed::VeryHigh); | ||
| 109 | d2.set_as_af_pull(d2.af_num(), AFType::OutputPushPull, Pull::None); | ||
| 110 | d2.set_speed(crate::gpio::Speed::VeryHigh); | ||
| 111 | d3.set_as_af_pull(d3.af_num(), AFType::OutputPushPull, Pull::None); | ||
| 112 | d3.set_speed(crate::gpio::Speed::VeryHigh); | ||
| 113 | |||
| 114 | Self::new_inner( | ||
| 115 | peri, | ||
| 116 | Some(d0.map_into()), | ||
| 117 | Some(d1.map_into()), | ||
| 118 | Some(d2.map_into()), | ||
| 119 | Some(d3.map_into()), | ||
| 120 | Some(sck.map_into()), | ||
| 121 | Some(nss.map_into()), | ||
| 122 | dma, | ||
| 123 | config, | ||
| 124 | FlashSelection::Flash1, | ||
| 125 | ) | ||
| 126 | } | ||
| 127 | |||
| 128 | /// Create a new QSPI driver for bank 2. | ||
| 129 | pub fn new_bk2( | ||
| 130 | peri: impl Peripheral<P = T> + 'd, | ||
| 131 | d0: impl Peripheral<P = impl BK2D0Pin<T>> + 'd, | ||
| 132 | d1: impl Peripheral<P = impl BK2D1Pin<T>> + 'd, | ||
| 133 | d2: impl Peripheral<P = impl BK2D2Pin<T>> + 'd, | ||
| 134 | d3: impl Peripheral<P = impl BK2D3Pin<T>> + 'd, | ||
| 135 | sck: impl Peripheral<P = impl SckPin<T>> + 'd, | ||
| 136 | nss: impl Peripheral<P = impl BK2NSSPin<T>> + 'd, | ||
| 137 | dma: impl Peripheral<P = Dma> + 'd, | ||
| 138 | config: Config, | ||
| 139 | ) -> Self { | ||
| 140 | into_ref!(peri, d0, d1, d2, d3, sck, nss); | ||
| 141 | |||
| 142 | sck.set_as_af_pull(sck.af_num(), AFType::OutputPushPull, Pull::None); | ||
| 143 | sck.set_speed(crate::gpio::Speed::VeryHigh); | ||
| 144 | nss.set_as_af_pull(nss.af_num(), AFType::OutputPushPull, Pull::Up); | ||
| 145 | nss.set_speed(crate::gpio::Speed::VeryHigh); | ||
| 146 | d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::None); | ||
| 147 | d0.set_speed(crate::gpio::Speed::VeryHigh); | ||
| 148 | d1.set_as_af_pull(d1.af_num(), AFType::OutputPushPull, Pull::None); | ||
| 149 | d1.set_speed(crate::gpio::Speed::VeryHigh); | ||
| 150 | d2.set_as_af_pull(d2.af_num(), AFType::OutputPushPull, Pull::None); | ||
| 151 | d2.set_speed(crate::gpio::Speed::VeryHigh); | ||
| 152 | d3.set_as_af_pull(d3.af_num(), AFType::OutputPushPull, Pull::None); | ||
| 153 | d3.set_speed(crate::gpio::Speed::VeryHigh); | ||
| 154 | |||
| 155 | Self::new_inner( | ||
| 156 | peri, | ||
| 157 | Some(d0.map_into()), | ||
| 158 | Some(d1.map_into()), | ||
| 159 | Some(d2.map_into()), | ||
| 160 | Some(d3.map_into()), | ||
| 161 | Some(sck.map_into()), | ||
| 162 | Some(nss.map_into()), | ||
| 163 | dma, | ||
| 164 | config, | ||
| 165 | FlashSelection::Flash2, | ||
| 166 | ) | ||
| 167 | } | ||
| 168 | |||
| 169 | fn new_inner( | 91 | fn new_inner( |
| 170 | peri: impl Peripheral<P = T> + 'd, | 92 | peri: impl Peripheral<P = T> + 'd, |
| 171 | d0: Option<PeripheralRef<'d, AnyPin>>, | 93 | d0: Option<PeripheralRef<'d, AnyPin>>, |
| @@ -174,11 +96,11 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { | |||
| 174 | d3: Option<PeripheralRef<'d, AnyPin>>, | 96 | d3: Option<PeripheralRef<'d, AnyPin>>, |
| 175 | sck: Option<PeripheralRef<'d, AnyPin>>, | 97 | sck: Option<PeripheralRef<'d, AnyPin>>, |
| 176 | nss: Option<PeripheralRef<'d, AnyPin>>, | 98 | nss: Option<PeripheralRef<'d, AnyPin>>, |
| 177 | dma: impl Peripheral<P = Dma> + 'd, | 99 | dma: Option<ChannelAndRequest<'d>>, |
| 178 | config: Config, | 100 | config: Config, |
| 179 | fsel: FlashSelection, | 101 | fsel: FlashSelection, |
| 180 | ) -> Self { | 102 | ) -> Self { |
| 181 | into_ref!(peri, dma); | 103 | into_ref!(peri); |
| 182 | 104 | ||
| 183 | T::enable_and_reset(); | 105 | T::enable_and_reset(); |
| 184 | 106 | ||
| @@ -220,6 +142,7 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { | |||
| 220 | d3, | 142 | d3, |
| 221 | nss, | 143 | nss, |
| 222 | dma, | 144 | dma, |
| 145 | _phantom: PhantomData, | ||
| 223 | config, | 146 | config, |
| 224 | } | 147 | } |
| 225 | } | 148 | } |
| @@ -278,11 +201,146 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { | |||
| 278 | T::REGS.fcr().modify(|v| v.set_ctcf(true)); | 201 | T::REGS.fcr().modify(|v| v.set_ctcf(true)); |
| 279 | } | 202 | } |
| 280 | 203 | ||
| 204 | fn setup_transaction(&mut self, fmode: QspiMode, transaction: &TransferConfig, data_len: Option<usize>) { | ||
| 205 | T::REGS.fcr().modify(|v| { | ||
| 206 | v.set_csmf(true); | ||
| 207 | v.set_ctcf(true); | ||
| 208 | v.set_ctef(true); | ||
| 209 | v.set_ctof(true); | ||
| 210 | }); | ||
| 211 | |||
| 212 | while T::REGS.sr().read().busy() {} | ||
| 213 | |||
| 214 | if let Some(len) = data_len { | ||
| 215 | T::REGS.dlr().write(|v| v.set_dl(len as u32 - 1)); | ||
| 216 | } | ||
| 217 | |||
| 218 | T::REGS.ccr().write(|v| { | ||
| 219 | v.set_fmode(fmode.into()); | ||
| 220 | v.set_imode(transaction.iwidth.into()); | ||
| 221 | v.set_instruction(transaction.instruction); | ||
| 222 | v.set_admode(transaction.awidth.into()); | ||
| 223 | v.set_adsize(self.config.address_size.into()); | ||
| 224 | v.set_dmode(transaction.dwidth.into()); | ||
| 225 | v.set_abmode(QspiWidth::NONE.into()); | ||
| 226 | v.set_dcyc(transaction.dummy.into()); | ||
| 227 | }); | ||
| 228 | |||
| 229 | if let Some(addr) = transaction.address { | ||
| 230 | T::REGS.ar().write(|v| { | ||
| 231 | v.set_address(addr); | ||
| 232 | }); | ||
| 233 | } | ||
| 234 | } | ||
| 235 | } | ||
| 236 | |||
| 237 | impl<'d, T: Instance> Qspi<'d, T, Blocking> { | ||
| 238 | /// Create a new QSPI driver for bank 1, in blocking mode. | ||
| 239 | pub fn new_blocking_bank1( | ||
| 240 | peri: impl Peripheral<P = T> + 'd, | ||
| 241 | d0: impl Peripheral<P = impl BK1D0Pin<T>> + 'd, | ||
| 242 | d1: impl Peripheral<P = impl BK1D1Pin<T>> + 'd, | ||
| 243 | d2: impl Peripheral<P = impl BK1D2Pin<T>> + 'd, | ||
| 244 | d3: impl Peripheral<P = impl BK1D3Pin<T>> + 'd, | ||
| 245 | sck: impl Peripheral<P = impl SckPin<T>> + 'd, | ||
| 246 | nss: impl Peripheral<P = impl BK1NSSPin<T>> + 'd, | ||
| 247 | config: Config, | ||
| 248 | ) -> Self { | ||
| 249 | Self::new_inner( | ||
| 250 | peri, | ||
| 251 | new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), | ||
| 252 | new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), | ||
| 253 | new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), | ||
| 254 | new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), | ||
| 255 | new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), | ||
| 256 | new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), | ||
| 257 | None, | ||
| 258 | config, | ||
| 259 | FlashSelection::Flash1, | ||
| 260 | ) | ||
| 261 | } | ||
| 262 | |||
| 263 | /// Create a new QSPI driver for bank 2, in blocking mode. | ||
| 264 | pub fn new_blocking_bank2( | ||
| 265 | peri: impl Peripheral<P = T> + 'd, | ||
| 266 | d0: impl Peripheral<P = impl BK2D0Pin<T>> + 'd, | ||
| 267 | d1: impl Peripheral<P = impl BK2D1Pin<T>> + 'd, | ||
| 268 | d2: impl Peripheral<P = impl BK2D2Pin<T>> + 'd, | ||
| 269 | d3: impl Peripheral<P = impl BK2D3Pin<T>> + 'd, | ||
| 270 | sck: impl Peripheral<P = impl SckPin<T>> + 'd, | ||
| 271 | nss: impl Peripheral<P = impl BK2NSSPin<T>> + 'd, | ||
| 272 | config: Config, | ||
| 273 | ) -> Self { | ||
| 274 | Self::new_inner( | ||
| 275 | peri, | ||
| 276 | new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), | ||
| 277 | new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), | ||
| 278 | new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), | ||
| 279 | new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), | ||
| 280 | new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), | ||
| 281 | new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), | ||
| 282 | None, | ||
| 283 | config, | ||
| 284 | FlashSelection::Flash2, | ||
| 285 | ) | ||
| 286 | } | ||
| 287 | } | ||
| 288 | |||
| 289 | impl<'d, T: Instance> Qspi<'d, T, Async> { | ||
| 290 | /// Create a new QSPI driver for bank 1. | ||
| 291 | pub fn new_bank1( | ||
| 292 | peri: impl Peripheral<P = T> + 'd, | ||
| 293 | d0: impl Peripheral<P = impl BK1D0Pin<T>> + 'd, | ||
| 294 | d1: impl Peripheral<P = impl BK1D1Pin<T>> + 'd, | ||
| 295 | d2: impl Peripheral<P = impl BK1D2Pin<T>> + 'd, | ||
| 296 | d3: impl Peripheral<P = impl BK1D3Pin<T>> + 'd, | ||
| 297 | sck: impl Peripheral<P = impl SckPin<T>> + 'd, | ||
| 298 | nss: impl Peripheral<P = impl BK1NSSPin<T>> + 'd, | ||
| 299 | dma: impl Peripheral<P = impl QuadDma<T>> + 'd, | ||
| 300 | config: Config, | ||
| 301 | ) -> Self { | ||
| 302 | Self::new_inner( | ||
| 303 | peri, | ||
| 304 | new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), | ||
| 305 | new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), | ||
| 306 | new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), | ||
| 307 | new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), | ||
| 308 | new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), | ||
| 309 | new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), | ||
| 310 | new_dma!(dma), | ||
| 311 | config, | ||
| 312 | FlashSelection::Flash1, | ||
| 313 | ) | ||
| 314 | } | ||
| 315 | |||
| 316 | /// Create a new QSPI driver for bank 2. | ||
| 317 | pub fn new_bank2( | ||
| 318 | peri: impl Peripheral<P = T> + 'd, | ||
| 319 | d0: impl Peripheral<P = impl BK2D0Pin<T>> + 'd, | ||
| 320 | d1: impl Peripheral<P = impl BK2D1Pin<T>> + 'd, | ||
| 321 | d2: impl Peripheral<P = impl BK2D2Pin<T>> + 'd, | ||
| 322 | d3: impl Peripheral<P = impl BK2D3Pin<T>> + 'd, | ||
| 323 | sck: impl Peripheral<P = impl SckPin<T>> + 'd, | ||
| 324 | nss: impl Peripheral<P = impl BK2NSSPin<T>> + 'd, | ||
| 325 | dma: impl Peripheral<P = impl QuadDma<T>> + 'd, | ||
| 326 | config: Config, | ||
| 327 | ) -> Self { | ||
| 328 | Self::new_inner( | ||
| 329 | peri, | ||
| 330 | new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), | ||
| 331 | new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), | ||
| 332 | new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), | ||
| 333 | new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), | ||
| 334 | new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), | ||
| 335 | new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), | ||
| 336 | new_dma!(dma), | ||
| 337 | config, | ||
| 338 | FlashSelection::Flash2, | ||
| 339 | ) | ||
| 340 | } | ||
| 341 | |||
| 281 | /// Blocking read data, using DMA. | 342 | /// Blocking read data, using DMA. |
| 282 | pub fn blocking_read_dma(&mut self, buf: &mut [u8], transaction: TransferConfig) | 343 | pub fn blocking_read_dma(&mut self, buf: &mut [u8], transaction: TransferConfig) { |
| 283 | where | ||
| 284 | Dma: QuadDma<T>, | ||
| 285 | { | ||
| 286 | self.setup_transaction(QspiMode::IndirectWrite, &transaction, Some(buf.len())); | 344 | self.setup_transaction(QspiMode::IndirectWrite, &transaction, Some(buf.len())); |
| 287 | 345 | ||
| 288 | T::REGS.ccr().modify(|v| { | 346 | T::REGS.ccr().modify(|v| { |
| @@ -293,15 +351,11 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { | |||
| 293 | v.set_address(current_ar); | 351 | v.set_address(current_ar); |
| 294 | }); | 352 | }); |
| 295 | 353 | ||
| 296 | let request = self.dma.request(); | ||
| 297 | let transfer = unsafe { | 354 | let transfer = unsafe { |
| 298 | Transfer::new_read( | 355 | self.dma |
| 299 | &mut self.dma, | 356 | .as_mut() |
| 300 | request, | 357 | .unwrap() |
| 301 | T::REGS.dr().as_ptr() as *mut u8, | 358 | .read(T::REGS.dr().as_ptr() as *mut u8, buf, Default::default()) |
| 302 | buf, | ||
| 303 | Default::default(), | ||
| 304 | ) | ||
| 305 | }; | 359 | }; |
| 306 | 360 | ||
| 307 | // STM32H7 does not have dmaen | 361 | // STM32H7 does not have dmaen |
| @@ -312,25 +366,18 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { | |||
| 312 | } | 366 | } |
| 313 | 367 | ||
| 314 | /// Blocking write data, using DMA. | 368 | /// Blocking write data, using DMA. |
| 315 | pub fn blocking_write_dma(&mut self, buf: &[u8], transaction: TransferConfig) | 369 | pub fn blocking_write_dma(&mut self, buf: &[u8], transaction: TransferConfig) { |
| 316 | where | ||
| 317 | Dma: QuadDma<T>, | ||
| 318 | { | ||
| 319 | self.setup_transaction(QspiMode::IndirectWrite, &transaction, Some(buf.len())); | 370 | self.setup_transaction(QspiMode::IndirectWrite, &transaction, Some(buf.len())); |
| 320 | 371 | ||
| 321 | T::REGS.ccr().modify(|v| { | 372 | T::REGS.ccr().modify(|v| { |
| 322 | v.set_fmode(QspiMode::IndirectWrite.into()); | 373 | v.set_fmode(QspiMode::IndirectWrite.into()); |
| 323 | }); | 374 | }); |
| 324 | 375 | ||
| 325 | let request = self.dma.request(); | ||
| 326 | let transfer = unsafe { | 376 | let transfer = unsafe { |
| 327 | Transfer::new_write( | 377 | self.dma |
| 328 | &mut self.dma, | 378 | .as_mut() |
| 329 | request, | 379 | .unwrap() |
| 330 | buf, | 380 | .write(buf, T::REGS.dr().as_ptr() as *mut u8, Default::default()) |
| 331 | T::REGS.dr().as_ptr() as *mut u8, | ||
| 332 | Default::default(), | ||
| 333 | ) | ||
| 334 | }; | 381 | }; |
| 335 | 382 | ||
| 336 | // STM32H7 does not have dmaen | 383 | // STM32H7 does not have dmaen |
| @@ -339,38 +386,6 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { | |||
| 339 | 386 | ||
| 340 | transfer.blocking_wait(); | 387 | transfer.blocking_wait(); |
| 341 | } | 388 | } |
| 342 | |||
| 343 | fn setup_transaction(&mut self, fmode: QspiMode, transaction: &TransferConfig, data_len: Option<usize>) { | ||
| 344 | T::REGS.fcr().modify(|v| { | ||
| 345 | v.set_csmf(true); | ||
| 346 | v.set_ctcf(true); | ||
| 347 | v.set_ctef(true); | ||
| 348 | v.set_ctof(true); | ||
| 349 | }); | ||
| 350 | |||
| 351 | while T::REGS.sr().read().busy() {} | ||
| 352 | |||
| 353 | if let Some(len) = data_len { | ||
| 354 | T::REGS.dlr().write(|v| v.set_dl(len as u32 - 1)); | ||
| 355 | } | ||
| 356 | |||
| 357 | T::REGS.ccr().write(|v| { | ||
| 358 | v.set_fmode(fmode.into()); | ||
| 359 | v.set_imode(transaction.iwidth.into()); | ||
| 360 | v.set_instruction(transaction.instruction); | ||
| 361 | v.set_admode(transaction.awidth.into()); | ||
| 362 | v.set_adsize(self.config.address_size.into()); | ||
| 363 | v.set_dmode(transaction.dwidth.into()); | ||
| 364 | v.set_abmode(QspiWidth::NONE.into()); | ||
| 365 | v.set_dcyc(transaction.dummy.into()); | ||
| 366 | }); | ||
| 367 | |||
| 368 | if let Some(addr) = transaction.address { | ||
| 369 | T::REGS.ar().write(|v| { | ||
| 370 | v.set_address(addr); | ||
| 371 | }); | ||
| 372 | } | ||
| 373 | } | ||
| 374 | } | 389 | } |
| 375 | 390 | ||
| 376 | trait SealedInstance { | 391 | trait SealedInstance { |
diff --git a/examples/stm32f7/src/bin/qspi.rs b/examples/stm32f7/src/bin/qspi.rs index 005694db3..90d319b7a 100644 --- a/examples/stm32f7/src/bin/qspi.rs +++ b/examples/stm32f7/src/bin/qspi.rs | |||
| @@ -4,8 +4,9 @@ | |||
| 4 | 4 | ||
| 5 | use defmt::info; | 5 | use defmt::info; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::mode::Async; | ||
| 7 | use embassy_stm32::qspi::enums::{AddressSize, ChipSelectHighTime, FIFOThresholdLevel, MemorySize, *}; | 8 | use embassy_stm32::qspi::enums::{AddressSize, ChipSelectHighTime, FIFOThresholdLevel, MemorySize, *}; |
| 8 | use embassy_stm32::qspi::{Config as QspiCfg, Instance, Qspi, QuadDma, TransferConfig}; | 9 | use embassy_stm32::qspi::{Config as QspiCfg, Instance, Qspi, TransferConfig}; |
| 9 | use embassy_stm32::time::mhz; | 10 | use embassy_stm32::time::mhz; |
| 10 | use embassy_stm32::Config as StmCfg; | 11 | use embassy_stm32::Config as StmCfg; |
| 11 | use {defmt_rtt as _, panic_probe as _}; | 12 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -43,12 +44,12 @@ const MEMORY_ADDR: u32 = 0x00000000u32; | |||
| 43 | /// Implementation of access to flash chip. | 44 | /// Implementation of access to flash chip. |
| 44 | /// Chip commands are hardcoded as it depends on used chip. | 45 | /// Chip commands are hardcoded as it depends on used chip. |
| 45 | /// This implementation is using chip GD25Q64C from Giga Device | 46 | /// This implementation is using chip GD25Q64C from Giga Device |
| 46 | pub struct FlashMemory<I: Instance, D: QuadDma<I>> { | 47 | pub struct FlashMemory<I: Instance> { |
| 47 | qspi: Qspi<'static, I, D>, | 48 | qspi: Qspi<'static, I, Async>, |
| 48 | } | 49 | } |
| 49 | 50 | ||
| 50 | impl<I: Instance, D: QuadDma<I>> FlashMemory<I, D> { | 51 | impl<I: Instance> FlashMemory<I> { |
| 51 | pub fn new(qspi: Qspi<'static, I, D>) -> Self { | 52 | pub fn new(qspi: Qspi<'static, I, Async>) -> Self { |
| 52 | let mut memory = Self { qspi }; | 53 | let mut memory = Self { qspi }; |
| 53 | 54 | ||
| 54 | memory.reset_memory(); | 55 | memory.reset_memory(); |
| @@ -279,7 +280,7 @@ async fn main(_spawner: Spawner) -> ! { | |||
| 279 | cs_high_time: ChipSelectHighTime::_1Cycle, | 280 | cs_high_time: ChipSelectHighTime::_1Cycle, |
| 280 | fifo_threshold: FIFOThresholdLevel::_16Bytes, | 281 | fifo_threshold: FIFOThresholdLevel::_16Bytes, |
| 281 | }; | 282 | }; |
| 282 | let driver = Qspi::new_bk1( | 283 | let driver = Qspi::new_bank1( |
| 283 | p.QUADSPI, p.PF8, p.PF9, p.PE2, p.PF6, p.PF10, p.PB10, p.DMA2_CH7, config, | 284 | p.QUADSPI, p.PF8, p.PF9, p.PE2, p.PF6, p.PF10, p.PB10, p.DMA2_CH7, config, |
| 284 | ); | 285 | ); |
| 285 | let mut flash = FlashMemory::new(driver); | 286 | let mut flash = FlashMemory::new(driver); |
