Pin

Struct Pin 

Source
pub struct Pin<T: Trait, S: State> { /* private fields */ }
Expand description

Main API for controlling pins

Pin has two type parameters:

  • T, to indicate which specific pin this instance of Pin represents (PIO0_0, PIO0_1, and so on).
  • S, to indicate which state the represented pin is currently in.

A pin instance can be in one of the following states:

  • state::Unused, to indicate that the pin is currently not used.
  • state::Swm, to indicate that the pin is available for switch matrix function assignment.
  • state::Analog, to indicate that the pin is being used for analog input.

A pin that is in the GPIO state is represented by its own struct, GpioPin.

§State Management

All pins start out in their initial state, as defined in the user manual. To prevent the user from making a mistake, only the methods that induce a valid state transition are available. Code that tries to call a method that would cause an invalid state transition will simply not compile:

// Assign a function to a pin
let (clkout, pio0_12) = swm.movable_functions.clkout.assign(
    p.pins.pio0_12.into_swm_pin(),
    &mut swm_handle,
);

// As long as a function is assigned, we can't use the pin for general-
// purpose I/O. Therefore the following method call would cause a compile-
// time error.
// let pio0_12 = pio0_12.into_input_pin(&p.GPIO);

To use the pin in the above example for GPIO, we first have to unassign the movable function and transition the pin to the unused state:


let (clkout, pio0_12) = clkout.unassign(pio0_12, &mut swm_handle);
let pio0_12 = pio0_12.into_unused_pin();

// Now we can transition the pin into a GPIO state.
let pio0_12 = pio0_12.into_input_pin(gpio.tokens.pio0_12);

§General Purpose I/O

All pins can be used for general-purpose I/O (GPIO), meaning they can be used for reading digital input signals and writing digital output signals. To set up a pin for GPIO use, you need to call Pin::into_input_pin or Pin::into_output_pin when it is in its unused state.

This will return a GpioPin, which provides the GPIO API.

§Fixed and Movable Functions

Besides general-purpose I/O, pins can be used for a number of more specialized functions. Some of those can be used only on one specific pin (fixed functions), others can be assigned to any pin (movable functions).

Before you can assign any functions to a pin, you need to transition it from the unused state to the SWM state using Pin::into_swm_pin.

let pin = p.pins.pio0_12
    .into_swm_pin();

// Functions can be assigned now using the SWM API

As mentioned above, a function can be fixed or movable. But there is also another distinction: Functions can be input or output functions. Any number of input functions can be assigned to a pin at the same time, but at most one output function can be assigned to a pin at once (see user manual, section 7.4). These rules are enforced by the API at compile time.

NOTE: There is some uncertainty about whether those rules treat GPIO as just another kind of function, or if they don’t apply to it. Currently, this API treats GPIO as something entirely different from the switch matrix functions, which may be too restrictive. If you have any insight on this topic, please help us figure this out.

Once a pin is in the SWM state, you can assign functions to it. Please refer to the SWM API for more information on how to do that.

§Analog Input

To use a pin for analog input, you need to assign an ADC function:

use lpc8xx_hal::Peripherals;

let p = Peripherals::take().unwrap();

let mut syscon = p.SYSCON.split();
let mut swm = p.SWM.split();

#[cfg(feature = "82x")]
let mut swm_handle = swm.handle;
#[cfg(feature = "845")]
let mut swm_handle = swm.handle.enable(&mut syscon.handle);

// Transition pin to ADC state
let (adc_2, pio0_14) = swm.fixed_functions.adc_2.assign(
    p.pins.pio0_14.into_swm_pin(),
    &mut swm_handle,
);

Implementations§

Source§

impl<T> Pin<T, Unused>
where T: Trait,

Source

pub fn into_input_pin(self, _token: Token<T, Enabled>) -> GpioPin<T, Input>

Transition pin to GPIO input mode

This method is only available while the pin is in the unused state. Code that attempts to call this method while the pin is in any other state will not compile. See State Management for more information on managing pin states.

Consumes this Pin instance and returns an instance of GpioPin, which provides access to all GPIO functions.

This method requires a GPIO token from the GPIO struct, to ensure that the GPIO peripheral is enabled, and stays enabled while the pin is in the GPIO mode.

§Example
use lpc8xx_hal::prelude::*;
use lpc8xx_hal::Peripherals;

let p = Peripherals::take().unwrap();

let mut syscon = p.SYSCON.split();
let swm = p.SWM.split();

