From 5b7169389bfe65b425887c48393519fc8d0dc397 Mon Sep 17 00:00:00 2001 From: Julien Vincent Date: Mon, 9 Dec 2024 17:34:45 +0000 Subject: [PATCH] Allow using esp timer with `skip_unhandled_events` 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`. --- src/timer.rs | 73 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 19 deletions(-) diff --git a/src/timer.rs b/src/timer.rs index c7b9f05d43e..8a39d6b3aff 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -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 { - let notification = Arc::new(Notification::new()); - - let timer = { - let notification = Arc::downgrade(¬ification); + /// Same as `timer` but does not wake the device from light sleep. + pub fn timer_nowake(&self, callback: F) -> Result, 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 { + 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 { + self.internal_timer_async(true) } /// # Safety @@ -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, 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, EspError> + where + F: FnMut() + Send + 'a, + { + self.internal_timer(callback, true) + } + + fn internal_timer<'a, F>( + &self, + callback: F, + skip_unhandled_events: bool, + ) -> Result, EspError> where F: FnMut() + Send + 'a, { @@ -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 _, ) @@ -298,6 +311,28 @@ where _callback: callback, }) } + + fn internal_timer_async(&self, skip_unhandled_events: bool) -> Result { + let notification = Arc::new(Notification::new()); + + let timer = { + let notification = Arc::downgrade(¬ification); + + 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;