mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-25 08:12:30 +00:00
Add octospim support for octospi (#3102)
* feat: add octospim to ospi Signed-off-by: Haobo Gu <haobogu@outlook.com> * feat: make octospim behind feature gate Signed-off-by: Haobo Gu <haobogu@outlook.com> * refactor: fix fmt issue Signed-off-by: Haobo Gu <haobogu@outlook.com> * refactor: fix ci failure Signed-off-by: Haobo Gu <haobogu@outlook.com> * feat: add octospim reg writing code Signed-off-by: Haobo Gu <haobogu@outlook.com> * feat(octospi): enable rcc for octospim at the initialization Signed-off-by: Haobo Gu <haobogu@outlook.com> * fix: add octospim feature gate Signed-off-by: Haobo Gu <haobogu@outlook.com> * fix: fix cfg flag Signed-off-by: Haobo Gu <haobogu@outlook.com> * fix: fix rcc register on stm32l4 and stm32u5 Signed-off-by: Haobo Gu <haobogu@outlook.com> * feat(ospi): support OCTOSPI2 in build.rs Signed-off-by: Haobo Gu <haobogu@outlook.com> * feat(ospi): add OCTOSPI2 pin impls Signed-off-by: HaoboGu <haobogu@outlook.com> * feat(ospi): support both ospi instances in stm32 OCTOSPIM Signed-off-by: Haobo Gu <haobogu@outlook.com> --------- Signed-off-by: Haobo Gu <haobogu@outlook.com> Signed-off-by: HaoboGu <haobogu@outlook.com>
This commit is contained in:
parent
2f6273bb5d
commit
0222faa8a1
@ -1054,6 +1054,30 @@ fn main() {
|
|||||||
(("octospi", "NCS"), quote!(crate::ospi::NSSPin)),
|
(("octospi", "NCS"), quote!(crate::ospi::NSSPin)),
|
||||||
(("octospi", "CLK"), quote!(crate::ospi::SckPin)),
|
(("octospi", "CLK"), quote!(crate::ospi::SckPin)),
|
||||||
(("octospi", "NCLK"), quote!(crate::ospi::NckPin)),
|
(("octospi", "NCLK"), quote!(crate::ospi::NckPin)),
|
||||||
|
(("octospim", "P1_IO0"), quote!(crate::ospi::D0Pin)),
|
||||||
|
(("octospim", "P1_IO1"), quote!(crate::ospi::D1Pin)),
|
||||||
|
(("octospim", "P1_IO2"), quote!(crate::ospi::D2Pin)),
|
||||||
|
(("octospim", "P1_IO3"), quote!(crate::ospi::D3Pin)),
|
||||||
|
(("octospim", "P1_IO4"), quote!(crate::ospi::D4Pin)),
|
||||||
|
(("octospim", "P1_IO5"), quote!(crate::ospi::D5Pin)),
|
||||||
|
(("octospim", "P1_IO6"), quote!(crate::ospi::D6Pin)),
|
||||||
|
(("octospim", "P1_IO7"), quote!(crate::ospi::D7Pin)),
|
||||||
|
(("octospim", "P1_DQS"), quote!(crate::ospi::DQSPin)),
|
||||||
|
(("octospim", "P1_NCS"), quote!(crate::ospi::NSSPin)),
|
||||||
|
(("octospim", "P1_CLK"), quote!(crate::ospi::SckPin)),
|
||||||
|
(("octospim", "P1_NCLK"), quote!(crate::ospi::NckPin)),
|
||||||
|
(("octospim", "P2_IO0"), quote!(crate::ospi::D0Pin)),
|
||||||
|
(("octospim", "P2_IO1"), quote!(crate::ospi::D1Pin)),
|
||||||
|
(("octospim", "P2_IO2"), quote!(crate::ospi::D2Pin)),
|
||||||
|
(("octospim", "P2_IO3"), quote!(crate::ospi::D3Pin)),
|
||||||
|
(("octospim", "P2_IO4"), quote!(crate::ospi::D4Pin)),
|
||||||
|
(("octospim", "P2_IO5"), quote!(crate::ospi::D5Pin)),
|
||||||
|
(("octospim", "P2_IO6"), quote!(crate::ospi::D6Pin)),
|
||||||
|
(("octospim", "P2_IO7"), quote!(crate::ospi::D7Pin)),
|
||||||
|
(("octospim", "P2_DQS"), quote!(crate::ospi::DQSPin)),
|
||||||
|
(("octospim", "P2_NCS"), quote!(crate::ospi::NSSPin)),
|
||||||
|
(("octospim", "P2_CLK"), quote!(crate::ospi::SckPin)),
|
||||||
|
(("octospim", "P2_NCLK"), quote!(crate::ospi::NckPin)),
|
||||||
(("tsc", "G1_IO1"), quote!(crate::tsc::G1IO1Pin)),
|
(("tsc", "G1_IO1"), quote!(crate::tsc::G1IO1Pin)),
|
||||||
(("tsc", "G1_IO2"), quote!(crate::tsc::G1IO2Pin)),
|
(("tsc", "G1_IO2"), quote!(crate::tsc::G1IO2Pin)),
|
||||||
(("tsc", "G1_IO3"), quote!(crate::tsc::G1IO3Pin)),
|
(("tsc", "G1_IO3"), quote!(crate::tsc::G1IO3Pin)),
|
||||||
@ -1111,6 +1135,15 @@ fn main() {
|
|||||||
peri = format_ident!("{}", pin.signal.replace('_', ""));
|
peri = format_ident!("{}", pin.signal.replace('_', ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OCTOSPIM is special
|
||||||
|
if p.name == "OCTOSPIM" {
|
||||||
|
peri = format_ident!("{}", "OCTOSPI1");
|
||||||
|
g.extend(quote! {
|
||||||
|
pin_trait_impl!(#tr, #peri, #pin_name, #af);
|
||||||
|
});
|
||||||
|
peri = format_ident!("{}", "OCTOSPI2");
|
||||||
|
}
|
||||||
|
|
||||||
g.extend(quote! {
|
g.extend(quote! {
|
||||||
pin_trait_impl!(#tr, #peri, #pin_name, #af);
|
pin_trait_impl!(#tr, #peri, #pin_name, #af);
|
||||||
})
|
})
|
||||||
|
@ -16,6 +16,8 @@ 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::octospi::{vals, Octospi as Regs};
|
use crate::pac::octospi::{vals, Octospi as Regs};
|
||||||
|
#[cfg(octospim_v1)]
|
||||||
|
use crate::pac::octospim::Octospim;
|
||||||
use crate::rcc::{self, RccPeripheral};
|
use crate::rcc::{self, RccPeripheral};
|
||||||
use crate::{peripherals, Peripheral};
|
use crate::{peripherals, Peripheral};
|
||||||
|
|
||||||
@ -197,6 +199,83 @@ impl<'d, T: Instance, M: PeriMode> Ospi<'d, T, M> {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(peri);
|
into_ref!(peri);
|
||||||
|
|
||||||
|
#[cfg(octospim_v1)]
|
||||||
|
{
|
||||||
|
// RCC for octospim should be enabled before writing register
|
||||||
|
#[cfg(stm32l4)]
|
||||||
|
crate::pac::RCC.ahb2smenr().modify(|w| w.set_octospimsmen(true));
|
||||||
|
#[cfg(stm32u5)]
|
||||||
|
crate::pac::RCC.ahb2enr1().modify(|w| w.set_octospimen(true));
|
||||||
|
#[cfg(not(any(stm32l4, stm32u5)))]
|
||||||
|
crate::pac::RCC.ahb3enr().modify(|w| w.set_iomngren(true));
|
||||||
|
|
||||||
|
// Disable OctoSPI peripheral first
|
||||||
|
T::REGS.cr().modify(|w| {
|
||||||
|
w.set_en(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// OctoSPI IO Manager has been enabled before
|
||||||
|
T::OCTOSPIM_REGS.cr().modify(|w| {
|
||||||
|
w.set_muxen(false);
|
||||||
|
w.set_req2ack_time(0xff);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Clear config
|
||||||
|
T::OCTOSPIM_REGS.p1cr().modify(|w| {
|
||||||
|
w.set_clksrc(false);
|
||||||
|
w.set_dqssrc(false);
|
||||||
|
w.set_ncssrc(false);
|
||||||
|
w.set_clken(false);
|
||||||
|
w.set_dqsen(false);
|
||||||
|
w.set_ncsen(false);
|
||||||
|
w.set_iolsrc(0);
|
||||||
|
w.set_iohsrc(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
T::OCTOSPIM_REGS.p1cr().modify(|w| {
|
||||||
|
let octospi_src = if T::OCTOSPI_IDX == 1 { false } else { true };
|
||||||
|
w.set_ncsen(true);
|
||||||
|
w.set_ncssrc(octospi_src);
|
||||||
|
w.set_clken(true);
|
||||||
|
w.set_clksrc(octospi_src);
|
||||||
|
if dqs.is_some() {
|
||||||
|
w.set_dqsen(true);
|
||||||
|
w.set_dqssrc(octospi_src);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set OCTOSPIM IOL and IOH according to the index of OCTOSPI instance
|
||||||
|
if T::OCTOSPI_IDX == 1 {
|
||||||
|
w.set_iolen(true);
|
||||||
|
w.set_iolsrc(0);
|
||||||
|
// Enable IOH in octo and dual quad mode
|
||||||
|
if let OspiWidth::OCTO = width {
|
||||||
|
w.set_iohen(true);
|
||||||
|
w.set_iohsrc(0b01);
|
||||||
|
} else if dual_quad {
|
||||||
|
w.set_iohen(true);
|
||||||
|
w.set_iohsrc(0b00);
|
||||||
|
} else {
|
||||||
|
w.set_iohen(false);
|
||||||
|
w.set_iohsrc(0b00);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
w.set_iolen(true);
|
||||||
|
w.set_iolsrc(0b10);
|
||||||
|
// Enable IOH in octo and dual quad mode
|
||||||
|
if let OspiWidth::OCTO = width {
|
||||||
|
w.set_iohen(true);
|
||||||
|
w.set_iohsrc(0b11);
|
||||||
|
} else if dual_quad {
|
||||||
|
w.set_iohen(true);
|
||||||
|
w.set_iohsrc(0b10);
|
||||||
|
} else {
|
||||||
|
w.set_iohen(false);
|
||||||
|
w.set_iohsrc(0b00);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// System configuration
|
// System configuration
|
||||||
rcc::enable_and_reset::<T>();
|
rcc::enable_and_reset::<T>();
|
||||||
while T::REGS.sr().read().busy() {}
|
while T::REGS.sr().read().busy() {}
|
||||||
@ -1056,11 +1135,25 @@ fn finish_dma(regs: Regs) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(octospim_v1)]
|
||||||
|
/// OctoSPI I/O manager instance trait.
|
||||||
|
pub(crate) trait SealedOctospimInstance {
|
||||||
|
const OCTOSPIM_REGS: Octospim;
|
||||||
|
const OCTOSPI_IDX: u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// OctoSPI instance trait.
|
||||||
pub(crate) trait SealedInstance {
|
pub(crate) trait SealedInstance {
|
||||||
const REGS: Regs;
|
const REGS: Regs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// OSPI instance trait.
|
/// OSPI instance trait.
|
||||||
|
#[cfg(octospim_v1)]
|
||||||
|
#[allow(private_bounds)]
|
||||||
|
pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral + SealedOctospimInstance {}
|
||||||
|
|
||||||
|
/// OSPI instance trait.
|
||||||
|
#[cfg(not(octospim_v1))]
|
||||||
#[allow(private_bounds)]
|
#[allow(private_bounds)]
|
||||||
pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {}
|
pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {}
|
||||||
|
|
||||||
@ -1078,6 +1171,31 @@ pin_trait!(DQSPin, Instance);
|
|||||||
pin_trait!(NSSPin, Instance);
|
pin_trait!(NSSPin, Instance);
|
||||||
dma_trait!(OctoDma, Instance);
|
dma_trait!(OctoDma, Instance);
|
||||||
|
|
||||||
|
// Hard-coded the octospi index, for OCTOSPIM
|
||||||
|
#[cfg(octospim_v1)]
|
||||||
|
impl SealedOctospimInstance for peripherals::OCTOSPI1 {
|
||||||
|
const OCTOSPIM_REGS: Octospim = crate::pac::OCTOSPIM;
|
||||||
|
const OCTOSPI_IDX: u8 = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(octospim_v1)]
|
||||||
|
impl SealedOctospimInstance for peripherals::OCTOSPI2 {
|
||||||
|
const OCTOSPIM_REGS: Octospim = crate::pac::OCTOSPIM;
|
||||||
|
const OCTOSPI_IDX: u8 = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(octospim_v1)]
|
||||||
|
foreach_peripheral!(
|
||||||
|
(octospi, $inst:ident) => {
|
||||||
|
impl SealedInstance for peripherals::$inst {
|
||||||
|
const REGS: Regs = crate::pac::$inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Instance for peripherals::$inst {}
|
||||||
|
};
|
||||||
|
);
|
||||||
|
|
||||||
|
#[cfg(not(octospim_v1))]
|
||||||
foreach_peripheral!(
|
foreach_peripheral!(
|
||||||
(octospi, $inst:ident) => {
|
(octospi, $inst:ident) => {
|
||||||
impl SealedInstance for peripherals::$inst {
|
impl SealedInstance for peripherals::$inst {
|
||||||
|
Loading…
Reference in New Issue
Block a user