#[cfg(feature = "82x")]
let gpio = p.GPIO;
#[cfg(feature = "845")]
let gpio = p.GPIO.enable(&mut syscon.handle);

// Transition pin into GPIO state, then set it to output
let mut pin = p.pins.pio0_12
    .into_input_pin(gpio.tokens.pio0_12);

// Input level can now be read
if pin.is_high() {
    // The pin is high
} else {
    // The pin is low
}
Source

pub fn into_output_pin( self, _token: Token<T, Enabled>, initial: Level, ) -> GpioPin<T, Output>

Transition pin to GPIO output mode

This method is only available while the pin is in the unused state. Code that attempts to call this method while the pin is in any other state will not compile. See State Management for more information on managing pin states.

Consumes this Pin instance and returns an instance of GpioPin, which provides access to all GPIO functions.

This method requires a GPIO token from the GPIO struct, to ensure that the GPIO peripheral is enabled, and stays enabled while the pin is in the GPIO mode.

§Example
use lpc8xx_hal::{
    prelude::*,
    Peripherals,
    gpio,
};

let p = Peripherals::take().unwrap();

let mut syscon = p.SYSCON.split();
let swm = p.SWM.split();

#[cfg(feature = "82x")]
let gpio = p.GPIO;
#[cfg(feature = "845")]
let gpio = p.GPIO.enable(&mut syscon.handle);

// Transition pin into GPIO state, then set it to output
let mut pin = p.pins.pio0_12.into_output_pin(
    gpio.tokens.pio0_12,
    gpio::Level::Low,
);

// Output level can now be controlled
pin.set_high();
pin.set_low();
Source

pub fn into_dynamic_pin( self, _token: Token<T, Enabled>, level: Level, direction: DynamicPinDirection, ) -> GpioPin<T, Dynamic>

Transition pin to Dynamic mode, i.e. GPIO direction switchable at runtime

This method is only available while the pin is in the unused state. Code that attempts to call this method while the pin is in any other state will not compile. See State Management for more information on managing pin states.

Consumes this Pin instance and returns an instance of GpioPin, which provides access to all GPIO functions.

This method requires a GPIO token from the GPIO struct, to ensure that the GPIO peripheral is enabled, and stays enabled while the pin is in the GPIO mode.

§Example
use lpc8xx_hal::{
    prelude::*,
    Peripherals,
    gpio,
    pins
};

let p = Peripherals::take().unwrap();

let mut syscon = p.SYSCON.split();
let swm = p.SWM.split();

#[cfg(feature = "82x")]
let gpio = p.GPIO;
#[cfg(feature = "845")]
let gpio = p.GPIO.enable(&mut syscon.handle);

// Transition pin into GPIO state, then set it to output
let mut pin = p.pins.pio0_12.into_dynamic_pin(
    gpio.tokens.pio0_12,
    gpio::Level::Low,
    pins::DynamicPinDirection::Input,
);

// Direction can now be switched
pin.switch_to_input();

// in/output pin functions are available while pin has the matching direction
let is_high = pin.is_high();
let is_low = pin.is_low();

pin.switch_to_output(gpio::Level::Low);
pin.set_high();
pin.set_low();

// pin direction can be queried
let is_input = pin.direction_is_input();
let is_output = pin.direction_is_output();
Source

pub fn into_swm_pin(self) -> Pin<T, Swm<(), ()>>

Transition pin to SWM mode

This method is only available while the pin is in the unused state. Code that attempts to call this method while the pin is in any other state will not compile. See State Management for more information on managing pin states.

Consumes this pin instance and returns a new instance that is in the SWM state, making this pin available for switch matrix function assignment.

Please refer to the SWM API to learn more about SWM function assignment.

§Example
use lpc8xx_hal::Peripherals;

let p = Peripherals::take().unwrap();

let pin = p.pins.pio0_12
    .into_swm_pin();

// `pin` is now ready for function assignment
Source

pub fn into_generic_dynamic_pin( self, _token: Token<T, Enabled>, level: Level, direction: DynamicPinDirection, ) -> GpioPin<GenericPin, Dynamic>

Transition pin into a Dynamic Generic Pin, i.e.

  • GPIO direction switchable at runtime
  • Pin identifying information is not part of the Pin’s type, e.g. can be generalized and managed in collections

If you don’t absolutely need this flexibility, it is recommended you use In/Output Pins or regular (i.e. pin-specific at compile time) Dynamic Pins instead, as they will prevent wrong usage of level- and direction changes at compile time.

