aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32
diff options
context:
space:
mode:
authorHaoboGu <[email protected]>2024-10-14 04:32:22 +0800
committerGitHub <[email protected]>2024-10-13 22:32:22 +0200
commit0222faa8a1f3afbc60eb455989fc581ec9adfac1 (patch)
tree2adc52d9b460fbad7fb4d06c512a3b79032e107b /embassy-stm32
parent2f6273bb5df1ce2aacc0470b4f3194db6687e0d1 (diff)
Add octospim support for octospi (#3102)
* feat: add octospim to ospi Signed-off-by: Haobo Gu <[email protected]> * feat: make octospim behind feature gate Signed-off-by: Haobo Gu <[email protected]> * refactor: fix fmt issue Signed-off-by: Haobo Gu <[email protected]> * refactor: fix ci failure Signed-off-by: Haobo Gu <[email protected]> * feat: add octospim reg writing code Signed-off-by: Haobo Gu <[email protected]> * feat(octospi): enable rcc for octospim at the initialization Signed-off-by: Haobo Gu <[email protected]> * fix: add octospim feature gate Signed-off-by: Haobo Gu <[email protected]> * fix: fix cfg flag Signed-off-by: Haobo Gu <[email protected]> * fix: fix rcc register on stm32l4 and stm32u5 Signed-off-by: Haobo Gu <[email protected]> * feat(ospi): support OCTOSPI2 in build.rs Signed-off-by: Haobo Gu <[email protected]> * feat(ospi): add OCTOSPI2 pin impls Signed-off-by: HaoboGu <[email protected]> * feat(ospi): support both ospi instances in stm32 OCTOSPIM Signed-off-by: Haobo Gu <[email protected]> --------- Signed-off-by: Haobo Gu <[email protected]> Signed-off-by: HaoboGu <[email protected]>
Diffstat (limited to 'embassy-stm32')
-rw-r--r--embassy-stm32/build.rs33
-rw-r--r--embassy-stm32/src/ospi/mod.rs118
2 files changed, 151 insertions, 0 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index 28c619c6b..966dce121 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -1054,6 +1054,30 @@ fn main() {
1054 (("octospi", "NCS"), quote!(crate::ospi::NSSPin)), 1054 (("octospi", "NCS"), quote!(crate::ospi::NSSPin)),
1055 (("octospi", "CLK"), quote!(crate::ospi::SckPin)), 1055 (("octospi", "CLK"), quote!(crate::ospi::SckPin)),
1056 (("octospi", "NCLK"), quote!(crate::ospi::NckPin)), 1056 (("octospi", "NCLK"), quote!(crate::ospi::NckPin)),
1057 (("octospim", "P1_IO0"), quote!(crate::ospi::D0Pin)),
1058 (("octospim", "P1_IO1"), quote!(crate::ospi::D1Pin)),
1059 (("octospim", "P1_IO2"), quote!(crate::ospi::D2Pin)),
1060 (("octospim", "P1_IO3"), quote!(crate::ospi::D3Pin)),
1061 (("octospim", "P1_IO4"), quote!(crate::ospi::D4Pin)),
1062 (("octospim", "P1_IO5"), quote!(crate::ospi::D5Pin)),
1063 (("octospim", "P1_IO6"), quote!(crate::ospi::D6Pin)),
1064 (("octospim", "P1_IO7"), quote!(crate::ospi::D7Pin)),
1065 (("octospim", "P1_DQS"), quote!(crate::ospi::DQSPin)),
1066 (("octospim", "P1_NCS"), quote!(crate::ospi::NSSPin)),
1067 (("octospim", "P1_CLK"), quote!(crate::ospi::SckPin)),
1068 (("octospim", "P1_NCLK"), quote!(crate::ospi::NckPin)),
1069 (("octospim", "P2_IO0"), quote!(crate::ospi::D0Pin)),
1070 (("octospim", "P2_IO1"), quote!(crate::ospi::D1Pin)),
1071 (("octospim", "P2_IO2"), quote!(crate::ospi::D2Pin)),
1072 (("octospim", "P2_IO3"), quote!(crate::ospi::D3Pin)),
1073 (("octospim", "P2_IO4"), quote!(crate::ospi::D4Pin)),
1074 (("octospim", "P2_IO5"), quote!(crate::ospi::D5Pin)),
1075 (("octospim", "P2_IO6"), quote!(crate::ospi::D6Pin)),
1076 (("octospim", "P2_IO7"), quote!(crate::ospi::D7Pin)),
1077 (("octospim", "P2_DQS"), quote!(crate::ospi::DQSPin)),
1078 (("octospim", "P2_NCS"), quote!(crate::ospi::NSSPin)),
1079 (("octospim", "P2_CLK"), quote!(crate::ospi::SckPin)),
1080 (("octospim", "P2_NCLK"), quote!(crate::ospi::NckPin)),
1057 (("tsc", "G1_IO1"), quote!(crate::tsc::G1IO1Pin)), 1081 (("tsc", "G1_IO1"), quote!(crate::tsc::G1IO1Pin)),
1058 (("tsc", "G1_IO2"), quote!(crate::tsc::G1IO2Pin)), 1082 (("tsc", "G1_IO2"), quote!(crate::tsc::G1IO2Pin)),
1059 (("tsc", "G1_IO3"), quote!(crate::tsc::G1IO3Pin)), 1083 (("tsc", "G1_IO3"), quote!(crate::tsc::G1IO3Pin)),
@@ -1111,6 +1135,15 @@ fn main() {
1111 peri = format_ident!("{}", pin.signal.replace('_', "")); 1135 peri = format_ident!("{}", pin.signal.replace('_', ""));
1112 } 1136 }
1113 1137
1138 // OCTOSPIM is special
1139 if p.name == "OCTOSPIM" {
1140 peri = format_ident!("{}", "OCTOSPI1");
1141 g.extend(quote! {
1142 pin_trait_impl!(#tr, #peri, #pin_name, #af);
1143 });
1144 peri = format_ident!("{}", "OCTOSPI2");
1145 }
1146
1114 g.extend(quote! { 1147 g.extend(quote! {
1115 pin_trait_impl!(#tr, #peri, #pin_name, #af); 1148 pin_trait_impl!(#tr, #peri, #pin_name, #af);
1116 }) 1149 })
diff --git a/embassy-stm32/src/ospi/mod.rs b/embassy-stm32/src/ospi/mod.rs
index 289bfa672..48a1ea5e6 100644
--- a/embassy-stm32/src/ospi/mod.rs
+++ b/embassy-stm32/src/ospi/mod.rs
@@ -16,6 +16,8 @@ use crate::dma::{word, ChannelAndRequest};
16use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed}; 16use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed};
17use crate::mode::{Async, Blocking, Mode as PeriMode}; 17use crate::mode::{Async, Blocking, Mode as PeriMode};
18use crate::pac::octospi::{vals, Octospi as Regs}; 18use crate::pac::octospi::{vals, Octospi as Regs};
19#[cfg(octospim_v1)]
20use crate::pac::octospim::Octospim;
19use crate::rcc::{self, RccPeripheral}; 21use crate::rcc::{self, RccPeripheral};
20use crate::{peripherals, Peripheral}; 22use crate::{peripherals, Peripheral};
21 23
@@ -197,6 +199,83 @@ impl<'d, T: Instance, M: PeriMode> Ospi<'d, T, M> {
197 ) -> Self { 199 ) -> Self {
198 into_ref!(peri); 200 into_ref!(peri);
199 201
202 #[cfg(octospim_v1)]
203 {
204 // RCC for octospim should be enabled before writing register
205 #[cfg(stm32l4)]
206 crate::pac::RCC.ahb2smenr().modify(|w| w.set_octospimsmen(true));
207 #[cfg(stm32u5)]
208 crate::pac::RCC.ahb2enr1().modify(|w| w.set_octospimen(true));
209 #[cfg(not(any(stm32l4, stm32u5)))]
210 crate::pac::RCC.ahb3enr().modify(|w| w.set_iomngren(true));
211
212 // Disable OctoSPI peripheral first
213 T::REGS.cr().modify(|w| {
214 w.set_en(false);
215 });
216
217 // OctoSPI IO Manager has been enabled before
218 T::OCTOSPIM_REGS.cr().modify(|w| {
219 w.set_muxen(false);
220 w.set_req2ack_time(0xff);
221 });
222
223 // Clear config
224 T::OCTOSPIM_REGS.p1cr().modify(|w| {
225 w.set_clksrc(false);
226 w.set_dqssrc(false);
227 w.set_ncssrc(false);
228 w.set_clken(false);
229 w.set_dqsen(false);
230 w.set_ncsen(false);
231 w.set_iolsrc(0);
232 w.set_iohsrc(0);
233 });
234
235 T::OCTOSPIM_REGS.p1cr().modify(|w| {
236 let octospi_src = if T::OCTOSPI_IDX == 1 { false } else { true };
237 w.set_ncsen(true);
238 w.set_ncssrc(octospi_src);
239 w.set_clken(true);
240 w.set_clksrc(octospi_src);
241 if dqs.is_some() {
242 w.set_dqsen(true);
243 w.set_dqssrc(octospi_src);
244 }
245
246 // Set OCTOSPIM IOL and IOH according to the index of OCTOSPI instance
247 if T::OCTOSPI_IDX == 1 {
248 w.set_iolen(true);
249 w.set_iolsrc(0);
250 // Enable IOH in octo and dual quad mode
251 if let OspiWidth::OCTO = width {
252 w.set_iohen(true);
253 w.set_iohsrc(0b01);
254 } else if dual_quad {
255 w.set_iohen(true);
256 w.set_iohsrc(0b00);
257 } else {
258 w.set_iohen(false);
259 w.set_iohsrc(0b00);
260 }
261 } else {
262 w.set_iolen(true);
263 w.set_iolsrc(0b10);
264 // Enable IOH in octo and dual quad mode
265 if let OspiWidth::OCTO = width {
266 w.set_iohen(true);
267 w.set_iohsrc(0b11);
268 } else if dual_quad {
269 w.set_iohen(true);
270 w.set_iohsrc(0b10);
271 } else {
272 w.set_iohen(false);
273 w.set_iohsrc(0b00);
274 }
275 }
276 });
277 }
278
200 // System configuration 279 // System configuration
201 rcc::enable_and_reset::<T>(); 280 rcc::enable_and_reset::<T>();
202 while T::REGS.sr().read().busy() {} 281 while T::REGS.sr().read().busy() {}
@@ -1056,11 +1135,25 @@ fn finish_dma(regs: Regs) {
1056 }); 1135 });
1057} 1136}
1058 1137
1138#[cfg(octospim_v1)]
1139/// OctoSPI I/O manager instance trait.
1140pub(crate) trait SealedOctospimInstance {
1141 const OCTOSPIM_REGS: Octospim;
1142 const OCTOSPI_IDX: u8;
1143}
1144
1145/// OctoSPI instance trait.
1059pub(crate) trait SealedInstance { 1146pub(crate) trait SealedInstance {
1060 const REGS: Regs; 1147 const REGS: Regs;
1061} 1148}
1062 1149
1063/// OSPI instance trait. 1150/// OSPI instance trait.
1151#[cfg(octospim_v1)]
1152#[allow(private_bounds)]
1153pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral + SealedOctospimInstance {}
1154
1155/// OSPI instance trait.
1156#[cfg(not(octospim_v1))]
1064#[allow(private_bounds)] 1157#[allow(private_bounds)]
1065pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {} 1158pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {}
1066 1159
@@ -1078,6 +1171,31 @@ pin_trait!(DQSPin, Instance);
1078pin_trait!(NSSPin, Instance); 1171pin_trait!(NSSPin, Instance);
1079dma_trait!(OctoDma, Instance); 1172dma_trait!(OctoDma, Instance);
1080 1173
1174// Hard-coded the octospi index, for OCTOSPIM
1175#[cfg(octospim_v1)]
1176impl SealedOctospimInstance for peripherals::OCTOSPI1 {
1177 const OCTOSPIM_REGS: Octospim = crate::pac::OCTOSPIM;
1178 const OCTOSPI_IDX: u8 = 1;
1179}
1180
1181#[cfg(octospim_v1)]
1182impl SealedOctospimInstance for peripherals::OCTOSPI2 {
1183 const OCTOSPIM_REGS: Octospim = crate::pac::OCTOSPIM;
1184 const OCTOSPI_IDX: u8 = 2;
1185}
1186
1187#[cfg(octospim_v1)]
1188foreach_peripheral!(
1189 (octospi, $inst:ident) => {
1190 impl SealedInstance for peripherals::$inst {
1191 const REGS: Regs = crate::pac::$inst;
1192 }
1193
1194 impl Instance for peripherals::$inst {}
1195 };
1196);
1197
1198#[cfg(not(octospim_v1))]
1081foreach_peripheral!( 1199foreach_peripheral!(
1082 (octospi, $inst:ident) => { 1200 (octospi, $inst:ident) => {
1083 impl SealedInstance for peripherals::$inst { 1201 impl SealedInstance for peripherals::$inst {