Skip to content

Commit

Permalink
gpio: rearrange Pad into Alternate and other structures
Browse files Browse the repository at this point in the history
Simplify inner structures into `Inner` struct.

Now struct Pad is split into Disabled, Input, Output and Alternate structures to make code clearer.

Signed-off-by: Zhouqi Jiang <[email protected]>
  • Loading branch information
luojia65 committed Dec 19, 2024
1 parent bd5965d commit 3678333
Show file tree
Hide file tree
Showing 11 changed files with 668 additions and 623 deletions.
103 changes: 6 additions & 97 deletions bouffalo-hal/src/gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
//! # }
//! ```
mod alternate;
mod convert;
mod disabled;
mod gpio_group;
Expand All @@ -129,6 +130,7 @@ mod pad_v1;
mod pad_v2;
mod typestate;

pub use alternate::Alternate;
pub use convert::{IntoPad, IntoPadv2};
pub use disabled::Disabled;
pub use gpio_group::Pads;
Expand All @@ -137,105 +139,12 @@ pub use output::Output;
pub use typestate::*;
pub use {pad_v1::Padv1, pad_v2::Padv2};

use crate::glb;
use core::ops::Deref;

cfg_if::cfg_if! {
if #[cfg(feature = "glb-v1")] {
pub use crate::glb::v1;
pub(crate) use pad_v1::Padv1 as Inner;
} else if #[cfg(feature = "glb-v2")] {
pub use crate::glb::v2;
}
}

/// Individual GPIO pad.
pub struct Pad<GLB, const N: usize, M> {
#[cfg(feature = "glb-v1")]
inner: pad_v1::Padv1<GLB, N, M>,
#[cfg(feature = "glb-v2")]
inner: pad_v2::Padv2<GLB, N, M>,
#[cfg(not(any(feature = "glb-v1", feature = "glb-v2")))]
inner: pad_dummy::PadDummy<GLB, N, M>,
}

// TODO: #[doc(cfg(feature = "glb-v2"))] once feature(doc_cfg) is stablized
#[cfg(any(doc, feature = "glb-v2"))]
impl<GLB: Deref<Target = glb::RegisterBlock>, const N: usize, M> Pad<GLB, N, M> {
/// Configures the pin to operate as a SPI pin.
#[inline]
pub fn into_spi<const I: usize>(self) -> Pad<GLB, N, Spi<I>> {
Pad {
inner: self.inner.into_spi(),
}
}
/// Configures the pin to operate as a SDH pin.
#[inline]
pub fn into_sdh(self) -> Pad<GLB, N, Sdh> {
Pad {
inner: self.inner.into_sdh(),
}
}
/// Configures the pin to operate as UART signal.
#[inline]
pub fn into_uart(self) -> Pad<GLB, N, Uart> {
Pad {
inner: self.inner.into_uart(),
}
}
/// Configures the pin to operate as multi-media cluster UART signal.
#[inline]
pub fn into_mm_uart(self) -> Pad<GLB, N, MmUart> {
Pad {
inner: self.inner.into_mm_uart(),
}
}
/// Configures the pin to operate as a pull up Pulse Width Modulation signal pin.
#[inline]
pub fn into_pull_up_pwm<const I: usize>(self) -> Pad<GLB, N, Pwm<I>> {
Pad {
inner: self.inner.into_pull_up_pwm(),
}
}
/// Configures the pin to operate as a pull down Pulse Width Modulation signal pin.
#[inline]
pub fn into_pull_down_pwm<const I: usize>(self) -> Pad<GLB, N, Pwm<I>> {
Pad {
inner: self.inner.into_pull_down_pwm(),
}
}
/// Configures the pin to operate as floating Pulse Width Modulation signal pin.
#[inline]
pub fn into_floating_pwm<const I: usize>(self) -> Pad<GLB, N, Pwm<I>> {
Pad {
inner: self.inner.into_floating_pwm(),
}
}
/// Configures the pin to operate as an Inter-Integrated Circuit signal pin.
#[inline]
pub fn into_i2c<const I: usize>(self) -> Pad<GLB, N, I2c<I>> {
Pad {
inner: self.inner.into_i2c(),
}
}
/// Configures the pin to operate as D0 core JTAG.
#[inline]
pub fn into_jtag_d0(self) -> Pad<GLB, N, JtagD0> {
Pad {
inner: self.inner.into_jtag_d0(),
}
}
/// Configures the pin to operate as M0 core JTAG.
#[inline]
pub fn into_jtag_m0(self) -> Pad<GLB, N, JtagM0> {
Pad {
inner: self.inner.into_jtag_m0(),
}
}
/// Configures the pin to operate as LP core JTAG.
#[inline]
pub fn into_jtag_lp(self) -> Pad<GLB, N, JtagLp> {
Pad {
inner: self.inner.into_jtag_lp(),
}
pub(crate) use pad_v2::Padv2 as Inner;
} else {
pub(crate) use pad_dummy::PadDummy as Inner;
}
}
99 changes: 99 additions & 0 deletions bouffalo-hal/src/gpio/alternate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
use super::{
convert::{IntoPad, IntoPadv2},

Check warning on line 2 in bouffalo-hal/src/gpio/alternate.rs

View workflow job for this annotation

GitHub Actions / Test (bouffalo-hal)

unused imports: `IntoPadv2` and `self`

Check warning on line 2 in bouffalo-hal/src/gpio/alternate.rs

View workflow job for this annotation

GitHub Actions / Test (bouffalo-rt)

unused imports: `IntoPadv2` and `self`
input::Input,
output::Output,
typestate::{self, Floating, PullDown, PullUp},
};
use crate::glb::RegisterBlock;
use core::ops::Deref;

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

