Skip to content

Commit

Permalink
gpio: use reference of glb RegisterBlock other than struct with Deref…
Browse files Browse the repository at this point in the history
… to RegisterBlock

This change shortens code and number of type generics. Code cleanup, pass tests on all feature gate options.

Signed-off-by: Zhouqi Jiang <[email protected]>
  • Loading branch information
luojia65 committed Dec 19, 2024
1 parent a672c9d commit 63c17cb
Show file tree
Hide file tree
Showing 24 changed files with 889 additions and 780 deletions.
21 changes: 9 additions & 12 deletions bouffalo-hal/src/gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@
//!
//! ```no_run
//! # use bouffalo_hal::gpio::{Pads, IntoPad};
//! # pub struct Peripherals { gpio: Pads<GLBv2> }
//! # pub struct Peripherals { gpio: Pads<'static> }
//! # pub struct GLBv2;
//! # impl core::ops::Deref for GLBv2 {
//! # type Target = bouffalo_hal::glb::RegisterBlock;
//! # fn deref(&self) -> &Self::Target { unimplemented!() }
//! # }
//! # fn main() -> ! {
//! # let p: Peripherals = unsafe { core::mem::transmute(()) };
//! # let glb: &bouffalo_hal::glb::RegisterBlock = unsafe { &*core::ptr::null() };
//! # let p: Peripherals = Peripherals { gpio: Pads::__pads_from_glb(glb) };
//! use embedded_hal::digital::{OutputPin, PinState};
//!
//! // Switch io8 pin into floating output mode to prepare setting its state.
Expand Down Expand Up @@ -61,35 +62,31 @@
//! # use embedded_time::rate::*;
//! # use bouffalo_hal::{
//! # clocks::Clocks,
//! # gpio::Pads,
//! # gpio::{Pads, IntoPadv2},
//! # uart::{BitOrder, Config, Parity, StopBits, WordLength},
//! # };
//! # use embedded_io::Write;
//! # pub struct Serial<PADS> { pads: PADS }
//! # impl<PADS> Serial<PADS> {
//! # pub fn new<UART>(_: UART, _: Config, _: Baud,
//! # #[cfg(feature = "glb-v2")] _: PADS, _: &Clocks, _: &GLBv2)
//! # #[cfg(feature = "glb-v2")] _: PADS, _: &Clocks, _: &())
//! # -> Self { unimplemented!() }
//! # pub fn write_fmt(&mut self, fmt: core::fmt::Arguments<'_>) -> Result<(), ()> { unimplemented!() }
//! # pub fn flush(&mut self) -> Result<(), ()> { unimplemented!() }
//! # }
//! # pub struct Peripherals {
//! # gpio: Pads<GLBv2>,
//! # glb: GLBv2,
//! # gpio: Pads<'static>,
//! # glb: (),
//! # uart0: UART0,
//! # }
//! # pub struct GLBv2;
//! # impl core::ops::Deref for GLBv2 {
//! # type Target = bouffalo_hal::glb::RegisterBlock;
//! # fn deref(&self) -> &Self::Target { unimplemented!() }
//! # }
//! # pub struct UART0;
//! # impl core::ops::Deref for UART0 {
//! # type Target = bouffalo_hal::uart::RegisterBlock;
//! # fn deref(&self) -> &Self::Target { unimplemented!() }
//! # }
//! # fn main() {
//! # let p: Peripherals = unsafe { core::mem::transmute(()) };
//! # let glb: &bouffalo_hal::glb::RegisterBlock = unsafe { &*core::ptr::null() };
//! # let p: Peripherals = Peripherals { gpio: Pads::__pads_from_glb(glb), glb: (), uart0: UART0 };
//! # let clocks = Clocks { xtal: Hertz(40_000_000) };
//! // Prepare UART transmit and receive pads by converting io14 and io15 into
//! // UART signal alternate mode.
Expand Down
58 changes: 27 additions & 31 deletions bouffalo-hal/src/gpio/alternate.rs
Original file line number Diff line number Diff line change
@@ -1,99 +1,95 @@
use super::{
convert::{IntoPad, IntoPadv2},
convert::IntoPad,
input::Input,
output::Output,
typestate::{self, Floating, PullDown, PullUp},
typestate::{Floating, PullDown, PullUp},
};
use crate::glb::RegisterBlock;
use core::ops::Deref;
#[cfg(any(doc, feature = "glb-v2"))]
use super::{convert::IntoPadv2, typestate};

