aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbofh <[email protected]>2023-07-30 18:01:34 +0200
committerbofh <[email protected]>2023-07-30 18:01:34 +0200
commit6b1d802caa9ca5a2b6d33bf345c0599b990311fa (patch)
tree4e630dad0de62a956a0dc88b79021d6e452005b1
parent8bed573b88b5b387c7e0183c006520b3b60a7c54 (diff)
Move frequency to SPI config
-rw-r--r--embassy-stm32/src/spi/mod.rs66
1 files changed, 49 insertions, 17 deletions
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index bdf3c85b0..bbc7c3b91 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -36,6 +36,7 @@ pub enum BitOrder {
36pub struct Config { 36pub struct Config {
37 pub mode: Mode, 37 pub mode: Mode,
38 pub bit_order: BitOrder, 38 pub bit_order: BitOrder,
39 pub frequency: Hertz,
39} 40}
40 41
41impl Default for Config { 42impl Default for Config {
@@ -43,6 +44,7 @@ impl Default for Config {
43 Self { 44 Self {
44 mode: MODE_0, 45 mode: MODE_0,
45 bit_order: BitOrder::MsbFirst, 46 bit_order: BitOrder::MsbFirst,
47 frequency: Hertz(1_000_000),
46 } 48 }
47 } 49 }
48} 50}
@@ -88,7 +90,6 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
88 miso: impl Peripheral<P = impl MisoPin<T>> + 'd, 90 miso: impl Peripheral<P = impl MisoPin<T>> + 'd,
89 txdma: impl Peripheral<P = Tx> + 'd, 91 txdma: impl Peripheral<P = Tx> + 'd,
90 rxdma: impl Peripheral<P = Rx> + 'd, 92 rxdma: impl Peripheral<P = Rx> + 'd,
91 freq: Hertz,
92 config: Config, 93 config: Config,
93 ) -> Self { 94 ) -> Self {
94 into_ref!(peri, sck, mosi, miso); 95 into_ref!(peri, sck, mosi, miso);
@@ -112,7 +113,6 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
112 Some(miso.map_into()), 113 Some(miso.map_into()),
113 txdma, 114 txdma,
114 rxdma, 115 rxdma,
115 freq,
116 config, 116 config,
117 ) 117 )
118 } 118 }
@@ -123,7 +123,6 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
123 miso: impl Peripheral<P = impl MisoPin<T>> + 'd, 123 miso: impl Peripheral<P = impl MisoPin<T>> + 'd,
124 txdma: impl Peripheral<P = Tx> + 'd, // TODO remove 124 txdma: impl Peripheral<P = Tx> + 'd, // TODO remove
125 rxdma: impl Peripheral<P = Rx> + 'd, 125 rxdma: impl Peripheral<P = Rx> + 'd,
126 freq: Hertz,
127 config: Config, 126 config: Config,
128 ) -> Self { 127 ) -> Self {
129 into_ref!(sck, miso); 128 into_ref!(sck, miso);
@@ -139,7 +138,6 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
139 Some(miso.map_into()), 138 Some(miso.map_into()),
140 txdma, 139 txdma,
141 rxdma, 140 rxdma,
142 freq,
143 config, 141 config,
144 ) 142 )
145 } 143 }
@@ -150,7 +148,6 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
150 mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, 148 mosi: impl Peripheral<P = impl MosiPin<T>> + 'd,
151 txdma: impl Peripheral<P = Tx> + 'd, 149 txdma: impl Peripheral<P = Tx> + 'd,
152 rxdma: impl Peripheral<P = Rx> + 'd, // TODO remove 150 rxdma: impl Peripheral<P = Rx> + 'd, // TODO remove
153 freq: Hertz,
154 config: Config, 151 config: Config,
155 ) -> Self { 152 ) -> Self {
156 into_ref!(sck, mosi); 153 into_ref!(sck, mosi);
@@ -166,7 +163,6 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
166 None, 163 None,
167 txdma, 164 txdma,
168 rxdma, 165 rxdma,
169 freq,
170 config, 166 config,
171 ) 167 )
172 } 168 }
@@ -176,14 +172,13 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
176 mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, 172 mosi: impl Peripheral<P = impl MosiPin<T>> + 'd,
177 txdma: impl Peripheral<P = Tx> + 'd, 173 txdma: impl Peripheral<P = Tx> + 'd,
178 rxdma: impl Peripheral<P = Rx> + 'd, // TODO: remove 174 rxdma: impl Peripheral<P = Rx> + 'd, // TODO: remove
179 freq: Hertz,
180 config: Config, 175 config: Config,
181 ) -> Self { 176 ) -> Self {
182 into_ref!(mosi); 177 into_ref!(mosi);
183 mosi.set_as_af_pull(mosi.af_num(), AFType::OutputPushPull, Pull::Down); 178 mosi.set_as_af_pull(mosi.af_num(), AFType::OutputPushPull, Pull::Down);
184 mosi.set_speed(crate::gpio::Speed::Medium); 179 mosi.set_speed(crate::gpio::Speed::Medium);
185 180
186 Self::new_inner(peri, None, Some(mosi.map_into()), None, txdma, rxdma, freq, config) 181 Self::new_inner(peri, None, Some(mosi.map_into()), None, txdma, rxdma, config)
187 } 182 }
188 183
189 #[cfg(stm32wl)] 184 #[cfg(stm32wl)]
@@ -201,7 +196,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
201 let mut config = Config::default(); 196 let mut config = Config::default();
202 config.mode = MODE_0; 197 config.mode = MODE_0;
203 config.bit_order = BitOrder::MsbFirst; 198 config.bit_order = BitOrder::MsbFirst;
204 Self::new_inner(peri, None, None, None, txdma, rxdma, freq, config) 199 config.frequency = freq;
200 Self::new_inner(peri, None, None, None, txdma, rxdma, config)
205 } 201 }
206 202
207 #[allow(dead_code)] 203 #[allow(dead_code)]
@@ -209,10 +205,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
209 peri: impl Peripheral<P = T> + 'd, 205 peri: impl Peripheral<P = T> + 'd,
210 txdma: impl Peripheral<P = Tx> + 'd, 206 txdma: impl Peripheral<P = Tx> + 'd,
211 rxdma: impl Peripheral<P = Rx> + 'd, 207 rxdma: impl Peripheral<P = Rx> + 'd,
212 freq: Hertz,
213 config: Config, 208 config: Config,
214 ) -> Self { 209 ) -> Self {
215 Self::new_inner(peri, None, None, None, txdma, rxdma, freq, config) 210 Self::new_inner(peri, None, None, None, txdma, rxdma, config)
216 } 211 }
217 212
218 fn new_inner( 213 fn new_inner(
@@ -222,12 +217,12 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
222 miso: Option<PeripheralRef<'d, AnyPin>>, 217 miso: Option<PeripheralRef<'d, AnyPin>>,
223 txdma: impl Peripheral<P = Tx> + 'd, 218 txdma: impl Peripheral<P = Tx> + 'd,
224 rxdma: impl Peripheral<P = Rx> + 'd, 219 rxdma: impl Peripheral<P = Rx> + 'd,
225 freq: Hertz,
226 config: Config, 220 config: Config,
227 ) -> Self { 221 ) -> Self {
228 into_ref!(peri, txdma, rxdma); 222 into_ref!(peri, txdma, rxdma);
229 223
230 let pclk = T::frequency(); 224 let pclk = T::frequency();
225 let freq = config.frequency;
231 let br = compute_baud_rate(pclk, freq.into()); 226 let br = compute_baud_rate(pclk, freq.into());
232 227
233 let cpha = config.raw_phase(); 228 let cpha = config.raw_phase();
@@ -334,19 +329,29 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
334 329
335 let lsbfirst = config.raw_byte_order(); 330 let lsbfirst = config.raw_byte_order();
336 331
332 let pclk = T::frequency();
333 let freq = config.frequency;
334 let br = compute_baud_rate(pclk, freq.into());
335
337 #[cfg(any(spi_v1, spi_f1, spi_v2))] 336 #[cfg(any(spi_v1, spi_f1, spi_v2))]
338 T::REGS.cr1().modify(|w| { 337 T::REGS.cr1().modify(|w| {
339 w.set_cpha(cpha); 338 w.set_cpha(cpha);
340 w.set_cpol(cpol); 339 w.set_cpol(cpol);
340 w.set_br(br);
341 w.set_lsbfirst(lsbfirst); 341 w.set_lsbfirst(lsbfirst);
342 }); 342 });
343 343
344 #[cfg(any(spi_v3, spi_v4, spi_v5))] 344 #[cfg(any(spi_v3, spi_v4, spi_v5))]
345 T::REGS.cfg2().modify(|w| { 345 {
346 w.set_cpha(cpha); 346 T::REGS.cfg2().modify(|w| {
347 w.set_cpol(cpol); 347 w.set_cpha(cpha);
348 w.set_lsbfirst(lsbfirst); 348 w.set_cpol(cpol);
349 }); 349 w.set_lsbfirst(lsbfirst);
350 });
351 T::REGS.cfg1().modify(|w| {
352 w.set_mbr(br);
353 });
354 }
350 } 355 }
351 356
352 pub fn get_current_config(&self) -> Config { 357 pub fn get_current_config(&self) -> Config {
@@ -354,6 +359,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
354 let cfg = T::REGS.cr1().read(); 359 let cfg = T::REGS.cr1().read();
355 #[cfg(any(spi_v3, spi_v4, spi_v5))] 360 #[cfg(any(spi_v3, spi_v4, spi_v5))]
356 let cfg = T::REGS.cfg2().read(); 361 let cfg = T::REGS.cfg2().read();
362 #[cfg(any(spi_v3, spi_v4, spi_v5))]
363 let cfg1 = T::REGS.cfg1().read();
364
357 let polarity = if cfg.cpol() == vals::Cpol::IDLELOW { 365 let polarity = if cfg.cpol() == vals::Cpol::IDLELOW {
358 Polarity::IdleLow 366 Polarity::IdleLow
359 } else { 367 } else {
@@ -371,9 +379,18 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
371 BitOrder::MsbFirst 379 BitOrder::MsbFirst
372 }; 380 };
373 381
382 #[cfg(any(spi_v1, spi_f1, spi_v2))]
383 let br = cfg.br();
384 #[cfg(any(spi_v3, spi_v4, spi_v5))]
385 let br = cfg1.mbr();
386
387 let pclk = T::frequency();
388 let frequency = compute_frequency(pclk, br);
389
374 Config { 390 Config {
375 mode: Mode { polarity, phase }, 391 mode: Mode { polarity, phase },
376 bit_order, 392 bit_order,
393 frequency,
377 } 394 }
378 } 395 }
379 396
@@ -653,6 +670,21 @@ fn compute_baud_rate(clocks: Hertz, freq: Hertz) -> Br {
653 Br::from_bits(val) 670 Br::from_bits(val)
654} 671}
655 672
673fn compute_frequency(clocks: Hertz, br: Br) -> Hertz {
674 let div: u16 = match br {
675 Br::DIV2 => 2,
676 Br::DIV4 => 4,
677 Br::DIV8 => 8,
678 Br::DIV16 => 16,
679 Br::DIV32 => 32,
680 Br::DIV64 => 64,
681 Br::DIV128 => 128,
682 Br::DIV256 => 256,
683 };
684
685 clocks / div
686}
687
656trait RegsExt { 688trait RegsExt {
657 fn tx_ptr<W>(&self) -> *mut W; 689 fn tx_ptr<W>(&self) -> *mut W;
658 fn rx_ptr<W>(&self) -> *mut W; 690 fn rx_ptr<W>(&self) -> *mut W;