diff --git a/CHANGELOG.md b/CHANGELOG.md index 833043c0..ccf7d44b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Implement `embedded_hal::i2c::I2c` for `I2cMasterDma` [#838] - Back to `stm32f4` - Implement `Ptr`, `Sealed`, `Steal` for generic `Periph` [#834] + - Rename `ErasedPin` to `AnyPin` [#841] - Use `&mut RCC` for `PER::enable/reset` - Unmacro `Adc` [#832] - Use `write` instead of `modify` to clear flags [#829] @@ -29,6 +30,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). [#834]: https://github.com/stm32-rs/stm32f4xx-hal/pull/834 [#838]: https://github.com/stm32-rs/stm32f4xx-hal/pull/838 [#839]: https://github.com/stm32-rs/stm32f4xx-hal/pull/839 +[#841]: https://github.com/stm32-rs/stm32f4xx-hal/pull/841 ## [v0.22.1] - 2024-11-03 diff --git a/src/gpio.rs b/src/gpio.rs index 83d58124..1033e82d 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -401,8 +401,8 @@ impl Pin { /// /// This is useful when you want to collect the pins into an array where you /// need all the elements to have the same type - pub fn erase(self) -> ErasedPin { - ErasedPin::new(P as u8 - b'A', N) + pub fn erase(self) -> AnyPin { + AnyPin::new(P as u8 - b'A', N) } } @@ -415,7 +415,7 @@ impl From> for PartiallyErased } } -impl From> for ErasedPin { +impl From> for AnyPin { /// Pin-to-erased pin conversion using the [`From`] trait. /// /// Note that [`From`] is the reciprocal of [`Into`]. diff --git a/src/gpio/convert.rs b/src/gpio/convert.rs index 2ac350c0..97fb04cf 100644 --- a/src/gpio/convert.rs +++ b/src/gpio/convert.rs @@ -166,8 +166,8 @@ macro_rules! change_mode { } use change_mode; -use super::ErasedPin; -impl ErasedPin { +use super::AnyPin; +impl AnyPin { #[inline(always)] pub(super) fn mode(&mut self) { let n = self.pin_id(); @@ -176,9 +176,9 @@ impl ErasedPin { #[inline(always)] /// Converts pin into specified mode - pub fn into_mode(mut self) -> ErasedPin { + pub fn into_mode(mut self) -> AnyPin { self.mode::(); - ErasedPin::from_pin_port(self.into_pin_port()) + AnyPin::from_pin_port(self.into_pin_port()) } } diff --git a/src/gpio/erased.rs b/src/gpio/erased.rs index 163e227f..cb28ad16 100644 --- a/src/gpio/erased.rs +++ b/src/gpio/erased.rs @@ -1,17 +1,17 @@ use super::*; -pub use ErasedPin as AnyPin; +pub use AnyPin as ErasedPin; /// Fully erased pin /// /// `MODE` is one of the pin modes (see [Modes](crate::gpio#modes) section). -pub struct ErasedPin { +pub struct AnyPin { // Bits 0-3: Pin, Bits 4-7: Port pin_port: u8, _mode: PhantomData, } -impl fmt::Debug for ErasedPin { +impl fmt::Debug for AnyPin { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_fmt(format_args!( "P({}{})<{}>", @@ -23,7 +23,7 @@ impl fmt::Debug for ErasedPin { } #[cfg(feature = "defmt")] -impl defmt::Format for ErasedPin { +impl defmt::Format for AnyPin { fn format(&self, f: defmt::Formatter) { defmt::write!( f, @@ -35,7 +35,7 @@ impl defmt::Format for ErasedPin { } } -impl PinExt for ErasedPin { +impl PinExt for AnyPin { type Mode = MODE; #[inline(always)] @@ -48,7 +48,7 @@ impl PinExt for ErasedPin { } } -impl ErasedPin { +impl AnyPin { pub(crate) fn from_pin_port(pin_port: u8) -> Self { Self { pin_port, @@ -93,23 +93,17 @@ impl ErasedPin { } } -impl ErasedPin> { +impl AnyPin> { /// Drives the pin high #[inline(always)] pub fn set_high(&mut self) { - // NOTE(unsafe) atomic write to a stateless register - unsafe { self.block().bsrr().write(|w| w.bits(1 << self.pin_id())) }; + self.block().bsrr().write(|w| w.bs(self.pin_id()).set_bit()); } /// Drives the pin low #[inline(always)] pub fn set_low(&mut self) { - // NOTE(unsafe) atomic write to a stateless register - unsafe { - self.block() - .bsrr() - .write(|w| w.bits(1 << (self.pin_id() + 16))) - }; + self.block().bsrr().write(|w| w.br(self.pin_id()).set_bit()); } /// Is the pin in drive high or low mode? @@ -140,7 +134,7 @@ impl ErasedPin> { /// Is the pin in drive low mode? #[inline(always)] pub fn is_set_low(&self) -> bool { - self.block().odr().read().bits() & (1 << self.pin_id()) == 0 + self.block().odr().read().odr(self.pin_id()).bit_is_clear() } /// Toggle pin output @@ -154,7 +148,7 @@ impl ErasedPin> { } } -impl ErasedPin +impl AnyPin where MODE: marker::Readable, { @@ -167,6 +161,6 @@ where /// Is the input pin low? #[inline(always)] pub fn is_low(&self) -> bool { - self.block().idr().read().bits() & (1 << self.pin_id()) == 0 + self.block().idr().read().idr(self.pin_id()).bit_is_clear() } } diff --git a/src/gpio/hal_02.rs b/src/gpio/hal_02.rs index d3254ab3..bf33c356 100644 --- a/src/gpio/hal_02.rs +++ b/src/gpio/hal_02.rs @@ -1,7 +1,7 @@ use core::convert::Infallible; use super::{ - dynamic::PinModeError, marker, DynamicPin, ErasedPin, Input, OpenDrain, Output, + dynamic::PinModeError, marker, AnyPin, DynamicPin, Input, OpenDrain, Output, PartiallyErasedPin, Pin, PinMode, PinState, }; @@ -107,7 +107,7 @@ where // Implementations for `ErasedPin` -impl OutputPin for ErasedPin> { +impl OutputPin for AnyPin> { type Error = core::convert::Infallible; #[inline(always)] @@ -123,7 +123,7 @@ impl OutputPin for ErasedPin> { } } -impl StatefulOutputPin for ErasedPin> { +impl StatefulOutputPin for AnyPin> { #[inline(always)] fn is_set_high(&self) -> Result { Ok(self.is_set_high()) @@ -135,7 +135,7 @@ impl StatefulOutputPin for ErasedPin> { } } -impl ToggleableOutputPin for ErasedPin> { +impl ToggleableOutputPin for AnyPin> { type Error = Infallible; #[inline(always)] @@ -145,7 +145,7 @@ impl ToggleableOutputPin for ErasedPin> { } } -impl InputPin for ErasedPin +impl InputPin for AnyPin where MODE: marker::Readable, { diff --git a/src/gpio/hal_1.rs b/src/gpio/hal_1.rs index 11db87cb..e33e2627 100644 --- a/src/gpio/hal_1.rs +++ b/src/gpio/hal_1.rs @@ -1,8 +1,6 @@ use core::convert::Infallible; -use super::{ - dynamic::PinModeError, marker, DynamicPin, ErasedPin, Output, PartiallyErasedPin, Pin, -}; +use super::{dynamic::PinModeError, marker, AnyPin, DynamicPin, Output, PartiallyErasedPin, Pin}; use embedded_hal::digital::{ErrorType, InputPin, OutputPin, StatefulOutputPin}; @@ -53,11 +51,11 @@ where } // Implementations for `ErasedPin` -impl ErrorType for ErasedPin { +impl ErrorType for AnyPin { type Error = core::convert::Infallible; } -impl OutputPin for ErasedPin> { +impl OutputPin for AnyPin> { #[inline(always)] fn set_high(&mut self) -> Result<(), Self::Error> { self.set_high(); @@ -71,7 +69,7 @@ impl OutputPin for ErasedPin> { } } -impl StatefulOutputPin for ErasedPin> { +impl StatefulOutputPin for AnyPin> { #[inline(always)] fn is_set_high(&mut self) -> Result { Ok(Self::is_set_high(self)) @@ -83,7 +81,7 @@ impl StatefulOutputPin for ErasedPin> { } } -impl InputPin for ErasedPin +impl InputPin for AnyPin where MODE: marker::Readable, { diff --git a/src/gpio/partially_erased.rs b/src/gpio/partially_erased.rs index 812ea2c0..7c5863bd 100644 --- a/src/gpio/partially_erased.rs +++ b/src/gpio/partially_erased.rs @@ -68,18 +68,18 @@ impl PartiallyErasedPin> { #[inline(always)] pub fn set_high(&mut self) { // NOTE(unsafe) atomic write to a stateless register - unsafe { - (*gpiox::

()).bsrr().write(|w| w.bits(1 << self.i)); - } + unsafe { &*gpiox::

() } + .bsrr() + .write(|w| w.bs(self.i).set_bit()); } /// Drives the pin low #[inline(always)] pub fn set_low(&mut self) { // NOTE(unsafe) atomic write to a stateless register - unsafe { - (*gpiox::

