use crate::target_device::PORT;
use hal::digital::v2::OutputPin;
#[cfg(feature = "unproven")]
use hal::digital::v2::{InputPin, StatefulOutputPin, ToggleableOutputPin};
pub use crate::gpio::v2::PinMode;
use crate::gpio::v2::{self, Alternate, AlternateConfig, InputConfig, OutputConfig, PinId};
pub trait GpioExt {
type Parts;
fn split(self) -> Self::Parts;
}
pub type Input<MODE> = v2::Input<MODE>;
pub type Output<MODE> = v2::Output<MODE>;
pub type Floating = v2::Floating;
pub type PullDown = v2::PullDown;
pub type PullUp = v2::PullUp;
pub type PushPull = v2::PushPull;
pub type OpenDrain = v2::PushPull;
pub type ReadableOpenDrain = v2::Readable;
pub type PfA = v2::AlternateA;
pub type PfB = v2::AlternateB;
pub type PfC = v2::AlternateC;
pub type PfD = v2::AlternateD;
pub type PfE = v2::AlternateE;
pub type PfF = v2::AlternateF;
pub type PfG = v2::AlternateG;
#[cfg(any(feature = "samd21", feature = "min-samd51g"))]
pub type PfH = v2::AlternateH;
#[cfg(feature = "min-samd51g")]
pub type PfI = v2::AlternateI;
#[cfg(feature = "min-samd51g")]
pub type PfJ = v2::AlternateJ;
#[cfg(feature = "min-samd51g")]
pub type PfK = v2::AlternateK;
#[cfg(feature = "min-samd51g")]
pub type PfL = v2::AlternateL;
#[cfg(feature = "min-samd51g")]
pub type PfM = v2::AlternateM;
#[cfg(feature = "min-samd51g")]
pub type PfN = v2::AlternateN;
pub trait IntoFunction<T> {
fn into_function(self, port: &mut Port) -> T;
}
pub struct Pin<I, M>
where
I: PinId,
M: PinMode,
{
pub(crate) pin: v2::Pin<I, M>,
}
impl<I, M> Pin<I, M>
where
I: PinId,
M: PinMode,
{
#[inline]
fn new() -> Pin<I, M> {
Pin {
pin: v2::Pin::new(),
}
}
#[allow(unused_variables)]
#[inline]
pub fn into_floating_input(self, port: &mut Port) -> Pin<I, Input<Floating>> {
Pin {
pin: self.pin.into_floating_input(),
}
}
#[allow(unused_variables)]
#[inline]
pub fn into_pull_down_input(self, port: &mut Port) -> Pin<I, Input<PullDown>> {
Pin {
pin: self.pin.into_pull_down_input(),
}
}
#[allow(unused_variables)]
#[inline]
pub fn into_pull_up_input(self, port: &mut Port) -> Pin<I, Input<PullUp>> {
Pin {
pin: self.pin.into_pull_up_input(),
}
}
#[allow(unused_variables)]
#[inline]
pub fn into_open_drain_output(self, port: &mut Port) -> Pin<I, Output<OpenDrain>> {
Pin {
pin: self.pin.into_push_pull_output(),
}
}
#[allow(unused_variables)]
#[inline]
pub fn into_readable_open_drain_output(
self,
port: &mut Port,
) -> Pin<I, Output<ReadableOpenDrain>> {
Pin {
pin: self.pin.into_readable_output(),
}
}
#[allow(unused_variables)]
#[inline]
pub fn into_push_pull_output(self, port: &mut Port) -> Pin<I, Output<PushPull>> {
Pin {
pin: self.pin.into_push_pull_output(),
}
}
#[inline]
fn into_alternate<C: AlternateConfig>(self) -> Pin<I, Alternate<C>> {
Pin {
pin: self.pin.into_alternate(),
}
}
#[allow(unused_variables)]
#[inline]
pub fn into_function_a(self, port: &mut Port) -> Pin<I, PfA> {
self.into_alternate()
}
#[allow(unused_variables)]
#[inline]
pub fn into_function_b(self, port: &mut Port) -> Pin<I, PfB> {
self.into_alternate()
}
#[allow(unused_variables)]
#[inline]
pub fn into_function_c(self, port: &mut Port) -> Pin<I, PfC> {
self.into_alternate()
}
#[allow(unused_variables)]
#[inline]
pub fn into_function_d(self, port: &mut Port) -> Pin<I, PfD> {
self.into_alternate()
}
#[allow(unused_variables)]
#[inline]
pub fn into_function_e(self, port: &mut Port) -> Pin<I, PfE> {
self.into_alternate()
}
#[allow(unused_variables)]
#[inline]
pub fn into_function_f(self, port: &mut Port) -> Pin<I, PfF> {
self.into_alternate()
}
#[allow(unused_variables)]
#[inline]
pub fn into_function_g(self, port: &mut Port) -> Pin<I, PfG> {
self.into_alternate()
}
#[cfg(any(feature = "samd21", feature = "min-samd51g"))]
#[allow(unused_variables)]
#[inline]
pub fn into_function_h(self, port: &mut Port) -> Pin<I, PfH> {
self.into_alternate()
}
#[cfg(feature = "min-samd51g")]
#[allow(unused_variables)]
#[inline]
pub fn into_function_i(self, port: &mut Port) -> Pin<I, PfI> {
self.into_alternate()
}
#[cfg(feature = "min-samd51g")]
#[allow(unused_variables)]
#[inline]
pub fn into_function_j(self, port: &mut Port) -> Pin<I, PfJ> {
self.into_alternate()
}
#[cfg(feature = "min-samd51g")]
#[allow(unused_variables)]
#[inline]
pub fn into_function_k(self, port: &mut Port) -> Pin<I, PfK> {
self.into_alternate()
}
#[cfg(feature = "min-samd51g")]
#[allow(unused_variables)]
#[inline]
pub fn into_function_l(self, port: &mut Port) -> Pin<I, PfL> {
self.into_alternate()
}
#[cfg(feature = "min-samd51g")]
#[allow(unused_variables)]
#[inline]
pub fn into_function_m(self, port: &mut Port) -> Pin<I, PfM> {
self.into_alternate()
}
#[cfg(feature = "min-samd51g")]
#[allow(unused_variables)]
#[inline]
pub fn into_function_n(self, port: &mut Port) -> Pin<I, PfN> {
self.into_alternate()
}
}
impl<I: PinId> Pin<I, Output<OpenDrain>> {
#[allow(unused_variables)]
#[inline]
pub fn internal_pull_up(&mut self, port: &mut Port, on: bool) {
unimplemented!();
}
}
impl<I, M> Pin<I, Output<M>>
where
I: PinId,
M: OutputConfig,
{
#[inline]
pub fn toggle(&mut self) {
self.pin._toggle();
}
}
#[cfg(feature = "unproven")]
impl<I, M> ToggleableOutputPin for Pin<I, Output<M>>
where
I: PinId,
M: OutputConfig,
{
type Error = ();
#[inline]
fn toggle(&mut self) -> Result<(), Self::Error> {
self.pin._toggle();
Ok(())
}
}
#[cfg(feature = "unproven")]
impl<I: PinId> InputPin for Pin<I, Output<ReadableOpenDrain>> {
type Error = ();
#[inline]
fn is_high(&self) -> Result<bool, Self::Error> {
Ok(self.pin._is_high())
}
#[inline]
fn is_low(&self) -> Result<bool, Self::Error> {
Ok(self.pin._is_low())
}
}
#[cfg(feature = "unproven")]
impl<I, M> InputPin for Pin<I, Input<M>>
where
I: PinId,
M: InputConfig,
{
type Error = ();
#[inline]
fn is_high(&self) -> Result<bool, Self::Error> {
Ok(self.pin._is_high())
}
#[inline]
fn is_low(&self) -> Result<bool, Self::Error> {
Ok(self.pin._is_low())
}
}
#[cfg(feature = "unproven")]
impl<I, M> StatefulOutputPin for Pin<I, Output<M>>
where
I: PinId,
M: OutputConfig,
{
#[inline]
fn is_set_high(&self) -> Result<bool, Self::Error> {
Ok(self.pin._is_set_high())
}
#[inline]
fn is_set_low(&self) -> Result<bool, Self::Error> {
Ok(self.pin._is_set_low())
}
}
impl<I, M> OutputPin for Pin<I, Output<M>>
where
I: PinId,
M: OutputConfig,
{
type Error = ();
#[inline]
fn set_high(&mut self) -> Result<(), Self::Error> {
self.pin._set_high();
Ok(())
}
#[inline]
fn set_low(&mut self) -> Result<(), Self::Error> {
self.pin._set_low();
Ok(())
}
}
impl<I, M, C> IntoFunction<Pin<I, Alternate<C>>> for Pin<I, M>
where
I: PinId,
M: PinMode,
C: AlternateConfig,
{
#[allow(unused_variables)]
#[inline]
fn into_function(self, port: &mut Port) -> Pin<I, Alternate<C>> {
self.into_alternate()
}
}
impl<I, M> From<v2::Pin<I, M>> for Pin<I, M>
where
I: PinId,
M: PinMode,
{
fn from(pin: v2::Pin<I, M>) -> Pin<I, M> {
Pin { pin }
}
}
impl<I, M> From<Pin<I, M>> for v2::Pin<I, M>
where
I: PinId,
M: PinMode,
{
fn from(pin: Pin<I, M>) -> v2::Pin<I, M> {
pin.pin
}
}
pub struct Port {
_0: (),
}
macro_rules! port {
([
$(
$( #[$cfg:meta] )?
($PinId:ident, $PinType:ident),
)+
]) => {
$crate::paste::item! {
$(
$( #[$cfg] )?
use v2::$PinId;
$( #[$cfg] )?
pub type $PinType<M> = Pin<$PinId, M>;
)+
pub struct Parts {
pub port: Port,
$(
$( #[$cfg] )?
pub [<$PinType:lower>]: $PinType<Input<Floating>>,
)+
}
impl GpioExt for PORT {
type Parts = Parts;
fn split(self) -> Parts {
Parts {
port: Port {_0: ()},
$(
$( #[$cfg] )?
[<$PinType:lower>]: Pin::<$PinId, _>::new(),
)+
}
}
}
}
};
}
port!([
#[cfg(not(feature = "samd11"))]
(PA00, Pa0),
#[cfg(not(feature = "samd11"))]
(PA01, Pa1),
(PA02, Pa2),
#[cfg(not(feature = "samd11"))]
(PA03, Pa3),
(PA04, Pa4),
(PA05, Pa5),
#[cfg(not(feature = "samd11"))]
(PA06, Pa6),
#[cfg(not(feature = "samd11"))]
(PA07, Pa7),
(PA08, Pa8),
(PA09, Pa9),
#[cfg(not(feature = "samd11"))]
(PA10, Pa10),
#[cfg(not(feature = "samd11"))]
(PA11, Pa11),
#[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))]
(PA12, Pa12),
#[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))]
(PA13, Pa13),
(PA14, Pa14),
(PA15, Pa15),
#[cfg(not(feature = "samd11"))]
(PA16, Pa16),
#[cfg(not(feature = "samd11"))]
(PA17, Pa17),
#[cfg(not(feature = "samd11"))]
(PA18, Pa18),
#[cfg(not(feature = "samd11"))]
(PA19, Pa19),
#[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))]
(PA20, Pa20),
#[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))]
(PA21, Pa21),
#[cfg(not(feature = "samd11"))]
(PA22, Pa22),
#[cfg(not(feature = "samd11"))]
(PA23, Pa23),
(PA24, Pa24),
(PA25, Pa25),
#[cfg(not(feature = "samd11"))]
(PA27, Pa27),
#[cfg(any(feature = "samd11", feature = "samd21"))]
(PA28, Pa28),
(PA30, Pa30),
(PA31, Pa31),
#[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))]
(PB00, Pb0),
#[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))]
(PB01, Pb1),
#[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))]
(PB02, Pb2),
#[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))]
(PB03, Pb3),
#[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))]
(PB04, Pb4),
#[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))]
(PB05, Pb5),
#[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))]
(PB06, Pb6),
#[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))]
(PB07, Pb7),
#[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))]
(PB08, Pb8),
#[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))]
(PB09, Pb9),
#[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))]
(PB10, Pb10),
#[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))]
(PB11, Pb11),
#[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))]
(PB12, Pb12),
#[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))]
(PB13, Pb13),
#[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))]
(PB14, Pb14),
#[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))]
(PB15, Pb15),
#[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))]
(PB16, Pb16),
#[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))]
(PB17, Pb17),
#[cfg(any(feature = "min-samd51n"))]
(PB18, Pb18),
#[cfg(any(feature = "min-samd51n"))]
(PB19, Pb19),
#[cfg(any(feature = "min-samd51n"))]
(PB20, Pb20),
#[cfg(any(feature = "min-samd51n"))]
(PB21, Pb21),
#[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))]
(PB22, Pb22),
#[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))]
(PB23, Pb23),
#[cfg(any(feature = "min-samd51n"))]
(PB24, Pb24),
#[cfg(any(feature = "min-samd51n"))]
(PB25, Pb25),
#[cfg(any(feature = "min-samd51p"))]
(PB26, Pb26),
#[cfg(any(feature = "min-samd51p"))]
(PB27, Pb27),
#[cfg(any(feature = "min-samd51p"))]
(PB28, Pb28),
#[cfg(any(feature = "min-samd51p"))]
(PB29, Pb29),
#[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))]
(PB30, Pb30),
#[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))]
(PB31, Pb31),
#[cfg(any(feature = "min-samd51n"))]
(PC00, Pc0),
#[cfg(any(feature = "min-samd51n"))]
(PC01, Pc1),
#[cfg(any(feature = "min-samd51n"))]
(PC02, Pc2),
#[cfg(any(feature = "min-samd51n"))]
(PC03, Pc3),
#[cfg(any(feature = "min-samd51p"))]
(PC04, Pc4),
#[cfg(any(feature = "min-samd51n"))]
(PC05, Pc5),
#[cfg(any(feature = "min-samd51n"))]
(PC06, Pc6),
#[cfg(any(feature = "min-samd51n"))]
(PC07, Pc7),
#[cfg(any(feature = "min-samd51n"))]
(PC10, Pc10),
#[cfg(any(feature = "min-samd51n"))]
(PC11, Pc11),
#[cfg(any(feature = "min-samd51n"))]
(PC12, Pc12),
#[cfg(any(feature = "min-samd51n"))]
(PC13, Pc13),
#[cfg(any(feature = "min-samd51n"))]
(PC14, Pc14),
#[cfg(any(feature = "min-samd51n"))]
(PC15, Pc15),
#[cfg(any(feature = "min-samd51n"))]
(PC16, Pc16),
#[cfg(any(feature = "min-samd51n"))]
(PC17, Pc17),
#[cfg(any(feature = "min-samd51n"))]
(PC18, Pc18),
#[cfg(any(feature = "min-samd51n"))]
(PC19, Pc19),
#[cfg(any(feature = "min-samd51n"))]
(PC20, Pc20),
#[cfg(any(feature = "min-samd51n"))]
(PC21, Pc21),
#[cfg(any(feature = "min-samd51p"))]
(PC22, Pc22),
#[cfg(any(feature = "min-samd51p"))]
(PC23, Pc23),
#[cfg(any(feature = "min-samd51n"))]
(PC24, Pc24),
#[cfg(any(feature = "min-samd51n"))]
(PC25, Pc25),
#[cfg(any(feature = "min-samd51n"))]
(PC26, Pc26),
#[cfg(any(feature = "min-samd51n"))]
(PC27, Pc27),
#[cfg(any(feature = "min-samd51n"))]
(PC28, Pc28),
#[cfg(any(feature = "min-samd51p"))]
(PC30, Pc30),
#[cfg(any(feature = "min-samd51p"))]
(PC31, Pc31),
#[cfg(any(feature = "min-samd51p"))]
(PD00, Pd0),
#[cfg(any(feature = "min-samd51p"))]
(PD01, Pd1),
#[cfg(any(feature = "min-samd51p"))]
(PD08, Pd8),
#[cfg(any(feature = "min-samd51p"))]
(PD09, Pd9),
#[cfg(any(feature = "min-samd51p"))]
(PD10, Pd10),
#[cfg(any(feature = "min-samd51p"))]
(PD11, Pd11),
#[cfg(any(feature = "min-samd51p"))]
(PD12, Pd12),
#[cfg(any(feature = "min-samd51p"))]
(PD20, Pd20),
#[cfg(any(feature = "min-samd51p"))]
(PD21, Pd21),
]);
#[macro_export]
macro_rules! define_pins {
($(#[$topattr:meta])* struct $Type:ident,
target_device: $target_device:ident,
$( $(#[$attr:meta])* pin $name:ident = $pin_ident:ident),+ , ) => {
$crate::paste::item! {
$(#[$topattr])*
pub struct $Type {
pub port: Port,
$(
$(#[$attr])*
pub $name: gpio::[<P $pin_ident>]<Input<Floating>>
),+
}
}
impl $Type {
$crate::paste::item! {
pub fn new(port: $target_device::PORT) -> Self {
let pins = port.split();
$Type {
port: pins.port,
$(
$(#[$attr])*
$name: pins.[<p $pin_ident>]
),+
}
}
}
}
}}