[−][src]Module trellis_m4::gpio::v2::pin
Type-level module for GPIO pins
This module provides a type-level API for GPIO pins. It uses the type system
to track the state of pins at compile-time. To do so, it uses traits to
represent meta-types and types as instances of those meta-types. For
example, the trait InputConfig
acts as a type-level enum
of the
available input configurations, and the types Floating
, PullDown
and
PullUp
are the type-level variants of InputConfig
.
When applied as a trait bound, meta-types restrict type parameters to the
corresponding variants. All of the traits in this module are closed, using
the Sealed
trait pattern, so the type-level instances found in this module
are the only possible variants.
Type-level pins are parameterized by two main meta-types, PinId
and
PinMode
.
The PinId
meta-type identifies a pin by it's group (A, B, C or D) and
pin number. Each PinId
instance is named according to its datasheet
identifier, e.g. PA27
.
The PinMode
meta-type represents the various pin modes. The available
PinMode
variants are Disabled
, Input
, Output
and
Alternate
, each with its own corresponding configurations.
The Pin
struct acts as a type-level instance of a pin. It is
parameterized by two type parameters, a PinId
and a PinMode
.
Pin
s with different PinId
s or PinMode
s are considered distinct
types by the compiler. As a consequence, converting from one PinMode
to
another requires changing type. Functions that change PinMode
must
consume the existing instance and return a new instance.
It is not possible for users to create new instances of a Pin
. Singleton
instances of each pin are made available to users through the Pins
struct.
To create the Pins
struct, users must supply the PAC
PORT
peripheral. The Pins
struct takes
ownership of the PORT
and provides the
corresponding pins. Each Pin
within the Pins
struct can be moved out
and used individually.
let mut peripherals = Peripherals::take().unwrap(); let pins = Pins::new(peripherals.PORT);
Pins can be converted between modes using several different methods.
// Use one of the literal function names let pa27 = pins.pa27.into_floating_input(); // Use a generic method and one of the `PinMode` variant types let pa27 = pins.pa27.into_mode::<FloatingInput>(); // Specify the target type and use `From`/`Into` let pa27: Pin<PA27, FloatingInput> = pins.pa27.into();
Embedded HAL traits
This module implements all of the embedded HAL GPIO traits for each Pin
in the corresponding PinMode
s, namely:
InputPin
,
OutputPin
,
ToggleableOutputPin
and
StatefulOutputPin
.
Type-level encapsulation
Normally, storing a generic pin within some data structure requires two type parameters.
struct UserStruct<I: PinId, M: PinMode> { pin: Pin<I, M> }
As an alternative, this module provides a trait to encapsulate a pin with a
single type-parameter, AnyPin
. The AnyPin
trait is implemented by
every possible variant of Pin
, so it can be used as a trait bound for
pins. With this approach, only one type parameter is required.
struct UserStruct<P: AnyPin> { pin: P }
Moreover, no information is lost with this approach, because the AnyPin
trait has associated types for each type parameter of Pin
. Use these
associated types to apply trait bounds or restrict the pin in some way.
struct UserStruct<P> where P: AnyPin<Mode = AlternateE>, P::Id: SomeUserTrait, { pin: P }
However, note that working with a generic type constrained by AnyPin
is
a bit different than working directly with a concrete type. See the
AnyPin
documentation for more details.
Optional pins
Finally, this module provides an easy way to implement optional pins. The
trait OptionalPin
is implemented for each Pin
as well as the
NoneT
struct.
NoneT
acts as a type-level version of the
None
variant. The SomePin
trait has both
OptionalPin
and AnyPin
as super traits, so it can be used as a bound
to guarantee a valid pin and provide access to the AnyPin
associated
types.
struct UserStruct<P: OptionalPin> { pin: P } impl<P: OptionalPin> UserStruct<P> { pub fn new() -> UserStruct<NoneT> { UserStruct { pin: NoneT } } pub fn init<Q>(self, pin: Q) -> UserStruct<Q> where Q: SomePin<Mode = PushPullOutput>, { UserStruct { pin } } }
Structs
Alternate | Type-level variant of |
Disabled | Type-level variant of |
Input | Type-level variant of |
Output | Type-level variant of |
Pin | A type-level GPIO pin, parameterized by |
Pins | Collection of all the individual |
Enums
A | Type-level variant of |
B | Type-level variant of |
C | Type-level variant of |
D | Type-level variant of |
E | Type-level variant of |
F | Type-level variant of |
Floating | Type-level variant of both |
G | Type-level variant of |
GroupA | Type-level variant of |
GroupB | Type-level variant of |
H | Type-level variant of |
I | Type-level variant of |
J | Type-level variant of |
K | Type-level variant of |
L | Type-level variant of |
M | Type-level variant of |
N | Type-level variant of |
PA00 | Pin ID representing pin PA00 |
PA01 | Pin ID representing pin PA01 |
PA02 | Pin ID representing pin PA02 |
PA03 | Pin ID representing pin PA03 |
PA04 | Pin ID representing pin PA04 |
PA05 | Pin ID representing pin PA05 |
PA06 | Pin ID representing pin PA06 |
PA07 | Pin ID representing pin PA07 |
PA08 | Pin ID representing pin PA08 |
PA09 | Pin ID representing pin PA09 |
PA10 | Pin ID representing pin PA10 |
PA11 | Pin ID representing pin PA11 |
PA12 | Pin ID representing pin PA12 |
PA13 | Pin ID representing pin PA13 |
PA14 | Pin ID representing pin PA14 |
PA15 | Pin ID representing pin PA15 |
PA16 | Pin ID representing pin PA16 |
PA17 | Pin ID representing pin PA17 |
PA18 | Pin ID representing pin PA18 |
PA19 | Pin ID representing pin PA19 |
PA20 | Pin ID representing pin PA20 |
PA21 | Pin ID representing pin PA21 |
PA22 | Pin ID representing pin PA22 |
PA23 | Pin ID representing pin PA23 |
PA24 | Pin ID representing pin PA24 |
PA25 | Pin ID representing pin PA25 |
PA27 | Pin ID representing pin PA27 |
PA30 | Pin ID representing pin PA30 |
PA31 | Pin ID representing pin PA31 |
PB02 | Pin ID representing pin PB02 |
PB03 | Pin ID representing pin PB03 |
PB08 | Pin ID representing pin PB08 |
PB09 | Pin ID representing pin PB09 |
PB10 | Pin ID representing pin PB10 |
PB11 | Pin ID representing pin PB11 |
PB22 | Pin ID representing pin PB22 |
PB23 | Pin ID representing pin PB23 |
PullDown | Type-level variant of both |
PullUp | Type-level variant of both |
PushPull | Type-level variant of |
Readable | Type-level variant of |
Traits
AlternateConfig | Type-level |
AnyPin | Meta-type representing any |
DisabledConfig | Type-level |
InputConfig | Type-level |
OptionalPin | Meta-type representing an optional |
OutputConfig | Type-level |
PinId | Type-level |
PinMode | Type-level |
SomePin | Meta-type representing a valid |
Type Definitions
AlternateA | Type-level variant of |
AlternateB | Type-level variant of |
AlternateC | Type-level variant of |
AlternateD | Type-level variant of |
AlternateE | Type-level variant of |
AlternateF | Type-level variant of |
AlternateG | Type-level variant of |
AlternateH | Type-level variant of |
AlternateI | Type-level variant of |
AlternateJ | Type-level variant of |
AlternateK | Type-level variant of |
AlternateL | Type-level variant of |
AlternateM | Type-level variant of |
AlternateN | Type-level variant of |
ConcretePin | Type alias to recover the corresponding concrete |
FloatingDisabled | Type-level variant of |
FloatingInput | Type-level variant of |
PullDownDisabled | Type-level variant of |
PullDownInput | Type-level variant of |
PullUpDisabled | Type-level variant of |
PullUpInput | Type-level variant of |
PushPullOutput | Type-level variant of |
ReadableOutput | Type-level variant of |
Reset | Type alias for the |