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)]).
This commit is contained in:
parent
6d384a1a39
commit
36a5b02774
@ -62,7 +62,13 @@ fn main() {
|
|||||||
// generate one singleton per peripheral (with many exceptions...)
|
// generate one singleton per peripheral (with many exceptions...)
|
||||||
for p in METADATA.peripherals {
|
for p in METADATA.peripherals {
|
||||||
if let Some(r) = &p.registers {
|
if let Some(r) = &p.registers {
|
||||||
if r.kind == "adccommon" || r.kind == "sai" || r.kind == "ucpd" || r.kind == "otg" || r.kind == "octospi" {
|
if r.kind == "adccommon"
|
||||||
|
|| r.kind == "sai"
|
||||||
|
|| r.kind == "ucpd"
|
||||||
|
|| r.kind == "otg"
|
||||||
|
|| r.kind == "octospi"
|
||||||
|
|| r.kind == "xspi"
|
||||||
|
{
|
||||||
// TODO: should we emit this for all peripherals? if so, we will need a list of all
|
// TODO: should we emit this for all peripherals? if so, we will need a list of all
|
||||||
// possible peripherals across all chips, so that we can declare the configs
|
// possible peripherals across all chips, so that we can declare the configs
|
||||||
// (replacing the hard-coded list of `peri_*` cfgs below)
|
// (replacing the hard-coded list of `peri_*` cfgs below)
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
//! Enums used in Xspi configuration.
|
//! Enums used in Xspi configuration.
|
||||||
#[allow(dead_code)]
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub(crate) enum XspiMode {
|
pub(crate) enum XspiMode {
|
||||||
IndirectWrite,
|
IndirectWrite,
|
||||||
IndirectRead,
|
IndirectRead,
|
||||||
|
#[expect(dead_code)]
|
||||||
AutoPolling,
|
AutoPolling,
|
||||||
|
#[expect(dead_code)]
|
||||||
MemoryMapped,
|
MemoryMapped,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,7 +21,6 @@ impl Into<u8> for XspiMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Xspi lane width
|
/// Xspi lane width
|
||||||
#[allow(dead_code)]
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum XspiWidth {
|
pub enum XspiWidth {
|
||||||
/// None
|
/// None
|
||||||
@ -47,27 +47,7 @@ impl Into<u8> for XspiWidth {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Flash bank selection
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub enum FlashSelection {
|
|
||||||
/// Bank 1
|
|
||||||
Flash1,
|
|
||||||
/// Bank 2
|
|
||||||
Flash2,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Into<bool> for FlashSelection {
|
|
||||||
fn into(self) -> bool {
|
|
||||||
match self {
|
|
||||||
FlashSelection::Flash1 => false,
|
|
||||||
FlashSelection::Flash2 => true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Wrap Size
|
/// Wrap Size
|
||||||
#[allow(dead_code)]
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum WrapSize {
|
pub enum WrapSize {
|
||||||
@ -92,7 +72,6 @@ impl Into<u8> for WrapSize {
|
|||||||
|
|
||||||
/// Memory Type
|
/// Memory Type
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[allow(dead_code)]
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum MemoryType {
|
pub enum MemoryType {
|
||||||
Micron,
|
Micron,
|
||||||
|
|||||||
@ -14,8 +14,9 @@ pub use enums::*;
|
|||||||
use crate::dma::{word, ChannelAndRequest};
|
use crate::dma::{word, ChannelAndRequest};
|
||||||
use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed};
|
use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed};
|
||||||
use crate::mode::{Async, Blocking, Mode as PeriMode};
|
use crate::mode::{Async, Blocking, Mode as PeriMode};
|
||||||
use crate::pac::xspi::{vals::*, Xspi as Regs};
|
use crate::pac::xspi::vals::*;
|
||||||
#[cfg(xspim_v2_1)]
|
use crate::pac::xspi::Xspi as Regs;
|
||||||
|
#[cfg(xspim_v1)]
|
||||||
use crate::pac::xspim::Xspim;
|
use crate::pac::xspim::Xspim;
|
||||||
use crate::rcc::{self, RccPeripheral};
|
use crate::rcc::{self, RccPeripheral};
|
||||||
use crate::{peripherals, Peripheral};
|
use crate::{peripherals, Peripheral};
|
||||||
@ -41,7 +42,7 @@ pub struct Config {
|
|||||||
/// Indicates the wrap size corresponding to the external device configuration
|
/// Indicates the wrap size corresponding to the external device configuration
|
||||||
pub wrap_size: WrapSize,
|
pub wrap_size: WrapSize,
|
||||||
/// Specified the prescaler factor used for generating the external clock based
|
/// Specified the prescaler factor used for generating the external clock based
|
||||||
/// on the AHB clock
|
/// on the AHB clock. 0 = Fkernel, 1 = Fkernel/2, 2 = Fkernel/3 etc.
|
||||||
pub clock_prescaler: u8,
|
pub clock_prescaler: u8,
|
||||||
/// Allows the delay of 1/2 cycle the data sampling to account for external
|
/// Allows the delay of 1/2 cycle the data sampling to account for external
|
||||||
/// signal delays
|
/// signal delays
|
||||||
@ -196,47 +197,35 @@ impl<'d, T: Instance, M: PeriMode> Xspi<'d, T, M> {
|
|||||||
self.configure_command(&read_config, None)?;
|
self.configure_command(&read_config, None)?;
|
||||||
|
|
||||||
let reg = T::REGS;
|
let reg = T::REGS;
|
||||||
while reg.xspi_sr().read().busy() {}
|
while reg.sr().read().busy() {}
|
||||||
|
|
||||||
reg.xspi_ccr().modify(|r| {
|
reg.ccr().modify(|r| {
|
||||||
r.set_dqse(XspiCcrDqse::B_0X0);
|
r.set_dqse(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set wrting configurations, there are separate registers for write configurations in memory mapped mode
|
// Set wrting configurations, there are separate registers for write configurations in memory mapped mode
|
||||||
reg.xspi_wccr().modify(|w| {
|
reg.wccr().modify(|w| {
|
||||||
w.set_imode(XspiWccrImode::from_bits(write_config.iwidth.into()));
|
w.set_imode(WccrImode::from_bits(write_config.iwidth.into()));
|
||||||
let idtr = match write_config.idtr {
|
w.set_idtr(write_config.idtr);
|
||||||
true => XspiWccrIdtr::B_0X1,
|
w.set_isize(WccrIsize::from_bits(write_config.isize.into()));
|
||||||
false => XspiWccrIdtr::B_0X0,
|
|
||||||
};
|
|
||||||
w.set_idtr(idtr);
|
|
||||||
w.set_isize(XspiWccrIsize::from_bits(write_config.isize.into()));
|
|
||||||
|
|
||||||
w.set_admode(XspiWccrAdmode::from_bits(write_config.adwidth.into()));
|
w.set_admode(WccrAdmode::from_bits(write_config.adwidth.into()));
|
||||||
let addtr = match write_config.idtr {
|
w.set_addtr(write_config.idtr);
|
||||||
true => XspiWccrAddtr::B_0X1,
|
w.set_adsize(WccrAdsize::from_bits(write_config.adsize.into()));
|
||||||
false => XspiWccrAddtr::B_0X0,
|
|
||||||
};
|
|
||||||
w.set_addtr(addtr);
|
|
||||||
w.set_adsize(XspiWccrAdsize::from_bits(write_config.adsize.into()));
|
|
||||||
|
|
||||||
w.set_dmode(XspiWccrDmode::from_bits(write_config.dwidth.into()));
|
w.set_dmode(WccrDmode::from_bits(write_config.dwidth.into()));
|
||||||
let ddtr = match write_config.idtr {
|
w.set_ddtr(write_config.idtr);
|
||||||
true => XspiWccrDdtr::B_0X1,
|
|
||||||
false => XspiWccrDdtr::B_0X0,
|
|
||||||
};
|
|
||||||
w.set_ddtr(ddtr);
|
|
||||||
|
|
||||||
w.set_abmode(XspiWccrAbmode::from_bits(write_config.abwidth.into()));
|
w.set_abmode(WccrAbmode::from_bits(write_config.abwidth.into()));
|
||||||
w.set_dqse(XspiWccrDqse::B_0X1);
|
w.set_dqse(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
reg.xspi_wtcr().modify(|w| w.set_dcyc(write_config.dummy.into()));
|
reg.wtcr().modify(|w| w.set_dcyc(write_config.dummy.into()));
|
||||||
|
|
||||||
// Enable memory mapped mode
|
// Enable memory mapped mode
|
||||||
reg.xspi_cr().modify(|r| {
|
reg.cr().modify(|r| {
|
||||||
r.set_fmode(Fmode::B_0X3);
|
r.set_fmode(Fmode::B_0X3);
|
||||||
r.set_tcen(Tcen::B_0X0);
|
r.set_tcen(false);
|
||||||
});
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -245,19 +234,19 @@ impl<'d, T: Instance, M: PeriMode> Xspi<'d, T, M> {
|
|||||||
pub fn disable_memory_mapped_mode(&mut self) {
|
pub fn disable_memory_mapped_mode(&mut self) {
|
||||||
let reg = T::REGS;
|
let reg = T::REGS;
|
||||||
|
|
||||||
reg.xspi_cr().modify(|r| {
|
reg.cr().modify(|r| {
|
||||||
r.set_fmode(Fmode::B_0X0);
|
r.set_fmode(Fmode::B_0X0);
|
||||||
r.set_abort(Abort::B_0X1);
|
r.set_abort(true);
|
||||||
r.set_dmaen(Dmaen::B_0X0);
|
r.set_dmaen(false);
|
||||||
r.set_en(En::B_0X0);
|
r.set_en(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Clear transfer complete flag
|
// Clear transfer complete flag
|
||||||
reg.xspi_fcr().write(|w| w.set_ctcf(true));
|
reg.fcr().write(|w| w.set_ctcf(true));
|
||||||
|
|
||||||
// Re-enable ospi
|
// Re-enable ospi
|
||||||
reg.xspi_cr().modify(|r| {
|
reg.cr().modify(|r| {
|
||||||
r.set_en(En::B_0X1);
|
r.set_en(true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,18 +280,18 @@ impl<'d, T: Instance, M: PeriMode> Xspi<'d, T, M> {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(peri);
|
into_ref!(peri);
|
||||||
|
|
||||||
#[cfg(xspim_v2_1)]
|
#[cfg(xspim_v1)]
|
||||||
{
|
{
|
||||||
// RCC for xspim should be enabled before writing register
|
// RCC for xspim should be enabled before writing register
|
||||||
crate::pac::RCC.ahb5enr().modify(|w| w.set_iomngren(true));
|
crate::pac::RCC.ahb5enr().modify(|w| w.set_iomngren(true));
|
||||||
|
|
||||||
// Disable XSPI peripheral first
|
// Disable XSPI peripheral first
|
||||||
T::REGS.xspi_cr().modify(|w| {
|
T::REGS.cr().modify(|w| {
|
||||||
w.set_en(En::B_0X0);
|
w.set_en(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
// XSPI IO Manager has been enabled before
|
// XSPI IO Manager has been enabled before
|
||||||
T::SPIM_REGS.xspim_cr().modify(|w| {
|
T::SPIM_REGS.cr().modify(|w| {
|
||||||
w.set_muxen(false);
|
w.set_muxen(false);
|
||||||
w.set_req2ack_time(0xff);
|
w.set_req2ack_time(0xff);
|
||||||
});
|
});
|
||||||
@ -310,74 +299,70 @@ impl<'d, T: Instance, M: PeriMode> Xspi<'d, T, M> {
|
|||||||
|
|
||||||
// System configuration
|
// System configuration
|
||||||
rcc::enable_and_reset::<T>();
|
rcc::enable_and_reset::<T>();
|
||||||
while T::REGS.xspi_sr().read().busy() {}
|
while T::REGS.sr().read().busy() {}
|
||||||
|
|
||||||
// Device configuration
|
// Device configuration
|
||||||
T::REGS.xspi_dcr1().modify(|w| {
|
T::REGS.dcr1().modify(|w| {
|
||||||
w.set_devsize(config.device_size.into());
|
w.set_devsize(config.device_size.into());
|
||||||
w.set_mtyp(Mtyp::from_bits(config.memory_type.into()));
|
w.set_mtyp(Mtyp::from_bits(config.memory_type.into()));
|
||||||
w.set_csht(Csht::from_bits(config.chip_select_high_time.into()));
|
w.set_csht(Csht::from_bits(config.chip_select_high_time.into()));
|
||||||
w.set_frck(Frck::B_0X0);
|
w.set_frck(false);
|
||||||
w.set_ckmode(Ckmode::from_bits(config.clock_mode.into()));
|
w.set_ckmode(Ckmode::from_bits(config.clock_mode.into()));
|
||||||
});
|
});
|
||||||
|
|
||||||
T::REGS.xspi_dcr2().modify(|w| {
|
T::REGS.dcr2().modify(|w| {
|
||||||
w.set_wrapsize(Wrapsize::from_bits(config.wrap_size.into()));
|
w.set_wrapsize(Wrapsize::from_bits(config.wrap_size.into()));
|
||||||
});
|
});
|
||||||
|
|
||||||
T::REGS.xspi_dcr3().modify(|w| {
|
T::REGS.dcr3().modify(|w| {
|
||||||
w.set_csbound(Csbound::from_bits(config.chip_select_boundary.into()));
|
w.set_csbound(Csbound::from_bits(config.chip_select_boundary.into()));
|
||||||
#[cfg(xspi_v2_1)]
|
#[cfg(xspi_v1)]
|
||||||
{
|
{
|
||||||
w.set_maxtran(Maxtran::from_bits(config.max_transfer.into()));
|
w.set_maxtran(Maxtran::from_bits(config.max_transfer.into()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
T::REGS.xspi_dcr4().modify(|w| {
|
T::REGS.dcr4().modify(|w| {
|
||||||
w.set_refresh(Refresh::from_bits(config.refresh.into()));
|
w.set_refresh(Refresh::from_bits(config.refresh.into()));
|
||||||
});
|
});
|
||||||
|
|
||||||
T::REGS.xspi_cr().modify(|w| {
|
T::REGS.cr().modify(|w| {
|
||||||
w.set_fthres(Fthres::from_bits(config.fifo_threshold.into()));
|
w.set_fthres(Fthres::from_bits(config.fifo_threshold.into()));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Wait for busy flag to clear
|
// Wait for busy flag to clear
|
||||||
while T::REGS.xspi_sr().read().busy() {}
|
while T::REGS.sr().read().busy() {}
|
||||||
|
|
||||||
T::REGS.xspi_dcr2().modify(|w| {
|
T::REGS.dcr2().modify(|w| {
|
||||||
w.set_prescaler(Prescaler::from_bits(config.clock_prescaler.into()));
|
w.set_prescaler(config.clock_prescaler);
|
||||||
});
|
});
|
||||||
|
|
||||||
T::REGS.xspi_cr().modify(|w| {
|
T::REGS.cr().modify(|w| {
|
||||||
w.set_dmm(match dual_quad {
|
w.set_dmm(dual_quad);
|
||||||
true => Dmm::B_0X1,
|
|
||||||
false => Dmm::B_0X0,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
T::REGS.xspi_tcr().modify(|w| {
|
T::REGS.tcr().modify(|w| {
|
||||||
w.set_sshift(match config.sample_shifting {
|
w.set_sshift(config.sample_shifting);
|
||||||
true => XspiTcrSshift::B_0X1,
|
w.set_dhqc(config.delay_hold_quarter_cycle);
|
||||||
false => XspiTcrSshift::B_0X0,
|
});
|
||||||
});
|
|
||||||
w.set_dhqc(match config.delay_hold_quarter_cycle {
|
// TODO: at the moment only ncs1 seems to get passed in?
|
||||||
true => XspiTcrDhqc::B_0X1,
|
// Only one must be selected
|
||||||
false => XspiTcrDhqc::B_0X0,
|
assert!(!(ncs1.is_some() && ncs2.is_some()));
|
||||||
});
|
assert!(!(ncs1.is_none() && ncs2.is_none()));
|
||||||
|
T::REGS.cr().modify(|w| {
|
||||||
|
w.set_cssel(if ncs1.is_some() { Cssel::B_0X0 } else { Cssel::B_0X1 });
|
||||||
});
|
});
|
||||||
|
|
||||||
// Enable peripheral
|
// Enable peripheral
|
||||||
T::REGS.xspi_cr().modify(|w| {
|
T::REGS.cr().modify(|w| {
|
||||||
w.set_en(En::B_0X1);
|
w.set_en(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Free running clock needs to be set after peripheral enable
|
// Free running clock needs to be set after peripheral enable
|
||||||
if config.free_running_clock {
|
if config.free_running_clock {
|
||||||
T::REGS.xspi_dcr1().modify(|w| {
|
T::REGS.dcr1().modify(|w| {
|
||||||
w.set_frck(match config.free_running_clock {
|
w.set_frck(config.free_running_clock);
|
||||||
true => Frck::B_0X1,
|
|
||||||
false => Frck::B_0X0,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,87 +407,78 @@ impl<'d, T: Instance, M: PeriMode> Xspi<'d, T, M> {
|
|||||||
return Err(XspiError::InvalidCommand);
|
return Err(XspiError::InvalidCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
T::REGS.xspi_cr().modify(|w| {
|
T::REGS.cr().modify(|w| {
|
||||||
w.set_fmode(0.into());
|
w.set_fmode(0.into());
|
||||||
});
|
});
|
||||||
|
|
||||||
// Configure alternate bytes
|
// Configure alternate bytes
|
||||||
if let Some(ab) = command.alternate_bytes {
|
if let Some(ab) = command.alternate_bytes {
|
||||||
T::REGS.xspi_abr().write(|v| v.set_alternate(ab));
|
T::REGS.abr().write(|v| v.set_alternate(ab));
|
||||||
T::REGS.xspi_ccr().modify(|w| {
|
T::REGS.ccr().modify(|w| {
|
||||||
w.set_abmode(XspiCcrAbmode::from_bits(command.abwidth.into()));
|
w.set_abmode(CcrAbmode::from_bits(command.abwidth.into()));
|
||||||
w.set_abdtr(XspiCcrAbdtr::from_bits(command.abdtr.into()));
|
w.set_abdtr(command.abdtr);
|
||||||
w.set_absize(XspiCcrAbsize::from_bits(command.absize.into()));
|
w.set_absize(CcrAbsize::from_bits(command.absize.into()));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure dummy cycles
|
// Configure dummy cycles
|
||||||
T::REGS.xspi_tcr().modify(|w| {
|
T::REGS.tcr().modify(|w| {
|
||||||
w.set_dcyc(command.dummy.into());
|
w.set_dcyc(command.dummy.into());
|
||||||
});
|
});
|
||||||
|
|
||||||
// Configure data
|
// Configure data
|
||||||
if let Some(data_length) = data_len {
|
if let Some(data_length) = data_len {
|
||||||
T::REGS.xspi_dlr().write(|v| {
|
T::REGS.dlr().write(|v| {
|
||||||
v.set_dl((data_length - 1) as u32);
|
v.set_dl((data_length - 1) as u32);
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
T::REGS.xspi_dlr().write(|v| {
|
T::REGS.dlr().write(|v| {
|
||||||
v.set_dl((0) as u32);
|
v.set_dl((0) as u32);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure instruction/address/data modes
|
// Configure instruction/address/data modes
|
||||||
T::REGS.xspi_ccr().modify(|w| {
|
T::REGS.ccr().modify(|w| {
|
||||||
w.set_imode(XspiCcrImode::from_bits(command.iwidth.into()));
|
w.set_imode(CcrImode::from_bits(command.iwidth.into()));
|
||||||
w.set_idtr(match command.idtr {
|
w.set_idtr(command.idtr);
|
||||||
true => XspiCcrIdtr::B_0X1,
|
w.set_isize(CcrIsize::from_bits(command.isize.into()));
|
||||||
false => XspiCcrIdtr::B_0X0,
|
|
||||||
});
|
|
||||||
w.set_isize(XspiCcrIsize::from_bits(command.isize.into()));
|
|
||||||
|
|
||||||
w.set_admode(XspiCcrAdmode::from_bits(command.adwidth.into()));
|
w.set_admode(CcrAdmode::from_bits(command.adwidth.into()));
|
||||||
w.set_addtr(match command.idtr {
|
w.set_addtr(command.idtr);
|
||||||
true => XspiCcrAddtr::B_0X1,
|
w.set_adsize(CcrAdsize::from_bits(command.adsize.into()));
|
||||||
false => XspiCcrAddtr::B_0X0,
|
|
||||||
});
|
|
||||||
w.set_adsize(XspiCcrAdsize::from_bits(command.adsize.into()));
|
|
||||||
|
|
||||||
w.set_dmode(XspiCcrDmode::from_bits(command.dwidth.into()));
|
w.set_dmode(CcrDmode::from_bits(command.dwidth.into()));
|
||||||
w.set_ddtr(match command.ddtr {
|
w.set_ddtr(command.ddtr);
|
||||||
true => XspiCcrDdtr::B_0X1,
|
|
||||||
false => XspiCcrDdtr::B_0X0,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set information required to initiate transaction
|
// Set information required to initiate transaction
|
||||||
if let Some(instruction) = command.instruction {
|
if let Some(instruction) = command.instruction {
|
||||||
if let Some(address) = command.address {
|
if let Some(address) = command.address {
|
||||||
T::REGS.xspi_ir().write(|v| {
|
T::REGS.ir().write(|v| {
|
||||||
v.set_instruction(instruction);
|
v.set_instruction(instruction);
|
||||||
});
|
});
|
||||||
|
|
||||||
T::REGS.xspi_ar().write(|v| {
|
T::REGS.ar().write(|v| {
|
||||||
v.set_address(address);
|
v.set_address(address);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Double check requirements for delay hold and sample shifting
|
// Double check requirements for delay hold and sample shifting
|
||||||
// if let None = command.data_len {
|
// if let None = command.data_len {
|
||||||
// if self.config.delay_hold_quarter_cycle && command.idtr {
|
// if self.config.delay_hold_quarter_cycle && command.idtr {
|
||||||
// T::REGS.xspi_ccr().modify(|w| {
|
// T::REGS.ccr().modify(|w| {
|
||||||
// w.set_ddtr(true);
|
// w.set_ddtr(true);
|
||||||
// });
|
// });
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
warn!("instruction: {:#x}", instruction);
|
// warn!("instruction: {:#x}", instruction);
|
||||||
T::REGS.xspi_ir().write(|v| {
|
T::REGS.ir().write(|v| {
|
||||||
v.set_instruction(instruction);
|
v.set_instruction(instruction);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if let Some(address) = command.address {
|
if let Some(address) = command.address {
|
||||||
T::REGS.xspi_ar().write(|v| {
|
T::REGS.ar().write(|v| {
|
||||||
v.set_address(address);
|
v.set_address(address);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -517,14 +493,14 @@ impl<'d, T: Instance, M: PeriMode> Xspi<'d, T, M> {
|
|||||||
/// Function used to control or configure the target device without data transfer
|
/// Function used to control or configure the target device without data transfer
|
||||||
pub fn blocking_command(&mut self, command: &TransferConfig) -> Result<(), XspiError> {
|
pub fn blocking_command(&mut self, command: &TransferConfig) -> Result<(), XspiError> {
|
||||||
// Wait for peripheral to be free
|
// Wait for peripheral to be free
|
||||||
while T::REGS.xspi_sr().read().busy() {}
|
while T::REGS.sr().read().busy() {}
|
||||||
|
|
||||||
// Need additional validation that command configuration doesn't have data set
|
// Need additional validation that command configuration doesn't have data set
|
||||||
self.configure_command(command, None)?;
|
self.configure_command(command, None)?;
|
||||||
|
|
||||||
// Transaction initiated by setting final configuration, i.e the instruction register
|
// Transaction initiated by setting final configuration, i.e the instruction register
|
||||||
while !T::REGS.xspi_sr().read().tcf() {}
|
while !T::REGS.sr().read().tcf() {}
|
||||||
T::REGS.xspi_fcr().write(|w| {
|
T::REGS.fcr().write(|w| {
|
||||||
w.set_ctcf(true);
|
w.set_ctcf(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -538,36 +514,36 @@ impl<'d, T: Instance, M: PeriMode> Xspi<'d, T, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Wait for peripheral to be free
|
// Wait for peripheral to be free
|
||||||
while T::REGS.xspi_sr().read().busy() {}
|
while T::REGS.sr().read().busy() {}
|
||||||
|
|
||||||
// Ensure DMA is not enabled for this transaction
|
// Ensure DMA is not enabled for this transaction
|
||||||
T::REGS.xspi_cr().modify(|w| {
|
T::REGS.cr().modify(|w| {
|
||||||
w.set_dmaen(Dmaen::B_0X0);
|
w.set_dmaen(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
// self.configure_command(&transaction, Some(buf.len()))?;
|
// self.configure_command(&transaction, Some(buf.len()))?;
|
||||||
self.configure_command(&transaction, Some(buf.len())).unwrap();
|
self.configure_command(&transaction, Some(buf.len())).unwrap();
|
||||||
|
|
||||||
let current_address = T::REGS.xspi_ar().read().address();
|
let current_address = T::REGS.ar().read().address();
|
||||||
let current_instruction = T::REGS.xspi_ir().read().instruction();
|
let current_instruction = T::REGS.ir().read().instruction();
|
||||||
|
|
||||||
// For a indirect read transaction, the transaction begins when the instruction/address is set
|
// For a indirect read transaction, the transaction begins when the instruction/address is set
|
||||||
T::REGS
|
T::REGS
|
||||||
.xspi_cr()
|
.cr()
|
||||||
.modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectRead.into())));
|
.modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectRead.into())));
|
||||||
if T::REGS.xspi_ccr().read().admode() == XspiCcrAdmode::B_0X0 {
|
if T::REGS.ccr().read().admode() == CcrAdmode::B_0X0 {
|
||||||
T::REGS.xspi_ir().write(|v| v.set_instruction(current_instruction));
|
T::REGS.ir().write(|v| v.set_instruction(current_instruction));
|
||||||
} else {
|
} else {
|
||||||
T::REGS.xspi_ar().write(|v| v.set_address(current_address));
|
T::REGS.ar().write(|v| v.set_address(current_address));
|
||||||
}
|
}
|
||||||
|
|
||||||
for idx in 0..buf.len() {
|
for idx in 0..buf.len() {
|
||||||
while !T::REGS.xspi_sr().read().tcf() && !T::REGS.xspi_sr().read().ftf() {}
|
while !T::REGS.sr().read().tcf() && !T::REGS.sr().read().ftf() {}
|
||||||
buf[idx] = unsafe { (T::REGS.xspi_dr().as_ptr() as *mut W).read_volatile() };
|
buf[idx] = unsafe { (T::REGS.dr().as_ptr() as *mut W).read_volatile() };
|
||||||
}
|
}
|
||||||
|
|
||||||
while !T::REGS.xspi_sr().read().tcf() {}
|
while !T::REGS.sr().read().tcf() {}
|
||||||
T::REGS.xspi_fcr().write(|v| v.set_ctcf(true));
|
T::REGS.fcr().write(|v| v.set_ctcf(true));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -579,25 +555,25 @@ impl<'d, T: Instance, M: PeriMode> Xspi<'d, T, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Wait for peripheral to be free
|
// Wait for peripheral to be free
|
||||||
while T::REGS.xspi_sr().read().busy() {}
|
while T::REGS.sr().read().busy() {}
|
||||||
|
|
||||||
T::REGS.xspi_cr().modify(|w| {
|
T::REGS.cr().modify(|w| {
|
||||||
w.set_dmaen(Dmaen::B_0X0);
|
w.set_dmaen(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
self.configure_command(&transaction, Some(buf.len()))?;
|
self.configure_command(&transaction, Some(buf.len()))?;
|
||||||
|
|
||||||
T::REGS
|
T::REGS
|
||||||
.xspi_cr()
|
.cr()
|
||||||
.modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectWrite.into())));
|
.modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectWrite.into())));
|
||||||
|
|
||||||
for idx in 0..buf.len() {
|
for idx in 0..buf.len() {
|
||||||
while !T::REGS.xspi_sr().read().ftf() {}
|
while !T::REGS.sr().read().ftf() {}
|
||||||
unsafe { (T::REGS.xspi_dr().as_ptr() as *mut W).write_volatile(buf[idx]) };
|
unsafe { (T::REGS.dr().as_ptr() as *mut W).write_volatile(buf[idx]) };
|
||||||
}
|
}
|
||||||
|
|
||||||
while !T::REGS.xspi_sr().read().tcf() {}
|
while !T::REGS.sr().read().tcf() {}
|
||||||
T::REGS.xspi_fcr().write(|v| v.set_ctcf(true));
|
T::REGS.fcr().write(|v| v.set_ctcf(true));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -605,75 +581,66 @@ impl<'d, T: Instance, M: PeriMode> Xspi<'d, T, M> {
|
|||||||
/// Set new bus configuration
|
/// Set new bus configuration
|
||||||
pub fn set_config(&mut self, config: &Config) {
|
pub fn set_config(&mut self, config: &Config) {
|
||||||
// Wait for busy flag to clear
|
// Wait for busy flag to clear
|
||||||
while T::REGS.xspi_sr().read().busy() {}
|
while T::REGS.sr().read().busy() {}
|
||||||
|
|
||||||
// Disable DMA channel while configuring the peripheral
|
// Disable DMA channel while configuring the peripheral
|
||||||
T::REGS.xspi_cr().modify(|w| {
|
T::REGS.cr().modify(|w| {
|
||||||
w.set_dmaen(Dmaen::B_0X0);
|
w.set_dmaen(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Device configuration
|
// Device configuration
|
||||||
T::REGS.xspi_dcr1().modify(|w| {
|
T::REGS.dcr1().modify(|w| {
|
||||||
w.set_devsize(config.device_size.into());
|
w.set_devsize(config.device_size.into());
|
||||||
w.set_mtyp(Mtyp::from_bits(config.memory_type.into()));
|
w.set_mtyp(Mtyp::from_bits(config.memory_type.into()));
|
||||||
w.set_csht(Csht::from_bits(config.chip_select_high_time.into()));
|
w.set_csht(Csht::from_bits(config.chip_select_high_time.into()));
|
||||||
w.set_frck(Frck::B_0X0);
|
w.set_frck(false);
|
||||||
w.set_ckmode(match config.clock_mode {
|
w.set_ckmode(match config.clock_mode {
|
||||||
true => Ckmode::B_0X1,
|
true => Ckmode::B_0X1,
|
||||||
false => Ckmode::B_0X0,
|
false => Ckmode::B_0X0,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
T::REGS.xspi_dcr2().modify(|w| {
|
T::REGS.dcr2().modify(|w| {
|
||||||
w.set_wrapsize(Wrapsize::from_bits(config.wrap_size.into()));
|
w.set_wrapsize(Wrapsize::from_bits(config.wrap_size.into()));
|
||||||
});
|
});
|
||||||
|
|
||||||
T::REGS.xspi_dcr3().modify(|w| {
|
T::REGS.dcr3().modify(|w| {
|
||||||
w.set_csbound(Csbound::from_bits(config.chip_select_boundary.into()));
|
w.set_csbound(Csbound::from_bits(config.chip_select_boundary.into()));
|
||||||
#[cfg(xspi_v2_1)]
|
#[cfg(xspi_v1)]
|
||||||
{
|
{
|
||||||
w.set_maxtran(Maxtran::from_bits(config.max_transfer.into()));
|
w.set_maxtran(Maxtran::from_bits(config.max_transfer.into()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
T::REGS.xspi_dcr4().modify(|w| {
|
T::REGS.dcr4().modify(|w| {
|
||||||
w.set_refresh(Refresh::from_bits(config.refresh.into()));
|
w.set_refresh(Refresh::from_bits(config.refresh.into()));
|
||||||
});
|
});
|
||||||
|
|
||||||
T::REGS.xspi_cr().modify(|w| {
|
T::REGS.cr().modify(|w| {
|
||||||
w.set_fthres(Fthres::from_bits(config.fifo_threshold.into()));
|
w.set_fthres(Fthres::from_bits(config.fifo_threshold.into()));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Wait for busy flag to clear
|
// Wait for busy flag to clear
|
||||||
while T::REGS.xspi_sr().read().busy() {}
|
while T::REGS.sr().read().busy() {}
|
||||||
|
|
||||||
T::REGS.xspi_dcr2().modify(|w| {
|
T::REGS.dcr2().modify(|w| {
|
||||||
w.set_prescaler(Prescaler::from_bits(config.clock_prescaler.into()));
|
w.set_prescaler(config.clock_prescaler);
|
||||||
});
|
});
|
||||||
|
|
||||||
T::REGS.xspi_tcr().modify(|w| {
|
T::REGS.tcr().modify(|w| {
|
||||||
w.set_sshift(match config.sample_shifting {
|
w.set_sshift(config.sample_shifting);
|
||||||
true => XspiTcrSshift::B_0X1,
|
w.set_dhqc(config.delay_hold_quarter_cycle);
|
||||||
false => XspiTcrSshift::B_0X0,
|
|
||||||
});
|
|
||||||
w.set_dhqc(match config.delay_hold_quarter_cycle {
|
|
||||||
true => XspiTcrDhqc::B_0X1,
|
|
||||||
false => XspiTcrDhqc::B_0X0,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Enable peripheral
|
// Enable peripheral
|
||||||
T::REGS.xspi_cr().modify(|w| {
|
T::REGS.cr().modify(|w| {
|
||||||
w.set_en(En::B_0X1);
|
w.set_en(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Free running clock needs to be set after peripheral enable
|
// Free running clock needs to be set after peripheral enable
|
||||||
if config.free_running_clock {
|
if config.free_running_clock {
|
||||||
T::REGS.xspi_dcr1().modify(|w| {
|
T::REGS.dcr1().modify(|w| {
|
||||||
w.set_frck(match config.free_running_clock {
|
w.set_frck(config.free_running_clock);
|
||||||
true => Frck::B_0X1,
|
|
||||||
false => Frck::B_0X0,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1143,31 +1110,31 @@ impl<'d, T: Instance> Xspi<'d, T, Async> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Wait for peripheral to be free
|
// Wait for peripheral to be free
|
||||||
while T::REGS.xspi_sr().read().busy() {}
|
while T::REGS.sr().read().busy() {}
|
||||||
|
|
||||||
self.configure_command(&transaction, Some(buf.len()))?;
|
self.configure_command(&transaction, Some(buf.len()))?;
|
||||||
|
|
||||||
let current_address = T::REGS.xspi_ar().read().address();
|
let current_address = T::REGS.ar().read().address();
|
||||||
let current_instruction = T::REGS.xspi_ir().read().instruction();
|
let current_instruction = T::REGS.ir().read().instruction();
|
||||||
|
|
||||||
// For a indirect read transaction, the transaction begins when the instruction/address is set
|
// For a indirect read transaction, the transaction begins when the instruction/address is set
|
||||||
T::REGS
|
T::REGS
|
||||||
.xspi_cr()
|
.cr()
|
||||||
.modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectRead.into())));
|
.modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectRead.into())));
|
||||||
if T::REGS.xspi_ccr().read().admode() == XspiCcrAdmode::B_0X0 {
|
if T::REGS.ccr().read().admode() == CcrAdmode::B_0X0 {
|
||||||
T::REGS.xspi_ir().write(|v| v.set_instruction(current_instruction));
|
T::REGS.ir().write(|v| v.set_instruction(current_instruction));
|
||||||
} else {
|
} else {
|
||||||
T::REGS.xspi_ar().write(|v| v.set_address(current_address));
|
T::REGS.ar().write(|v| v.set_address(current_address));
|
||||||
}
|
}
|
||||||
|
|
||||||
let transfer = unsafe {
|
let transfer = unsafe {
|
||||||
self.dma
|
self.dma
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.read(T::REGS.xspi_dr().as_ptr() as *mut W, buf, Default::default())
|
.read(T::REGS.dr().as_ptr() as *mut W, buf, Default::default())
|
||||||
};
|
};
|
||||||
|
|
||||||
T::REGS.xspi_cr().modify(|w| w.set_dmaen(Dmaen::B_0X1));
|
T::REGS.cr().modify(|w| w.set_dmaen(true));
|
||||||
|
|
||||||
transfer.blocking_wait();
|
transfer.blocking_wait();
|
||||||
|
|
||||||
@ -1183,21 +1150,21 @@ impl<'d, T: Instance> Xspi<'d, T, Async> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Wait for peripheral to be free
|
// Wait for peripheral to be free
|
||||||
while T::REGS.xspi_sr().read().busy() {}
|
while T::REGS.sr().read().busy() {}
|
||||||
|
|
||||||
self.configure_command(&transaction, Some(buf.len()))?;
|
self.configure_command(&transaction, Some(buf.len()))?;
|
||||||
T::REGS
|
T::REGS
|
||||||
.xspi_cr()
|
.cr()
|
||||||
.modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectWrite.into())));
|
.modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectWrite.into())));
|
||||||
|
|
||||||
let transfer = unsafe {
|
let transfer = unsafe {
|
||||||
self.dma
|
self.dma
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.write(buf, T::REGS.xspi_dr().as_ptr() as *mut W, Default::default())
|
.write(buf, T::REGS.dr().as_ptr() as *mut W, Default::default())
|
||||||
};
|
};
|
||||||
|
|
||||||
T::REGS.xspi_cr().modify(|w| w.set_dmaen(Dmaen::B_0X1));
|
T::REGS.cr().modify(|w| w.set_dmaen(true));
|
||||||
|
|
||||||
transfer.blocking_wait();
|
transfer.blocking_wait();
|
||||||
|
|
||||||
@ -1213,31 +1180,31 @@ impl<'d, T: Instance> Xspi<'d, T, Async> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Wait for peripheral to be free
|
// Wait for peripheral to be free
|
||||||
while T::REGS.xspi_sr().read().busy() {}
|
while T::REGS.sr().read().busy() {}
|
||||||
|
|
||||||
self.configure_command(&transaction, Some(buf.len()))?;
|
self.configure_command(&transaction, Some(buf.len()))?;
|
||||||
|
|
||||||
let current_address = T::REGS.xspi_ar().read().address();
|
let current_address = T::REGS.ar().read().address();
|
||||||
let current_instruction = T::REGS.xspi_ir().read().instruction();
|
let current_instruction = T::REGS.ir().read().instruction();
|
||||||
|
|
||||||
// For a indirect read transaction, the transaction begins when the instruction/address is set
|
// For a indirect read transaction, the transaction begins when the instruction/address is set
|
||||||
T::REGS
|
T::REGS
|
||||||
.xspi_cr()
|
.cr()
|
||||||
.modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectRead.into())));
|
.modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectRead.into())));
|
||||||
if T::REGS.xspi_ccr().read().admode() == XspiCcrAdmode::B_0X0 {
|
if T::REGS.ccr().read().admode() == CcrAdmode::B_0X0 {
|
||||||
T::REGS.xspi_ir().write(|v| v.set_instruction(current_instruction));
|
T::REGS.ir().write(|v| v.set_instruction(current_instruction));
|
||||||
} else {
|
} else {
|
||||||
T::REGS.xspi_ar().write(|v| v.set_address(current_address));
|
T::REGS.ar().write(|v| v.set_address(current_address));
|
||||||
}
|
}
|
||||||
|
|
||||||
let transfer = unsafe {
|
let transfer = unsafe {
|
||||||
self.dma
|
self.dma
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.read(T::REGS.xspi_dr().as_ptr() as *mut W, buf, Default::default())
|
.read(T::REGS.dr().as_ptr() as *mut W, buf, Default::default())
|
||||||
};
|
};
|
||||||
|
|
||||||
T::REGS.xspi_cr().modify(|w| w.set_dmaen(Dmaen::B_0X1));
|
T::REGS.cr().modify(|w| w.set_dmaen(true));
|
||||||
|
|
||||||
transfer.await;
|
transfer.await;
|
||||||
|
|
||||||
@ -1253,21 +1220,21 @@ impl<'d, T: Instance> Xspi<'d, T, Async> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Wait for peripheral to be free
|
// Wait for peripheral to be free
|
||||||
while T::REGS.xspi_sr().read().busy() {}
|
while T::REGS.sr().read().busy() {}
|
||||||
|
|
||||||
self.configure_command(&transaction, Some(buf.len()))?;
|
self.configure_command(&transaction, Some(buf.len()))?;
|
||||||
T::REGS
|
T::REGS
|
||||||
.xspi_cr()
|
.cr()
|
||||||
.modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectWrite.into())));
|
.modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectWrite.into())));
|
||||||
|
|
||||||
let transfer = unsafe {
|
let transfer = unsafe {
|
||||||
self.dma
|
self.dma
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.write(buf, T::REGS.xspi_dr().as_ptr() as *mut W, Default::default())
|
.write(buf, T::REGS.dr().as_ptr() as *mut W, Default::default())
|
||||||
};
|
};
|
||||||
|
|
||||||
T::REGS.xspi_cr().modify(|w| w.set_dmaen(Dmaen::B_0X1));
|
T::REGS.cr().modify(|w| w.set_dmaen(true));
|
||||||
|
|
||||||
transfer.await;
|
transfer.await;
|
||||||
|
|
||||||
@ -1306,16 +1273,16 @@ impl<'d, T: Instance, M: PeriMode> Drop for Xspi<'d, T, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn finish_dma(regs: Regs) {
|
fn finish_dma(regs: Regs) {
|
||||||
while !regs.xspi_sr().read().tcf() {}
|
while !regs.sr().read().tcf() {}
|
||||||
regs.xspi_fcr().write(|v| v.set_ctcf(true));
|
regs.fcr().write(|v| v.set_ctcf(true));
|
||||||
|
|
||||||
regs.xspi_cr().modify(|w| {
|
regs.cr().modify(|w| {
|
||||||
w.set_dmaen(Dmaen::B_0X0);
|
w.set_dmaen(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// XSPI I/O manager instance trait.
|
/// XSPI I/O manager instance trait.
|
||||||
#[cfg(xspim_v2_1)]
|
#[cfg(xspim_v1)]
|
||||||
pub(crate) trait SealedXspimInstance {
|
pub(crate) trait SealedXspimInstance {
|
||||||
const SPIM_REGS: Xspim;
|
const SPIM_REGS: Xspim;
|
||||||
const SPI_IDX: u8;
|
const SPI_IDX: u8;
|
||||||
@ -1327,12 +1294,12 @@ pub(crate) trait SealedInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// XSPI instance trait.
|
/// XSPI instance trait.
|
||||||
#[cfg(xspim_v2_1)]
|
#[cfg(xspim_v1)]
|
||||||
#[allow(private_bounds)]
|
#[allow(private_bounds)]
|
||||||
pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral + SealedXspimInstance {}
|
pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral + SealedXspimInstance {}
|
||||||
|
|
||||||
/// XSPI instance trait.
|
/// XSPI instance trait.
|
||||||
#[cfg(not(xspim_v2_1))]
|
#[cfg(not(xspim_v1))]
|
||||||
#[allow(private_bounds)]
|
#[allow(private_bounds)]
|
||||||
pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {}
|
pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {}
|
||||||
|
|
||||||
@ -1361,20 +1328,20 @@ pin_trait!(NCLKPin, Instance);
|
|||||||
dma_trait!(XDma, Instance);
|
dma_trait!(XDma, Instance);
|
||||||
|
|
||||||
// Hard-coded the xspi index, for SPIM
|
// Hard-coded the xspi index, for SPIM
|
||||||
#[cfg(xspim_v2_1)]
|
#[cfg(xspim_v1)]
|
||||||
impl SealedXspimInstance for peripherals::XSPI1 {
|
impl SealedXspimInstance for peripherals::XSPI1 {
|
||||||
const SPIM_REGS: Xspim = crate::pac::XSPIM;
|
const SPIM_REGS: Xspim = crate::pac::XSPIM;
|
||||||
const SPI_IDX: u8 = 1;
|
const SPI_IDX: u8 = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[cfg(all(xspim_v2_1, peri_xspi2))]
|
// Some cubedb files are missing XSPI2, for example STM32H7R3Z8
|
||||||
#[cfg(xspim_v2_1)]
|
#[cfg(all(xspim_v1, peri_xspi2))]
|
||||||
impl SealedXspimInstance for peripherals::XSPI2 {
|
impl SealedXspimInstance for peripherals::XSPI2 {
|
||||||
const SPIM_REGS: Xspim = crate::pac::XSPIM;
|
const SPIM_REGS: Xspim = crate::pac::XSPIM;
|
||||||
const SPI_IDX: u8 = 2;
|
const SPI_IDX: u8 = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(xspim_v2_1)]
|
#[cfg(xspim_v1)]
|
||||||
foreach_peripheral!(
|
foreach_peripheral!(
|
||||||
(xspi, $inst:ident) => {
|
(xspi, $inst:ident) => {
|
||||||
impl SealedInstance for peripherals::$inst {
|
impl SealedInstance for peripherals::$inst {
|
||||||
@ -1385,7 +1352,7 @@ foreach_peripheral!(
|
|||||||
};
|
};
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(not(xspim_v2_1))]
|
#[cfg(not(xspim_v1))]
|
||||||
foreach_peripheral!(
|
foreach_peripheral!(
|
||||||
(xspi, $inst:ident) => {
|
(xspi, $inst:ident) => {
|
||||||
impl SealedInstance for peripherals::$inst {
|
impl SealedInstance for peripherals::$inst {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user