Struct avr_hal_generic::port::Pin

source ·
pub struct Pin<MODE, PIN> { /* private fields */ }
Expand description

Representation of an MCU pin.

Design Rationale

We want individual types per pin to model constraints which depend on a specific pin. For example, some peripherals are internally hard-wired to certain pins of the MCU.

Additionally, the mode of a pin should also be a part of the type to model enforcement of pins being in a certain mode and preventing misuse like for example calling set_high() on a pin configured as input.

To do this, the Pin type is generic over the MODE (input, output, …) and the PIN (pd0, pb5, pc6, …).

Of course, in some applications one does not care about the specific pin used. For these situations, the specific pin types can be “downgraded” into a dynamic type that can represent any pin. See Downgrading for more details.

Instantiation

The Peripherals struct in HAL and board-support crates usually contains a .pins field which is of type Pins. This Pins struct in turn has fields for each individual pin, in its default mode. You can then move the pin out of this struct to reconfigure it (examples in this documentation are for atmega-hal):

use atmega_hal::port::{Pin, mode, self};

let dp = atmega_hal::Peripherals::take().unwrap();
let pins = atmega_hal::pins!(dp);

let output: Pin<mode::Output, port::PD3> = pins.pd3.into_output();

Implementations§

source§

impl<PIN: PinOps, MODE: Io> Pin<MODE, PIN>

Configuration

To change the mode of a pin, use one of the following conversion functions. They consume the original Pin and return one with the desired mode. Only when a pin is in the correct mode, does it have the mode-relevant methods availailable (e.g. set_high() is only available for Output pins).

source

pub fn into_output(self) -> Pin<Output, PIN>

Convert this pin into an output pin, setting the state to low. See Digital Output.

source

pub fn into_output_high(self) -> Pin<Output, PIN>

Convert this pin into an output pin, setting the state to high. See Digital Output.

source

pub fn into_opendrain(self) -> Pin<OpenDrain, PIN>

Convert this pin into an open-drain output pin, setting the state to low. See Digital Output Open Drain

source

pub fn into_opendrain_high(self) -> Pin<OpenDrain, PIN>

Convert this pin into an open-drain output pin, setting the state to high. See Digital Output Open Drain

source

pub fn into_floating_input(self) -> Pin<Input<Floating>, PIN>

Convert this pin into a floating input pin. See Digital Input.

Note: To read deterministic values from the pin, it must be externally pulled to a defined level (either VCC or GND).

source

pub fn into_pull_up_input(self) -> Pin<Input<PullUp>, PIN>

Convert this pin into a pulled-up input pin. See Digital Input.

With no external circuit pulling the pin low, it will be read high.

source

pub fn into_analog_input<H, ADC, CLOCK>( self, adc: &mut Adc<H, ADC, CLOCK> ) -> Pin<Analog, PIN>
where Pin<Analog, PIN>: AdcChannel<H, ADC>, ADC: AdcOps<H>, CLOCK: Clock,

Convert this pin into an analog input (ADC channel). See Analog Input.

Some pins can be repurposed as ADC channels. For those pins, the into_analog_input() method is available.

source§

impl<PIN: PinOps, MODE: Io> Pin<MODE, PIN>

Downgrading

For applications where the exact pin is irrelevant, a specific pin can be downgraded to a “dynamic pin” which can represent any pin:

use atmega_hal::port::{Pin, mode};

let dp = atmega_hal::Peripherals::take().unwrap();
let pins = atmega_hal::pins!(dp);

let any_output_pin1: Pin<mode::Output> = pins.pd0.into_output().downgrade();
let any_output_pin2: Pin<mode::Output> = pins.pd1.into_output().downgrade();

// Because they now have the same type, you can, for example, stuff them into an array:
let pins: [Pin<mode::Output>; 2] = [any_output_pin1, any_output_pin2];
source

pub fn downgrade(self) -> Pin<MODE, PIN::Dynamic>

“Erase” type-level information about which specific pin is represented.

Note: The returned “dynamic” pin has runtime overhead compared to a specific pin.

source§

impl<PIN: PinOps, IMODE> Pin<Input<IMODE>, PIN>

Input-Mode Downgrading

There is a second kind of downgrading: In some cases it is not important whether an input pin is configured as mode::PullUp or mode::Floating. For this, you can “forget” the concrete input mode, leaving you with a type that is the same for pull-up or floating inputs:

use atmega_hal::port::{Pin, mode};

let dp = atmega_hal::Peripherals::take().unwrap();
let pins = atmega_hal::pins!(dp);

// This demo uses downgraded pins, but it works just as well
// with non-downgraded ones!
let input_pin1: Pin<mode::Input<mode::Floating>> = pins.pd0
    .into_floating_input()
    .downgrade();
let input_pin2: Pin<mode::Input<mode::Floating>> = pins.pd1
    .into_pull_up_input()
    .downgrade();

// With the input mode "forgotten", they have the same type now,
// even if electically different.
let any_inputs: [Pin<mode::Input>; 2] = [
    input_pin1.forget_imode(),
    input_pin2.forget_imode(),
];
source

