aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Johnston <[email protected]>2025-04-02 11:16:31 +0800
committerMatt Johnston <[email protected]>2025-04-04 17:41:52 +0800
commit36a5b02774a5254fd3a1b715515c84d04dee2d58 (patch)
tree1abff8c22b517c4a42d17e494fc44b0a2c3d0da3
parent6d384a1a39f586c86cabe912fef639336cdc1ac7 (diff)
stm32: Update xspi for stm32-metapac changes
This is now closer to the original ospi, using more idiomatic naming. Some dead code is removed (previously was hidden by [allow(dead_code)]).
-rw-r--r--embassy-stm32/build.rs8
-rw-r--r--embassy-stm32/src/xspi/enums.rs25
-rw-r--r--embassy-stm32/src/xspi/mod.rs371
3 files changed, 178 insertions, 226 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index 13ef74f16..fa9e3f953 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -62,7 +62,13 @@ fn main() {
62 // generate one singleton per peripheral (with many exceptions...) 62 // generate one singleton per peripheral (with many exceptions...)
63 for p in METADATA.peripherals { 63 for p in METADATA.peripherals {
64 if let Some(r) = &p.registers { 64 if let Some(r) = &p.registers {
65 if r.kind == "adccommon" || r.kind == "sai" || r.kind == "ucpd" || r.kind == "otg" || r.kind == "octospi" { 65 if r.kind == "adccommon"
66 || r.kind == "sai"
67 || r.kind == "ucpd"
68 || r.kind == "otg"
69 || r.kind == "octospi"
70 || r.kind == "xspi"
71 {
66 // TODO: should we emit this for all peripherals? if so, we will need a list of all 72 // TODO: should we emit this for all peripherals? if so, we will need a list of all
67 // possible peripherals across all chips, so that we can declare the configs 73 // possible peripherals across all chips, so that we can declare the configs
68 // (replacing the hard-coded list of `peri_*` cfgs below) 74 // (replacing the hard-coded list of `peri_*` cfgs below)
diff --git a/embassy-stm32/src/xspi/enums.rs b/embassy-stm32/src/xspi/enums.rs
index 4214dde37..e02ec797e 100644
--- a/embassy-stm32/src/xspi/enums.rs
+++ b/embassy-stm32/src/xspi/enums.rs
@@ -1,10 +1,11 @@
1//! Enums used in Xspi configuration. 1//! Enums used in Xspi configuration.
2#[allow(dead_code)]
3#[derive(Copy, Clone)] 2#[derive(Copy, Clone)]
4pub(crate) enum XspiMode { 3pub(crate) enum XspiMode {
5 IndirectWrite, 4 IndirectWrite,
6 IndirectRead, 5 IndirectRead,
6 #[expect(dead_code)]
7 AutoPolling, 7 AutoPolling,
8 #[expect(dead_code)]
8 MemoryMapped, 9 MemoryMapped,
9} 10}
10 11
@@ -20,7 +21,6 @@ impl Into<u8> for XspiMode {
20} 21}
21 22
22/// Xspi lane width 23/// Xspi lane width
23#[allow(dead_code)]
24#[derive(Copy, Clone)] 24#[derive(Copy, Clone)]
25pub enum XspiWidth { 25pub enum XspiWidth {
26 /// None 26 /// None
@@ -47,27 +47,7 @@ impl Into<u8> for XspiWidth {
47 } 47 }
48} 48}
49 49
50/// Flash bank selection
51#[allow(dead_code)]
52#[derive(Copy, Clone)]
53pub enum FlashSelection {
54 /// Bank 1
55 Flash1,
56 /// Bank 2
57 Flash2,
58}
59
60impl Into<bool> for FlashSelection {
61 fn into(self) -> bool {
62 match self {
63 FlashSelection::Flash1 => false,
64 FlashSelection::Flash2 => true,
65 }
66 }
67}
68
69/// Wrap Size 50/// Wrap Size
70#[allow(dead_code)]
71#[allow(missing_docs)] 51#[allow(missing_docs)]
72#[derive(Copy, Clone)] 52#[derive(Copy, Clone)]
73pub enum WrapSize { 53pub enum WrapSize {
@@ -92,7 +72,6 @@ impl Into<u8> for WrapSize {
92 72
93/// Memory Type 73/// Memory Type
94#[allow(missing_docs)] 74#[allow(missing_docs)]
95#[allow(dead_code)]
96#[derive(Copy, Clone)] 75#[derive(Copy, Clone)]
97pub enum MemoryType { 76pub enum MemoryType {
98 Micron, 77 Micron,
diff --git a/embassy-stm32/src/xspi/mod.rs b/embassy-stm32/src/xspi/mod.rs
index b2fdebe75..3b5406a57 100644
--- a/embassy-stm32/src/xspi/mod.rs
+++ b/embassy-stm32/src/xspi/mod.rs
@@ -14,8 +14,9 @@ pub use enums::*;
14use crate::dma::{word, ChannelAndRequest}; 14use crate::dma::{word, ChannelAndRequest};
15use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed}; 15use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed};
16use crate::mode::{Async, Blocking, Mode as PeriMode}; 16use crate::mode::{Async, Blocking, Mode as PeriMode};
17use crate::pac::xspi::{vals::*, Xspi as Regs}; 17use crate::pac::xspi::vals::*;
18#[cfg(xspim_v2_1)] 18use crate::pac::xspi::Xspi as Regs;
19#[cfg(xspim_v1)]
19use crate::pac::xspim::Xspim; 20use crate::pac::xspim::Xspim;
20use crate::rcc::{self, RccPeripheral}; 21use crate::rcc::{self, RccPeripheral};
21use crate::{peripherals, Peripheral}; 22use crate::{peripherals, Peripheral};
@@ -41,7 +42,7 @@ pub struct Config {
41 /// Indicates the wrap size corresponding to the external device configuration 42 /// Indicates the wrap size corresponding to the external device configuration
42 pub wrap_size: WrapSize, 43 pub wrap_size: WrapSize,
43 /// Specified the prescaler factor used for generating the external clock based 44 /// Specified the prescaler factor used for generating the external clock based
44 /// on the AHB clock 45 /// on the AHB clock. 0 = Fkernel, 1 = Fkernel/2, 2 = Fkernel/3 etc.
45 pub clock_prescaler: u8, 46 pub clock_prescaler: u8,
46 /// Allows the delay of 1/2 cycle the data sampling to account for external 47 /// Allows the delay of 1/2 cycle the data sampling to account for external
47 /// signal delays 48 /// signal delays
@@ -196,47 +197,35 @@ impl<'d, T: Instance, M: PeriMode> Xspi<'d, T, M> {
196 self.configure_command(&read_config, None)?; 197 self.configure_command(&read_config, None)?;
197 198
198 let reg = T::REGS; 199 let reg = T::REGS;
199 while reg.xspi_sr().read().busy() {} 200 while reg.sr().read().busy() {}
200 201
201 reg.xspi_ccr().modify(|r| { 202 reg.ccr().modify(|r| {
202 r.set_dqse(XspiCcrDqse::B_0X0); 203 r.set_dqse(false);
203 }); 204 });
204 205
205 // Set wrting configurations, there are separate registers for write configurations in memory mapped mode 206 // Set wrting configurations, there are separate registers for write configurations in memory mapped mode
206 reg.xspi_wccr().modify(|w| { 207 reg.wccr().modify(|w| {
207 w.set_imode(XspiWccrImode::from_bits(write_config.iwidth.into())); 208 w.set_imode(WccrImode::from_bits(write_config.iwidth.into()));
208 let idtr = match write_config.idtr { 209 w.set_idtr(write_config.idtr);
209 true => XspiWccrIdtr::B_0X1, 210 w.set_isize(WccrIsize::from_bits(write_config.isize.into()));
210 false => XspiWccrIdtr::B_0X0, 211
211 }; 212 w.set_admode(WccrAdmode::from_bits(write_config.adwidth.into()));
212 w.set_idtr(idtr); 213 w.set_addtr(write_config.idtr);
213 w.set_isize(XspiWccrIsize::from_bits(write_config.isize.into())); 214 w.set_adsize(WccrAdsize::from_bits(write_config.adsize.into()));
214 215
215 w.set_admode(XspiWccrAdmode::from_bits(write_config.adwidth.into())); 216 w.set_dmode(WccrDmode::from_bits(write_config.dwidth.into()));
216 let addtr = match write_config.idtr { 217 w.set_ddtr(write_config.idtr);
217 true => XspiWccrAddtr::B_0X1, 218
218 false => XspiWccrAddtr::B_0X0, 219 w.set_abmode(WccrAbmode::from_bits(write_config.abwidth.into()));
219 }; 220 w.set_dqse(true);
220 w.set_addtr(addtr);
221 w.set_adsize(XspiWccrAdsize::from_bits(write_config.adsize.into()));
222
223 w.set_dmode(XspiWccrDmode::from_bits(write_config.dwidth.into()));
224 let ddtr = match write_config.idtr {
225 true => XspiWccrDdtr::B_0X1,
226 false => XspiWccrDdtr::B_0X0,
227 };
228 w.set_ddtr(ddtr);
229
230 w.set_abmode(XspiWccrAbmode::from_bits(write_config.abwidth.into()));
231 w.set_dqse(XspiWccrDqse::B_0X1);
232 }); 221 });
233 222
234 reg.xspi_wtcr().modify(|w| w.set_dcyc(write_config.dummy.into())); 223 reg.wtcr().modify(|w| w.set_dcyc(write_config.dummy.into()));
235 224
236 // Enable memory mapped mode 225 // Enable memory mapped mode
237 reg.xspi_cr().modify(|r| { 226 reg.cr().modify(|r| {
238 r.set_fmode(Fmode::B_0X3); 227 r.set_fmode(Fmode::B_0X3);
239 r.set_tcen(Tcen::B_0X0); 228 r.set_tcen(false);
240 }); 229 });
241 Ok(()) 230 Ok(())
242 } 231 }
@@ -245,19 +234,19 @@ impl<'d, T: Instance, M: PeriMode> Xspi<'d, T, M> {
245 pub fn disable_memory_mapped_mode(&mut self) { 234 pub fn disable_memory_mapped_mode(&mut self) {
246 let reg = T::REGS; 235 let reg = T::REGS;
247 236
248 reg.xspi_cr().modify(|r| { 237 reg.cr().modify(|r| {
249 r.set_fmode(Fmode::B_0X0); 238 r.set_fmode(Fmode::B_0X0);
250 r.set_abort(Abort::B_0X1); 239 r.set_abort(true);
251 r.set_dmaen(Dmaen::B_0X0); 240 r.set_dmaen(false);
252 r.set_en(En::B_0X0); 241 r.set_en(false);
253 }); 242 });
254 243
255 // Clear transfer complete flag 244 // Clear transfer complete flag
256 reg.xspi_fcr().write(|w| w.set_ctcf(true)); 245 reg.fcr().write(|w| w.set_ctcf(true));
257 246
258 // Re-enable ospi 247 // Re-enable ospi
259 reg.xspi_cr().modify(|r| { 248 reg.cr().modify(|r| {
260 r.set_en(En::B_0X1); 249 r.set_en(true);
261 }); 250 });
262 } 251 }
263 252
@@ -291,18 +280,18 @@ impl<'d, T: Instance, M: PeriMode> Xspi<'d, T, M> {
291 ) -> Self { 280 ) -> Self {
292 into_ref!(peri); 281 into_ref!(peri);
293 282
294 #[cfg(xspim_v2_1)] 283 #[cfg(xspim_v1)]
295 { 284 {
296 // RCC for xspim should be enabled before writing register 285 // RCC for xspim should be enabled before writing register
297 crate::pac::RCC.ahb5enr().modify(|w| w.set_iomngren(true)); 286 crate::pac::RCC.ahb5enr().modify(|w| w.set_iomngren(true));
298 287
299 // Disable XSPI peripheral first 288 // Disable XSPI peripheral first
300 T::REGS.xspi_cr().modify(|w| { 289 T::REGS.cr().modify(|w| {
301 w.set_en(En::B_0X0); 290 w.set_en(false);
302 }); 291 });
303 292
304 // XSPI IO Manager has been enabled before 293 // XSPI IO Manager has been enabled before
305 T::SPIM_REGS.xspim_cr().modify(|w| { 294 T::SPIM_REGS.cr().modify(|w| {
306 w.set_muxen(false); 295 w.set_muxen(false);
307 w.set_req2ack_time(0xff); 296 w.set_req2ack_time(0xff);
308 }); 297 });
@@ -310,74 +299,70 @@ impl<'d, T: Instance, M: PeriMode> Xspi<'d, T, M> {
310 299
311 // System configuration 300 // System configuration
312 rcc::enable_and_reset::<T>(); 301 rcc::enable_and_reset::<T>();
313 while T::REGS.xspi_sr().read().busy() {} 302 while T::REGS.sr().read().busy() {}
314 303
315 // Device configuration 304 // Device configuration
316 T::REGS.xspi_dcr1().modify(|w| { 305 T::REGS.dcr1().modify(|w| {
317 w.set_devsize(config.device_size.into()); 306 w.set_devsize(config.device_size.into());
318 w.set_mtyp(Mtyp::from_bits(config.memory_type.into())); 307 w.set_mtyp(Mtyp::from_bits(config.memory_type.into()));
319 w.set_csht(Csht::from_bits(config.chip_select_high_time.into())); 308 w.set_csht(Csht::from_bits(config.chip_select_high_time.into()));
320 w.set_frck(Frck::B_0X0); 309 w.set_frck(false);
321 w.set_ckmode(Ckmode::from_bits(config.clock_mode.into())); 310 w.set_ckmode(Ckmode::from_bits(config.clock_mode.into()));
322 }); 311 });
323 312
324 T::REGS.xspi_dcr2().modify(|w| { 313 T::REGS.dcr2().modify(|w| {
325 w.set_wrapsize(Wrapsize::from_bits(config.wrap_size.into())); 314 w.set_wrapsize(Wrapsize::from_bits(config.wrap_size.into()));
326 }); 315 });
327 316
328 T::REGS.xspi_dcr3().modify(|w| { 317 T::REGS.dcr3().modify(|w| {
329 w.set_csbound(Csbound::from_bits(config.chip_select_boundary.into())); 318 w.set_csbound(Csbound::from_bits(config.chip_select_boundary.into()));
330 #[cfg(xspi_v2_1)] 319 #[cfg(xspi_v1)]
331 { 320 {
332 w.set_maxtran(Maxtran::from_bits(config.max_transfer.into())); 321 w.set_maxtran(Maxtran::from_bits(config.max_transfer.into()));
333 } 322 }
334 }); 323 });
335 324
336 T::REGS.xspi_dcr4().modify(|w| { 325 T::REGS.dcr4().modify(|w| {
337 w.set_refresh(Refresh::from_bits(config.refresh.into())); 326 w.set_refresh(Refresh::from_bits(config.refresh.into()));
338 }); 327 });
339 328
340 T::REGS.xspi_cr().modify(|w| { 329 T::REGS.cr().modify(|w| {
341 w.set_fthres(Fthres::from_bits(config.fifo_threshold.into())); 330 w.set_fthres(Fthres::from_bits(config.fifo_threshold.into()));
342 }); 331 });
343 332
344 // Wait for busy flag to clear 333 // Wait for busy flag to clear
345 while T::REGS.xspi_sr().read().busy() {} 334 while T::REGS.sr().read().busy() {}
346 335
347 T::REGS.xspi_dcr2().modify(|w| { 336 T::REGS.dcr2().modify(|w| {
348 w.set_prescaler(Prescaler::from_bits(config.clock_prescaler.into())); 337 w.set_prescaler(config.clock_prescaler);
349 }); 338 });
350 339
351 T::REGS.xspi_cr().modify(|w| { 340 T::REGS.cr().modify(|w| {
352 w.set_dmm(match dual_quad { 341 w.set_dmm(dual_quad);
353 true => Dmm::B_0X1,
354 false => Dmm::B_0X0,
355 });
356 }); 342 });
357 343
358 T::REGS.xspi_tcr().modify(|w| { 344 T::REGS.tcr().modify(|w| {
359 w.set_sshift(match config.sample_shifting { 345 w.set_sshift(config.sample_shifting);
360 true => XspiTcrSshift::B_0X1, 346 w.set_dhqc(config.delay_hold_quarter_cycle);
361 false => XspiTcrSshift::B_0X0, 347 });
362 }); 348
363 w.set_dhqc(match config.delay_hold_quarter_cycle { 349 // TODO: at the moment only ncs1 seems to get passed in?
364 true => XspiTcrDhqc::B_0X1, 350 // Only one must be selected
365 false => XspiTcrDhqc::B_0X0, 351 assert!(!(ncs1.is_some() && ncs2.is_some()));
366 }); 352 assert!(!(ncs1.is_none() && ncs2.is_none()));
353 T::REGS.cr().modify(|w| {
354 w.set_cssel(if ncs1.is_some() { Cssel::B_0X0 } else { Cssel::B_0X1 });
367 }); 355 });
368 356
369 // Enable peripheral 357 // Enable peripheral
370 T::REGS.xspi_cr().modify(|w| { 358 T::REGS.cr().modify(|w| {
371 w.set_en(En::B_0X1); 359 w.set_en(true);
372 }); 360 });
373 361
374 // Free running clock needs to be set after peripheral enable 362 // Free running clock needs to be set after peripheral enable
375 if config.free_running_clock { 363 if config.free_running_clock {
376 T::REGS.xspi_dcr1().modify(|w| { 364 T::REGS.dcr1().modify(|w| {
377 w.set_frck(match config.free_running_clock { 365 w.set_frck(config.free_running_clock);
378 true => Frck::B_0X1,
379 false => Frck::B_0X0,
380 });
381 }); 366 });
382 } 367 }
383 368
@@ -422,87 +407,78 @@ impl<'d, T: Instance, M: PeriMode> Xspi<'d, T, M> {
422 return Err(XspiError::InvalidCommand); 407 return Err(XspiError::InvalidCommand);
423 } 408 }
424 409
425 T::REGS.xspi_cr().modify(|w| { 410 T::REGS.cr().modify(|w| {
426 w.set_fmode(0.into()); 411 w.set_fmode(0.into());
427 }); 412 });
428 413
429 // Configure alternate bytes 414 // Configure alternate bytes
430 if let Some(ab) = command.alternate_bytes { 415 if let Some(ab) = command.alternate_bytes {
431 T::REGS.xspi_abr().write(|v| v.set_alternate(ab)); 416 T::REGS.abr().write(|v| v.set_alternate(ab));
432 T::REGS.xspi_ccr().modify(|w| { 417 T::REGS.ccr().modify(|w| {
433 w.set_abmode(XspiCcrAbmode::from_bits(command.abwidth.into())); 418 w.set_abmode(CcrAbmode::from_bits(command.abwidth.into()));
434 w.set_abdtr(XspiCcrAbdtr::from_bits(command.abdtr.into())); 419 w.set_abdtr(command.abdtr);
435 w.set_absize(XspiCcrAbsize::from_bits(command.absize.into())); 420 w.set_absize(CcrAbsize::from_bits(command.absize.into()));
436 }) 421 })
437 } 422 }
438 423
439 // Configure dummy cycles 424 // Configure dummy cycles
440 T::REGS.xspi_tcr().modify(|w| { 425 T::REGS.tcr().modify(|w| {
441 w.set_dcyc(command.dummy.into()); 426 w.set_dcyc(command.dummy.into());
442 }); 427 });
443 428
444 // Configure data 429 // Configure data
445 if let Some(data_length) = data_len { 430 if let Some(data_length) = data_len {
446 T::REGS.xspi_dlr().write(|v| { 431 T::REGS.dlr().write(|v| {
447 v.set_dl((data_length - 1) as u32); 432 v.set_dl((data_length - 1) as u32);
448 }) 433 })
449 } else { 434 } else {
450 T::REGS.xspi_dlr().write(|v| { 435 T::REGS.dlr().write(|v| {
451 v.set_dl((0) as u32); 436 v.set_dl((0) as u32);
452 }) 437 })
453 } 438 }
454 439
455 // Configure instruction/address/data modes 440 // Configure instruction/address/data modes
456 T::REGS.xspi_ccr().modify(|w| { 441 T::REGS.ccr().modify(|w| {
457 w.set_imode(XspiCcrImode::from_bits(command.iwidth.into())); 442 w.set_imode(CcrImode::from_bits(command.iwidth.into()));
458 w.set_idtr(match command.idtr { 443 w.set_idtr(command.idtr);
459 true => XspiCcrIdtr::B_0X1, 444 w.set_isize(CcrIsize::from_bits(command.isize.into()));
460 false => XspiCcrIdtr::B_0X0,
461 });
462 w.set_isize(XspiCcrIsize::from_bits(command.isize.into()));
463 445
464 w.set_admode(XspiCcrAdmode::from_bits(command.adwidth.into())); 446 w.set_admode(CcrAdmode::from_bits(command.adwidth.into()));
465 w.set_addtr(match command.idtr { 447 w.set_addtr(command.idtr);
466 true => XspiCcrAddtr::B_0X1, 448 w.set_adsize(CcrAdsize::from_bits(command.adsize.into()));
467 false => XspiCcrAddtr::B_0X0,
468 });
469 w.set_adsize(XspiCcrAdsize::from_bits(command.adsize.into()));
470 449
471 w.set_dmode(XspiCcrDmode::from_bits(command.dwidth.into())); 450 w.set_dmode(CcrDmode::from_bits(command.dwidth.into()));
472 w.set_ddtr(match command.ddtr { 451 w.set_ddtr(command.ddtr);
473 true => XspiCcrDdtr::B_0X1,
474 false => XspiCcrDdtr::B_0X0,
475 });
476 }); 452 });
477 453
478 // Set information required to initiate transaction 454 // Set information required to initiate transaction
479 if let Some(instruction) = command.instruction { 455 if let Some(instruction) = command.instruction {
480 if let Some(address) = command.address { 456 if let Some(address) = command.address {
481 T::REGS.xspi_ir().write(|v| { 457 T::REGS.ir().write(|v| {
482 v.set_instruction(instruction); 458 v.set_instruction(instruction);
483 }); 459 });
484 460
485 T::REGS.xspi_ar().write(|v| { 461 T::REGS.ar().write(|v| {
486 v.set_address(address); 462 v.set_address(address);
487 }); 463 });
488 } else { 464 } else {
489 // Double check requirements for delay hold and sample shifting 465 // Double check requirements for delay hold and sample shifting
490 // if let None = command.data_len { 466 // if let None = command.data_len {
491 // if self.config.delay_hold_quarter_cycle && command.idtr { 467 // if self.config.delay_hold_quarter_cycle && command.idtr {
492 // T::REGS.xspi_ccr().modify(|w| { 468 // T::REGS.ccr().modify(|w| {
493 // w.set_ddtr(true); 469 // w.set_ddtr(true);
494 // }); 470 // });
495 // } 471 // }
496 // } 472 // }
497 473
498 warn!("instruction: {:#x}", instruction); 474 // warn!("instruction: {:#x}", instruction);
499 T::REGS.xspi_ir().write(|v| { 475 T::REGS.ir().write(|v| {
500 v.set_instruction(instruction); 476 v.set_instruction(instruction);
501 }); 477 });
502 } 478 }
503 } else { 479 } else {
504 if let Some(address) = command.address { 480 if let Some(address) = command.address {
505 T::REGS.xspi_ar().write(|v| { 481 T::REGS.ar().write(|v| {
506 v.set_address(address); 482 v.set_address(address);
507 }); 483 });
508 } else { 484 } else {
@@ -517,14 +493,14 @@ impl<'d, T: Instance, M: PeriMode> Xspi<'d, T, M> {
517 /// Function used to control or configure the target device without data transfer 493 /// Function used to control or configure the target device without data transfer
518 pub fn blocking_command(&mut self, command: &TransferConfig) -> Result<(), XspiError> { 494 pub fn blocking_command(&mut self, command: &TransferConfig) -> Result<(), XspiError> {
519 // Wait for peripheral to be free 495 // Wait for peripheral to be free
520 while T::REGS.xspi_sr().read().busy() {} 496 while T::REGS.sr().read().busy() {}
521 497
522 // Need additional validation that command configuration doesn't have data set 498 // Need additional validation that command configuration doesn't have data set
523 self.configure_command(command, None)?; 499 self.configure_command(command, None)?;
524 500
525 // Transaction initiated by setting final configuration, i.e the instruction register 501 // Transaction initiated by setting final configuration, i.e the instruction register
526 while !T::REGS.xspi_sr().read().tcf() {} 502 while !T::REGS.sr().read().tcf() {}
527 T::REGS.xspi_fcr().write(|w| { 503 T::REGS.fcr().write(|w| {
528 w.set_ctcf(true); 504 w.set_ctcf(true);
529 }); 505 });
530 506
@@ -538,36 +514,36 @@ impl<'d, T: Instance, M: PeriMode> Xspi<'d, T, M> {
538 } 514 }
539 515
540 // Wait for peripheral to be free 516 // Wait for peripheral to be free
541 while T::REGS.xspi_sr().read().busy() {} 517 while T::REGS.sr().read().busy() {}
542 518
543 // Ensure DMA is not enabled for this transaction 519 // Ensure DMA is not enabled for this transaction
544 T::REGS.xspi_cr().modify(|w| { 520 T::REGS.cr().modify(|w| {
545 w.set_dmaen(Dmaen::B_0X0); 521 w.set_dmaen(false);
546 }); 522 });
547 523
548 // self.configure_command(&transaction, Some(buf.len()))?; 524 // self.configure_command(&transaction, Some(buf.len()))?;
549 self.configure_command(&transaction, Some(buf.len())).unwrap(); 525 self.configure_command(&transaction, Some(buf.len())).unwrap();
550 526
551 let current_address = T::REGS.xspi_ar().read().address(); 527 let current_address = T::REGS.ar().read().address();
552 let current_instruction = T::REGS.xspi_ir().read().instruction(); 528 let current_instruction = T::REGS.ir().read().instruction();
553 529
554 // For a indirect read transaction, the transaction begins when the instruction/address is set 530 // For a indirect read transaction, the transaction begins when the instruction/address is set
555 T::REGS 531 T::REGS
556 .xspi_cr() 532 .cr()
557 .modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectRead.into()))); 533 .modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectRead.into())));
558 if T::REGS.xspi_ccr().read().admode() == XspiCcrAdmode::B_0X0 { 534 if T::REGS.ccr().read().admode() == CcrAdmode::B_0X0 {
559 T::REGS.xspi_ir().write(|v| v.set_instruction(current_instruction)); 535 T::REGS.ir().write(|v| v.set_instruction(current_instruction));
560 } else { 536 } else {
561 T::REGS.xspi_ar().write(|v| v.set_address(current_address)); 537 T::REGS.ar().write(|v| v.set_address(current_address));
562 } 538 }
563 539
564 for idx in 0..buf.len() { 540 for idx in 0..buf.len() {
565 while !T::REGS.xspi_sr().read().tcf() && !T::REGS.xspi_sr().read().ftf() {} 541 while !T::REGS.sr().read().tcf() && !T::REGS.sr().read().ftf() {}
566 buf[idx] = unsafe { (T::REGS.xspi_dr().as_ptr() as *mut W).read_volatile() }; 542 buf[idx] = unsafe { (T::REGS.dr().as_ptr() as *mut W).read_volatile() };
567 } 543 }
568 544
569 while !T::REGS.xspi_sr().read().tcf() {} 545 while !T::REGS.sr().read().tcf() {}
570 T::REGS.xspi_fcr().write(|v| v.set_ctcf(true)); 546 T::REGS.fcr().write(|v| v.set_ctcf(true));
571 547
572 Ok(()) 548 Ok(())
573 } 549 }
@@ -579,25 +555,25 @@ impl<'d, T: Instance, M: PeriMode> Xspi<'d, T, M> {
579 } 555 }
580 556
581 // Wait for peripheral to be free 557 // Wait for peripheral to be free
582 while T::REGS.xspi_sr().read().busy() {} 558 while T::REGS.sr().read().busy() {}
583 559
584 T::REGS.xspi_cr().modify(|w| { 560 T::REGS.cr().modify(|w| {
585 w.set_dmaen(Dmaen::B_0X0); 561 w.set_dmaen(false);
586 }); 562 });
587 563
588 self.configure_command(&transaction, Some(buf.len()))?; 564 self.configure_command(&transaction, Some(buf.len()))?;
589 565
590 T::REGS 566 T::REGS
591 .xspi_cr() 567 .cr()
592 .modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectWrite.into()))); 568 .modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectWrite.into())));
593 569
594 for idx in 0..buf.len() { 570 for idx in 0..buf.len() {
595 while !T::REGS.xspi_sr().read().ftf() {} 571 while !T::REGS.sr().read().ftf() {}
596 unsafe { (T::REGS.xspi_dr().as_ptr() as *mut W).write_volatile(buf[idx]) }; 572 unsafe { (T::REGS.dr().as_ptr() as *mut W).write_volatile(buf[idx]) };
597 } 573 }
598 574
599 while !T::REGS.xspi_sr().read().tcf() {} 575 while !T::REGS.sr().read().tcf() {}
600 T::REGS.xspi_fcr().write(|v| v.set_ctcf(true)); 576 T::REGS.fcr().write(|v| v.set_ctcf(true));
601 577
602 Ok(()) 578 Ok(())
603 } 579 }
@@ -605,75 +581,66 @@ impl<'d, T: Instance, M: PeriMode> Xspi<'d, T, M> {
605 /// Set new bus configuration 581 /// Set new bus configuration
606 pub fn set_config(&mut self, config: &Config) { 582 pub fn set_config(&mut self, config: &Config) {
607 // Wait for busy flag to clear 583 // Wait for busy flag to clear
608 while T::REGS.xspi_sr().read().busy() {} 584 while T::REGS.sr().read().busy() {}
609 585
610 // Disable DMA channel while configuring the peripheral 586 // Disable DMA channel while configuring the peripheral
611 T::REGS.xspi_cr().modify(|w| { 587 T::REGS.cr().modify(|w| {
612 w.set_dmaen(Dmaen::B_0X0); 588 w.set_dmaen(false);
613 }); 589 });
614 590
615 // Device configuration 591 // Device configuration
616 T::REGS.xspi_dcr1().modify(|w| { 592 T::REGS.dcr1().modify(|w| {
617 w.set_devsize(config.device_size.into()); 593 w.set_devsize(config.device_size.into());
618 w.set_mtyp(Mtyp::from_bits(config.memory_type.into())); 594 w.set_mtyp(Mtyp::from_bits(config.memory_type.into()));
619 w.set_csht(Csht::from_bits(config.chip_select_high_time.into())); 595 w.set_csht(Csht::from_bits(config.chip_select_high_time.into()));
620 w.set_frck(Frck::B_0X0); 596 w.set_frck(false);
621 w.set_ckmode(match config.clock_mode { 597 w.set_ckmode(match config.clock_mode {
622 true => Ckmode::B_0X1, 598 true => Ckmode::B_0X1,
623 false => Ckmode::B_0X0, 599 false => Ckmode::B_0X0,
624 }); 600 });
625 }); 601 });
626 602
627 T::REGS.xspi_dcr2().modify(|w| { 603 T::REGS.dcr2().modify(|w| {
628 w.set_wrapsize(Wrapsize::from_bits(config.wrap_size.into())); 604 w.set_wrapsize(Wrapsize::from_bits(config.wrap_size.into()));
629 }); 605 });
630 606
631 T::REGS.xspi_dcr3().modify(|w| { 607 T::REGS.dcr3().modify(|w| {
632 w.set_csbound(Csbound::from_bits(config.chip_select_boundary.into())); 608 w.set_csbound(Csbound::from_bits(config.chip_select_boundary.into()));
633 #[cfg(xspi_v2_1)] 609 #[cfg(xspi_v1)]
634 { 610 {
635 w.set_maxtran(Maxtran::from_bits(config.max_transfer.into())); 611 w.set_maxtran(Maxtran::from_bits(config.max_transfer.into()));
636 } 612 }
637 }); 613 });
638 614
639 T::REGS.xspi_dcr4().modify(|w| { 615 T::REGS.dcr4().modify(|w| {
640 w.set_refresh(Refresh::from_bits(config.refresh.into())); 616 w.set_refresh(Refresh::from_bits(config.refresh.into()));
641 }); 617 });
642 618
643 T::REGS.xspi_cr().modify(|w| { 619 T::REGS.cr().modify(|w| {
644 w.set_fthres(Fthres::from_bits(config.fifo_threshold.into())); 620 w.set_fthres(Fthres::from_bits(config.fifo_threshold.into()));
645 }); 621 });
646 622
647 // Wait for busy flag to clear 623 // Wait for busy flag to clear
648 while T::REGS.xspi_sr().read().busy() {} 624 while T::REGS.sr().read().busy() {}
649 625
650 T::REGS.xspi_dcr2().modify(|w| { 626 T::REGS.dcr2().modify(|w| {
651 w.set_prescaler(Prescaler::from_bits(config.clock_prescaler.into())); 627 w.set_prescaler(config.clock_prescaler);
652 }); 628 });
653 629
654 T::REGS.xspi_tcr().modify(|w| { 630 T::REGS.tcr().modify(|w| {
655 w.set_sshift(match config.sample_shifting { 631 w.set_sshift(config.sample_shifting);
656 true => XspiTcrSshift::B_0X1, 632 w.set_dhqc(config.delay_hold_quarter_cycle);
657 false => XspiTcrSshift::B_0X0,
658 });
659 w.set_dhqc(match config.delay_hold_quarter_cycle {
660 true => XspiTcrDhqc::B_0X1,
661 false => XspiTcrDhqc::B_0X0,
662 });
663 }); 633 });
664 634
665 // Enable peripheral 635 // Enable peripheral
666 T::REGS.xspi_cr().modify(|w| { 636 T::REGS.cr().modify(|w| {
667 w.set_en(En::B_0X1); 637 w.set_en(true);
668 }); 638 });
669 639
670 // Free running clock needs to be set after peripheral enable 640 // Free running clock needs to be set after peripheral enable
671 if config.free_running_clock { 641 if config.free_running_clock {
672 T::REGS.xspi_dcr1().modify(|w| { 642 T::REGS.dcr1().modify(|w| {
673 w.set_frck(match config.free_running_clock { 643 w.set_frck(config.free_running_clock);
674 true => Frck::B_0X1,
675 false => Frck::B_0X0,
676 });
677 }); 644 });
678 } 645 }
679 646
@@ -1143,31 +1110,31 @@ impl<'d, T: Instance> Xspi<'d, T, Async> {
1143 } 1110 }
1144 1111
1145 // Wait for peripheral to be free 1112 // Wait for peripheral to be free
1146 while T::REGS.xspi_sr().read().busy() {} 1113 while T::REGS.sr().read().busy() {}
1147 1114
1148 self.configure_command(&transaction, Some(buf.len()))?; 1115 self.configure_command(&transaction, Some(buf.len()))?;
1149 1116
1150 let current_address = T::REGS.xspi_ar().read().address(); 1117 let current_address = T::REGS.ar().read().address();
1151 let current_instruction = T::REGS.xspi_ir().read().instruction(); 1118 let current_instruction = T::REGS.ir().read().instruction();
1152 1119
1153 // For a indirect read transaction, the transaction begins when the instruction/address is set 1120 // For a indirect read transaction, the transaction begins when the instruction/address is set
1154 T::REGS 1121 T::REGS
1155 .xspi_cr() 1122 .cr()
1156 .modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectRead.into()))); 1123 .modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectRead.into())));
1157 if T::REGS.xspi_ccr().read().admode() == XspiCcrAdmode::B_0X0 { 1124 if T::REGS.ccr().read().admode() == CcrAdmode::B_0X0 {
1158 T::REGS.xspi_ir().write(|v| v.set_instruction(current_instruction)); 1125 T::REGS.ir().write(|v| v.set_instruction(current_instruction));
1159 } else { 1126 } else {
1160 T::REGS.xspi_ar().write(|v| v.set_address(current_address)); 1127 T::REGS.ar().write(|v| v.set_address(current_address));
1161 } 1128 }
1162 1129
1163 let transfer = unsafe { 1130 let transfer = unsafe {
1164 self.dma 1131 self.dma
1165 .as_mut() 1132 .as_mut()
1166 .unwrap() 1133 .unwrap()
1167 .read(T::REGS.xspi_dr().as_ptr() as *mut W, buf, Default::default()) 1134 .read(T::REGS.dr().as_ptr() as *mut W, buf, Default::default())
1168 }; 1135 };
1169 1136
1170 T::REGS.xspi_cr().modify(|w| w.set_dmaen(Dmaen::B_0X1)); 1137 T::REGS.cr().modify(|w| w.set_dmaen(true));
1171 1138
1172 transfer.blocking_wait(); 1139 transfer.blocking_wait();
1173 1140
@@ -1183,21 +1150,21 @@ impl<'d, T: Instance> Xspi<'d, T, Async> {
1183 } 1150 }
1184 1151
1185 // Wait for peripheral to be free 1152 // Wait for peripheral to be free
1186 while T::REGS.xspi_sr().read().busy() {} 1153 while T::REGS.sr().read().busy() {}
1187 1154
1188 self.configure_command(&transaction, Some(buf.len()))?; 1155 self.configure_command(&transaction, Some(buf.len()))?;
1189 T::REGS 1156 T::REGS
1190 .xspi_cr() 1157 .cr()
1191 .modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectWrite.into()))); 1158 .modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectWrite.into())));
1192 1159
1193 let transfer = unsafe { 1160 let transfer = unsafe {
1194 self.dma 1161 self.dma
1195 .as_mut() 1162 .as_mut()
1196 .unwrap() 1163 .unwrap()
1197 .write(buf, T::REGS.xspi_dr().as_ptr() as *mut W, Default::default()) 1164 .write(buf, T::REGS.dr().as_ptr() as *mut W, Default::default())
1198 }; 1165 };
1199 1166
1200 T::REGS.xspi_cr().modify(|w| w.set_dmaen(Dmaen::B_0X1)); 1167 T::REGS.cr().modify(|w| w.set_dmaen(true));
1201 1168
1202 transfer.blocking_wait(); 1169 transfer.blocking_wait();
1203 1170
@@ -1213,31 +1180,31 @@ impl<'d, T: Instance> Xspi<'d, T, Async> {
1213 } 1180 }
1214 1181
1215 // Wait for peripheral to be free 1182 // Wait for peripheral to be free
1216 while T::REGS.xspi_sr().read().busy() {} 1183 while T::REGS.sr().read().busy() {}
1217 1184
1218 self.configure_command(&transaction, Some(buf.len()))?; 1185 self.configure_command(&transaction, Some(buf.len()))?;
1219 1186
1220 let current_address = T::REGS.xspi_ar().read().address(); 1187 let current_address = T::REGS.ar().read().address();
1221 let current_instruction = T::REGS.xspi_ir().read().instruction(); 1188 let current_instruction = T::REGS.ir().read().instruction();
1222 1189
1223 // For a indirect read transaction, the transaction begins when the instruction/address is set 1190 // For a indirect read transaction, the transaction begins when the instruction/address is set
1224 T::REGS 1191 T::REGS
1225 .xspi_cr() 1192 .cr()
1226 .modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectRead.into()))); 1193 .modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectRead.into())));
1227 if T::REGS.xspi_ccr().read().admode() == XspiCcrAdmode::B_0X0 { 1194 if T::REGS.ccr().read().admode() == CcrAdmode::B_0X0 {
1228 T::REGS.xspi_ir().write(|v| v.set_instruction(current_instruction)); 1195 T::REGS.ir().write(|v| v.set_instruction(current_instruction));
1229 } else { 1196 } else {
1230 T::REGS.xspi_ar().write(|v| v.set_address(current_address)); 1197 T::REGS.ar().write(|v| v.set_address(current_address));
1231 } 1198 }
1232 1199
1233 let transfer = unsafe { 1200 let transfer = unsafe {
1234 self.dma 1201 self.dma
1235 .as_mut() 1202 .as_mut()
1236 .unwrap() 1203 .unwrap()
1237 .read(T::REGS.xspi_dr().as_ptr() as *mut W, buf, Default::default()) 1204 .read(T::REGS.dr().as_ptr() as *mut W, buf, Default::default())
1238 }; 1205 };
1239 1206
1240 T::REGS.xspi_cr().modify(|w| w.set_dmaen(Dmaen::B_0X1)); 1207 T::REGS.cr().modify(|w| w.set_dmaen(true));
1241 1208
1242 transfer.await; 1209 transfer.await;
1243 1210
@@ -1253,21 +1220,21 @@ impl<'d, T: Instance> Xspi<'d, T, Async> {
1253 } 1220 }
1254 1221
1255 // Wait for peripheral to be free 1222 // Wait for peripheral to be free
1256 while T::REGS.xspi_sr().read().busy() {} 1223 while T::REGS.sr().read().busy() {}
1257 1224
1258 self.configure_command(&transaction, Some(buf.len()))?; 1225 self.configure_command(&transaction, Some(buf.len()))?;
1259 T::REGS 1226 T::REGS
1260 .xspi_cr() 1227 .cr()
1261 .modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectWrite.into()))); 1228 .modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectWrite.into())));
1262 1229
1263 let transfer = unsafe { 1230 let transfer = unsafe {
1264 self.dma 1231 self.dma
1265 .as_mut() 1232 .as_mut()
1266 .unwrap() 1233 .unwrap()
1267 .write(buf, T::REGS.xspi_dr().as_ptr() as *mut W, Default::default()) 1234 .write(buf, T::REGS.dr().as_ptr() as *mut W, Default::default())
1268 }; 1235 };
1269 1236
1270 T::REGS.xspi_cr().modify(|w| w.set_dmaen(Dmaen::B_0X1)); 1237 T::REGS.cr().modify(|w| w.set_dmaen(true));
1271 1238
1272 transfer.await; 1239 transfer.await;
1273 1240
@@ -1306,16 +1273,16 @@ impl<'d, T: Instance, M: PeriMode> Drop for Xspi<'d, T, M> {
1306} 1273}
1307 1274
1308fn finish_dma(regs: Regs) { 1275fn finish_dma(regs: Regs) {
1309 while !regs.xspi_sr().read().tcf() {} 1276 while !regs.sr().read().tcf() {}
1310 regs.xspi_fcr().write(|v| v.set_ctcf(true)); 1277 regs.fcr().write(|v| v.set_ctcf(true));
1311 1278
1312 regs.xspi_cr().modify(|w| { 1279 regs.cr().modify(|w| {
1313 w.set_dmaen(Dmaen::B_0X0); 1280 w.set_dmaen(false);
1314 }); 1281 });
1315} 1282}
1316 1283
1317/// XSPI I/O manager instance trait. 1284/// XSPI I/O manager instance trait.
1318#[cfg(xspim_v2_1)] 1285#[cfg(xspim_v1)]
1319pub(crate) trait SealedXspimInstance { 1286pub(crate) trait SealedXspimInstance {
1320 const SPIM_REGS: Xspim; 1287 const SPIM_REGS: Xspim;
1321 const SPI_IDX: u8; 1288 const SPI_IDX: u8;
@@ -1327,12 +1294,12 @@ pub(crate) trait SealedInstance {
1327} 1294}
1328 1295
1329/// XSPI instance trait. 1296/// XSPI instance trait.
1330#[cfg(xspim_v2_1)] 1297#[cfg(xspim_v1)]
1331#[allow(private_bounds)] 1298#[allow(private_bounds)]
1332pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral + SealedXspimInstance {} 1299pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral + SealedXspimInstance {}
1333 1300
1334/// XSPI instance trait. 1301/// XSPI instance trait.
1335#[cfg(not(xspim_v2_1))] 1302#[cfg(not(xspim_v1))]
1336#[allow(private_bounds)] 1303#[allow(private_bounds)]
1337pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {} 1304pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {}
1338 1305
@@ -1361,20 +1328,20 @@ pin_trait!(NCLKPin, Instance);
1361dma_trait!(XDma, Instance); 1328dma_trait!(XDma, Instance);
1362 1329
1363// Hard-coded the xspi index, for SPIM 1330// Hard-coded the xspi index, for SPIM
1364#[cfg(xspim_v2_1)] 1331#[cfg(xspim_v1)]
1365impl SealedXspimInstance for peripherals::XSPI1 { 1332impl SealedXspimInstance for peripherals::XSPI1 {
1366 const SPIM_REGS: Xspim = crate::pac::XSPIM; 1333 const SPIM_REGS: Xspim = crate::pac::XSPIM;
1367 const SPI_IDX: u8 = 1; 1334 const SPI_IDX: u8 = 1;
1368} 1335}
1369 1336
1370// #[cfg(all(xspim_v2_1, peri_xspi2))] 1337// Some cubedb files are missing XSPI2, for example STM32H7R3Z8
1371#[cfg(xspim_v2_1)] 1338#[cfg(all(xspim_v1, peri_xspi2))]
1372impl SealedXspimInstance for peripherals::XSPI2 { 1339impl SealedXspimInstance for peripherals::XSPI2 {
1373 const SPIM_REGS: Xspim = crate::pac::XSPIM; 1340 const SPIM_REGS: Xspim = crate::pac::XSPIM;
1374 const SPI_IDX: u8 = 2; 1341 const SPI_IDX: u8 = 2;
1375} 1342}
1376 1343
1377#[cfg(xspim_v2_1)] 1344#[cfg(xspim_v1)]
1378foreach_peripheral!( 1345foreach_peripheral!(
1379 (xspi, $inst:ident) => { 1346 (xspi, $inst:ident) => {
1380 impl SealedInstance for peripherals::$inst { 1347 impl SealedInstance for peripherals::$inst {
@@ -1385,7 +1352,7 @@ foreach_peripheral!(
1385 }; 1352 };
1386); 1353);
1387 1354
1388#[cfg(not(xspim_v2_1))] 1355#[cfg(not(xspim_v1))]
1389foreach_peripheral!( 1356foreach_peripheral!(
1390 (xspi, $inst:ident) => { 1357 (xspi, $inst:ident) => {
1391 impl SealedInstance for peripherals::$inst { 1358 impl SealedInstance for peripherals::$inst {