diff options
| author | xoviat <[email protected]> | 2025-12-01 23:57:56 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-12-01 23:57:56 +0000 |
| commit | ac57c9f667adff094627aac07164da2f220c12ed (patch) | |
| tree | b720a2bddd2945de5fd09c80bbc28ab34a603736 | |
| parent | ec417c70565aac291403fb5f8e2a93c773fb25e7 (diff) | |
| parent | 24b675a23a3288c7f164de74540006249c00bbe9 (diff) | |
Merge pull request #4970 from beeelias/feature/spi-bidi
Feature SPI Bidirectional Mode
| -rw-r--r-- | embassy-stm32/CHANGELOG.md | 1 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/mod.rs | 48 |
2 files changed, 49 insertions, 0 deletions
diff --git a/embassy-stm32/CHANGELOG.md b/embassy-stm32/CHANGELOG.md index 70c46b025..851c22afd 100644 --- a/embassy-stm32/CHANGELOG.md +++ b/embassy-stm32/CHANGELOG.md | |||
| @@ -86,6 +86,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 86 | - fix: build script ensures EXTI2_TSC is listed as the IRQ of EXTI2 even if the PAC doesn't | 86 | - fix: build script ensures EXTI2_TSC is listed as the IRQ of EXTI2 even if the PAC doesn't |
| 87 | - feat: stm32/lcd: added implementation | 87 | - feat: stm32/lcd: added implementation |
| 88 | - change: add error messages to can timing calculations ([#4961](https://github.com/embassy-rs/embassy/pull/4961)) | 88 | - change: add error messages to can timing calculations ([#4961](https://github.com/embassy-rs/embassy/pull/4961)) |
| 89 | - feat: stm32/spi bidirectional mode | ||
| 89 | - fix: stm32/i2c v2: add stop flag on stop received | 90 | - fix: stm32/i2c v2: add stop flag on stop received |
| 90 | - fix: stm32l47*/stm32l48* adc analog pin setup | 91 | - fix: stm32l47*/stm32l48* adc analog pin setup |
| 91 | 92 | ||
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index abb80ed26..0048d5d21 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs | |||
| @@ -54,6 +54,16 @@ pub enum BitOrder { | |||
| 54 | MsbFirst, | 54 | MsbFirst, |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | /// SPI Direction. | ||
| 58 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | ||
| 59 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 60 | pub enum Direction { | ||
| 61 | /// Transmit | ||
| 62 | Transmit, | ||
| 63 | /// Receive | ||
| 64 | Receive, | ||
| 65 | } | ||
| 66 | |||
| 57 | /// SPI configuration. | 67 | /// SPI configuration. |
| 58 | #[non_exhaustive] | 68 | #[non_exhaustive] |
| 59 | #[derive(Copy, Clone)] | 69 | #[derive(Copy, Clone)] |
| @@ -348,6 +358,20 @@ impl<'d, M: PeriMode, CM: CommunicationMode> Spi<'d, M, CM> { | |||
| 348 | Ok(()) | 358 | Ok(()) |
| 349 | } | 359 | } |
| 350 | 360 | ||
| 361 | /// Set SPI direction | ||
| 362 | #[cfg(any(spi_v1, spi_v2, spi_v3))] | ||
| 363 | pub fn set_direction(&mut self, dir: Option<Direction>) { | ||
| 364 | let (bidimode, bidioe) = match dir { | ||
| 365 | Some(Direction::Transmit) => (vals::Bidimode::BIDIRECTIONAL, vals::Bidioe::TRANSMIT), | ||
| 366 | Some(Direction::Receive) => (vals::Bidimode::BIDIRECTIONAL, vals::Bidioe::RECEIVE), | ||
| 367 | None => (vals::Bidimode::UNIDIRECTIONAL, vals::Bidioe::TRANSMIT), | ||
| 368 | }; | ||
| 369 | self.info.regs.cr1().modify(|w| { | ||
| 370 | w.set_bidimode(bidimode); | ||
| 371 | w.set_bidioe(bidioe); | ||
| 372 | }); | ||
| 373 | } | ||
| 374 | |||
| 351 | /// Get current SPI configuration. | 375 | /// Get current SPI configuration. |
| 352 | pub fn get_current_config(&self) -> Config { | 376 | pub fn get_current_config(&self) -> Config { |
| 353 | #[cfg(any(spi_v1, spi_v2, spi_v3))] | 377 | #[cfg(any(spi_v1, spi_v2, spi_v3))] |
| @@ -708,6 +732,30 @@ impl<'d> Spi<'d, Async, Master> { | |||
| 708 | ) | 732 | ) |
| 709 | } | 733 | } |
| 710 | 734 | ||
| 735 | /// Create a new SPI driver, in bidirectional mode, specifically in tranmit mode | ||
| 736 | #[cfg(any(spi_v1, spi_v2, spi_v3))] | ||
| 737 | pub fn new_bidi<T: Instance, #[cfg(afio)] A>( | ||
| 738 | peri: Peri<'d, T>, | ||
| 739 | sck: Peri<'d, if_afio!(impl SckPin<T, A>)>, | ||
| 740 | sdio: Peri<'d, if_afio!(impl MosiPin<T, A>)>, | ||
| 741 | tx_dma: Peri<'d, impl TxDma<T>>, | ||
| 742 | rx_dma: Peri<'d, impl RxDma<T>>, | ||
| 743 | config: Config, | ||
| 744 | ) -> Self { | ||
| 745 | let mut this = Self::new_inner( | ||
| 746 | peri, | ||
| 747 | new_pin!(sck, config.sck_af()), | ||
| 748 | new_pin!(sdio, AfType::output(OutputType::PushPull, config.gpio_speed)), | ||
| 749 | None, | ||
| 750 | None, | ||
| 751 | new_dma!(tx_dma), | ||
| 752 | new_dma!(rx_dma), | ||
| 753 | config, | ||
| 754 | ); | ||
| 755 | this.set_direction(Some(Direction::Transmit)); | ||
| 756 | this | ||
| 757 | } | ||
| 758 | |||
| 711 | /// Create a new SPI driver, in TX-only mode, without SCK pin. | 759 | /// Create a new SPI driver, in TX-only mode, without SCK pin. |
| 712 | /// | 760 | /// |
| 713 | /// This can be useful for bit-banging non-SPI protocols. | 761 | /// This can be useful for bit-banging non-SPI protocols. |
