//! Type-level tools to configure SERCOM pads
//!
//! This module helps configure [`Pin`]s as SERCOM pads. It provides type-level
//! tools to convert `Pin`s to the correct [`PinMode`] and to enforce type-level
//! constraints at compile-time.
//!
//! # Overview
//!
//! A SERCOM pad is defined by two types, its corresponding [`Sercom`] instance
//! and its [`PadNum`], from [`Pad0`] to [`Pad3`]. However, a given SERCOM pad
//! can usually be mapped to several possible [`PinId`]s.
//!
//! There are two primary traits defined in this module:
//! - The [`IsPad`] trait is implemented on `Pin` types that are properly
//! configured as SERCOM pads, with `PinMode` [`AlternateC`] or
//! [`AlternateD`]. It acts as both a [type class] for SERCOM pads and as a
//! [type-level function] to recover the corresponding [`Sercom`] and
//! [`PadNum`] types from the `Pin`.
//! - The [`GetPad`] trait maps each [`PinId`] to its corresponding, pad-related
//! types. The [`PadMode`] alias uses `GetPad` to recover the corresponding
//! `PinMode` for a given SERCOM pad, while the [`Pad`] alias recovers the
//! configured [`Pin`] type.
//!
//! [`AlternateC`]: crate::gpio::AlternateC
//! [`AlternateD`]: crate::gpio::AlternateD
//! [type class]: crate::typelevel#type-classes
//! [type-level function]: crate::typelevel#type-level-functions
use paste;
use seq;
use Sercom;
use crate OptionalPinId;
use crate;
use crate;
//==============================================================================
// PadNum
//==============================================================================
/// Type-level enum representing a SERCOM pad number
///
/// It has variants [`Pad0`], [`Pad1`], [`Pad2`] & [`Pad3`]. See the [type-level
/// enum] documentation for an explanation of the pattern.
///
/// [type-level enum]: crate::typelevel#type-level-enum
seq!;
//==============================================================================
// OptionalPadNum
//==============================================================================
/// Type-level equivalent of `Option<PadNum>`
///
/// See the [`OptionalKind`] documentation for more details on the pattern.
///
/// [`OptionalKind`]: crate::typelevel#optionalkind-trait-pattern
//==============================================================================
// IsPad
//==============================================================================
/// Type class for [`Pin`]s configured as SERCOM pads
///
/// This trait serves as both a [type class] for `Pin`s configured as SERCOM
/// pads and as a [type-level function] mapping each `Pin` type to its
/// corresponding [`Sercom`] and [`PadNum`].
///
/// [type class]: crate::typelevel#type-classes
/// [type-level function]: crate::typelevel#type-level-functions
//==============================================================================
// IsI2cPad
//==============================================================================
/// Type class for [`Pin`]s which can be used as I2C pads
///
/// This trait serves as a [type class] for `Pin`s configured as I2C pads.
///
/// [type class]: crate::typelevel#type-classes
//==============================================================================
// OptionalPad
//==============================================================================
/// Type-level equivalent of `Option<Pad>`
///
/// See the [`OptionalKind`] documentation for more details on the pattern.
///
/// [`OptionalKind`]: crate::typelevel#optionalkind-trait-pattern
/// Type-level equivalent of `Some(Pad)`
///
/// See the [`OptionalKind`] documentation for more details on the pattern.
///
/// [`OptionalKind`]: crate::typelevel#optionalkind-trait-pattern
//==============================================================================
// GetPad
//==============================================================================
/// Type-level function mapping [`PinId`]s to SERCOM-pad-related types
///
/// For SAMD21 and SAMx5x chips, a [`Sercom`] and a [`PinId`] is enough
/// information to uniquely identify a pad, so this trait returns the
/// corresponding [`PadNum`] and [`PinMode`].
///
/// For SAMD11 chips, on the other hand, some `PinId`s can serve as two
/// different `PadNum`s for the *same* `Sercom`. For these chips, `GetPad`
/// requires a second type parameter to specify the `PadNum` and only returns
/// the `PinMode`.
///
/// See the documentation on [type-level functions] for more details.
///
/// [type-level functions]: crate::typelevel#type-level-functions
/// Type-level function mapping [`PinId`]s to SERCOM-pad-related types
///
/// For SAMD21 and SAMx5x chips, a [`Sercom`] and a [`PinId`] is enough
/// information to uniquely identify a pad, so this trait returns the
/// corresponding [`PadNum`] and [`PinMode`].
///
/// For SAMD11 chips, on the other hand, some `PinId`s can serve as two
/// different `PadNum`s for the *same* `Sercom`. For these chips, `GetPad`
/// requires a second type parameter to specify the `PadNum` and only returns
/// the `PinMode`.
///
/// See the documentation on [type-level functions] for more details.
///
/// [type-level functions]: crate::typelevel#type-level-functions
//==============================================================================
// GetPad aliases
//==============================================================================
/// Type alias using [`GetPad`] to recover the [`PinMode`] for a given SERCOM
/// pad
pub type PadMode<S, N, I> = PinMode;
/// Type alias using [`GetPad`] to recover the [`PinMode`] for a given SERCOM
/// pad
pub type PadMode<S, I> = PinMode;
/// Type alias to recover a [`Pin`] configured as a SERCOM pad in the correct
/// [`PadMode`]
pub type Pad<S, N, I> = ;
/// Type alias to recover a [`Pin`] configured as a SERCOM pad in the correct
/// [`PadMode`]
pub type Pad<S, I> = ;
//==============================================================================
// GetOptionalPad
//==============================================================================
/// Type-level function mapping [`OptionalPinId`]s to their corresponding
/// [`OptionalPad`]s
///
/// This trait acts as a [type-level function] mapping `OptionalPinId`s to their
/// corresponding `OptionalPad`. In pseudo-Rust, it is the type-level equivalent
/// of starting with `Option<PinId>` and calling `.map(GetPad)` to recover an
/// `Option<Pad>`.
///
/// [type-level functions]: crate::typelevel#type-level-functions
//==============================================================================
// IoSet
//==============================================================================
pub use *;