impl<GLB: Deref<Target = RegisterBlock>, const N: usize, M> IntoPad<GLB, N>
for Alternate<GLB, N, M>
{
#[inline]
fn into_pull_up_output(self) -> Output<GLB, N, PullUp> {
self.inner.into_pull_up_output().into()
}
#[inline]
fn into_pull_down_output(self) -> Output<GLB, N, PullDown> {
self.inner.into_pull_down_output().into()
}
#[inline]
fn into_floating_output(self) -> Output<GLB, N, Floating> {
self.inner.into_floating_output().into()
}
#[inline]
fn into_pull_up_input(self) -> Input<GLB, N, PullUp> {
self.inner.into_pull_up_input().into()
}
#[inline]
fn into_pull_down_input(self) -> Input<GLB, N, PullDown> {
self.inner.into_pull_down_input().into()
}
#[inline]
fn into_floating_input(self) -> Input<GLB, 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>
{
#[inline]
fn into_spi<const I: usize>(self) -> Alternate<GLB, N, typestate::Spi<I>> {
self.inner.into_spi().into()
}
#[inline]
fn into_sdh(self) -> Alternate<GLB, N, typestate::Sdh> {
self.inner.into_sdh().into()
}
#[inline]
fn into_uart(self) -> Alternate<GLB, N, typestate::Uart> {
self.inner.into_uart().into()
}
#[inline]
fn into_mm_uart(self) -> Alternate<GLB, 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>> {
self.inner.into_pull_up_pwm().into()
}
#[inline]
fn into_pull_down_pwm<const I: usize>(self) -> Alternate<GLB, 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>> {
self.inner.into_floating_pwm().into()
}
#[inline]
fn into_i2c<const I: usize>(self) -> Alternate<GLB, N, typestate::I2c<I>> {
self.inner.into_i2c().into()
}
#[inline]
fn into_jtag_d0(self) -> Alternate<GLB, N, typestate::JtagD0> {
self.inner.into_jtag_d0().into()
}
#[inline]
fn into_jtag_m0(self) -> Alternate<GLB, N, typestate::JtagM0> {
self.inner.into_jtag_m0().into()
}
#[inline]
fn into_jtag_lp(self) -> Alternate<GLB, 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> {
#[inline]
fn from(inner: super::Inner<GLB, N, M>) -> Self {
Self { inner }
}
}
23 changes: 12 additions & 11 deletions bouffalo-hal/src/gpio/convert.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::{
alternate::Alternate,
input::Input,
output::Output,
typestate::{Floating, PullDown, PullUp},
Expand All @@ -23,25 +24,25 @@ pub trait IntoPad<GLB, const N: usize> {
/// Trait for GLBv2 pad mode conversations.
pub trait IntoPadv2<GLB, const N: usize> {
/// Configures the pin to operate as a SPI pin.
fn into_spi<const I: usize>(self) -> super::Pad<GLB, N, super::typestate::Spi<I>>;
fn into_spi<const I: usize>(self) -> Alternate<GLB, N, super::typestate::Spi<I>>;
/// Configures the pin to operate as a SDH pin.
fn into_sdh(self) -> super::Pad<GLB, N, super::typestate::Sdh>;
fn into_sdh(self) -> Alternate<GLB, N, super::typestate::Sdh>;
/// Configures the pin to operate as UART signal.
fn into_uart(self) -> super::Pad<GLB, N, super::typestate::Uart>;
fn into_uart(self) -> Alternate<GLB, N, super::typestate::Uart>;
/// Configures the pin to operate as multi-media cluster UART signal.
fn into_mm_uart(self) -> super::Pad<GLB, N, super::typestate::MmUart>;
fn into_mm_uart(self) -> Alternate<GLB, N, super::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) -> super::Pad<GLB, N, super::typestate::Pwm<I>>;
fn into_pull_up_pwm<const I: usize>(self) -> Alternate<GLB, N, super::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) -> super::Pad<GLB, N, super::typestate::Pwm<I>>;
fn into_pull_down_pwm<const I: usize>(self) -> Alternate<GLB, N, super::typestate::Pwm<I>>;
/// Configures the pin to operate as floating Pulse Width Modulation signal pin.
fn into_floating_pwm<const I: usize>(self) -> super::Pad<GLB, N, super::typestate::Pwm<I>>;
fn into_floating_pwm<const I: usize>(self) -> Alternate<GLB, N, super::typestate::Pwm<I>>;
/// Configures the pin to operate as an Inter-Integrated Circuit signal pin.
fn into_i2c<const I: usize>(self) -> super::Pad<GLB, N, super::typestate::I2c<I>>;
fn into_i2c<const I: usize>(self) -> Alternate<GLB, N, super::typestate::I2c<I>>;
/// Configures the pin to operate as D0 core JTAG.
fn into_jtag_d0(self) -> super::Pad<GLB, N, super::typestate::JtagD0>;
fn into_jtag_d0(self) -> Alternate<GLB, N, super::typestate::JtagD0>;
/// Configures the pin to operate as M0 core JTAG.
fn into_jtag_m0(self) -> super::Pad<GLB, N, super::typestate::JtagM0>;
fn into_jtag_m0(self) -> Alternate<GLB, N, super::typestate::JtagM0>;
/// Configures the pin to operate as LP core JTAG.
fn into_jtag_lp(self) -> super::Pad<GLB, N, super::typestate::JtagLp>;
fn into_jtag_lp(self) -> Alternate<GLB, N, super::typestate::JtagLp>;
}
81 changes: 31 additions & 50 deletions bouffalo-hal/src/gpio/disabled.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::{
alternate::Alternate,

Check warning on line 2 in bouffalo-hal/src/gpio/disabled.rs

View workflow job for this annotation

GitHub Actions / Test (bouffalo-hal)

unused imports: `IntoPadv2` and `alternate::Alternate`

Check warning on line 2 in bouffalo-hal/src/gpio/disabled.rs

View workflow job for this annotation

GitHub Actions / Test (bouffalo-rt)

unused imports: `IntoPadv2` and `alternate::Alternate`
convert::{IntoPad, IntoPadv2},
input::Input,
output::Output,
Expand All @@ -9,12 +10,7 @@ use core::ops::Deref;

/// GPIO pad which is disabled.
pub struct Disabled<GLB, const N: usize> {
#[cfg(feature = "glb-v1")]
inner: super::pad_v1::Padv1<GLB, N, typestate::Disabled>,
#[cfg(feature = "glb-v2")]
inner: super::pad_v2::Padv2<GLB, N, typestate::Disabled>,
#[cfg(not(any(feature = "glb-v1", feature = "glb-v2")))]
inner: super::pad_dummy::PadDummy<GLB, N, typestate::Disabled>,
inner: super::Inner<GLB, N, typestate::Disabled>,
}

impl<GLB: Deref<Target = RegisterBlock>, const N: usize> IntoPad<GLB, N> for Disabled<GLB, N> {
Expand Down Expand Up @@ -47,69 +43,54 @@ impl<GLB: Deref<Target = RegisterBlock>, const N: usize> IntoPad<GLB, N> for Dis
#[cfg(any(doc, feature = "glb-v2"))]
impl<GLB: Deref<Target = RegisterBlock>, const N: usize> IntoPadv2<GLB, N> for Disabled<GLB, N> {
#[inline]
fn into_spi<const I: usize>(self) -> super::Pad<GLB, N, super::typestate::Spi<I>> {
super::Pad {
inner: self.inner.into_spi(),
}
fn into_spi<const I: usize>(self) -> Alternate<GLB, N, typestate::Spi<I>> {
self.inner.into_spi().into()
}
#[inline]
fn into_sdh(self) -> super::Pad<GLB, N, super::typestate::Sdh> {
super::Pad {
inner: self.inner.into_sdh(),
}
fn into_sdh(self) -> Alternate<GLB, N, typestate::Sdh> {
self.inner.into_sdh().into()
}
#[inline]
fn into_uart(self) -> super::Pad<GLB, N, super::typestate::Uart> {
super::Pad {
inner: self.inner.into_uart(),
}
fn into_uart(self) -> Alternate<GLB, N, typestate::Uart> {
self.inner.into_uart().into()
}
#[inline]
fn into_mm_uart(self) -> super::Pad<GLB, N, super::typestate::MmUart> {
super::Pad {
inner: self.inner.into_mm_uart(),
}
fn into_mm_uart(self) -> Alternate<GLB, N, typestate::MmUart> {
self.inner.into_mm_uart().into()
}
#[inline]
fn into_pull_up_pwm<const I: usize>(self) -> super::Pad<GLB, N, super::typestate::Pwm<I>> {
super::Pad {
inner: self.inner.into_pull_up_pwm(),
}
fn into_pull_up_pwm<const I: usize>(self) -> Alternate<GLB, N, typestate::Pwm<I>> {
self.inner.into_pull_up_pwm().into()
}
#[inline]
fn into_pull_down_pwm<const I: usize>(self) -> super::Pad<GLB, N, super::typestate::Pwm<I>> {
super::Pad {
inner: self.inner.into_pull_down_pwm(),
}
fn into_pull_down_pwm<const I: usize>(self) -> Alternate<GLB, N, typestate::Pwm<I>> {
self.inner.into_pull_down_pwm().into()
}
#[inline]
fn into_floating_pwm<const I: usize>(self) -> super::Pad<GLB, N, super::typestate::Pwm<I>> {
super::Pad {
inner: self.inner.into_floating_pwm(),
}
fn into_floating_pwm<const I: usize>(self) -> Alternate<GLB, N, typestate::Pwm<I>> {
self.inner.into_floating_pwm().into()
}
#[inline]
fn into_i2c<const I: usize>(self) -> super::Pad<GLB, N, super::typestate::I2c<I>> {
super::Pad {
inner: self.inner.into_i2c(),
}
fn into_i2c<const I: usize>(self) -> Alternate<GLB, N, typestate::I2c<I>> {
self.inner.into_i2c().into()
}
#[inline]
fn into_jtag_d0(self) -> super::Pad<GLB, N, super::typestate::JtagD0> {
super::Pad {
inner: self.inner.into_jtag_d0(),
}
fn into_jtag_d0(self) -> Alternate<GLB, N, typestate::JtagD0> {
self.inner.into_jtag_d0().into()
}
#[inline]
fn into_jtag_m0(self) -> super::Pad<GLB, N, super::typestate::JtagM0> {
super::Pad {
inner: self.inner.into_jtag_m0(),
}
fn into_jtag_m0(self) -> Alternate<GLB, N, typestate::JtagM0> {
self.inner.into_jtag_m0().into()
}
#[inline]
fn into_jtag_lp(self) -> super::Pad<GLB, N, super::typestate::JtagLp> {
super::Pad {
inner: self.inner.into_jtag_lp(),
}
fn into_jtag_lp(self) -> Alternate<GLB, 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> {
#[inline]
fn from(inner: super::Inner<GLB, N, typestate::Disabled>) -> Self {
Self { inner }
}
}
Loading

0 comments on commit 3678333

Please sign in to comment.