diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index fa9e3f953..b4e61878c 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -1123,8 +1123,8 @@ fn main() { (("xspi", "IO15"), quote!(crate::xspi::D15Pin)), (("xspi", "DQS0"), quote!(crate::xspi::DQS0Pin)), (("xspi", "DQS1"), quote!(crate::xspi::DQS1Pin)), - (("xspi", "NCS1"), quote!(crate::xspi::NCS1Pin)), - (("xspi", "NCS2"), quote!(crate::xspi::NCS2Pin)), + (("xspi", "NCS1"), quote!(crate::xspi::NCSPin)), + (("xspi", "NCS2"), quote!(crate::xspi::NCSPin)), (("xspi", "CLK"), quote!(crate::xspi::CLKPin)), (("xspi", "NCLK"), quote!(crate::xspi::NCLKPin)), (("xspim", "P1_IO0"), quote!(crate::xspi::D0Pin)), @@ -1145,8 +1145,8 @@ fn main() { (("xspim", "P1_IO15"), quote!(crate::xspi::D15Pin)), (("xspim", "P1_DQS0"), quote!(crate::xspi::DQS0Pin)), (("xspim", "P1_DQS1"), quote!(crate::xspi::DQS1Pin)), - (("xspim", "P1_NCS1"), quote!(crate::xspi::NCS1Pin)), - (("xspim", "P1_NCS2"), quote!(crate::xspi::NCS2Pin)), + (("xspim", "P1_NCS1"), quote!(crate::xspi::NCSPin)), + (("xspim", "P1_NCS2"), quote!(crate::xspi::NCSPin)), (("xspim", "P1_CLK"), quote!(crate::xspi::CLKPin)), (("xspim", "P1_NCLK"), quote!(crate::xspi::NCLKPin)), (("xspim", "P2_IO0"), quote!(crate::xspi::D0Pin)), @@ -1167,8 +1167,8 @@ fn main() { (("xspim", "P2_IO15"), quote!(crate::xspi::D15Pin)), (("xspim", "P2_DQS0"), quote!(crate::xspi::DQS0Pin)), (("xspim", "P2_DQS1"), quote!(crate::xspi::DQS1Pin)), - (("xspim", "P2_NCS1"), quote!(crate::xspi::NCS1Pin)), - (("xspim", "P2_NCS2"), quote!(crate::xspi::NCS2Pin)), + (("xspim", "P2_NCS1"), quote!(crate::xspi::NCSPin)), + (("xspim", "P2_NCS2"), quote!(crate::xspi::NCSPin)), (("xspim", "P2_CLK"), quote!(crate::xspi::CLKPin)), (("xspim", "P2_NCLK"), quote!(crate::xspi::NCLKPin)), (("hspi", "IO0"), quote!(crate::hspi::D0Pin)), @@ -1274,6 +1274,18 @@ fn main() { } } + // XSPI NCS pin to CSSEL mapping + if pin.signal.ends_with("NCS1") { + g.extend(quote! { + sel_trait_impl!(crate::xspi::NCSEither, #peri, #pin_name, 0); + }) + } + if pin.signal.ends_with("NCS2") { + g.extend(quote! { + sel_trait_impl!(crate::xspi::NCSEither, #peri, #pin_name, 1); + }) + } + g.extend(quote! { pin_trait_impl!(#tr, #peri, #pin_name, #af); }) diff --git a/embassy-stm32/src/macros.rs b/embassy-stm32/src/macros.rs index 2c181a254..7526bb180 100644 --- a/embassy-stm32/src/macros.rs +++ b/embassy-stm32/src/macros.rs @@ -60,6 +60,17 @@ macro_rules! pin_trait_impl { }; } +#[allow(unused_macros)] +macro_rules! sel_trait_impl { + (crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, $pin:ident, $sel:expr) => { + impl crate::$mod::$trait for crate::peripherals::$pin { + fn sel(&self) -> u8 { + $sel + } + } + }; +} + // ==================== macro_rules! dma_trait { diff --git a/embassy-stm32/src/xspi/mod.rs b/embassy-stm32/src/xspi/mod.rs index c315e2320..bc3007fe8 100644 --- a/embassy-stm32/src/xspi/mod.rs +++ b/embassy-stm32/src/xspi/mod.rs @@ -175,8 +175,12 @@ pub struct Xspi<'d, T: Instance, M: PeriMode> { d13: Option>, d14: Option>, d15: Option>, - ncs1: Option>, - ncs2: Option>, + ncs: Option>, + // TODO: allow switching between multiple chips + ncs_alt: Option>, + // false if ncs == NCS1, true if ncs == NCS2 + // (ncs_alt will be the opposite to ncs). + _cssel_swap: bool, dqs0: Option>, dqs1: Option>, dma: Option>, @@ -269,8 +273,9 @@ impl<'d, T: Instance, M: PeriMode> Xspi<'d, T, M> { d14: Option>, d15: Option>, clk: Option>, - ncs1: Option>, - ncs2: Option>, + ncs_cssel: u8, + ncs: Option>, + ncs_alt: Option>, dqs0: Option>, dqs1: Option>, dma: Option>, @@ -341,11 +346,9 @@ impl<'d, T: Instance, M: PeriMode> Xspi<'d, T, M> { T::REGS.cr().modify(|w| { w.set_dmm(dual_quad); - // TODO: at the moment only ncs1 seems to get passed in? - // Only one must be selected - assert!(!(ncs1.is_some() && ncs2.is_some())); - assert!(!(ncs1.is_none() && ncs2.is_none())); - w.set_cssel(if ncs1.is_some() { Cssel::B_0X0 } else { Cssel::B_0X1 }); + assert!(ncs_alt.is_none(), "ncs_alt TODO"); + let cssel = if ncs_cssel == 0 { Cssel::B_0X0 } else { Cssel::B_0X1 }; + w.set_cssel(cssel); }); T::REGS.tcr().modify(|w| { @@ -384,8 +387,9 @@ impl<'d, T: Instance, M: PeriMode> Xspi<'d, T, M> { d13, d14, d15, - ncs1, - ncs2, + ncs, + ncs_alt, + _cssel_swap: ncs_cssel == 1, dqs0, dqs1, dma, @@ -659,7 +663,7 @@ impl<'d, T: Instance> Xspi<'d, T, Blocking> { clk: Peri<'d, impl CLKPin>, d0: Peri<'d, impl D0Pin>, d1: Peri<'d, impl D1Pin>, - ncs: Peri<'d, impl NCS1Pin>, + ncs: Peri<'d, impl NCSEither>, config: Config, ) -> Self { Self::new_inner( @@ -681,6 +685,7 @@ impl<'d, T: Instance> Xspi<'d, T, Blocking> { None, None, new_pin!(clk, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + ncs.sel(), new_pin!(ncs, AfType::output(OutputType::OpenDrain, Speed::VeryHigh)), None, None, @@ -698,7 +703,7 @@ impl<'d, T: Instance> Xspi<'d, T, Blocking> { clk: Peri<'d, impl CLKPin>, d0: Peri<'d, impl D0Pin>, d1: Peri<'d, impl D1Pin>, - ncs: Peri<'d, impl NCS1Pin>, + ncs: Peri<'d, impl NCSEither>, config: Config, ) -> Self { Self::new_inner( @@ -720,6 +725,7 @@ impl<'d, T: Instance> Xspi<'d, T, Blocking> { None, None, new_pin!(clk, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + ncs.sel(), new_pin!( ncs, AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up) @@ -742,7 +748,7 @@ impl<'d, T: Instance> Xspi<'d, T, Blocking> { d1: Peri<'d, impl D1Pin>, d2: Peri<'d, impl D2Pin>, d3: Peri<'d, impl D3Pin>, - ncs: Peri<'d, impl NCS1Pin>, + ncs: Peri<'d, impl NCSEither>, config: Config, ) -> Self { Self::new_inner( @@ -764,6 +770,7 @@ impl<'d, T: Instance> Xspi<'d, T, Blocking> { None, None, new_pin!(clk, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + ncs.sel(), new_pin!( ncs, AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up) @@ -790,7 +797,7 @@ impl<'d, T: Instance> Xspi<'d, T, Blocking> { d5: Peri<'d, impl D5Pin>, d6: Peri<'d, impl D6Pin>, d7: Peri<'d, impl D7Pin>, - ncs: Peri<'d, impl NCS1Pin>, + ncs: Peri<'d, impl NCSEither>, config: Config, ) -> Self { Self::new_inner( @@ -812,6 +819,7 @@ impl<'d, T: Instance> Xspi<'d, T, Blocking> { None, None, new_pin!(clk, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + ncs.sel(), new_pin!( ncs, AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up) @@ -838,7 +846,7 @@ impl<'d, T: Instance> Xspi<'d, T, Blocking> { d5: Peri<'d, impl D5Pin>, d6: Peri<'d, impl D6Pin>, d7: Peri<'d, impl D7Pin>, - ncs: Peri<'d, impl NCS1Pin>, + ncs: Peri<'d, impl NCSEither>, config: Config, ) -> Self { Self::new_inner( @@ -860,6 +868,7 @@ impl<'d, T: Instance> Xspi<'d, T, Blocking> { None, None, new_pin!(clk, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + ncs.sel(), new_pin!( ncs, AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up) @@ -882,7 +891,7 @@ impl<'d, T: Instance> Xspi<'d, T, Async> { clk: Peri<'d, impl CLKPin>, d0: Peri<'d, impl D0Pin>, d1: Peri<'d, impl D1Pin>, - ncs: Peri<'d, impl NCS1Pin>, + ncs: Peri<'d, impl NCSEither>, dma: Peri<'d, impl XDma>, config: Config, ) -> Self { @@ -905,6 +914,7 @@ impl<'d, T: Instance> Xspi<'d, T, Async> { None, None, new_pin!(clk, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + ncs.sel(), new_pin!(ncs, AfType::output(OutputType::PushPull, Speed::VeryHigh)), None, None, @@ -922,7 +932,7 @@ impl<'d, T: Instance> Xspi<'d, T, Async> { clk: Peri<'d, impl CLKPin>, d0: Peri<'d, impl D0Pin>, d1: Peri<'d, impl D1Pin>, - ncs: Peri<'d, impl NCS1Pin>, + ncs: Peri<'d, impl NCSEither>, dma: Peri<'d, impl XDma>, config: Config, ) -> Self { @@ -945,6 +955,7 @@ impl<'d, T: Instance> Xspi<'d, T, Async> { None, None, new_pin!(clk, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + ncs.sel(), new_pin!( ncs, AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up) @@ -967,7 +978,7 @@ impl<'d, T: Instance> Xspi<'d, T, Async> { d1: Peri<'d, impl D1Pin>, d2: Peri<'d, impl D2Pin>, d3: Peri<'d, impl D3Pin>, - ncs: Peri<'d, impl NCS1Pin>, + ncs: Peri<'d, impl NCSEither>, dma: Peri<'d, impl XDma>, config: Config, ) -> Self { @@ -990,6 +1001,7 @@ impl<'d, T: Instance> Xspi<'d, T, Async> { None, None, new_pin!(clk, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + ncs.sel(), new_pin!( ncs, AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up) @@ -1016,7 +1028,7 @@ impl<'d, T: Instance> Xspi<'d, T, Async> { d5: Peri<'d, impl D5Pin>, d6: Peri<'d, impl D6Pin>, d7: Peri<'d, impl D7Pin>, - ncs: Peri<'d, impl NCS1Pin>, + ncs: Peri<'d, impl NCSEither>, dma: Peri<'d, impl XDma>, config: Config, ) -> Self { @@ -1039,6 +1051,7 @@ impl<'d, T: Instance> Xspi<'d, T, Async> { None, None, new_pin!(clk, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + ncs.sel(), new_pin!( ncs, AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up) @@ -1065,7 +1078,7 @@ impl<'d, T: Instance> Xspi<'d, T, Async> { d5: Peri<'d, impl D5Pin>, d6: Peri<'d, impl D6Pin>, d7: Peri<'d, impl D7Pin>, - ncs: Peri<'d, impl NCS1Pin>, + ncs: Peri<'d, impl NCSEither>, dma: Peri<'d, impl XDma>, config: Config, ) -> Self { @@ -1088,6 +1101,7 @@ impl<'d, T: Instance> Xspi<'d, T, Async> { None, None, new_pin!(clk, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + ncs.sel(), new_pin!( ncs, AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up) @@ -1262,8 +1276,8 @@ impl<'d, T: Instance, M: PeriMode> Drop for Xspi<'d, T, M> { self.d13.as_ref().map(|x| x.set_as_disconnected()); self.d14.as_ref().map(|x| x.set_as_disconnected()); self.d15.as_ref().map(|x| x.set_as_disconnected()); - self.ncs1.as_ref().map(|x| x.set_as_disconnected()); - self.ncs2.as_ref().map(|x| x.set_as_disconnected()); + self.ncs.as_ref().map(|x| x.set_as_disconnected()); + self.ncs_alt.as_ref().map(|x| x.set_as_disconnected()); self.dqs0.as_ref().map(|x| x.set_as_disconnected()); self.dqs1.as_ref().map(|x| x.set_as_disconnected()); @@ -1320,12 +1334,17 @@ pin_trait!(D14Pin, Instance); pin_trait!(D15Pin, Instance); pin_trait!(DQS0Pin, Instance); pin_trait!(DQS1Pin, Instance); -pin_trait!(NCS1Pin, Instance); -pin_trait!(NCS2Pin, Instance); +pin_trait!(NCSPin, Instance); pin_trait!(CLKPin, Instance); pin_trait!(NCLKPin, Instance); dma_trait!(XDma, Instance); +/// Trait for either NCS1 or NCS2 pins +pub trait NCSEither: NCSPin { + /// Get the CSSEL for this NCS pin + fn sel(&self) -> u8; +} + // Hard-coded the xspi index, for SPIM #[cfg(xspim_v1)] impl SealedXspimInstance for peripherals::XSPI1 {