Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add octospim support for octospi #3102

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
21 changes: 21 additions & 0 deletions embassy-stm32/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1040,6 +1040,18 @@ fn main() {
(("octospi", "NCS"), quote!(crate::ospi::NSSPin)),
(("octospi", "CLK"), quote!(crate::ospi::SckPin)),
(("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)),
(("tsc", "G1_IO1"), quote!(crate::tsc::G1IO1Pin)),
HaoboGu marked this conversation as resolved.
Show resolved Hide resolved
(("tsc", "G1_IO2"), quote!(crate::tsc::G1IO2Pin)),
(("tsc", "G1_IO3"), quote!(crate::tsc::G1IO3Pin)),
Expand Down Expand Up @@ -1097,6 +1109,15 @@ fn main() {
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! {
pin_trait_impl!(#tr, #peri, #pin_name, #af);
})
Expand Down
92 changes: 92 additions & 0 deletions embassy-stm32/src/ospi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ use crate::dma::{word, ChannelAndRequest};
use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed};
use crate::mode::{Async, Blocking, Mode as PeriMode};
use crate::pac::octospi::{vals, Octospi as Regs};
#[cfg(octospim_v1)]
use crate::pac::octospim::Octospim;
use crate::rcc::{self, RccPeripheral};
use crate::{peripherals, Peripheral};

Expand Down Expand Up @@ -197,6 +199,66 @@ impl<'d, T: Instance, M: PeriMode> Ospi<'d, T, M> {
) -> Self {
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| {
w.set_ncsen(true);
w.set_ncssrc(false);
w.set_clken(true);
w.set_clksrc(false);
if dqs.is_some() {
w.set_dqsen(true);
w.set_dqssrc(false);
}

// IOL and IOH are enabled only for OCTOSPI1 currently
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(0);
} else if dual_quad {
w.set_iohen(true);
w.set_iohsrc(0);
} else {
w.set_iohen(false);
w.set_iohsrc(0);
}
});
}

// System configuration
rcc::enable_and_reset::<T>();
while T::REGS.sr().read().busy() {}
Expand Down Expand Up @@ -1056,6 +1118,13 @@ fn finish_dma(regs: Regs) {
});
}

#[cfg(octospim_v1)]
/// OctoSPI I/O manager instance trait.
pub(crate) trait SealedOctospimInstance {
const OCTOSPIM_REGS: Octospim;
}

/// OctoSPI instance trait.
pub(crate) trait SealedInstance {
const REGS: Regs;
}
Expand All @@ -1065,6 +1134,12 @@ trait SealedWord {
}

/// 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)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {}

Expand All @@ -1082,6 +1157,23 @@ pin_trait!(DQSPin, Instance);
pin_trait!(NSSPin, Instance);
dma_trait!(OctoDma, Instance);

#[cfg(octospim_v1)]
foreach_peripheral!(
(octospi, $inst:ident) => {
impl SealedInstance for peripherals::$inst {
const REGS: Regs = crate::pac::$inst;
}

impl SealedOctospimInstance for peripherals::$inst {
// Hardcoded, is it good?
const OCTOSPIM_REGS: Octospim = crate::pac::OCTOSPIM;
}

impl Instance for peripherals::$inst {}
};
);

#[cfg(not(octospim_v1))]
foreach_peripheral!(
(octospi, $inst:ident) => {
impl SealedInstance for peripherals::$inst {
Expand Down