pub fn forget_imode(self) -> Pin<Input, PIN>

“Erase” type-level information about whether the pin is currently a pull-up or a floating input.

source§

impl<PIN: PinOps> Pin<Output, PIN>

source

pub fn set_high(&mut self)

Set pin high (pull it to supply voltage).

source

pub fn set_low(&mut self)

Set pin low (pull it to GND).

source

pub fn toggle(&mut self)

Toggle a high pin to low and a low pin to high.

source

pub fn is_set_high(&self) -> bool

Check whether the pin is set high.

Note: The electrical state of the pin might differ due to external circuitry.

source

pub fn is_set_low(&self) -> bool

Check whether the pin is set low.

Note: The electrical state of the pin might differ due to external circuitry.

source§

impl<PIN: PinOps> Pin<OpenDrain, PIN>

source

pub fn set_high(&mut self)

Set the pin high (Input without PullUp so it is floating)

source

pub fn set_low(&mut self)

Set pin low (pull it to GND, Output to low).

source

pub fn is_high(&self) -> bool

Check whether the pin is set high.

Note: The electrical state of the pin might differ due to external circuitry.

source

pub fn is_low(&self) -> bool

Check whether the pin is set low.

Note: The electrical state of the pin might differ due to external circuitry.

source§

impl<PIN: PinOps, IMODE: InputMode> Pin<Input<IMODE>, PIN>

source

pub fn is_high(&self) -> bool

Check whether the pin is driven high.

source

pub fn is_low(&self) -> bool

Check whether the pin is driven low.

source§

impl<PIN: PinOps> Pin<Analog, PIN>

Analog Input

Some pins can be configured as ADC channels. For those pins, analog_read() can be used to read the voltage. analog_read() corresponds to a blocking ADC read:

let dp = atmega_hal::Peripherals::take().unwrap();
let pins = atmega_hal::pins!(dp);
let mut adc = atmega_hal::Adc::new(dp.ADC, Default::default());

let a0 = pins.pc0.into_analog_input(&mut adc);

let voltage = a0.analog_read(&mut adc);
// ^- this is equivalent to -v
let voltage = adc.read_blocking(&a0);
source

pub fn analog_read<H, ADC, CLOCK>(&self, adc: &mut Adc<H, ADC, CLOCK>) -> u16
where Pin<Analog, PIN>: AdcChannel<H, ADC>, ADC: AdcOps<H>, CLOCK: Clock,

source

pub fn into_channel<H, ADC>(self) -> Channel<H, ADC>
where Pin<Analog, PIN>: AdcChannel<H, ADC>, ADC: AdcOps<H>,

Convert this pin into a generic Channel type.

The generic channel type can be used to store multiple channels in an array.

source

pub fn into_digital<H, ADC, CLOCK>( self, adc: &mut Adc<H, ADC, CLOCK> ) -> Pin<Input<Floating>, PIN>
where Pin<Analog, PIN>: AdcChannel<H, ADC>, ADC: AdcOps<H>, CLOCK: Clock,

Convert this pin to a floating digital input pin.

The pin is re-enabled in the digital input buffer and is no longer usable as an analog input. You can get to other digital modes by calling one of the usual into_... methods on the return value of this function.

source§

impl<TC, PIN: PwmPinOps<TC>> Pin<PwmOutput<TC>, PIN>

source

pub fn enable(&mut self)

source

pub fn disable(&mut self)

source

pub fn get_duty(&self) -> <PIN as PwmPinOps<TC>>::Duty

source

pub fn get_max_duty(&self) -> <PIN as PwmPinOps<TC>>::Duty

source

pub fn set_duty(&mut self, duty: u8)

Trait Implementations§

source§

impl<PIN: PinOps, IMODE: InputMode> ErrorType for Pin<Input<IMODE>, PIN>

§

type Error = Infallible

Error type
source§

impl<PIN: PinOps> ErrorType for Pin<OpenDrain, PIN>

§

type Error = Infallible

Error type
source§

impl<PIN: PinOps> ErrorType for Pin<Output, PIN>

§

type Error = Infallible

Error type
source§

impl<TC, PIN: PwmPinOps<TC>> ErrorType for Pin<PwmOutput<TC>, PIN>

§

type Error = PwmError

Error type
source§

impl<PIN: PinOps, IMODE: InputMode> InputPin for Pin<Input<IMODE>, PIN>

source§

fn is_high(&mut self) -> Result<bool, Self::Error>

Is the input pin high?
source§

fn is_low(&mut self) -> Result<bool, Self::Error>

Is the input pin low?
source§

impl<PIN: PinOps, IMODE: InputMode> InputPin for Pin<Input<IMODE>, PIN>

§

type Error = Infallible

Error type
source§

fn is_high(&self) -> Result<bool, Self::Error>

Is the input pin high?
source§

fn is_low(&self) -> Result<bool, Self::Error>

Is the input pin low?
source§

impl<PIN: PinOps> InputPin for Pin<OpenDrain, PIN>

§

type Error = Infallible

Error type
source§

