From 04b84469c197e01d0b655754cf6ff19a66ba8ef6 Mon Sep 17 00:00:00 2001 From: Andrey Zgarbul Date: Sat, 14 Dec 2024 21:46:10 +0300 Subject: [PATCH 1/3] I2c::new remap --- src/afio.rs | 6 ++++++ src/i2c.rs | 8 ++++---- src/i2c/blocking.rs | 6 +++--- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/afio.rs b/src/afio.rs index 27b34ad7..80c8bbb1 100644 --- a/src/afio.rs +++ b/src/afio.rs @@ -240,6 +240,12 @@ remap! { pub struct Rmp(pub(crate) T); +impl From for Rmp { + fn from(value: T) -> Self { + Self(value) + } +} + pub trait RFrom { fn rfrom(value: T) -> Self; } diff --git a/src/i2c.rs b/src/i2c.rs index 6bdd9f64..5bb896a6 100644 --- a/src/i2c.rs +++ b/src/i2c.rs @@ -164,9 +164,9 @@ impl Instance for pac::I2C2 {} impl I2c { /// Creates a generic I2C object - pub fn new( - i2c: I2C, - pins: (impl RInto, impl RInto), + pub fn new( + i2c: impl Into>, + pins: (impl RInto, impl RInto), mode: impl Into, clocks: &Clocks, ) -> Self { @@ -180,7 +180,7 @@ impl I2c { assert!(mode.get_frequency() <= kHz(400)); let mut i2c = I2c { - i2c, + i2c: i2c.into().0, pins: (pins.0.rinto(), pins.1.rinto()), mode, pclk1, diff --git a/src/i2c/blocking.rs b/src/i2c/blocking.rs index 05398005..aa22a38c 100644 --- a/src/i2c/blocking.rs +++ b/src/i2c/blocking.rs @@ -20,9 +20,9 @@ pub struct DwtTimeouts { impl BlockingI2c { /// Creates a blocking I2C1 object on pins PB6 and PB7 or PB8 and PB9 using the embedded-hal `BlockingI2c` trait. #[allow(clippy::too_many_arguments)] - pub fn new( - i2c: I2C, - pins: (impl RInto, impl RInto), + pub fn new( + i2c: impl Into>, + pins: (impl RInto, impl RInto), mode: impl Into, clocks: &Clocks, start_timeout_us: u32, From e8b2e082428029e1c3a9d2760f23bcba8c96c422 Mon Sep 17 00:00:00 2001 From: Andrey Zgarbul Date: Sun, 15 Dec 2024 09:18:48 +0300 Subject: [PATCH 2/3] remap cleanups --- .zed/settings.json | 15 ++++ src/can.rs | 39 +++------- src/i2c.rs | 18 +---- src/serial.rs | 58 ++++---------- src/spi.rs | 183 ++++++++++++++++++++------------------------- 5 files changed, 122 insertions(+), 191 deletions(-) create mode 100644 .zed/settings.json diff --git a/.zed/settings.json b/.zed/settings.json new file mode 100644 index 00000000..d43a68e7 --- /dev/null +++ b/.zed/settings.json @@ -0,0 +1,15 @@ +{ + "lsp": { + "rust-analyzer": { + "initialization_options": { + "cargo": { + "features": ["defmt", "rtic", "stm32f103", "medium"] + }, + "check": { + "allTargets": false, + "targets": "thumbv7em-none-eabi" + } + } + } + } +} diff --git a/src/can.rs b/src/can.rs index dd2662d8..05eb2ed6 100644 --- a/src/can.rs +++ b/src/can.rs @@ -72,15 +72,14 @@ pub struct Can { impl Rmp { pub fn can( self, - #[cfg(not(feature = "connectivity"))] usb: pac::USB, + #[cfg(not(feature = "connectivity"))] _usb: pac::USB, pins: (impl RInto, impl RInto, R>), ) -> Can { - Can::_new( - self.0, - #[cfg(not(feature = "connectivity"))] - usb, - (Some(pins.0), Some(pins.1)), - ) + let rcc = unsafe { &(*RCC::ptr()) }; + CAN::enable(rcc); + + let pins = (Some(pins.0.rinto()), Some(pins.1.rinto())); + Can { can: self.0, pins } } pub fn can_loopback( self, @@ -99,34 +98,18 @@ impl Can { /// /// CAN shares SRAM with the USB peripheral. Take ownership of USB to /// prevent accidental shared usage. - pub fn new( - can: CAN, + pub fn new( + can: impl Into>, #[cfg(not(feature = "connectivity"))] _usb: pac::USB, - pins: (impl RInto, impl RInto, 0>), + pins: (impl RInto, impl RInto, R>), ) -> Can { - Self::_new( - can, + can.into().can( #[cfg(not(feature = "connectivity"))] _usb, - (Some(pins.0), Some(pins.1)), + pins, ) } - fn _new( - can: CAN, - #[cfg(not(feature = "connectivity"))] _usb: pac::USB, - pins: ( - Option>, - Option, R>>, - ), - ) -> Can { - let rcc = unsafe { &(*RCC::ptr()) }; - CAN::enable(rcc); - - let pins = (pins.0.map(RInto::rinto), pins.1.map(RInto::rinto)); - Can { can, pins } - } - /// Creates a CAN interface in loopback mode pub fn new_loopback( can: CAN, diff --git a/src/i2c.rs b/src/i2c.rs index 5bb896a6..102bb528 100644 --- a/src/i2c.rs +++ b/src/i2c.rs @@ -170,23 +170,7 @@ impl I2c { mode: impl Into, clocks: &Clocks, ) -> Self { - let mode = mode.into(); - let rcc = unsafe { &(*RCC::ptr()) }; - I2C::enable(rcc); - I2C::reset(rcc); - - let pclk1 = I2C::clock(clocks); - - assert!(mode.get_frequency() <= kHz(400)); - - let mut i2c = I2c { - i2c: i2c.into().0, - pins: (pins.0.rinto(), pins.1.rinto()), - mode, - pclk1, - }; - i2c.init(); - i2c + i2c.into().i2c(pins, mode, clocks) } } diff --git a/src/serial.rs b/src/serial.rs index 6cf1960d..856ead86 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -147,14 +147,7 @@ impl SerialExt for USART { config: impl Into, clocks: &Clocks, ) -> Tx { - Serial::_new( - self, - (Some(tx_pin), None::>), - config, - clocks, - ) - .split() - .0 + Serial::tx(self, tx_pin, config, clocks) } fn rx( self, @@ -162,14 +155,7 @@ impl SerialExt for USART { config: impl Into, clocks: &Clocks, ) -> Rx { - Serial::_new( - self, - (None::>, Some(rx_pin)), - config, - clocks, - ) - .split() - .1 + Serial::rx(self, rx_pin, config, clocks) } } @@ -388,38 +374,24 @@ impl Rmp { } impl Serial { - pub fn tx( - usart: USART, - tx_pin: impl RInto, 0>, + pub fn tx( + usart: impl Into>, + tx_pin: impl RInto, R>, config: impl Into, clocks: &Clocks, ) -> Tx { - Self::_new( - usart, - (Some(tx_pin), None::>), - config, - clocks, - ) - .split() - .0 + usart.into().tx(tx_pin, config, clocks) } } impl Serial { - pub fn rx( - usart: USART, - rx_pin: impl RInto, 0>, + pub fn rx( + usart: impl Into>, + rx_pin: impl RInto, R>, config: impl Into, clocks: &Clocks, ) -> Rx { - Self::_new( - usart, - (None::>, Some(rx_pin)), - config, - clocks, - ) - .split() - .1 + usart.into().rx(rx_pin, config, clocks) } } @@ -439,16 +411,16 @@ impl Serial { /// `MAPR` and `APBX` are register handles which are passed for /// configuration. (`MAPR` is used to map the USART to the /// corresponding pins. `APBX` is used to reset the USART.) - pub fn new( - usart: USART, + pub fn new( + usart: impl Into>, pins: ( - impl RInto, 0>, - impl RInto, 0>, + impl RInto, R>, + impl RInto, R>, ), config: impl Into, clocks: &Clocks, ) -> Self { - Self::_new(usart, (Some(pins.0), Some(pins.1)), config, clocks) + usart.into().serial(pins, config, clocks) } fn _new( diff --git a/src/spi.rs b/src/spi.rs index 3655e0bf..ff7558ed 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -301,78 +301,7 @@ impl Rmp { freq: Hertz, clocks: &Clocks, ) -> Spi { - Spi::_new(self.0, pins, mode, freq, clocks) - } - pub fn spi_u16( - self, - pins: ( - Option>, - Option, R>>, - Option>, - ), - mode: Mode, - freq: Hertz, - clocks: &Clocks, - ) -> Spi { - self.spi(pins, mode, freq, clocks).frame_size_16bit() - } - pub fn spi_slave( - self, - pins: ( - Option>, - Option, R>>, - Option, R>>, - ), - mode: Mode, - ) -> SpiSlave { - SpiSlave::_new(self.0, pins, mode) - } - pub fn spi_slave_u16( - self, - pins: ( - Option>, - Option, R>>, - Option, R>>, - ), - mode: Mode, - ) -> SpiSlave { - self.spi_slave(pins, mode).frame_size_16bit() - } -} - -impl Spi { - /** - Constructs an SPI instance using SPI1 in 8bit dataframe mode. - - The pin parameter tuple (sck, miso, mosi) should be `(PA5, PA6, PA7)` or `(PB3, PB4, PB5)` configured as `(Alternate, Input<...>, Alternate)`. - - You can also use `NoSck`, `NoMiso` or `NoMosi` if you don't want to use the pins - */ - pub fn new( - spi: SPI, - pins: ( - Option>, - Option, 0>>, - Option>, - ), - mode: Mode, - freq: Hertz, - clocks: &Clocks, - ) -> Self { - Self::_new(spi, pins, mode, freq, clocks) - } - - fn _new( - spi: SPI, - pins: ( - Option>, - Option, R>>, - Option>, - ), - mode: Mode, - freq: Hertz, - clocks: &Clocks, - ) -> Self { + let spi = self.0; // enable or reset SPI let rcc = unsafe { &(*RCC::ptr()) }; SPI::enable(rcc); @@ -429,48 +358,29 @@ impl Spi { pins, } } -} - -impl Spi { - #[allow(clippy::type_complexity)] - pub fn release( + pub fn spi_u16( self, - ) -> ( - SPI, - (Option, Option>, Option), - ) { - (self.inner.spi, self.pins) - } -} - -impl SpiSlave { - /** - Constructs an SPI instance using SPI1 in 8bit dataframe mode. - - The pin parameter tuple (sck, miso, mosi) should be `(PA5, PA6, PA7)` or `(PB3, PB4, PB5)` configured as `(Input, Alternate<...>, Input<...>)`. - - You can also use `NoMiso` or `NoMosi` if you don't want to use the pins - */ - pub fn new( - spi: SPI, pins: ( - Option>, - Option, 0>>, - Option, 0>>, + Option>, + Option, R>>, + Option>, ), mode: Mode, - ) -> Self { - Self::_new(spi, pins, mode) + freq: Hertz, + clocks: &Clocks, + ) -> Spi { + self.spi(pins, mode, freq, clocks).frame_size_16bit() } - fn _new( - spi: SPI, + pub fn spi_slave( + self, pins: ( Option>, Option, R>>, Option, R>>, ), mode: Mode, - ) -> Self { + ) -> SpiSlave { + let spi = self.0; // enable or reset SPI let rcc = unsafe { &(*RCC::ptr()) }; SPI::enable(rcc); @@ -513,6 +423,73 @@ impl SpiSlave { pins, } } + pub fn spi_slave_u16( + self, + pins: ( + Option>, + Option, R>>, + Option, R>>, + ), + mode: Mode, + ) -> SpiSlave { + self.spi_slave(pins, mode).frame_size_16bit() + } +} + +impl Spi { + /** + Constructs an SPI instance using SPI1 in 8bit dataframe mode. + + The pin parameter tuple (sck, miso, mosi) should be `(PA5, PA6, PA7)` or `(PB3, PB4, PB5)` configured as `(Alternate, Input<...>, Alternate)`. + + You can also use `NoSck`, `NoMiso` or `NoMosi` if you don't want to use the pins + */ + pub fn new( + spi: impl Into>, + pins: ( + Option>, + Option, R>>, + Option>, + ), + mode: Mode, + freq: Hertz, + clocks: &Clocks, + ) -> Self { + spi.into().spi(pins, mode, freq, clocks) + } +} + +impl Spi { + #[allow(clippy::type_complexity)] + pub fn release( + self, + ) -> ( + SPI, + (Option, Option>, Option), + ) { + (self.inner.spi, self.pins) + } +} + +impl SpiSlave { + /** + Constructs an SPI instance using SPI1 in 8bit dataframe mode. + + The pin parameter tuple (sck, miso, mosi) should be `(PA5, PA6, PA7)` or `(PB3, PB4, PB5)` configured as `(Input, Alternate<...>, Input<...>)`. + + You can also use `NoMiso` or `NoMosi` if you don't want to use the pins + */ + pub fn new( + spi: impl Into>, + pins: ( + Option>, + Option, R>>, + Option, R>>, + ), + mode: Mode, + ) -> Self { + spi.into().spi_slave(pins, mode) + } } impl SpiSlave { From d9f7eab04c527678067b4be285a7becdb192c291 Mon Sep 17 00:00:00 2001 From: Andrey Zgarbul Date: Sun, 15 Dec 2024 09:20:56 +0300 Subject: [PATCH 3/3] changelog --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c59295c3..c615acf0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Relax pin type generics for `Serial`, `I2c`, `Spi`, `Can`, `Qei`, `PwmInput`. [#462] [#516] ~~Use enums of pin tuples and `Enum::from<(tuple)>` for pin remap before passing to peripheral.~~ Use pin enums and `impl RInto<(enum), R>` for peripheral constructors. - Add `RInto` trait and `Rmp` peripheral wrapper, add `remap` for peripherals. [#514] + Add `RInto` trait and `Rmp` peripheral wrapper, add `remap` for peripherals. [#514] [#520] Remove `RemapStruct`s. [#462] [#506] [#509] - Use independent `Spi` and `SpiSlave` structures instead of `OP` generic [#462] - Take `&Clocks` instead of `Clocks` [#498] @@ -33,7 +33,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Unmacro `dma.rs` [#505] - Updated `usb-device` and `usbd-serial` to latest versions [#510] - Rework pin remaps, fix CAN1 remap [#511] -- Rework USART remap, +- Rework USART remap, ### Added @@ -68,6 +68,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). [#511]: https://github.com/stm32-rs/stm32f1xx-hal/pull/511 [#514]: https://github.com/stm32-rs/stm32f1xx-hal/pull/514 [#516]: https://github.com/stm32-rs/stm32f1xx-hal/pull/516 +[#520]: https://github.com/stm32-rs/stm32f1xx-hal/pull/520 ## [v0.10.0] - 2022-12-12