()).bsrr().write(|w| w.bits(1 << (self.i + 16))); - } + unsafe { &*gpiox::

() } + .bsrr() + .write(|w| w.br(self.i).set_bit()); } /// Is the pin in drive high or low mode? @@ -111,7 +111,11 @@ impl PartiallyErasedPin> { #[inline(always)] pub fn is_set_low(&self) -> bool { // NOTE(unsafe) atomic read with no side effects - unsafe { (*gpiox::

()).odr().read().bits() & (1 << self.i) == 0 } + unsafe { &*gpiox::

() } + .odr() + .read() + .odr(self.i) + .bit_is_clear() } /// Toggle pin output @@ -139,15 +143,19 @@ where #[inline(always)] pub fn is_low(&self) -> bool { // NOTE(unsafe) atomic read with no side effects - unsafe { (*gpiox::

()).idr().read().bits() & (1 << self.i) == 0 } + unsafe { &*gpiox::

() } + .idr() + .read() + .idr(self.i) + .bit_is_clear() } } -impl From> for ErasedPin { +impl From> for AnyPin { /// Partially erased pin-to-erased pin conversion using the [`From`] trait. /// /// Note that [`From`] is the reciprocal of [`Into`]. fn from(p: PartiallyErasedPin) -> Self { - ErasedPin::new(P as u8 - b'A', p.i) + AnyPin::new(P as u8 - b'A', p.i) } } diff --git a/src/i2c/dma.rs b/src/i2c/dma.rs index c16d6e10..73b4c54b 100644 --- a/src/i2c/dma.rs +++ b/src/i2c/dma.rs @@ -934,7 +934,7 @@ pub struct Rx { unsafe impl PeriAddress for Rx { #[inline(always)] fn address(&self) -> u32 { - unsafe { (*I2C::ptr()).dr().as_ptr() as u32 } + unsafe { (*I2C::PTR).dr().as_ptr() as u32 } } type MemSize = u8; @@ -943,7 +943,7 @@ unsafe impl PeriAddress for Rx { unsafe impl PeriAddress for Tx { #[inline(always)] fn address(&self) -> u32 { - unsafe { (*I2C::ptr()).dr().as_ptr() as u32 } + unsafe { (*I2C::PTR).dr().as_ptr() as u32 } } type MemSize = u8; diff --git a/src/lib.rs b/src/lib.rs index 95c9d484..ecc0e994 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -210,15 +210,18 @@ impl Sealed for Periph {} pub trait Ptr: Sealed { /// RegisterBlock structure type RB; + /// Pointer to the register block + const PTR: *const Self::RB; /// Return the pointer to the register block - fn ptr() -> *const Self::RB; + #[inline(always)] + fn ptr() -> *const Self::RB { + Self::PTR + } } impl Ptr for Periph { type RB = RB; - fn ptr() -> *const Self::RB { - Self::ptr() - } + const PTR: *const Self::RB = Self::PTR; } pub trait Steal: Sealed { @@ -239,6 +242,7 @@ pub trait Steal: Sealed { } impl Steal for Periph { + #[inline(always)] unsafe fn steal() -> Self { Self::steal() } diff --git a/src/serial.rs b/src/serial.rs index fe5e6c35..624ecc21 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -138,7 +138,7 @@ pub trait Instance: #[doc(hidden)] #[inline(always)] fn peri_address() -> u32 { - unsafe { &*Self::ptr() }.peri_address() + unsafe { &*Self::PTR }.peri_address() } } diff --git a/src/spi.rs b/src/spi.rs index 2a187137..825be012 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -957,7 +957,7 @@ impl DmaBuilder { unsafe impl PeriAddress for Rx { #[inline(always)] fn address(&self) -> u32 { - unsafe { (*SPI::ptr()).dr().as_ptr() as u32 } + unsafe { (*SPI::PTR).dr().as_ptr() as u32 } } type MemSize = u8; @@ -971,7 +971,7 @@ unsafe impl DMASet PeriAddress for Tx { #[inline(always)] fn address(&self) -> u32 { - unsafe { (*SPI::ptr()).dr().as_ptr() as u32 } + unsafe { (*SPI::PTR).dr().as_ptr() as u32 } } type MemSize = u8;