aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-10-03 01:55:27 +0000
committerGitHub <[email protected]>2023-10-03 01:55:27 +0000
commit6e901846df7ab0c3cede02974d6d3bec14410f83 (patch)
treef3044d065603a8d79db5088b7061d4133ce9d660
parent58280048e332fadd73dc8b48588b0112c61b8ff9 (diff)
parent923f1851ee02f697989fd25b6e93d22f30cb6b28 (diff)
Merge pull request #1995 from JuliDi/quadspi
[STM32] QUADSPI support bank 2
-rw-r--r--embassy-stm32/build.rs15
-rw-r--r--embassy-stm32/src/qspi/enums.rs16
-rw-r--r--embassy-stm32/src/qspi/mod.rs120
3 files changed, 123 insertions, 28 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index 76db0a762..ed5fa84d6 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -719,12 +719,17 @@ fn main() {
719 (("sdmmc", "D6"), quote!(crate::sdmmc::D6Pin)), 719 (("sdmmc", "D6"), quote!(crate::sdmmc::D6Pin)),
720 (("sdmmc", "D6"), quote!(crate::sdmmc::D7Pin)), 720 (("sdmmc", "D6"), quote!(crate::sdmmc::D7Pin)),
721 (("sdmmc", "D8"), quote!(crate::sdmmc::D8Pin)), 721 (("sdmmc", "D8"), quote!(crate::sdmmc::D8Pin)),
722 (("quadspi", "BK1_IO0"), quote!(crate::qspi::D0Pin)), 722 (("quadspi", "BK1_IO0"), quote!(crate::qspi::BK1D0Pin)),
723 (("quadspi", "BK1_IO1"), quote!(crate::qspi::D1Pin)), 723 (("quadspi", "BK1_IO1"), quote!(crate::qspi::BK1D1Pin)),
724 (("quadspi", "BK1_IO2"), quote!(crate::qspi::D2Pin)), 724 (("quadspi", "BK1_IO2"), quote!(crate::qspi::BK1D2Pin)),
725 (("quadspi", "BK1_IO3"), quote!(crate::qspi::D3Pin)), 725 (("quadspi", "BK1_IO3"), quote!(crate::qspi::BK1D3Pin)),
726 (("quadspi", "BK1_NCS"), quote!(crate::qspi::BK1NSSPin)),
727 (("quadspi", "BK2_IO0"), quote!(crate::qspi::BK2D0Pin)),
728 (("quadspi", "BK2_IO1"), quote!(crate::qspi::BK2D1Pin)),
729 (("quadspi", "BK2_IO2"), quote!(crate::qspi::BK2D2Pin)),
730 (("quadspi", "BK2_IO3"), quote!(crate::qspi::BK2D3Pin)),
731 (("quadspi", "BK2_NCS"), quote!(crate::qspi::BK2NSSPin)),
726 (("quadspi", "CLK"), quote!(crate::qspi::SckPin)), 732 (("quadspi", "CLK"), quote!(crate::qspi::SckPin)),
727 (("quadspi", "BK1_NCS"), quote!(crate::qspi::NSSPin)),
728 ].into(); 733 ].into();
729 734
730 for p in METADATA.peripherals { 735 for p in METADATA.peripherals {
diff --git a/embassy-stm32/src/qspi/enums.rs b/embassy-stm32/src/qspi/enums.rs
index 2dbe2b061..0412d991a 100644
--- a/embassy-stm32/src/qspi/enums.rs
+++ b/embassy-stm32/src/qspi/enums.rs
@@ -38,6 +38,22 @@ impl Into<u8> for QspiWidth {
38 } 38 }
39} 39}
40 40
41#[allow(dead_code)]
42#[derive(Copy, Clone)]
43pub enum FlashSelection {
44 Flash1,
45 Flash2,
46}
47
48impl Into<bool> for FlashSelection {
49 fn into(self) -> bool {
50 match self {
51 FlashSelection::Flash1 => false,
52 FlashSelection::Flash2 => true,
53 }
54 }
55}
56
41#[derive(Copy, Clone)] 57#[derive(Copy, Clone)]
42pub enum MemorySize { 58pub enum MemorySize {
43 _1KiB, 59 _1KiB,
diff --git a/embassy-stm32/src/qspi/mod.rs b/embassy-stm32/src/qspi/mod.rs
index 32382fb28..8fb7df646 100644
--- a/embassy-stm32/src/qspi/mod.rs
+++ b/embassy-stm32/src/qspi/mod.rs
@@ -7,7 +7,7 @@ use enums::*;
7 7
8use crate::dma::Transfer; 8use crate::dma::Transfer;
9use crate::gpio::sealed::AFType; 9use crate::gpio::sealed::AFType;
10use crate::gpio::AnyPin; 10use crate::gpio::{AnyPin, Pull};
11use crate::pac::quadspi::Quadspi as Regs; 11use crate::pac::quadspi::Quadspi as Regs;
12use crate::rcc::RccPeripheral; 12use crate::rcc::RccPeripheral;
13use crate::{peripherals, Peripheral}; 13use crate::{peripherals, Peripheral};
@@ -83,30 +83,30 @@ pub struct Qspi<'d, T: Instance, Dma> {
83} 83}
84 84
85impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { 85impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
86 pub fn new( 86 pub fn new_bk1(
87 peri: impl Peripheral<P = T> + 'd, 87 peri: impl Peripheral<P = T> + 'd,
88 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 88 d0: impl Peripheral<P = impl BK1D0Pin<T>> + 'd,
89 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 89 d1: impl Peripheral<P = impl BK1D1Pin<T>> + 'd,
90 d2: impl Peripheral<P = impl D2Pin<T>> + 'd, 90 d2: impl Peripheral<P = impl BK1D2Pin<T>> + 'd,
91 d3: impl Peripheral<P = impl D3Pin<T>> + 'd, 91 d3: impl Peripheral<P = impl BK1D3Pin<T>> + 'd,
92 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 92 sck: impl Peripheral<P = impl SckPin<T>> + 'd,
93 nss: impl Peripheral<P = impl NSSPin<T>> + 'd, 93 nss: impl Peripheral<P = impl BK1NSSPin<T>> + 'd,
94 dma: impl Peripheral<P = Dma> + 'd, 94 dma: impl Peripheral<P = Dma> + 'd,
95 config: Config, 95 config: Config,
96 ) -> Self { 96 ) -> Self {
97 into_ref!(peri, d0, d1, d2, d3, sck, nss); 97 into_ref!(peri, d0, d1, d2, d3, sck, nss);
98 98
99 sck.set_as_af(sck.af_num(), AFType::OutputPushPull); 99 sck.set_as_af_pull(sck.af_num(), AFType::OutputPushPull, Pull::None);
100 sck.set_speed(crate::gpio::Speed::VeryHigh); 100 sck.set_speed(crate::gpio::Speed::VeryHigh);
101 nss.set_as_af(nss.af_num(), AFType::OutputPushPull); 101 nss.set_as_af_pull(nss.af_num(), AFType::OutputPushPull, Pull::Up);
102 nss.set_speed(crate::gpio::Speed::VeryHigh); 102 nss.set_speed(crate::gpio::Speed::VeryHigh);
103 d0.set_as_af(d0.af_num(), AFType::OutputPushPull); 103 d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::None);
104 d0.set_speed(crate::gpio::Speed::VeryHigh); 104 d0.set_speed(crate::gpio::Speed::VeryHigh);
105 d1.set_as_af(d1.af_num(), AFType::OutputPushPull); 105 d1.set_as_af_pull(d1.af_num(), AFType::OutputPushPull, Pull::None);
106 d1.set_speed(crate::gpio::Speed::VeryHigh); 106 d1.set_speed(crate::gpio::Speed::VeryHigh);
107 d2.set_as_af(d2.af_num(), AFType::OutputPushPull); 107 d2.set_as_af_pull(d2.af_num(), AFType::OutputPushPull, Pull::None);
108 d2.set_speed(crate::gpio::Speed::VeryHigh); 108 d2.set_speed(crate::gpio::Speed::VeryHigh);
109 d3.set_as_af(d3.af_num(), AFType::OutputPushPull); 109 d3.set_as_af_pull(d3.af_num(), AFType::OutputPushPull, Pull::None);
110 d3.set_speed(crate::gpio::Speed::VeryHigh); 110 d3.set_speed(crate::gpio::Speed::VeryHigh);
111 111
112 Self::new_inner( 112 Self::new_inner(
@@ -119,6 +119,47 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
119 Some(nss.map_into()), 119 Some(nss.map_into()),
120 dma, 120 dma,
121 config, 121 config,
122 FlashSelection::Flash2,
123 )
124 }
125
126 pub fn new_bk2(
127 peri: impl Peripheral<P = T> + 'd,
128 d0: impl Peripheral<P = impl BK2D0Pin<T>> + 'd,
129 d1: impl Peripheral<P = impl BK2D1Pin<T>> + 'd,
130 d2: impl Peripheral<P = impl BK2D2Pin<T>> + 'd,
131 d3: impl Peripheral<P = impl BK2D3Pin<T>> + 'd,
132 sck: impl Peripheral<P = impl SckPin<T>> + 'd,
133 nss: impl Peripheral<P = impl BK2NSSPin<T>> + 'd,
134 dma: impl Peripheral<P = Dma> + 'd,
135 config: Config,
136 ) -> Self {
137 into_ref!(peri, d0, d1, d2, d3, sck, nss);
138
139 sck.set_as_af_pull(sck.af_num(), AFType::OutputPushPull, Pull::None);
140 sck.set_speed(crate::gpio::Speed::VeryHigh);
141 nss.set_as_af_pull(nss.af_num(), AFType::OutputPushPull, Pull::Up);
142 nss.set_speed(crate::gpio::Speed::VeryHigh);
143 d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::None);
144 d0.set_speed(crate::gpio::Speed::VeryHigh);
145 d1.set_as_af_pull(d1.af_num(), AFType::OutputPushPull, Pull::None);
146 d1.set_speed(crate::gpio::Speed::VeryHigh);
147 d2.set_as_af_pull(d2.af_num(), AFType::OutputPushPull, Pull::None);
148 d2.set_speed(crate::gpio::Speed::VeryHigh);
149 d3.set_as_af_pull(d3.af_num(), AFType::OutputPushPull, Pull::None);
150 d3.set_speed(crate::gpio::Speed::VeryHigh);
151
152 Self::new_inner(
153 peri,
154 Some(d0.map_into()),
155 Some(d1.map_into()),
156 Some(d2.map_into()),
157 Some(d3.map_into()),
158 Some(sck.map_into()),
159 Some(nss.map_into()),
160 dma,
161 config,
162 FlashSelection::Flash2,
122 ) 163 )
123 } 164 }
124 165
@@ -132,22 +173,40 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
132 nss: Option<PeripheralRef<'d, AnyPin>>, 173 nss: Option<PeripheralRef<'d, AnyPin>>,
133 dma: impl Peripheral<P = Dma> + 'd, 174 dma: impl Peripheral<P = Dma> + 'd,
134 config: Config, 175 config: Config,
176 fsel: FlashSelection,
135 ) -> Self { 177 ) -> Self {
136 into_ref!(peri, dma); 178 into_ref!(peri, dma);
137 179
138 T::enable(); 180 T::enable();
139 T::REGS.cr().write(|w| w.set_fthres(config.fifo_threshold.into())); 181 T::reset();
140 182
141 while T::REGS.sr().read().busy() {} 183 while T::REGS.sr().read().busy() {}
142 184
143 T::REGS.cr().write(|w| { 185 #[cfg(stm32h7)]
144 w.set_prescaler(config.prescaler); 186 {
187 use stm32_metapac::quadspi::regs::Cr;
188 // Apply precautionary steps according to the errata...
189 T::REGS.cr().write_value(Cr(0));
190 while T::REGS.sr().read().busy() {}
191 T::REGS.cr().write_value(Cr(0xFF000001));
192 T::REGS.ccr().write(|w| w.set_frcm(true));
193 T::REGS.ccr().write(|w| w.set_frcm(true));
194 T::REGS.cr().write_value(Cr(0));
195 while T::REGS.sr().read().busy() {}
196 }
197
198 T::REGS.cr().modify(|w| {
145 w.set_en(true); 199 w.set_en(true);
200 //w.set_tcen(false);
201 w.set_sshift(false);
202 w.set_fthres(config.fifo_threshold.into());
203 w.set_prescaler(config.prescaler);
204 w.set_fsel(fsel.into());
146 }); 205 });
147 T::REGS.dcr().write(|w| { 206 T::REGS.dcr().modify(|w| {
148 w.set_fsize(config.memory_size.into()); 207 w.set_fsize(config.memory_size.into());
149 w.set_csht(config.cs_high_time.into()); 208 w.set_csht(config.cs_high_time.into());
150 w.set_ckmode(false); 209 w.set_ckmode(true);
151 }); 210 });
152 211
153 Self { 212 Self {
@@ -164,6 +223,7 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
164 } 223 }
165 224
166 pub fn command(&mut self, transaction: TransferConfig) { 225 pub fn command(&mut self, transaction: TransferConfig) {
226 #[cfg(not(stm32h7))]
167 T::REGS.cr().modify(|v| v.set_dmaen(false)); 227 T::REGS.cr().modify(|v| v.set_dmaen(false));
168 self.setup_transaction(QspiMode::IndirectWrite, &transaction); 228 self.setup_transaction(QspiMode::IndirectWrite, &transaction);
169 229
@@ -172,6 +232,7 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
172 } 232 }
173 233
174 pub fn blocking_read(&mut self, buf: &mut [u8], transaction: TransferConfig) { 234 pub fn blocking_read(&mut self, buf: &mut [u8], transaction: TransferConfig) {
235 #[cfg(not(stm32h7))]
175 T::REGS.cr().modify(|v| v.set_dmaen(false)); 236 T::REGS.cr().modify(|v| v.set_dmaen(false));
176 self.setup_transaction(QspiMode::IndirectWrite, &transaction); 237 self.setup_transaction(QspiMode::IndirectWrite, &transaction);
177 238
@@ -195,7 +256,10 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
195 } 256 }
196 257
197 pub fn blocking_write(&mut self, buf: &[u8], transaction: TransferConfig) { 258 pub fn blocking_write(&mut self, buf: &[u8], transaction: TransferConfig) {
259 // STM32H7 does not have dmaen
260 #[cfg(not(stm32h7))]
198 T::REGS.cr().modify(|v| v.set_dmaen(false)); 261 T::REGS.cr().modify(|v| v.set_dmaen(false));
262
199 self.setup_transaction(QspiMode::IndirectWrite, &transaction); 263 self.setup_transaction(QspiMode::IndirectWrite, &transaction);
200 264
201 if let Some(len) = transaction.data_len { 265 if let Some(len) = transaction.data_len {
@@ -238,6 +302,8 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
238 ) 302 )
239 }; 303 };
240 304
305 // STM32H7 does not have dmaen
306 #[cfg(not(stm32h7))]
241 T::REGS.cr().modify(|v| v.set_dmaen(true)); 307 T::REGS.cr().modify(|v| v.set_dmaen(true));
242 308
243 transfer.blocking_wait(); 309 transfer.blocking_wait();
@@ -264,6 +330,8 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
264 ) 330 )
265 }; 331 };
266 332
333 // STM32H7 does not have dmaen
334 #[cfg(not(stm32h7))]
267 T::REGS.cr().modify(|v| v.set_dmaen(true)); 335 T::REGS.cr().modify(|v| v.set_dmaen(true));
268 336
269 transfer.blocking_wait(); 337 transfer.blocking_wait();
@@ -313,11 +381,17 @@ pub(crate) mod sealed {
313pub trait Instance: Peripheral<P = Self> + sealed::Instance + RccPeripheral {} 381pub trait Instance: Peripheral<P = Self> + sealed::Instance + RccPeripheral {}
314 382
315pin_trait!(SckPin, Instance); 383pin_trait!(SckPin, Instance);
316pin_trait!(D0Pin, Instance); 384pin_trait!(BK1D0Pin, Instance);
317pin_trait!(D1Pin, Instance); 385pin_trait!(BK1D1Pin, Instance);
318pin_trait!(D2Pin, Instance); 386pin_trait!(BK1D2Pin, Instance);
319pin_trait!(D3Pin, Instance); 387pin_trait!(BK1D3Pin, Instance);
320pin_trait!(NSSPin, Instance); 388pin_trait!(BK1NSSPin, Instance);
389
390pin_trait!(BK2D0Pin, Instance);
391pin_trait!(BK2D1Pin, Instance);
392pin_trait!(BK2D2Pin, Instance);
393pin_trait!(BK2D3Pin, Instance);
394pin_trait!(BK2NSSPin, Instance);
321 395
322dma_trait!(QuadDma, Instance); 396dma_trait!(QuadDma, Instance);
323 397