This method is only available while the pin is in the unused state. Code that attempts to call this method while the pin is in any other state will not compile. See [State Management] for more information on managing pin states.

Consumes this Pin instance and returns an instance of GpioPin holding a GenericPin, which provides access to all GPIO functions.

This method requires a GPIO token from the GPIO struct, to ensure that the GPIO peripheral is enabled and not already in use. It consumes the GPIO token and converts its infromation into a GenericPin.

§Example
use lpc8xx_hal::{
    prelude::*,
    Peripherals,
    gpio::{direction::Dynamic, GpioPin, Level},
    pins
};

let p = Peripherals::take().unwrap();

let mut syscon = p.SYSCON.split();

#[cfg(feature = "82x")]
let gpio = p.GPIO;
#[cfg(feature = "845")]
let gpio = p.GPIO.enable(&mut syscon.handle);

// Gather pins in an array
let mut my_pins: [GpioPin<pins::GenericPin, Dynamic>; 2] = [
   p.pins.pio0_12.into_generic_dynamic_pin(
       gpio.tokens.pio0_12,
       Level::High,
       pins::DynamicPinDirection::Output,
   ),
   p.pins.pio0_15.into_generic_dynamic_pin(
       gpio.tokens.pio0_15,
       Level::High,
       pins::DynamicPinDirection::Output,
   ),
];

// loop through pins and change their direction without having to know their exact IDs
for pin in my_pins.iter_mut() {
    pin.switch_to_input();
}
Source§

impl<T> Pin<T, Swm<(), ()>>
where T: Trait,

Source

pub fn into_unused_pin(self) -> Pin<T, Unused>

Transitions this pin from the SWM state to the unused state

This method is only available, if two conditions are met:

  • The pin is in the SWM state.
  • No functions are assigned to this pin.

Unless both of these conditions are met, code trying to call this method will not compile.

Consumes the pin instance and returns a new pin instance, its type state indicating it is unused. This makes it possible to use the pin for something else. See State Management for more information on managing pin states.

Trait Implementations§

Source§

impl<T, F> AssignFunction<F, Analog> for Pin<T, Swm<(), ()>>
where T: Trait, F: FunctionTrait<T, Kind = Analog>,

Source§

type Assigned = Pin<T, Analog>

The type of the pin after the function has been assigned
Source§

fn assign(self) -> Self::Assigned

Internal method for assigning a function to a pin
Source§

impl<T, F, O, Is> AssignFunction<F, Input> for Pin<T, Swm<O, Is>>
where T: Trait, F: FunctionTrait<T, Kind = Input>,

Source§

type Assigned = Pin<T, Swm<O, (Is,)>>

The type of the pin after the function has been assigned
Source§

fn assign(self) -> Self::Assigned

Internal method for assigning a function to a pin
Source§

impl<T, F, Is> AssignFunction<F, Output> for Pin<T, Swm<(), Is>>
where T: Trait, F: FunctionTrait<T, Kind = Output>,

Source§

type Assigned = Pin<T, Swm<((),), Is>>

The type of the pin after the function has been assigned
Source§

fn assign(self) -> Self::Assigned

Internal method for assigning a function to a pin
Source§

impl<T, F, O, Is> UnassignFunction<F, Input> for Pin<T, Swm<O, (Is,)>>
where T: Trait, F: FunctionTrait<T, Kind = Input>,

Source§

type Unassigned = Pin<T, Swm<O, Is>>

The type of the pin after the function has been unassigned
Source§

fn unassign(self) -> Self::Unassigned

Internal method for unassigning a function from a pin
Source§

impl<T, F, Is> UnassignFunction<F, Output> for Pin<T, Swm<((),), Is>>
where T: Trait, F: FunctionTrait<T, Kind = Output>,

Source§

type Unassigned = Pin<T, Swm<(), Is>>

The type of the pin after the function has been unassigned
Source§

fn unassign(self) -> Self::Unassigned

Internal method for unassigning a function from a pin

Auto Trait Implementations§

§

impl<T, S> Freeze for Pin<T, S>
where T: Freeze, S: Freeze,

§

impl<T, S> RefUnwindSafe for Pin<T, S>

§

impl<T, S> Send for Pin<T, S>
where T: Send, S: Send,

§

impl<T, S> Sync for Pin<T, S>
where T: Sync, S: Sync,

§

impl<T, S> Unpin for Pin<T, S>
where T: Unpin, S: Unpin,

§

impl<T, S> UnwindSafe for Pin<T, S>
where T: UnwindSafe, S: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.