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:
HaoboGu 2024-10-14 04:32:22 +08:00 committed by GitHub
parent 2f6273bb5d
commit 0222faa8a1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 151 additions and 0 deletions

View File

@ -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);
}) })

View File

@ -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 {