Skip to content

Commit

Permalink
Allow using esp timer with skip_unhandled_events
Browse files Browse the repository at this point in the history
Currently the esp timer service hardcodes the `skip_unhandled_events`
flag to `false` which means there is no way to construct a timer that
doesn't wake the device from light sleep.

This commit introduces new `*_nowake` methods for each of the existing
`timer_*` methods which allow constructing timers with
`skip_unhandled_events` set to `true`.
  • Loading branch information
julienvincent committed Dec 11, 2024
1 parent 8368354 commit 5b71693
Showing 1 changed file with 54 additions and 19 deletions.
73 changes: 54 additions & 19 deletions src/timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,26 +207,24 @@ where
where
F: FnMut() + Send + 'static,
{
self.internal_timer(callback)
self.internal_timer(callback, false)
}

pub fn timer_async(&self) -> Result<EspAsyncTimer, EspError> {
let notification = Arc::new(Notification::new());

let timer = {
let notification = Arc::downgrade(&notification);
/// Same as `timer` but does not wake the device from light sleep.
pub fn timer_nowake<F>(&self, callback: F) -> Result<EspTimer<'static>, EspError>
where
F: FnMut() + Send + 'static,
{
self.internal_timer(callback, true)
}

self.timer(move || {
if let Some(notification) = notification.upgrade() {
notification.notify(NonZeroU32::new(1).unwrap());
}
})?
};
pub fn timer_async(&self) -> Result<EspAsyncTimer, EspError> {
self.internal_timer_async(false)
}

Ok(EspAsyncTimer {
timer,
notification,
})
/// Same as `timer_async` but does not wake the device from light sleep.
pub fn timer_async_nowake(&self) -> Result<EspAsyncTimer, EspError> {
self.internal_timer_async(true)
}

/// # Safety
Expand Down Expand Up @@ -256,10 +254,25 @@ where
where
F: FnMut() + Send + 'a,
{
self.internal_timer(callback)
self.internal_timer(callback, false)
}

fn internal_timer<'a, F>(&self, callback: F) -> Result<EspTimer<'a>, EspError>
/// Same as `timer_nonstatic` but does not wake the device from light sleep.
pub unsafe fn timer_nonstatic_nowake<'a, F>(
&self,
callback: F,
) -> Result<EspTimer<'a>, EspError>
where
F: FnMut() + Send + 'a,
{
self.internal_timer(callback, true)
}

fn internal_timer<'a, F>(
&self,
callback: F,
skip_unhandled_events: bool,
) -> Result<EspTimer<'a>, EspError>
where
F: FnMut() + Send + 'a,
{
Expand Down Expand Up @@ -287,7 +300,7 @@ where
name: b"rust\0" as *const _ as *const _, // TODO
arg: unsafe_callback.as_ptr(),
dispatch_method,
skip_unhandled_events: false, // TODO
skip_unhandled_events,
},
&mut handle as *mut _,
)
Expand All @@ -298,6 +311,28 @@ where
_callback: callback,
})
}

fn internal_timer_async(&self, skip_unhandled_events: bool) -> Result<EspAsyncTimer, EspError> {
let notification = Arc::new(Notification::new());

let timer = {
let notification = Arc::downgrade(&notification);

self.internal_timer(
move || {
if let Some(notification) = notification.upgrade() {
notification.notify(NonZeroU32::new(1).unwrap());
}
},
skip_unhandled_events,
)?
};

Ok(EspAsyncTimer {
timer,
notification,
})
}
}

pub type EspTaskTimerService = EspTimerService<Task>;
Expand Down

0 comments on commit 5b71693

Please sign in to comment.