1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
use anyhow::Result;
use esp_idf_hal::timer::TimerDriver;
use crate::{
message::{Notifier, Trigger},
thread::failure,
};
/// Represents a timer that can be used for various operations.
///
/// # Type Parameters
/// * `'a` - Lifetime of the timer.
/// * `T` - The trigger type implementing the `Trigger` trait.
pub struct Timer<'a, T: Trigger> {
timer: TimerDriver<'a>,
_marker: std::marker::PhantomData<T>,
}
impl<'a, T: Trigger> Timer<'a, T> {
/// Creates a new `Timer` instance.
///
/// # Arguments
/// * `timer` - A timer driver instance.
///
/// # Returns
/// A new `Timer` instance.
///
/// # Errors
/// Returns an error if the timer cannot be initialized.
pub fn new(timer: TimerDriver<'a>) -> Result<Self> {
Ok(Self {
timer,
_marker: std::marker::PhantomData,
})
}
/// Configures the timer interrupt.
///
/// # Arguments
/// * `freq` - Frequency of the timer interrupt in Hz.
/// * `notifier` - A notifier to send timer tick events.
/// * `trigger` - The trigger to emit when the timer ticks.
///
/// # Returns
/// `Ok(())` on success.
///
/// # Errors
/// Returns an error if the interrupt cannot be configured.
pub fn configure_interrupt(
&mut self,
freq: u64,
notifier: Notifier<T>,
trigger: &'static T,
) -> Result<()> {
unsafe {
self.timer.subscribe(move || {
notifier.notify(trigger).unwrap_or_else(|_| failure());
})?;
}
self.timer.set_alarm(self.timer.tick_hz() / freq)?;
self.timer.enable_interrupt()?;
Ok(())
}
/// Enables or disables the timer.
///
/// # Arguments
/// * `enable` - `true` to enable the timer, `false` to disable it.
///
/// # Errors
/// Returns an error if the timer cannot be enabled or disabled.
fn enable(&mut self, enable: bool) -> Result<()> {
self.timer.enable(enable)?;
self.timer.enable_alarm(enable)?;
Ok(())
}
/// Turns on the timer.
///
/// # Returns
/// `Ok(())` on success.
///
/// # Errors
/// Returns an error if the timer cannot be turned on.
pub fn on(&mut self) -> Result<()> {
self.enable(true)
}
/// Turns off the timer.
///
/// # Returns
/// `Ok(())` on success.
///
/// # Errors
/// Returns an error if the timer cannot be turned off.
pub fn off(&mut self) -> Result<()> {
self.enable(false)
}
/// Delays execution for a period determined by the given frequency.
///
/// The delay duration is `1 / freq` seconds (i.e., one period of the frequency).
///
/// # Arguments
/// * `freq` - Frequency in Hz; the delay lasts one period of this frequency.
///
/// # Returns
/// `Ok(())` when the delay completes.
///
/// # Errors
/// Returns an error if the delay cannot be performed.
pub async fn delay(&mut self, freq: u64) -> Result<()> {
self.timer.delay(self.timer.tick_hz() / freq).await?;
Ok(())
}
}