/// GPIO pad with alternate mode.
pub struct Alternate<GLB, const N: usize, M> {
inner: super::Inner<GLB, N, M>,
pub struct Alternate<'a, const N: usize, M> {
inner: super::Inner<'a, N, M>,
}

impl<GLB: Deref<Target = RegisterBlock>, const N: usize, M> IntoPad<GLB, N>
for Alternate<GLB, N, M>
{
impl<'a, const N: usize, M> IntoPad<'a, N> for Alternate<'a, N, M> {
#[inline]
fn into_pull_up_output(self) -> Output<GLB, N, PullUp> {
fn into_pull_up_output(self) -> Output<'a, N, PullUp> {
self.inner.into_pull_up_output().into()
}
#[inline]
fn into_pull_down_output(self) -> Output<GLB, N, PullDown> {
fn into_pull_down_output(self) -> Output<'a, N, PullDown> {
self.inner.into_pull_down_output().into()
}
#[inline]
fn into_floating_output(self) -> Output<GLB, N, Floating> {
fn into_floating_output(self) -> Output<'a, N, Floating> {
self.inner.into_floating_output().into()
}
#[inline]
fn into_pull_up_input(self) -> Input<GLB, N, PullUp> {
fn into_pull_up_input(self) -> Input<'a, N, PullUp> {
self.inner.into_pull_up_input().into()
}
#[inline]
fn into_pull_down_input(self) -> Input<GLB, N, PullDown> {
fn into_pull_down_input(self) -> Input<'a, N, PullDown> {
self.inner.into_pull_down_input().into()
}
#[inline]
fn into_floating_input(self) -> Input<GLB, N, Floating> {
fn into_floating_input(self) -> Input<'a, N, Floating> {
self.inner.into_floating_input().into()
}
}

#[cfg(any(doc, feature = "glb-v2"))]
impl<GLB: Deref<Target = RegisterBlock>, const N: usize, M> IntoPadv2<GLB, N>
for Alternate<GLB, N, M>
{
impl<'a, const N: usize, M> IntoPadv2<'a, N> for Alternate<'a, N, M> {
#[inline]
fn into_spi<const I: usize>(self) -> Alternate<GLB, N, typestate::Spi<I>> {
fn into_spi<const I: usize>(self) -> Alternate<'a, N, typestate::Spi<I>> {
self.inner.into_spi().into()
}
#[inline]
fn into_sdh(self) -> Alternate<GLB, N, typestate::Sdh> {
fn into_sdh(self) -> Alternate<'a, N, typestate::Sdh> {
self.inner.into_sdh().into()
}
#[inline]
fn into_uart(self) -> Alternate<GLB, N, typestate::Uart> {
fn into_uart(self) -> Alternate<'a, N, typestate::Uart> {
self.inner.into_uart().into()
}
#[inline]
fn into_mm_uart(self) -> Alternate<GLB, N, typestate::MmUart> {
fn into_mm_uart(self) -> Alternate<'a, N, typestate::MmUart> {
self.inner.into_mm_uart().into()
}
#[inline]
fn into_pull_up_pwm<const I: usize>(self) -> Alternate<GLB, N, typestate::Pwm<I>> {
fn into_pull_up_pwm<const I: usize>(self) -> Alternate<'a, N, typestate::Pwm<I>> {
self.inner.into_pull_up_pwm().into()
}
#[inline]
fn into_pull_down_pwm<const I: usize>(self) -> Alternate<GLB, N, typestate::Pwm<I>> {
fn into_pull_down_pwm<const I: usize>(self) -> Alternate<'a, N, typestate::Pwm<I>> {
self.inner.into_pull_down_pwm().into()
}
#[inline]
fn into_floating_pwm<const I: usize>(self) -> Alternate<GLB, N, typestate::Pwm<I>> {
fn into_floating_pwm<const I: usize>(self) -> Alternate<'a, N, typestate::Pwm<I>> {
self.inner.into_floating_pwm().into()
}
#[inline]
fn into_i2c<const I: usize>(self) -> Alternate<GLB, N, typestate::I2c<I>> {
fn into_i2c<const I: usize>(self) -> Alternate<'a, N, typestate::I2c<I>> {
self.inner.into_i2c().into()
}
#[inline]
fn into_jtag_d0(self) -> Alternate<GLB, N, typestate::JtagD0> {
fn into_jtag_d0(self) -> Alternate<'a, N, typestate::JtagD0> {
self.inner.into_jtag_d0().into()
}
#[inline]
fn into_jtag_m0(self) -> Alternate<GLB, N, typestate::JtagM0> {
fn into_jtag_m0(self) -> Alternate<'a, N, typestate::JtagM0> {
self.inner.into_jtag_m0().into()
}
#[inline]
fn into_jtag_lp(self) -> Alternate<GLB, N, typestate::JtagLp> {
fn into_jtag_lp(self) -> Alternate<'a, N, typestate::JtagLp> {
self.inner.into_jtag_lp().into()
}
}