fn is_high(&self) -> Result<bool, Self::Error>

Is the input pin high?
source§

fn is_low(&self) -> Result<bool, Self::Error>

Is the input pin low?
source§

impl<PIN: PinOps> InputPin for Pin<OpenDrain, PIN>

source§

fn is_high(&mut self) -> Result<bool, Self::Error>

Is the input pin high?
source§

fn is_low(&mut self) -> Result<bool, Self::Error>

Is the input pin low?
source§

impl<TC, PIN: PwmPinOps<TC>> IntoPwmPin<TC, PIN> for Pin<Output, PIN>

source§

fn into_pwm(self, _timer: &TC) -> Pin<PwmOutput<TC>, PIN>

source§

impl<PIN: PinOps> OutputPin for Pin<OpenDrain, PIN>

source§

fn set_low(&mut self) -> Result<(), Self::Error>

Drives the pin low. Read more
source§

fn set_high(&mut self) -> Result<(), Self::Error>

Drives the pin high. Read more
source§

fn set_state(&mut self, state: PinState) -> Result<(), Self::Error>

Drives the pin high or low depending on the provided value. Read more
source§

impl<PIN: PinOps> OutputPin for Pin<OpenDrain, PIN>

§

type Error = Infallible

Error type
source§

fn set_high(&mut self) -> Result<(), Self::Error>

Drives the pin high Read more
source§

fn set_low(&mut self) -> Result<(), Self::Error>

Drives the pin low Read more
source§

fn set_state(&mut self, state: PinState) -> Result<(), Self::Error>

Drives the pin high or low depending on the provided value Read more
source§

impl<PIN: PinOps> OutputPin for Pin<Output, PIN>

§

type Error = Infallible

Error type
source§

fn set_high(&mut self) -> Result<(), Self::Error>

Drives the pin high Read more
source§

fn set_low(&mut self) -> Result<(), Self::Error>

Drives the pin low Read more
source§

fn set_state(&mut self, state: PinState) -> Result<(), Self::Error>

Drives the pin high or low depending on the provided value Read more
source§

impl<PIN: PinOps> OutputPin for Pin<Output, PIN>

source§

fn set_low(&mut self) -> Result<(), Self::Error>

Drives the pin low. Read more
source§

fn set_high(&mut self) -> Result<(), Self::Error>

Drives the pin high. Read more
source§

fn set_state(&mut self, state: PinState) -> Result<(), Self::Error>

Drives the pin high or low depending on the provided value. Read more
source§

impl<TC, PIN: PwmPinOps<TC, Duty = u8>> SetDutyCycle for Pin<PwmOutput<TC>, PIN>

source§

fn max_duty_cycle(&self) -> u16

Get the maximum duty cycle value. Read more
source§

fn set_duty_cycle(&mut self, duty: u16) -> Result<(), Self::Error>

Set the duty cycle to duty / max_duty. Read more
source§

fn set_duty_cycle_fully_off(&mut self) -> Result<(), Self::Error>

Set the duty cycle to 0%, or always inactive.
source§

fn set_duty_cycle_fully_on(&mut self) -> Result<(), Self::Error>

Set the duty cycle to 100%, or always active.
source§

fn set_duty_cycle_fraction( &mut self, num: u16, denom: u16 ) -> Result<(), Self::Error>

Set the duty cycle to num / denom. Read more
source§

fn set_duty_cycle_percent(&mut self, percent: u8) -> Result<(), Self::Error>

Set the duty cycle to percent / 100 Read more
source§

impl<PIN: PinOps> StatefulOutputPin for Pin<OpenDrain, PIN>

source§

fn is_set_high(&mut self) -> Result<bool, Self::Error>

Is the pin in drive high mode? Read more
source§

fn is_set_low(&mut self) -> Result<bool, Self::Error>

Is the pin in drive low mode? Read more
source§

fn toggle(&mut self) -> Result<(), Self::Error>

Toggle pin output.
source§

impl<PIN: PinOps> StatefulOutputPin for Pin<Output, PIN>

source§

fn is_set_high(&mut self) -> Result<bool, Self::Error>

Is the pin in drive high mode? Read more
source§

fn is_set_low(&mut self) -> Result<bool, Self::Error>

Is the pin in drive low mode? Read more
source§

fn toggle(&mut self) -> Result<(), Self::Error>

Toggle pin output.

Auto Trait Implementations§

§

impl<MODE, PIN> RefUnwindSafe for Pin<MODE, PIN>
where MODE: RefUnwindSafe, PIN: RefUnwindSafe,

§

impl<MODE, PIN> Send for Pin<MODE, PIN>
where MODE: Send, PIN: Send,

§

impl<MODE, PIN> Sync for Pin<MODE, PIN>
where MODE: Sync, PIN: Sync,

§

impl<MODE, PIN> Unpin for Pin<MODE, PIN>
where MODE: Unpin, PIN: Unpin,

§

impl<MODE, PIN> UnwindSafe for Pin<MODE, PIN>
where MODE: UnwindSafe, PIN: 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>,

§

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>,

§

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.