diff options
| -rw-r--r-- | embassy-stm32/src/gpio.rs | 16 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/mod.rs | 34 |
2 files changed, 42 insertions, 8 deletions
diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs index 87519f51e..c047f84ae 100644 --- a/embassy-stm32/src/gpio.rs +++ b/embassy-stm32/src/gpio.rs | |||
| @@ -659,6 +659,16 @@ fn set_as_af(pin_port: u8, af_num: u8, af_type: AfType) { | |||
| 659 | } | 659 | } |
| 660 | 660 | ||
| 661 | #[inline(never)] | 661 | #[inline(never)] |
| 662 | #[cfg(gpio_v2)] | ||
| 663 | fn set_speed(pin_port: u8, speed: Speed) { | ||
| 664 | let pin = unsafe { AnyPin::steal(pin_port) }; | ||
| 665 | let r = pin.block(); | ||
| 666 | let n = pin._pin() as usize; | ||
| 667 | |||
| 668 | r.ospeedr().modify(|w| w.set_ospeedr(n, speed.to_ospeedr())); | ||
| 669 | } | ||
| 670 | |||
| 671 | #[inline(never)] | ||
| 662 | fn set_as_analog(pin_port: u8) { | 672 | fn set_as_analog(pin_port: u8) { |
| 663 | let pin = unsafe { AnyPin::steal(pin_port) }; | 673 | let pin = unsafe { AnyPin::steal(pin_port) }; |
| 664 | let r = pin.block(); | 674 | let r = pin.block(); |
| @@ -739,6 +749,12 @@ pub(crate) trait SealedPin { | |||
| 739 | } | 749 | } |
| 740 | 750 | ||
| 741 | #[inline] | 751 | #[inline] |
| 752 | #[cfg(gpio_v2)] | ||
| 753 | fn set_speed(&self, speed: Speed) { | ||
| 754 | set_speed(self.pin_port(), speed) | ||
| 755 | } | ||
| 756 | |||
| 757 | #[inline] | ||
| 742 | fn set_as_analog(&self) { | 758 | fn set_as_analog(&self) { |
| 743 | set_as_analog(self.pin_port()); | 759 | set_as_analog(self.pin_port()); |
| 744 | } | 760 | } |
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index a65b0cc64..bf8284233 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs | |||
| @@ -55,6 +55,9 @@ pub struct Config { | |||
| 55 | /// There are some ICs that require a pull-up on the MISO pin for some applications. | 55 | /// There are some ICs that require a pull-up on the MISO pin for some applications. |
| 56 | /// If you are unsure, you probably don't need this. | 56 | /// If you are unsure, you probably don't need this. |
| 57 | pub miso_pull: Pull, | 57 | pub miso_pull: Pull, |
| 58 | /// signal rise/fall speed (slew rate) - defaults to `Medium`. | ||
| 59 | /// Increase for high SPI speeds. Change to `Low` to reduce ringing. | ||
| 60 | pub rise_fall_speed: Speed, | ||
| 58 | } | 61 | } |
| 59 | 62 | ||
| 60 | impl Default for Config { | 63 | impl Default for Config { |
| @@ -64,6 +67,7 @@ impl Default for Config { | |||
| 64 | bit_order: BitOrder::MsbFirst, | 67 | bit_order: BitOrder::MsbFirst, |
| 65 | frequency: Hertz(1_000_000), | 68 | frequency: Hertz(1_000_000), |
| 66 | miso_pull: Pull::None, | 69 | miso_pull: Pull::None, |
| 70 | rise_fall_speed: Speed::VeryHigh, | ||
| 67 | } | 71 | } |
| 68 | } | 72 | } |
| 69 | } | 73 | } |
| @@ -92,14 +96,14 @@ impl Config { | |||
| 92 | 96 | ||
| 93 | #[cfg(gpio_v1)] | 97 | #[cfg(gpio_v1)] |
| 94 | fn sck_af(&self) -> AfType { | 98 | fn sck_af(&self) -> AfType { |
| 95 | AfType::output(OutputType::PushPull, Speed::VeryHigh) | 99 | AfType::output(OutputType::PushPull, self.rise_fall_speed) |
| 96 | } | 100 | } |
| 97 | 101 | ||
| 98 | #[cfg(gpio_v2)] | 102 | #[cfg(gpio_v2)] |
| 99 | fn sck_af(&self) -> AfType { | 103 | fn sck_af(&self) -> AfType { |
| 100 | AfType::output_pull( | 104 | AfType::output_pull( |
| 101 | OutputType::PushPull, | 105 | OutputType::PushPull, |
| 102 | Speed::VeryHigh, | 106 | self.rise_fall_speed, |
| 103 | match self.mode.polarity { | 107 | match self.mode.polarity { |
| 104 | Polarity::IdleLow => Pull::Down, | 108 | Polarity::IdleLow => Pull::Down, |
| 105 | Polarity::IdleHigh => Pull::Up, | 109 | Polarity::IdleHigh => Pull::Up, |
| @@ -118,6 +122,7 @@ pub struct Spi<'d, M: PeriMode> { | |||
| 118 | rx_dma: Option<ChannelAndRequest<'d>>, | 122 | rx_dma: Option<ChannelAndRequest<'d>>, |
| 119 | _phantom: PhantomData<M>, | 123 | _phantom: PhantomData<M>, |
| 120 | current_word_size: word_impl::Config, | 124 | current_word_size: word_impl::Config, |
| 125 | rise_fall_speed: Speed, | ||
| 121 | } | 126 | } |
| 122 | 127 | ||
| 123 | impl<'d, M: PeriMode> Spi<'d, M> { | 128 | impl<'d, M: PeriMode> Spi<'d, M> { |
| @@ -140,6 +145,7 @@ impl<'d, M: PeriMode> Spi<'d, M> { | |||
| 140 | rx_dma, | 145 | rx_dma, |
| 141 | current_word_size: <u8 as SealedWord>::CONFIG, | 146 | current_word_size: <u8 as SealedWord>::CONFIG, |
| 142 | _phantom: PhantomData, | 147 | _phantom: PhantomData, |
| 148 | rise_fall_speed: config.rise_fall_speed, | ||
| 143 | }; | 149 | }; |
| 144 | this.enable_and_init(config); | 150 | this.enable_and_init(config); |
| 145 | this | 151 | this |
| @@ -243,6 +249,17 @@ impl<'d, M: PeriMode> Spi<'d, M> { | |||
| 243 | 249 | ||
| 244 | let br = compute_baud_rate(self.kernel_clock, config.frequency); | 250 | let br = compute_baud_rate(self.kernel_clock, config.frequency); |
| 245 | 251 | ||
| 252 | #[cfg(gpio_v2)] | ||
| 253 | { | ||
| 254 | self.rise_fall_speed = config.rise_fall_speed; | ||
| 255 | if let Some(sck) = self.sck.as_ref() { | ||
| 256 | sck.set_speed(config.rise_fall_speed); | ||
| 257 | } | ||
| 258 | if let Some(mosi) = self.mosi.as_ref() { | ||
| 259 | mosi.set_speed(config.rise_fall_speed); | ||
| 260 | } | ||
| 261 | } | ||
| 262 | |||
| 246 | #[cfg(any(spi_v1, spi_f1, spi_v2))] | 263 | #[cfg(any(spi_v1, spi_f1, spi_v2))] |
| 247 | self.info.regs.cr1().modify(|w| { | 264 | self.info.regs.cr1().modify(|w| { |
| 248 | w.set_cpha(cpha); | 265 | w.set_cpha(cpha); |
| @@ -308,6 +325,7 @@ impl<'d, M: PeriMode> Spi<'d, M> { | |||
| 308 | bit_order, | 325 | bit_order, |
| 309 | frequency, | 326 | frequency, |
| 310 | miso_pull, | 327 | miso_pull, |
| 328 | rise_fall_speed: self.rise_fall_speed, | ||
| 311 | } | 329 | } |
| 312 | } | 330 | } |
| 313 | 331 | ||
| @@ -441,7 +459,7 @@ impl<'d> Spi<'d, Blocking> { | |||
| 441 | Self::new_inner( | 459 | Self::new_inner( |
| 442 | peri, | 460 | peri, |
| 443 | new_pin!(sck, config.sck_af()), | 461 | new_pin!(sck, config.sck_af()), |
| 444 | new_pin!(mosi, AfType::output(OutputType::PushPull, Speed::VeryHigh)), | 462 | new_pin!(mosi, AfType::output(OutputType::PushPull, config.rise_fall_speed)), |
| 445 | new_pin!(miso, AfType::input(config.miso_pull)), | 463 | new_pin!(miso, AfType::input(config.miso_pull)), |
| 446 | None, | 464 | None, |
| 447 | None, | 465 | None, |
| @@ -477,7 +495,7 @@ impl<'d> Spi<'d, Blocking> { | |||
| 477 | Self::new_inner( | 495 | Self::new_inner( |
| 478 | peri, | 496 | peri, |
| 479 | new_pin!(sck, config.sck_af()), | 497 | new_pin!(sck, config.sck_af()), |
| 480 | new_pin!(mosi, AfType::output(OutputType::PushPull, Speed::VeryHigh)), | 498 | new_pin!(mosi, AfType::output(OutputType::PushPull, config.rise_fall_speed)), |
| 481 | None, | 499 | None, |
| 482 | None, | 500 | None, |
| 483 | None, | 501 | None, |
| @@ -496,7 +514,7 @@ impl<'d> Spi<'d, Blocking> { | |||
| 496 | Self::new_inner( | 514 | Self::new_inner( |
| 497 | peri, | 515 | peri, |
| 498 | None, | 516 | None, |
| 499 | new_pin!(mosi, AfType::output(OutputType::PushPull, Speed::VeryHigh)), | 517 | new_pin!(mosi, AfType::output(OutputType::PushPull, config.rise_fall_speed)), |
| 500 | None, | 518 | None, |
| 501 | None, | 519 | None, |
| 502 | None, | 520 | None, |
| @@ -519,7 +537,7 @@ impl<'d> Spi<'d, Async> { | |||
| 519 | Self::new_inner( | 537 | Self::new_inner( |
| 520 | peri, | 538 | peri, |
| 521 | new_pin!(sck, config.sck_af()), | 539 | new_pin!(sck, config.sck_af()), |
| 522 | new_pin!(mosi, AfType::output(OutputType::PushPull, Speed::VeryHigh)), | 540 | new_pin!(mosi, AfType::output(OutputType::PushPull, config.rise_fall_speed)), |
| 523 | new_pin!(miso, AfType::input(config.miso_pull)), | 541 | new_pin!(miso, AfType::input(config.miso_pull)), |
| 524 | new_dma!(tx_dma), | 542 | new_dma!(tx_dma), |
| 525 | new_dma!(rx_dma), | 543 | new_dma!(rx_dma), |
| @@ -561,7 +579,7 @@ impl<'d> Spi<'d, Async> { | |||
| 561 | Self::new_inner( | 579 | Self::new_inner( |
| 562 | peri, | 580 | peri, |
| 563 | new_pin!(sck, config.sck_af()), | 581 | new_pin!(sck, config.sck_af()), |
| 564 | new_pin!(mosi, AfType::output(OutputType::PushPull, Speed::VeryHigh)), | 582 | new_pin!(mosi, AfType::output(OutputType::PushPull, config.rise_fall_speed)), |
| 565 | None, | 583 | None, |
| 566 | new_dma!(tx_dma), | 584 | new_dma!(tx_dma), |
| 567 | None, | 585 | None, |
| @@ -581,7 +599,7 @@ impl<'d> Spi<'d, Async> { | |||
| 581 | Self::new_inner( | 599 | Self::new_inner( |
| 582 | peri, | 600 | peri, |
| 583 | None, | 601 | None, |
| 584 | new_pin!(mosi, AfType::output(OutputType::PushPull, Speed::VeryHigh)), | 602 | new_pin!(mosi, AfType::output(OutputType::PushPull, config.rise_fall_speed)), |
| 585 | None, | 603 | None, |
| 586 | new_dma!(tx_dma), | 604 | new_dma!(tx_dma), |
| 587 | None, | 605 | None, |
