Skip to content

Commit 2d3653c

Browse files
dnerichardeoin
authored andcommitted
Add support for using different modes for each phase of an xspi operation
1 parent 0d1ab22 commit 2d3653c

File tree

3 files changed

+74
-31
lines changed

3 files changed

+74
-31
lines changed

src/xspi/mod.rs

Lines changed: 68 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,9 @@
101101
//! interface. Automatic polling or memory-mapped modes are not supported,
102102
//! except for the OCTOSPI Hyperbus mode.
103103
//!
104-
//! Using different operational modes (1-bit/2-bit/4-bit etc.) for different
105-
//! phases of a single transaction is not supported. It is possible to change
106-
//! operational mode between transactions by calling
107-
//! [`configure_mode`](#method.configure_mode).
104+
//! It is possible to change operational mode between transactions by
105+
//! calling [`configure_mode`](#method.configure_mode) or
106+
//! [`configure_modes`](#method.configure_modes)
108107
109108
// Parts of the Quad and Octo SPI support are shared (this file), but they are
110109
// different enough to require different initialisation routines and pin
@@ -117,7 +116,7 @@ mod qspi;
117116
#[cfg(any(feature = "rm0433", feature = "rm0399"))]
118117
pub use common::{
119118
Bank, BankError, BankSelect, Xspi as Qspi, XspiError as QspiError,
120-
XspiMode as QspiMode, XspiWord as QspiWord,
119+
XspiMode as QspiMode, XspiModes as QspiModes, XspiWord as QspiWord,
121120
};
122121
#[cfg(any(feature = "rm0433", feature = "rm0399"))]
123122
pub use qspi::QspiExt as XspiExt;
@@ -128,7 +127,7 @@ mod octospi;
128127
#[cfg(any(feature = "rm0455", feature = "rm0468"))]
129128
pub use common::{
130129
Xspi as Octospi, XspiError as OctospiError, XspiMode as OctospiMode,
131-
XspiWord as OctospiWord,
130+
XspiModes as OctospiModes, XspiWord as OctospiWord,
132131
};
133132
#[cfg(any(feature = "rm0455", feature = "rm0468"))]
134133
pub use octospi::{Hyperbus, HyperbusConfig, OctospiExt as XspiExt};
@@ -176,6 +175,28 @@ mod common {
176175
}
177176
}
178177
}
178+
#[derive(Debug, Copy, Clone)]
179+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
180+
pub struct XspiModes {
181+
/// IO lines used for the instruction phase.
182+
pub instruction: XspiMode,
183+
/// IO lines used for the address phase.
184+
pub address: XspiMode,
185+
/// IO lines used for the alternate byte phase.
186+
pub alt_byte: XspiMode,
187+
/// IO lines used for the data phase.
188+
pub data: XspiMode,
189+
}
190+
impl XspiModes {
191+
pub fn new(mode: XspiMode) -> Self {
192+
Self {
193+
instruction: mode,
194+
address: mode,
195+
alt_byte: mode,
196+
data: mode,
197+
}
198+
}
199+
}
179200
/// Indicates an error with the XSPI peripheral.
180201
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
181202
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -308,7 +329,7 @@ mod common {
308329
/// ```
309330
#[derive(Copy, Clone)]
310331
pub struct Config {
311-
pub(super) mode: XspiMode,
332+
pub(super) modes: XspiModes,
312333
pub(super) frequency: Hertz,
313334
pub(super) dummy_cycles: u8,
314335
pub(super) sampling_edge: SamplingEdge,
@@ -323,21 +344,32 @@ mod common {
323344
/// * Sample on falling edge
324345
pub fn new(frequency: Hertz) -> Self {
325346
Config {
326-
mode: XspiMode::OneBit,
347+
modes: XspiModes::new(XspiMode::OneBit),
327348
frequency,
328349
dummy_cycles: 0,
329350
sampling_edge: SamplingEdge::Falling,
330351
fifo_threshold: 1,
331352
}
332353
}
333354

334-
/// Specify the operating mode of the XSPI bus. Can be 1-bit, 2-bit or
335-
/// 4-bit for Quadspi; 1-bit, 2-bit, 4-bit or 8-bit for Octospi.
355+
/// Specify the operating mode for all phases of the XSPI bus
356+
/// operation. Can be 1-bit, 2-bit or 4-bit for Quadspi;
357+
/// 1-bit, 2-bit, 4-bit or 8-bit for Octospi.
336358
///
337359
/// The operating mode can also be changed using the
338360
/// [`configure_mode`](Xspi#method.configure_mode) method
339-
pub fn mode(mut self, mode: XspiMode) -> Self {
340-
self.mode = mode;
361+
pub fn mode(self, mode: XspiMode) -> Self {
362+
self.modes(XspiModes::new(mode))
363+
}
364+
365+
/// Specify the operating mode separately for each phase of
366+
/// the XSPI bus operation. Can be 1-bit, 2-bit or 4-bit for
367+
/// Quadspi; 1-bit, 2-bit, 4-bit or 8-bit for Octospi.
368+
///
369+
/// The operating modes can also be changed using the
370+
/// [`configure_modes`](Xspi#method.configure_modes) method
371+
pub fn modes(mut self, modes: XspiModes) -> Self {
372+
self.modes = modes;
341373
self
342374
}
343375

@@ -406,10 +438,10 @@ mod common {
406438
pub struct Xspi<XSPI> {
407439
pub(super) rb: XSPI,
408440

409-
/// We store the current mode here because for extended transactions
441+
/// We store the current modes here because for extended transactions
410442
/// various phases may be removed. Therefore we need to restore them
411443
/// after each transaction.
412-
pub(super) mode: XspiMode,
444+
pub(super) modes: XspiModes,
413445
}
414446

415447
#[cfg(any(feature = "rm0433", feature = "rm0399"))]
@@ -514,17 +546,29 @@ mod common {
514546
}
515547
}
516548

517-
/// Configure the operational mode (number of bits) of the XSPI
518-
/// interface.
549+
/// Configure the common mode (number of bits) for all phases of the XSPI
550+
/// operation.
519551
///
520552
/// # Args
521-
/// * `mode` - The newly desired mode of the interface.
553+
/// * `mode` - The newly desired mode for the operation.
522554
///
523555
/// # Errors
524556
/// Returns XspiError::Busy if an operation is ongoing
525557
pub fn configure_mode(&mut self, mode: XspiMode) -> Result<(), XspiError> {
558+
self.configure_modes(XspiModes::new(mode))
559+
}
560+
561+
/// Configure the operational mode (number of bits), separately for each phase
562+
/// of the XSPI interface.
563+
///
564+
/// # Args
565+
/// * `modes` - The newly desired modes for each phase of the operation.
566+
///
567+
/// # Errors
568+
/// Returns XspiError::Busy if an operation is ongoing
569+
pub fn configure_modes(&mut self, modes: XspiModes) -> Result<(), XspiError> {
526570
self.is_busy()?;
527-
self.mode = mode;
571+
self.modes = modes;
528572
self.set_mode_address_data_only();
529573

530574
Ok(())
@@ -537,13 +581,13 @@ mod common {
537581
w.imode() // NO instruction phase
538582
.bits(0)
539583
.admode() // address phase
540-
.bits(self.mode.reg_value())
584+
.bits(self.modes.address.reg_value())
541585
.adsize()
542586
.bits(0) // 8-bit address
543587
.abmode() // NO alternate-bytes phase
544588
.bits(0)
545589
.dmode() // data phase
546-
.bits(self.mode.reg_value())
590+
.bits(self.modes.data.reg_value())
547591
});
548592
}
549593

@@ -560,11 +604,10 @@ mod common {
560604
alternate_bytes: XspiWord, dummy_cycles: u8, data: bool, read: bool) {
561605

562606
let fmode = if read { 0b01 } else { 0b00 };
563-
let mode = self.mode.reg_value();
564-
let imode = if instruction != XspiWord::None { mode } else { 0 };
565-
let admode = if address != XspiWord::None { mode } else { 0 };
566-
let abmode = if alternate_bytes != XspiWord::None { mode } else { 0 };
567-
let dmode = if data { mode } else { 0 };
607+
let imode = if instruction != XspiWord::None { self.modes.instruction.reg_value() } else { 0 };
608+
let admode = if address != XspiWord::None { self.modes.address.reg_value() } else { 0 };
609+
let abmode = if alternate_bytes != XspiWord::None { self.modes.alt_byte.reg_value() } else { 0 };
610+
let dmode = if data { self.modes.data.reg_value() } else { 0 };
568611

569612
//writing to ccr will trigger the start of a transaction if there is no address or
570613
//data rm0433 pg 894, so we do it all in one go

src/xspi/octospi.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -459,9 +459,9 @@ macro_rules! octospi_impl {
459459
// Communications configuration register
460460
regs.ccr.write(|w| unsafe {
461461
w.dmode()
462-
.bits(config.mode.reg_value())
462+
.bits(config.modes.data.reg_value())
463463
.admode()
464-
.bits(config.mode.reg_value())
464+
.bits(config.modes.address.reg_value())
465465
.adsize()
466466
.bits(0) // Eight-bit address
467467
.imode()
@@ -498,7 +498,7 @@ macro_rules! octospi_impl {
498498

499499
Octospi {
500500
rb: regs,
501-
mode: config.mode,
501+
modes: config.modes,
502502
}
503503
}
504504

src/xspi/qspi.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,9 +290,9 @@ impl Qspi<stm32::QUADSPI> {
290290
w.fmode()
291291
.bits(0) // indirect mode
292292
.dmode()
293-
.bits(config.mode.reg_value())
293+
.bits(config.modes.data.reg_value())
294294
.admode()
295-
.bits(config.mode.reg_value())
295+
.bits(config.modes.address.reg_value())
296296
.adsize()
297297
.bits(0) // Eight-bit address
298298
.imode()
@@ -338,7 +338,7 @@ impl Qspi<stm32::QUADSPI> {
338338

339339
Qspi {
340340
rb: regs,
341-
mode: config.mode,
341+
modes: config.modes,
342342
}
343343
}
344344
}

0 commit comments

Comments
 (0)