Struct esp_idf_hal::gpio::PinDriver

source ·
pub struct PinDriver<'d, T: Pin, MODE> { /* private fields */ }
Expand description

A driver for a GPIO pin.

The driver can set the pin as a disconnected/disabled one, input, or output pin, or both or analog. On some chips (i.e. esp32 and esp32s*), the driver can also set the pin in RTC IO mode. Depending on the current operating mode, different sets of functions are available.

The mode-setting depends on the capabilities of the pin as well, i.e. input-only pins cannot be set into output or input-output mode.

Implementations§

source§

impl<'d, T: Pin> PinDriver<'d, T, Disabled>

source

pub fn disabled(pin: impl Peripheral<P = T> + 'd) -> Result<Self, EspError>

Creates the driver for a pin in disabled state.

source§

impl<'d, T: InputPin> PinDriver<'d, T, Input>

source

pub fn input(pin: impl Peripheral<P = T> + 'd) -> Result<Self, EspError>

Creates the driver for a pin in input state.

source§

impl<'d, T: InputPin + OutputPin> PinDriver<'d, T, InputOutput>

source

pub fn input_output(pin: impl Peripheral<P = T> + 'd) -> Result<Self, EspError>

Creates the driver for a pin in input-output state.

source§

impl<'d, T: InputPin + OutputPin> PinDriver<'d, T, InputOutput>

source

pub fn input_output_od( pin: impl Peripheral<P = T> + 'd ) -> Result<Self, EspError>

Creates the driver for a pin in input-output open-drain state.

source§

impl<'d, T: OutputPin> PinDriver<'d, T, Output>

source

pub fn output(pin: impl Peripheral<P = T> + 'd) -> Result<Self, EspError>

Creates the driver for a pin in output state.

source§

impl<'d, T: OutputPin> PinDriver<'d, T, Output>

source

pub fn output_od(pin: impl Peripheral<P = T> + 'd) -> Result<Self, EspError>

Creates the driver for a pin in output open-drain state.

source§

impl<'d, T: Pin, MODE> PinDriver<'d, T, MODE>

source

pub fn pin(&self) -> i32

Returns the pin number.

source

pub fn into_disabled(self) -> Result<PinDriver<'d, T, Disabled>, EspError>

Put the pin into disabled mode.

source

pub fn into_input(self) -> Result<PinDriver<'d, T, Input>, EspError>
where T: InputPin,

Put the pin into input mode.

source

pub fn into_input_output( self ) -> Result<PinDriver<'d, T, InputOutput>, EspError>
where T: InputPin + OutputPin,

Put the pin into input + output mode.

source

pub fn into_input_output_od( self ) -> Result<PinDriver<'d, T, InputOutput>, EspError>
where T: InputPin + OutputPin,

Put the pin into input + output Open Drain mode.

This is commonly used for “open drain” mode. the hardware will drive the line low if you set it to low, and will leave it floating if you set it to high, in which case you can read the input to figure out whether another device is driving the line low.

source

pub fn into_output(self) -> Result<PinDriver<'d, T, Output>, EspError>
where T: OutputPin,

Put the pin into output mode.

source

pub fn into_output_od(self) -> Result<PinDriver<'d, T, Output>, EspError>
where T: OutputPin,

Put the pin into output Open Drain mode.

source

pub fn get_drive_strength(&self) -> Result<DriveStrength, EspError>
where MODE: OutputMode,

source

pub fn set_drive_strength( &mut self, strength: DriveStrength ) -> Result<(), EspError>
where MODE: OutputMode,

source

pub fn is_high(&self) -> bool
where MODE: InputMode,

source

pub fn is_low(&self) -> bool
where MODE: InputMode,

source

pub fn get_level(&self) -> Level
where MODE: InputMode,

source

pub fn is_set_high(&self) -> bool
where MODE: OutputMode,

source

pub fn is_set_low(&self) -> bool
where MODE: OutputMode,

Is the output pin set as low?

source

pub fn set_high(&mut self) -> Result<(), EspError>
where MODE: OutputMode,

source

pub fn set_low(&mut self) -> Result<(), EspError>
where MODE: OutputMode,

Set the output as low.

source

pub fn set_level(&mut self, level: Level) -> Result<(), EspError>
where MODE: OutputMode,

source

pub fn toggle(&mut self) -> Result<(), EspError>
where MODE: OutputMode,

Toggle pin output

source

pub fn set_pull(&mut self, pull: Pull) -> Result<(), EspError>
where T: InputPin + OutputPin, MODE: InputMode,

source

pub unsafe fn subscribe<F: FnMut() + Send + 'static>( &mut self, callback: F ) -> Result<(), EspError>
where MODE: InputMode,

Subscribes the provided callback for ISR notifications. As a side effect, interrupts will be disabled, so to receive a notification, one has to also call PinDriver::enable_interrupt after calling this method.

Note that PinDriver::enable_interrupt should also be called after each received notification from non-ISR context, because the driver will automatically disable ISR interrupts on each received ISR notification (so as to avoid IWDT triggers).

§Safety

Care should be taken not to call STD, libc or FreeRTOS APIs (except for a few allowed ones) in the callback passed to this function, as it is executed in an ISR context.

source

pub unsafe fn subscribe_nonstatic<F: FnMut() + Send + 'd>( &mut self, callback: F ) -> Result<(), EspError>
where MODE: InputMode,

Subscribes the provided callback for ISR notifications. As a side effect, interrupts will be disabled, so to receive a notification, one has to also call PinDriver::enable_interrupt after calling this method.

Note that PinDriver::enable_interrupt should also be called after each received notification from non-ISR context, because the driver will automatically disable ISR interrupts on each received ISR notification (so as to avoid IWDT triggers).

§Safety

Care should be taken not to call STD, libc or FreeRTOS APIs (except for a few allowed ones) in the callback passed to this function, as it is executed in an ISR context.

Additionally, this method - in contrast to method subscribe - allows the passed-in callback/closure to be non-'static. This enables users to borrow

  • in the closure - variables that live on the stack - or more generally - in the same scope where the driver is created.

HOWEVER: care should be taken NOT to call core::mem::forget() on the driver, as that would immediately lead to an UB (crash). Also note that forgetting the driver might happen with Rc and Arc when circular references are introduced: https://github.com/rust-lang/rust/issues/24456

The reason is that the closure is actually sent and owned by an ISR routine, which means that if the driver is forgotten, Rust is free to e.g. unwind the stack and the ISR routine will end up with references to variables that no longer exist.

The destructor of the driver takes care - prior to the driver being dropped and e.g. the stack being unwind - to unsubscribe the ISR routine. Unfortunately, when the driver is forgotten, the un-subscription does not happen and invalid references are left dangling.

This “local borrowing” will only be possible to express in a safe way once/if !Leak types are introduced to Rust (i.e. the impossibility to “forget” a type and thus not call its destructor).

source

pub fn unsubscribe(&mut self) -> Result<(), EspError>
where MODE: InputMode,

source

pub fn enable_interrupt(&mut self) -> Result<(), EspError>
where MODE: InputMode,

Enables or re-enables the interrupt

Note that the interrupt is automatically disabled each time an interrupt is triggered (or else we risk entering a constant interrupt processing loop while the pin is in low/high state and the interrupt type is set to non-edge)

Therefore - to continue receiving ISR interrupts - user needs to call enable_interrupt

  • from a non-ISR context - after each successful interrupt triggering.
source

pub fn disable_interrupt(&mut self) -> Result<(), EspError>
where MODE: InputMode,

source

pub fn set_interrupt_type( &mut self, interrupt_type: InterruptType ) -> Result<(), EspError>
where MODE: InputMode,

source§

impl<T: Pin, MODE: InputMode> PinDriver<'_, T, MODE>

source

pub async fn wait_for( &mut self, interrupt_type: InterruptType ) -> Result<(), EspError>

source

pub async fn wait_for_high(&mut self) -> Result<(), EspError>

source

pub async fn wait_for_low(&mut self) -> Result<(), EspError>

source

pub async fn wait_for_rising_edge(&mut self) -> Result<(), EspError>

source

pub async fn wait_for_falling_edge(&mut self) -> Result<(), EspError>

source

pub async fn wait_for_any_edge(&mut self) -> Result<(), EspError>

Trait Implementations§

source§

impl<'d, T: Pin, MODE> Drop for PinDriver<'d, T, MODE>

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl<'d, T: Pin, MODE> ErrorType for PinDriver<'d, T, MODE>

§

type Error = GpioError

Error type
source§

impl<'d, T: Pin, MODE> InputPin for &PinDriver<'d, T, MODE>
where MODE: InputMode,

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<'d, T: Pin, MODE> InputPin for PinDriver<'d, T, MODE>
where MODE: InputMode,

§

type Error = EspError

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<'d, T: Pin, MODE> InputPin for PinDriver<'d, T, MODE>
where MODE: InputMode,

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<'d, T: Pin, MODE> OutputPin for PinDriver<'d, T, MODE>
where MODE: OutputMode,

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<'d, T: Pin, MODE> OutputPin for PinDriver<'d, T, MODE>
where MODE: OutputMode,

§

type Error = EspError

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<'d, T: Pin, MODE> StatefulOutputPin for PinDriver<'d, T, MODE>
where MODE: OutputMode,

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<'d, T: Pin, MODE> StatefulOutputPin for PinDriver<'d, T, MODE>
where MODE: OutputMode,

source§

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

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

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

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

impl<'d, T: Pin, MODE> ToggleableOutputPin for PinDriver<'d, T, MODE>
where MODE: OutputMode,

§

type Error = EspError

Error type
source§

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

Toggle pin output.
source§

impl<T: Pin, MODE: InputMode> Wait for PinDriver<'_, T, MODE>

source§

async fn wait_for_high(&mut self) -> Result<(), GpioError>

Wait until the pin is high. If it is already high, return immediately. Read more
source§

async fn wait_for_low(&mut self) -> Result<(), GpioError>

Wait until the pin is low. If it is already low, return immediately. Read more
source§

async fn wait_for_rising_edge(&mut self) -> Result<(), GpioError>

Wait for the pin to undergo a transition from low to high. Read more
source§

async fn wait_for_falling_edge(&mut self) -> Result<(), GpioError>

Wait for the pin to undergo a transition from high to low. Read more
source§

async fn wait_for_any_edge(&mut self) -> Result<(), GpioError>

Wait for the pin to undergo any transition, i.e low to high OR high to low.
source§

impl<'d, T: Pin, MODE> Send for PinDriver<'d, T, MODE>

Auto Trait Implementations§

§

impl<'d, T, MODE> RefUnwindSafe for PinDriver<'d, T, MODE>
where MODE: RefUnwindSafe, T: RefUnwindSafe,

§

impl<'d, T, MODE> Sync for PinDriver<'d, T, MODE>
where MODE: Sync, T: Sync,

§

impl<'d, T, MODE> Unpin for PinDriver<'d, T, MODE>
where MODE: Unpin, T: Unpin,

§

impl<'d, T, MODE> !UnwindSafe for PinDriver<'d, T, MODE>

Blanket Implementations§

§

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

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

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

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

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

§

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

Mutably borrows from an owned value. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

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

§

fn into(self) -> U

Calls U::from(self).

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

§

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

§

type Error = Infallible

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

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

Performs the conversion.
§

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.
§

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

Performs the conversion.