diff options
| author | bofh <[email protected]> | 2023-07-30 18:01:34 +0200 |
|---|---|---|
| committer | bofh <[email protected]> | 2023-07-30 18:01:34 +0200 |
| commit | 6b1d802caa9ca5a2b6d33bf345c0599b990311fa (patch) | |
| tree | 4e630dad0de62a956a0dc88b79021d6e452005b1 | |
| parent | 8bed573b88b5b387c7e0183c006520b3b60a7c54 (diff) | |
Move frequency to SPI config
| -rw-r--r-- | embassy-stm32/src/spi/mod.rs | 66 |
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 { | |||
| 36 | pub struct Config { | 36 | pub 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 | ||
| 41 | impl Default for Config { | 42 | impl 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 | ||
| 673 | fn 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 | |||
| 656 | trait RegsExt { | 688 | trait 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; |
