[][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. Pins with different PinIds or PinModes 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 PinModes, 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 PinMode for alternate peripheral functions

Disabled

Type-level variant of PinMode for disabled modes

Input

Type-level variant of PinMode for input modes

Output

Type-level variant of PinMode for output modes

Pin

A type-level GPIO pin, parameterized by PinId and PinMode types

Pins

Collection of all the individual Pins

Enums

A

Type-level variant of AlternateConfig for alternate peripheral function A

B

Type-level variant of AlternateConfig for alternate peripheral function B

C

Type-level variant of AlternateConfig for alternate peripheral function C

D

Type-level variant of AlternateConfig for alternate peripheral function D

E

Type-level variant of AlternateConfig for alternate peripheral function E

F

Type-level variant of AlternateConfig for alternate peripheral function F

Floating

Type-level variant of both DisabledConfig and InputConfig

G

Type-level variant of AlternateConfig for alternate peripheral function G

GroupA

Type-level variant of Group

GroupB

Type-level variant of Group

H

Type-level variant of AlternateConfig for alternate peripheral function H

I

Type-level variant of AlternateConfig for alternate peripheral function I

J

Type-level variant of AlternateConfig for alternate peripheral function J

K

Type-level variant of AlternateConfig for alternate peripheral function K

L

Type-level variant of AlternateConfig for alternate peripheral function L

M

Type-level variant of AlternateConfig for alternate peripheral function M

N

Type-level variant of AlternateConfig for alternate peripheral function N

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 DisabledConfig and InputConfig

PullUp

Type-level variant of both DisabledConfig and InputConfig

PushPull

Type-level variant of OutputConfig for a push-pull configuration

Readable

Type-level variant of OutputConfig for a readable push-pull configuration

Traits

AlternateConfig

Type-level enum for alternate peripheral function configurations

AnyPin

Meta-type representing any Pin

DisabledConfig

Type-level enum for disabled configurations

InputConfig

Type-level enum for input configurations

OptionalPin

Meta-type representing an optional Pin.

OutputConfig

Type-level enum for output configurations

PinId

Type-level enum for pin IDs

PinMode

Type-level enum representing pin modes

SomePin

Meta-type representing a valid Pin.

Type Definitions

AlternateA

Type-level variant of PinMode for alternate peripheral function A

AlternateB

Type-level variant of PinMode for alternate peripheral function B

AlternateC

Type-level variant of PinMode for alternate peripheral function C

AlternateD

Type-level variant of PinMode for alternate peripheral function D

AlternateE

Type-level variant of PinMode for alternate peripheral function E

AlternateF

Type-level variant of PinMode for alternate peripheral function F

AlternateG

Type-level variant of PinMode for alternate peripheral function G

AlternateH

Type-level variant of PinMode for alternate peripheral function H

AlternateI

Type-level variant of PinMode for alternate peripheral function I

AlternateJ

Type-level variant of PinMode for alternate peripheral function J

AlternateK

Type-level variant of PinMode for alternate peripheral function K

AlternateL

Type-level variant of PinMode for alternate peripheral function L

AlternateM

Type-level variant of PinMode for alternate peripheral function M

AlternateN

Type-level variant of PinMode for alternate peripheral function N

ConcretePin

Type alias to recover the corresponding concrete Pin type from a given implementation of AnyPin

FloatingDisabled

Type-level variant of PinMode for floating disabled mode

FloatingInput

Type-level variant of PinMode for floating input mode

PullDownDisabled

Type-level variant of PinMode for pull-down disabled mode

PullDownInput

Type-level variant of PinMode for pull-down input mode

PullUpDisabled

Type-level variant of PinMode for pull-up disabled mode

PullUpInput

Type-level variant of PinMode for pull-up input mode

PushPullOutput

Type-level variant of PinMode for push-pull output mode

ReadableOutput

Type-level variant of PinMode for readable push-pull output mode

Reset

Type alias for the PinMode at reset