Struct esp_idf_svc::hal::timer::TimerDriver

source ·
pub struct TimerDriver<'d> { /* private fields */ }

Implementations§

source§

impl<'d> TimerDriver<'d>

source

pub fn new<TIMER>( _timer: impl Peripheral<P = TIMER> + 'd, config: &Config, ) -> Result<TimerDriver<'d>, EspError>
where TIMER: Timer,

source

pub fn tick_hz(&self) -> u64

Returns the tick rate of the timer.

source

pub fn enable(&mut self, enable: bool) -> Result<(), EspError>

Enable or disable the timer.

Enabling the timer causes it to begin counting up from the current counter.

Disabling the timer effectively pauses the counter.

source

pub fn counter(&self) -> Result<u64, EspError>

Returns the current counter value of the timer

source

pub fn set_counter(&mut self, value: u64) -> Result<(), EspError>

Manually set the current counter value of the timer.

This does not enable or disable the timer.

source

pub fn enable_alarm(&mut self, enable: bool) -> Result<(), EspError>

Enable or disable the alarm.

Enabling the alarm activates the following behaviors once it is triggered:

  • The counter will reset to 0, if auto-reload is set
  • An interrupt will be triggered, if configured
source

pub fn alarm(&self) -> Result<u64, EspError>

Returns the configured alarm value

source

pub fn set_alarm(&mut self, value: u64) -> Result<(), EspError>

Set the alarm value of the timer.

NOTE: The alarm must be activated with enable_alarm for this value to take effect

Once the counter exceeds this value:

  • The counter will reset to 0, if auto-reload is set
  • An interrupt will be triggered, if configured
source

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

source

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

source

pub async fn delay(&mut self, counter: u64) -> Result<(), EspError>

Delays for counter ticks

NOTE: This function resets the counter

source

pub fn reset_wait(&mut self)

Resets the internal wait notification

source

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

Wait for an alarm interrupt to occur

NOTE: This requires interrupts to be enabled to work

source

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

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 TimerDriver::enable_interrupt after calling this method.

§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>( &mut self, callback: F, ) -> Result<(), EspError>
where F: FnMut() + Send + 'd,

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 TimerDriver::enable_interrupt after calling this method.

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

source

pub fn group(&self) -> u32

source

pub fn index(&self) -> u32

Trait Implementations§

source§

impl<'d> DelayNs for TimerDriver<'d>

source§

async fn delay_ns(&mut self, ns: u32)

Pauses execution for at minimum ns nanoseconds. Pause can be longer if the implementation requires it due to precision/timing issues.
source§

async fn delay_ms(&mut self, ms: u32)

Pauses execution for at minimum ms milliseconds. Pause can be longer if the implementation requires it due to precision/timing issues.
source§

async fn delay_us(&mut self, us: u32)

Pauses execution for at minimum us microseconds. Pause can be longer if the implementation requires it due to precision/timing issues.
source§

impl<'d> Drop for TimerDriver<'d>

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl<'d> Send for TimerDriver<'d>

Auto Trait Implementations§

§

impl<'d> Freeze for TimerDriver<'d>

§

impl<'d> RefUnwindSafe for TimerDriver<'d>

§

impl<'d> Sync for TimerDriver<'d>

§

impl<'d> Unpin for TimerDriver<'d>

§

impl<'d> !UnwindSafe for TimerDriver<'d>

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.