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(())
    }
}