impl<GLB, const N: usize, M> From<super::Inner<GLB, N, M>> for Alternate<GLB, N, M> {
impl<'a, const N: usize, M> From<super::Inner<'a, N, M>> for Alternate<'a, N, M> {
#[inline]
fn from(inner: super::Inner<GLB, N, M>) -> Self {
fn from(inner: super::Inner<'a, N, M>) -> Self {
Self { inner }
}
}
38 changes: 19 additions & 19 deletions bouffalo-hal/src/gpio/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,43 @@ use super::{
};

/// Trait for pad mode conversations.
pub trait IntoPad<GLB, const N: usize> {
pub trait IntoPad<'a, const N: usize> {
/// Configures the pad to operate as a pull up output pad.
fn into_pull_up_output(self) -> Output<GLB, N, PullUp>;
fn into_pull_up_output(self) -> Output<'a, N, PullUp>;
/// Configures the pad to operate as a pull down output pad.
fn into_pull_down_output(self) -> Output<GLB, N, PullDown>;
fn into_pull_down_output(self) -> Output<'a, N, PullDown>;
/// Configures the pad to operate as a floating output pad.
fn into_floating_output(self) -> Output<GLB, N, Floating>;
fn into_floating_output(self) -> Output<'a, N, Floating>;
/// Configures the pad to operate as a pull up input pad.
fn into_pull_up_input(self) -> Input<GLB, N, PullUp>;
fn into_pull_up_input(self) -> Input<'a, N, PullUp>;
/// Configures the pad to operate as a pull down input pad.
fn into_pull_down_input(self) -> Input<GLB, N, PullDown>;
fn into_pull_down_input(self) -> Input<'a, N, PullDown>;
/// Configures the pad to operate as a floating input pad.
fn into_floating_input(self) -> Input<GLB, N, Floating>;
fn into_floating_input(self) -> Input<'a, N, Floating>;
}

/// Trait for GLBv2 pad mode conversations.
pub trait IntoPadv2<GLB, const N: usize> {
pub trait IntoPadv2<'a, const N: usize> {
/// Configures the pin to operate as a SPI pin.
fn into_spi<const I: usize>(self) -> Alternate<GLB, N, typestate::Spi<I>>;
fn into_spi<const I: usize>(self) -> Alternate<'a, N, typestate::Spi<I>>;
/// Configures the pin to operate as a SDH pin.
fn into_sdh(self) -> Alternate<GLB, N, typestate::Sdh>;
fn into_sdh(self) -> Alternate<'a, N, typestate::Sdh>;
/// Configures the pin to operate as UART signal.
fn into_uart(self) -> Alternate<GLB, N, typestate::Uart>;
fn into_uart(self) -> Alternate<'a, N, typestate::Uart>;
/// Configures the pin to operate as multi-media cluster UART signal.
fn into_mm_uart(self) -> Alternate<GLB, N, typestate::MmUart>;
fn into_mm_uart(self) -> Alternate<'a, N, typestate::MmUart>;
/// Configures the pin to operate as a pull up Pulse Width Modulation signal pin.
fn into_pull_up_pwm<const I: usize>(self) -> Alternate<GLB, N, typestate::Pwm<I>>;
fn into_pull_up_pwm<const I: usize>(self) -> Alternate<'a, N, typestate::Pwm<I>>;
/// Configures the pin to operate as a pull down Pulse Width Modulation signal pin.
fn into_pull_down_pwm<const I: usize>(self) -> Alternate<GLB, N, typestate::Pwm<I>>;
fn into_pull_down_pwm<const I: usize>(self) -> Alternate<'a, N, typestate::Pwm<I>>;
/// Configures the pin to operate as floating Pulse Width Modulation signal pin.
fn into_floating_pwm<const I: usize>(self) -> Alternate<GLB, N, typestate::Pwm<I>>;
fn into_floating_pwm<const I: usize>(self) -> Alternate<'a, N, typestate::Pwm<I>>;
/// Configures the pin to operate as an Inter-Integrated Circuit signal pin.
fn into_i2c<const I: usize>(self) -> Alternate<GLB, N, typestate::I2c<I>>;
fn into_i2c<const I: usize>(self) -> Alternate<'a, N, typestate::I2c<I>>;
/// Configures the pin to operate as D0 core JTAG.
fn into_jtag_d0(self) -> Alternate<GLB, N, typestate::JtagD0>;
fn into_jtag_d0(self) -> Alternate<'a, N, typestate::JtagD0>;
/// Configures the pin to operate as M0 core JTAG.
fn into_jtag_m0(self) -> Alternate<GLB, N, typestate::JtagM0>;
fn into_jtag_m0(self) -> Alternate<'a, N, typestate::JtagM0>;
/// Configures the pin to operate as LP core JTAG.
fn into_jtag_lp(self) -> Alternate<GLB, N, typestate::JtagLp>;
fn into_jtag_lp(self) -> Alternate<'a, N, typestate::JtagLp>;
}
53 changes: 26 additions & 27 deletions bouffalo-hal/src/gpio/disabled.rs
Original file line number Diff line number Diff line change
@@ -1,96 +1,95 @@
#[cfg(any(doc, feature = "glb-v2"))]
use super::{alternate::Alternate, convert::IntoPadv2};
use super::{
alternate::Alternate,
convert::{IntoPad, IntoPadv2},
convert::IntoPad,
input::Input,
output::Output,
typestate::{self, Floating, PullDown, PullUp},
};
use crate::glb::RegisterBlock;
use core::ops::Deref;

/// GPIO pad which is disabled.
pub struct Disabled<GLB, const N: usize> {
inner: super::Inner<GLB, N, typestate::Disabled>,
pub struct Disabled<'a, const N: usize> {
inner: super::Inner<'a, N, typestate::Disabled>,
}

impl<GLB: Deref<Target = RegisterBlock>, const N: usize> IntoPad<GLB, N> for Disabled<GLB, N> {
impl<'a, const N: usize> IntoPad<'a, N> for Disabled<'a, N> {
#[inline]
fn into_pull_up_output(self) -> Output<GLB, N, PullUp> {
fn into_pull_up_output(self) -> Output<'a, N, PullUp> {
self.inner.into_pull_up_output().into()
}
#[inline]
fn into_pull_down_output(self) -> Output<GLB, N, PullDown> {
fn into_pull_down_output(self) -> Output<'a, N, PullDown> {
self.inner.into_pull_down_output().into()
}
#[inline]
fn into_floating_output(self) -> Output<GLB, N, Floating> {
fn into_floating_output(self) -> Output<'a, N, Floating> {
self.inner.into_floating_output().into()
}
#[inline]
fn into_pull_up_input(self) -> Input<GLB, N, PullUp> {
fn into_pull_up_input(self) -> Input<'a, N, PullUp> {
self.inner.into_pull_up_input().into()
}
#[inline]
fn into_pull_down_input(self) -> Input<GLB, N, PullDown> {
fn into_pull_down_input(self) -> Input<'a, N, PullDown> {
self.inner.into_pull_down_input().into()
}
#[inline]
fn into_floating_input(self) -> Input<GLB, N, Floating> {
fn into_floating_input(self) -> Input<'a, N, Floating> {
self.inner.into_floating_input().into()
}
}

#[cfg(any(doc, feature = "glb-v2"))]
impl<GLB: Deref<Target = RegisterBlock>, const N: usize> IntoPadv2<GLB, N> for Disabled<GLB, N> {
impl<'a, const N: usize> IntoPadv2<'a, N> for Disabled<'a, N> {
#[inline]
fn into_spi<const I: usize>(self) -> Alternate<GLB, N, typestate::Spi<I>> {
fn into_spi<const I: usize>(self) -> Alternate<'a, N, typestate::Spi<I>> {
self.inner.into_spi().into()
}
#[inline]
fn into_sdh(self) -> Alternate<GLB, N, typestate::Sdh> {
fn into_sdh(self) -> Alternate<'a, N, typestate::Sdh> {
self.inner.into_sdh().into()
}
#[inline]
fn into_uart(self) -> Alternate<GLB, N, typestate::Uart> {
fn into_uart(self) -> Alternate<'a, N, typestate::Uart> {
self.inner.into_uart().into()
}
#[inline]
fn into_mm_uart(self) -> Alternate<GLB, N, typestate::MmUart> {
fn into_mm_uart(self) -> Alternate<'a, N, typestate::MmUart> {
self.inner.into_mm_uart().into()
}
#[inline]
fn into_pull_up_pwm<const I: usize>(self) -> Alternate<GLB, N, typestate::Pwm<I>> {
fn into_pull_up_pwm<const I: usize>(self) -> Alternate<'a, N, typestate::Pwm<I>> {
self.inner.into_pull_up_pwm().into()
}
#[inline]
fn into_pull_down_pwm<const I: usize>(self) -> Alternate<GLB, N, typestate::Pwm<I>> {
fn into_pull_down_pwm<const I: usize>(self) -> Alternate<'a, N, typestate::Pwm<I>> {
self.inner.into_pull_down_pwm().into()
}
#[inline]
fn into_floating_pwm<const I: usize>(self) -> Alternate<GLB, N, typestate::Pwm<I>> {
fn into_floating_pwm<const I: usize>(self) -> Alternate<'a, N, typestate::Pwm<I>> {
self.inner.into_floating_pwm().into()
}
#[inline]
fn into_i2c<const I: usize>(self) -> Alternate<GLB, N, typestate::I2c<I>> {
fn into_i2c<const I: usize>(self) -> Alternate<'a, N, typestate::I2c<I>> {
self.inner.into_i2c().into()
}
#[inline]
fn into_jtag_d0(self) -> Alternate<GLB, N, typestate::JtagD0> {
fn into_jtag_d0(self) -> Alternate<'a, N, typestate::JtagD0> {
self.inner.into_jtag_d0().into()
}
#[inline]
fn into_jtag_m0(self) -> Alternate<GLB, N, typestate::JtagM0> {
fn into_jtag_m0(self) -> Alternate<'a, N, typestate::JtagM0> {
self.inner.into_jtag_m0().into()
}
#[inline]
fn into_jtag_lp(self) -> Alternate<GLB, N, typestate::JtagLp> {
fn into_jtag_lp(self) -> Alternate<'a, N, typestate::JtagLp> {
self.inner.into_jtag_lp().into()
}
}

impl<GLB, const N: usize> From<super::Inner<GLB, N, typestate::Disabled>> for Disabled<GLB, N> {
impl<'a, const N: usize> From<super::Inner<'a, N, typestate::Disabled>> for Disabled<'a, N> {
#[inline]
fn from(inner: super::Inner<GLB, N, typestate::Disabled>) -> Self {
fn from(inner: super::Inner<'a, N, typestate::Disabled>) -> Self {
Self { inner }
}
}
Loading

0 comments on commit 63c17cb

Please sign in to comment.