Skip to content

improve Ptr trait, rename ErasedPin to AnyPin #841

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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

Expand Down
6 changes: 3 additions & 3 deletions src/gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,8 @@ impl<const P: char, const N: u8, MODE> Pin<P, N, MODE> {
///
/// 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<MODE> {
ErasedPin::new(P as u8 - b'A', N)
pub fn erase(self) -> AnyPin<MODE> {
AnyPin::new(P as u8 - b'A', N)
}
}

Expand All @@ -415,7 +415,7 @@ impl<const P: char, const N: u8, MODE> From<Pin<P, N, MODE>> for PartiallyErased
}
}

impl<const P: char, const N: u8, MODE> From<Pin<P, N, MODE>> for ErasedPin<MODE> {
impl<const P: char, const N: u8, MODE> From<Pin<P, N, MODE>> for AnyPin<MODE> {
/// Pin-to-erased pin conversion using the [`From`] trait.
///
/// Note that [`From`] is the reciprocal of [`Into`].
Expand Down
8 changes: 4 additions & 4 deletions src/gpio/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,8 @@ macro_rules! change_mode {
}
use change_mode;

use super::ErasedPin;
impl<MODE: PinMode> ErasedPin<MODE> {
use super::AnyPin;
impl<MODE: PinMode> AnyPin<MODE> {
#[inline(always)]
pub(super) fn mode<M: PinMode>(&mut self) {
let n = self.pin_id();
Expand All @@ -176,9 +176,9 @@ impl<MODE: PinMode> ErasedPin<MODE> {

#[inline(always)]
/// Converts pin into specified mode
pub fn into_mode<M: PinMode>(mut self) -> ErasedPin<M> {
pub fn into_mode<M: PinMode>(mut self) -> AnyPin<M> {
self.mode::<M>();
ErasedPin::from_pin_port(self.into_pin_port())
AnyPin::from_pin_port(self.into_pin_port())
}
}

Expand Down
30 changes: 12 additions & 18 deletions src/gpio/erased.rs
Original file line number Diff line number Diff line change
@@ -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<MODE> {
pub struct AnyPin<MODE> {
// Bits 0-3: Pin, Bits 4-7: Port
pin_port: u8,
_mode: PhantomData<MODE>,
}

impl<MODE> fmt::Debug for ErasedPin<MODE> {
impl<MODE> fmt::Debug for AnyPin<MODE> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_fmt(format_args!(
"P({}{})<{}>",
Expand All @@ -23,7 +23,7 @@ impl<MODE> fmt::Debug for ErasedPin<MODE> {
}

#[cfg(feature = "defmt")]
impl<MODE> defmt::Format for ErasedPin<MODE> {
impl<MODE> defmt::Format for AnyPin<MODE> {
fn format(&self, f: defmt::Formatter) {
defmt::write!(
f,
Expand All @@ -35,7 +35,7 @@ impl<MODE> defmt::Format for ErasedPin<MODE> {
}
}

impl<MODE> PinExt for ErasedPin<MODE> {
impl<MODE> PinExt for AnyPin<MODE> {
type Mode = MODE;

#[inline(always)]
Expand All @@ -48,7 +48,7 @@ impl<MODE> PinExt for ErasedPin<MODE> {
}
}

impl<MODE> ErasedPin<MODE> {
impl<MODE> AnyPin<MODE> {
pub(crate) fn from_pin_port(pin_port: u8) -> Self {
Self {
pin_port,
Expand Down Expand Up @@ -93,23 +93,17 @@ impl<MODE> ErasedPin<MODE> {
}
}

impl<MODE> ErasedPin<Output<MODE>> {
impl<MODE> AnyPin<Output<MODE>> {
/// 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?
Expand Down Expand Up @@ -140,7 +134,7 @@ impl<MODE> ErasedPin<Output<MODE>> {
/// 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
Expand All @@ -154,7 +148,7 @@ impl<MODE> ErasedPin<Output<MODE>> {
}
}

impl<MODE> ErasedPin<MODE>
impl<MODE> AnyPin<MODE>
where
MODE: marker::Readable,
{
Expand All @@ -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()
}
}
10 changes: 5 additions & 5 deletions src/gpio/hal_02.rs
Original file line number Diff line number Diff line change
@@ -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,
};

Expand Down Expand Up @@ -107,7 +107,7 @@ where

// Implementations for `ErasedPin`

impl<MODE> OutputPin for ErasedPin<Output<MODE>> {
impl<MODE> OutputPin for AnyPin<Output<MODE>> {
type Error = core::convert::Infallible;

#[inline(always)]
Expand All @@ -123,7 +123,7 @@ impl<MODE> OutputPin for ErasedPin<Output<MODE>> {
}
}

impl<MODE> StatefulOutputPin for ErasedPin<Output<MODE>> {
impl<MODE> StatefulOutputPin for AnyPin<Output<MODE>> {
#[inline(always)]
fn is_set_high(&self) -> Result<bool, Self::Error> {
Ok(self.is_set_high())
Expand All @@ -135,7 +135,7 @@ impl<MODE> StatefulOutputPin for ErasedPin<Output<MODE>> {
}
}

impl<MODE> ToggleableOutputPin for ErasedPin<Output<MODE>> {
impl<MODE> ToggleableOutputPin for AnyPin<Output<MODE>> {
type Error = Infallible;

#[inline(always)]
Expand All @@ -145,7 +145,7 @@ impl<MODE> ToggleableOutputPin for ErasedPin<Output<MODE>> {
}
}

impl<MODE> InputPin for ErasedPin<MODE>
impl<MODE> InputPin for AnyPin<MODE>
where
MODE: marker::Readable,
{
Expand Down
12 changes: 5 additions & 7 deletions src/gpio/hal_1.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand Down Expand Up @@ -53,11 +51,11 @@ where
}

// Implementations for `ErasedPin`
impl<MODE> ErrorType for ErasedPin<MODE> {
impl<MODE> ErrorType for AnyPin<MODE> {
type Error = core::convert::Infallible;
}

impl<MODE> OutputPin for ErasedPin<Output<MODE>> {
impl<MODE> OutputPin for AnyPin<Output<MODE>> {
#[inline(always)]
fn set_high(&mut self) -> Result<(), Self::Error> {
self.set_high();
Expand All @@ -71,7 +69,7 @@ impl<MODE> OutputPin for ErasedPin<Output<MODE>> {
}
}

impl<MODE> StatefulOutputPin for ErasedPin<Output<MODE>> {
impl<MODE> StatefulOutputPin for AnyPin<Output<MODE>> {
#[inline(always)]
fn is_set_high(&mut self) -> Result<bool, Self::Error> {
Ok(Self::is_set_high(self))
Expand All @@ -83,7 +81,7 @@ impl<MODE> StatefulOutputPin for ErasedPin<Output<MODE>> {
}
}

impl<MODE> InputPin for ErasedPin<MODE>
impl<MODE> InputPin for AnyPin<MODE>
where
MODE: marker::Readable,
{
Expand Down
28 changes: 18 additions & 10 deletions src/gpio/partially_erased.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,18 @@ impl<const P: char, MODE> PartiallyErasedPin<P, Output<MODE>> {
#[inline(always)]
pub fn set_high(&mut self) {
// NOTE(unsafe) atomic write to a stateless register
unsafe {
(*gpiox::<P>()).bsrr().write(|w| w.bits(1 << self.i));
}
unsafe { &*gpiox::<P>() }
.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::<P>()).bsrr().write(|w| w.bits(1 << (self.i + 16)));
}
unsafe { &*gpiox::<P>() }
.bsrr()
.write(|w| w.br(self.i).set_bit());
}

/// Is the pin in drive high or low mode?
Expand Down Expand Up @@ -111,7 +111,11 @@ impl<const P: char, MODE> PartiallyErasedPin<P, Output<MODE>> {
#[inline(always)]
pub fn is_set_low(&self) -> bool {
// NOTE(unsafe) atomic read with no side effects
unsafe { (*gpiox::<P>()).odr().read().bits() & (1 << self.i) == 0 }
unsafe { &*gpiox::<P>() }
.odr()
.read()
.odr(self.i)
.bit_is_clear()
}

/// Toggle pin output
Expand Down Expand Up @@ -139,15 +143,19 @@ where
#[inline(always)]
pub fn is_low(&self) -> bool {
// NOTE(unsafe) atomic read with no side effects
unsafe { (*gpiox::<P>()).idr().read().bits() & (1 << self.i) == 0 }
unsafe { &*gpiox::<P>() }
.idr()
.read()
.idr(self.i)
.bit_is_clear()
}
}

impl<const P: char, MODE> From<PartiallyErasedPin<P, MODE>> for ErasedPin<MODE> {
impl<const P: char, MODE> From<PartiallyErasedPin<P, MODE>> for AnyPin<MODE> {
/// Partially erased pin-to-erased pin conversion using the [`From`] trait.
///
/// Note that [`From`] is the reciprocal of [`Into`].
fn from(p: PartiallyErasedPin<P, MODE>) -> Self {
ErasedPin::new(P as u8 - b'A', p.i)
AnyPin::new(P as u8 - b'A', p.i)
}
}
4 changes: 2 additions & 2 deletions src/i2c/dma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -934,7 +934,7 @@ pub struct Rx<I2C> {
unsafe impl<I2C: Instance> PeriAddress for Rx<I2C> {
#[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;
Expand All @@ -943,7 +943,7 @@ unsafe impl<I2C: Instance> PeriAddress for Rx<I2C> {
unsafe impl<I2C: Instance> PeriAddress for Tx<I2C> {
#[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;
Expand Down
12 changes: 8 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,15 +210,18 @@ impl<RB, const A: usize> Sealed for Periph<RB, A> {}
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<RB, const A: usize> Ptr for Periph<RB, A> {
type RB = RB;
fn ptr() -> *const Self::RB {
Self::ptr()
}
const PTR: *const Self::RB = Self::PTR;
}

pub trait Steal: Sealed {
Expand All @@ -239,6 +242,7 @@ pub trait Steal: Sealed {
}

impl<RB, const A: usize> Steal for Periph<RB, A> {
#[inline(always)]
unsafe fn steal() -> Self {
Self::steal()
}
Expand Down
2 changes: 1 addition & 1 deletion src/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/spi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -957,7 +957,7 @@ impl<SPI: Instance> DmaBuilder<SPI> {
unsafe impl<SPI: Instance> PeriAddress for Rx<SPI> {
#[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;
Expand All @@ -971,7 +971,7 @@ unsafe impl<SPI, STREAM, const CHANNEL: u8> DMASet<STREAM, CHANNEL, PeripheralTo
unsafe impl<SPI: Instance> PeriAddress for Tx<SPI> {
#[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;
Expand Down