From d477d54e2b3e7e44c9d9420b17ddec3b0a447bf3 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Mon, 20 Feb 2023 14:45:41 +0100 Subject: [PATCH] General purpose delay provider (#210) * Move delay implementations to dedicated subdirectory * Add general purpose delay provider --- examples/button.rs | 4 +-- src/delay/general_purpose.rs | 48 ++++++++++++++++++++++++++++++++++ src/{delay.rs => delay/mod.rs} | 27 ++++++++++++++----- 3 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 src/delay/general_purpose.rs rename src/{delay.rs => delay/mod.rs} (87%) diff --git a/examples/button.rs b/examples/button.rs index c1326592f..3619a6d9c 100644 --- a/examples/button.rs +++ b/examples/button.rs @@ -7,7 +7,7 @@ //! Depending on your target and the board you are using you should change the pins. //! If your board doesn't have on-board LEDs don't forget to add an appropriate resistor. -use esp_idf_hal::delay::FreeRtos; +use esp_idf_hal::delay::Delay; use esp_idf_hal::gpio::*; use esp_idf_hal::peripherals::Peripherals; @@ -22,7 +22,7 @@ fn main() -> anyhow::Result<()> { loop { // we are using thread::sleep here to make sure the watchdog isn't triggered - FreeRtos::delay_ms(10); + Delay::delay_ms(10); if button.is_high() { led.set_low()?; diff --git a/src/delay/general_purpose.rs b/src/delay/general_purpose.rs new file mode 100644 index 000000000..5053fcf5e --- /dev/null +++ b/src/delay/general_purpose.rs @@ -0,0 +1,48 @@ +use crate::delay::{Ets, FreeRtos}; + +/// A delay provider that uses [`Ets`] for delays <10ms, and [`FreeRtos`] for +/// delays >=10 ms +#[derive(Copy, Clone)] +pub struct Delay; + +impl Delay { + pub fn delay_us(us: u32) { + if us < 10_000 { + Ets::delay_us(us); + } else { + FreeRtos::delay_us(us); + } + } + + pub fn delay_ms(ms: u32) { + if ms < 10 { + Ets::delay_ms(ms); + } else { + FreeRtos::delay_ms(ms); + } + } +} + +impl embedded_hal_0_2::blocking::delay::DelayUs for Delay { + fn delay_us(&mut self, us: u16) { + Delay::delay_us(us as _); + } +} + +impl embedded_hal_0_2::blocking::delay::DelayUs for Delay { + fn delay_us(&mut self, us: u32) { + Delay::delay_us(us); + } +} + +impl embedded_hal_0_2::blocking::delay::DelayMs for Delay { + fn delay_ms(&mut self, ms: u16) { + Delay::delay_ms(ms as _) + } +} + +impl embedded_hal_0_2::blocking::delay::DelayMs for Delay { + fn delay_ms(&mut self, ms: u32) { + Delay::delay_ms(ms) + } +} diff --git a/src/delay.rs b/src/delay/mod.rs similarity index 87% rename from src/delay.rs rename to src/delay/mod.rs index 9929ae1e3..f0de00b04 100644 --- a/src/delay.rs +++ b/src/delay/mod.rs @@ -1,8 +1,18 @@ +//! Delay providers. +//! +//! If you don't know how large your delays will be, you'll probably want to +//! use [`Delay`]. Otherwise use [`Ets`] for delays <10ms and +//! [`FreeRtos`] for delays >=10ms. + use core::convert::Infallible; use core::time::Duration; use esp_idf_sys::*; +mod general_purpose; + +pub use general_purpose::Delay; + #[allow(non_upper_case_globals)] pub const BLOCK: TickType_t = TickType_t::MAX; @@ -49,9 +59,11 @@ impl From for Option { } } -/// Espressif built-in delay provider -/// Use only for very small delays (us or a few ms at most), or else the FreeRTOS IDLE tasks' might starve and -/// the IDLE tasks' watchdog will trigger +/// Espressif built-in delay provider for small delays +/// +/// Use only for very small delays (us or a few ms at most), or else the +/// FreeRTOS IDLE tasks' might starve and the IDLE tasks' watchdog will +/// trigger. pub struct Ets; // No longer available in the generated bindings for ESP-IDF 5 @@ -126,10 +138,11 @@ impl embedded_hal::delay::DelayUs for Ets { } } -/// FreeRTOS-based delay provider -/// Use for delays larger than 10ms (delays smaller than 10ms used in a loop would -/// starve the FreeRTOS IDLE tasks' as they are low prio tasks and hence the -/// the IDLE tasks' watchdog will trigger) +/// FreeRTOS-based delay provider for delays larger than 10ms +/// +/// Ddelays smaller than 10ms used in a loop would starve the FreeRTOS IDLE +/// tasks' as they are low prio tasks and hence the the IDLE tasks' watchdog +/// will trigger. pub struct FreeRtos; impl FreeRtos {