1
#![cfg_attr(docsrs, procmacros::doc_replace)]
2
//! # General-purpose Timers
3
//!
4
//! ## Overview
5
//! The [OneShotTimer] and [PeriodicTimer] types can be backed by any hardware
6
//! peripheral which implements the [Timer] trait. This means that the same API
7
//! can be used to interact with different hardware timers, like the `TIMG` and
8
//! SYSTIMER.
9
#![cfg_attr(
10
    systimer_driver_supported,
11
    doc = "See the [timg] and [systimer] modules for more information."
12
)]
13
#![cfg_attr(
14
    not(systimer_driver_supported),
15
    doc = "See the [timg] module for more information."
16
)]
17
//! ## Examples
18
//!
19
//! ### One-shot Timer
20
//!
21
//! ```rust, no_run
22
//! # {before_snippet}
23
//! # use esp_hal::timer::{OneShotTimer, PeriodicTimer, timg::TimerGroup};
24
//! #
25
//! let timg0 = TimerGroup::new(peripherals.TIMG0);
26
//! let mut one_shot = OneShotTimer::new(timg0.timer0);
27
//!
28
//! one_shot.delay_millis(500);
29
//! # {after_snippet}
30
//! ```
31
//!
32
//! ### Periodic Timer
33
//! ```rust, no_run
34
//! # {before_snippet}
35
//! # use esp_hal::timer::{PeriodicTimer, timg::TimerGroup};
36
//! #
37
//! let timg0 = TimerGroup::new(peripherals.TIMG0);
38
//! let mut periodic = PeriodicTimer::new(timg0.timer0);
39
//!
40
//! periodic.start(Duration::from_secs(1));
41
//! loop {
42
//!     periodic.wait();
43
//! }
44
//! # }
45
//! ```
46

            
47
use core::{
48
    marker::PhantomData,
49
    pin::Pin,
50
    task::{Context, Poll},
51
};
52

            
53
use crate::{
54
    Async,
55
    Blocking,
56
    DriverMode,
57
    asynch::AtomicWaker,
58
    interrupt::{InterruptConfigurable, InterruptHandler},
59
    peripherals::Interrupt,
60
    system::Cpu,
61
    time::{Duration, Instant},
62
};
63

            
64
#[cfg(systimer_driver_supported)]
65
pub mod systimer;
66
#[cfg(timergroup_driver_supported)]
67
pub mod timg;
68

            
69
/// Timer errors.
70
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
71
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
72
pub enum Error {
73
    /// The timer is already active.
74
    TimerActive,
75
    /// The timer is not currently active.
76
    TimerInactive,
77
    /// The alarm is not currently active.
78
    AlarmInactive,
79
    /// The provided timeout is too large.
80
    InvalidTimeout,
81
}
82

            
83
/// Functionality provided by any timer peripheral.
84
pub trait Timer: crate::private::Sealed {
85
    /// Starts the timer.
86
    #[doc(hidden)]
87
    fn start(&self);
88

            
89
    /// Stops the timer.
90
    #[doc(hidden)]
91
    fn stop(&self);
92

            
93
    /// Resets the timer value to 0.
94
    #[doc(hidden)]
95
    fn reset(&self);
96

            
97
    /// Is the timer running?
98
    #[doc(hidden)]
99
    fn is_running(&self) -> bool;
100

            
101
    /// The current timer value.
102
    #[doc(hidden)]
103
    fn now(&self) -> Instant;
104

            
105
    /// Loads a target value into the timer.
106
    #[doc(hidden)]
107
    fn load_value(&self, value: Duration) -> Result<(), Error>;
108

            
109
    /// Enables auto reload of the loaded value.
110
    #[doc(hidden)]
111
    fn enable_auto_reload(&self, auto_reload: bool);
112

            
113
    /// Enables or disables the timer's interrupt.
114
    #[doc(hidden)]
115
    fn enable_interrupt(&self, state: bool);
116

            
117
    /// Clears the timer's interrupt.
118
    fn clear_interrupt(&self);
119

            
120
    /// Returns whether the timer has triggered.
121
    fn is_interrupt_set(&self) -> bool;
122

            
123
    /// Returns the HAL provided async interrupt handler.
124
    #[doc(hidden)]
125
    fn async_interrupt_handler(&self) -> InterruptHandler;
126

            
127
    /// Returns the interrupt source for the underlying timer.
128
    fn peripheral_interrupt(&self) -> Interrupt;
129

            
130
    /// Configures the interrupt handler.
131
    #[doc(hidden)]
132
    fn set_interrupt_handler(&self, handler: InterruptHandler);
133

            
134
    #[doc(hidden)]
135
    fn waker(&self) -> &AtomicWaker;
136
}
137

            
138
/// A one-shot timer.
139
pub struct OneShotTimer<'d, Dm: DriverMode> {
140
    inner: AnyTimer<'d>,
141
    _ph: PhantomData<Dm>,
142
}
143

            
144
impl<'d> OneShotTimer<'d, Blocking> {
145
    /// Creates a new [`OneShotTimer`].
146
    pub fn new(inner: impl Timer + Into<AnyTimer<'d>>) -> OneShotTimer<'d, Blocking> {
147
65
        Self {
148
            inner: inner.into(),
149
            _ph: PhantomData,
150
        }
151
    }
152
}
153

            
154
impl<'d> OneShotTimer<'d, Blocking> {
155
    /// Converts the driver to [`Async`] mode.
156
    pub fn into_async(self) -> OneShotTimer<'d, Async> {
157
        let handler = self.inner.async_interrupt_handler();
158
        self.inner.set_interrupt_handler(handler);
159
        OneShotTimer {
160
            inner: self.inner,
161
            _ph: PhantomData,
162
        }
163
    }
164
}
165

            
166
impl<'d> OneShotTimer<'d, Async> {
167
    /// Converts the driver to [`Blocking`] mode.
168
    pub fn into_blocking(self) -> OneShotTimer<'d, Blocking> {
169
        crate::interrupt::disable(Cpu::current(), self.inner.peripheral_interrupt());
170
        OneShotTimer {
171
            inner: self.inner,
172
            _ph: PhantomData,
173
        }
174
    }
175

            
176
    /// Delays for *at least* `ns` nanoseconds.
177
36
    pub async fn delay_nanos_async(&mut self, ns: u32) {
178
36
        self.delay_async(Duration::from_micros(ns.div_ceil(1000) as u64))
179
            .await
180
    }
181

            
182
    /// Delays for *at least* `ms` milliseconds.
183
    pub async fn delay_millis_async(&mut self, ms: u32) {
184
        self.delay_async(Duration::from_millis(ms as u64)).await;
185
    }
186

            
187
    /// Delays for *at least* `us` microseconds.
188
    pub async fn delay_micros_async(&mut self, us: u32) {
189
        self.delay_async(Duration::from_micros(us as u64)).await;
190
    }
191

            
192
    /// Waits for *at least* the time interval `timeout`.
193
    ///
194
    /// Once the time period elapses, the underlying timer hardware does not automatically schedule
195
    /// the next timeout. The next timeout is scheduled only when `delay_async` is called again.
196
36
    async fn delay_async(&mut self, timeout: Duration) {
197
        unwrap!(self.schedule(timeout));
198

            
199
36
        WaitFuture::new(self.inner.reborrow()).await;
200

            
201
36
        self.stop();
202
24
        self.clear_interrupt();
203
    }
204
}
205

            
206
#[must_use = "futures do nothing unless you `.await` or poll them"]
207
struct WaitFuture<'d> {
208
    timer: AnyTimer<'d>,
209
}
210

            
211
impl<'d> WaitFuture<'d> {
212
    fn new(timer: AnyTimer<'d>) -> Self {
213
        // For some reason, on the S2 we need to enable the interrupt before we
214
        // read its status. Doing so in the other order causes the interrupt
215
        // request to never be fired.
216
        timer.enable_interrupt(true);
217
36
        Self { timer }
218
36
    }
219

            
220
    fn is_done(&self) -> bool {
221
        self.timer.is_interrupt_set()
222
    }
223
}
224

            
225
impl core::future::Future for WaitFuture<'_> {
226
    type Output = ();
227

            
228
64
    fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
229
        // Interrupts are enabled, so we need to register the waker before we check for
230
        // done. Otherwise we might miss the interrupt that would wake us.
231
        self.timer.waker().register(ctx.waker());
232

            
233
64
        if self.is_done() {
234
            Poll::Ready(())
235
        } else {
236
            Poll::Pending
237
        }
238
64
    }
239
}
240

            
241
impl Drop for WaitFuture<'_> {
242
    fn drop(&mut self) {
243
        self.timer.enable_interrupt(false);
244
24
    }
245
}
246

            
247
impl<Dm> OneShotTimer<'_, Dm>
248
where
249
    Dm: DriverMode,
250
{
251
    /// Delays for *at least* `ms` milliseconds.
252
    pub fn delay_millis(&mut self, ms: u32) {
253
        self.delay(Duration::from_millis(ms as u64));
254
    }
255

            
256
    /// Delays for *at least* `us` microseconds.
257
    pub fn delay_micros(&mut self, us: u32) {
258
        self.delay(Duration::from_micros(us as u64));
259
    }
260

            
261
    /// Delays for *at least* `ns` nanoseconds.
262
    pub fn delay_nanos(&mut self, ns: u32) {
263
        self.delay(Duration::from_micros(ns.div_ceil(1000) as u64))
264
    }
265

            
266
    fn delay(&mut self, us: Duration) {
267
        self.schedule(us).unwrap();
268

            
269
        while !self.inner.is_interrupt_set() {
270
            // Wait
271
        }
272

            
273
        self.stop();
274
        self.clear_interrupt();
275
    }
276

            
277
    /// Starts counting until the given timeout and raise an interrupt.
278
2
    pub fn schedule(&mut self, timeout: Duration) -> Result<(), Error> {
279
26
        if self.inner.is_running() {
280
            self.inner.stop();
281
        }
282

            
283
        self.inner.clear_interrupt();
284
        self.inner.reset();
285

            
286
        self.inner.enable_auto_reload(false);
287
        self.inner.load_value(timeout)?;
288
        self.inner.start();
289

            
290
        Ok(())
291
2
    }
292

            
293
    /// Stops the timer.
294
    pub fn stop(&mut self) {
295
        self.inner.stop();
296
    }
297

            
298
    /// Sets the interrupt handler.
299
    ///
300
    /// Replaces any previously set interrupt handler.
301
    #[instability::unstable]
302
    pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
303
        self.inner.set_interrupt_handler(handler);
304
    }
305

            
306
    /// Listens for interrupt.
307
    pub fn listen(&mut self) {
308
        self.inner.enable_interrupt(true);
309
    }
310

            
311
    /// Unlistens for interrupt.
312
    pub fn unlisten(&mut self) {
313
        self.inner.enable_interrupt(false);
314
    }
315

            
316
    /// Clears the interrupt flag.
317
    pub fn clear_interrupt(&mut self) {
318
        self.inner.clear_interrupt();
319
    }
320
}
321

            
322
impl<Dm> crate::private::Sealed for OneShotTimer<'_, Dm> where Dm: DriverMode {}
323

            
324
impl<Dm> InterruptConfigurable for OneShotTimer<'_, Dm>
325
where
326
    Dm: DriverMode,
327
{
328
    fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) {
329
        OneShotTimer::set_interrupt_handler(self, handler);
330
    }
331
}
332

            
333
impl embedded_hal::delay::DelayNs for OneShotTimer<'_, Blocking> {
334
    fn delay_ns(&mut self, ns: u32) {
335
        self.delay_nanos(ns);
336
    }
337
}
338

            
339
impl embedded_hal_async::delay::DelayNs for OneShotTimer<'_, Async> {
340
64
    async fn delay_ns(&mut self, ns: u32) {
341
36
        self.delay_nanos_async(ns).await
342
    }
343
}
344

            
345
/// A periodic timer.
346
pub struct PeriodicTimer<'d, Dm: DriverMode> {
347
    inner: AnyTimer<'d>,
348
    _ph: PhantomData<Dm>,
349
}
350

            
351
impl<'d> PeriodicTimer<'d, Blocking> {
352
    /// Creates a new instance of [`PeriodicTimer`].
353
    pub fn new(inner: impl Timer + Into<AnyTimer<'d>>) -> PeriodicTimer<'d, Blocking> {
354
        Self {
355
            inner: inner.into(),
356
            _ph: PhantomData,
357
        }
358
    }
359

            
360
    /// Converts the driver to [`Async`] mode.
361
9
    pub fn into_async(self) -> PeriodicTimer<'d, Async> {
362
        let handler = self.inner.async_interrupt_handler();
363
        self.inner.set_interrupt_handler(handler);
364
9
        PeriodicTimer {
365
            inner: self.inner,
366
            _ph: PhantomData,
367
        }
368
9
    }
369
}
370

            
371
impl<'d> PeriodicTimer<'d, Async> {
372
    /// Converts the driver to [`Blocking`] mode.
373
    pub fn into_blocking(self) -> PeriodicTimer<'d, Blocking> {
374
        crate::interrupt::disable(Cpu::current(), self.inner.peripheral_interrupt());
375
        PeriodicTimer {
376
            inner: self.inner,
377
            _ph: PhantomData,
378
        }
379
    }
380

            
381
    /// Waits for *at least* the time interval loaded by [`PeriodicTimer::start`].
382
    ///
383
    /// Once the time period elapses, the underlying timer hardware automatically schedules the
384
    /// next timeout.
385
    pub async fn wait_async(&mut self) {
386
        WaitFuture::new(self.inner.reborrow()).await;
387
        self.clear_interrupt();
388
    }
389
}
390

            
391
impl<Dm> PeriodicTimer<'_, Dm>
392
where
393
    Dm: DriverMode,
394
{
395
    /// Starts a new count down.
396
2
    pub fn start(&mut self, period: Duration) -> Result<(), Error> {
397
2
        if self.inner.is_running() {
398
            self.inner.stop();
399
        }
400

            
401
        self.inner.clear_interrupt();
402
        self.inner.reset();
403

            
404
        self.inner.enable_auto_reload(true);
405
        self.inner.load_value(period)?;
406
        self.inner.start();
407

            
408
        Ok(())
409
2
    }
410

            
411
    /// "Wait", by blocking, until the count down finishes.
412
    pub fn wait(&mut self) {
413
        while !self.inner.is_interrupt_set() {}
414
        self.inner.clear_interrupt();
415
    }
416

            
417
    /// Tries to cancel the active count down.
418
    pub fn cancel(&mut self) -> Result<(), Error> {
419
        if !self.inner.is_running() {
420
            return Err(Error::TimerInactive);
421
        }
422

            
423
        self.inner.stop();
424

            
425
        Ok(())
426
    }
427

            
428
    /// Sets the interrupt handler.
429
    ///
430
    /// Replaces any previously set interrupt handler.
431
    #[instability::unstable]
432
    pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
433
        self.inner.set_interrupt_handler(handler);
434
    }
435

            
436
    /// Listens for interrupt.
437
    pub fn listen(&mut self) {
438
        self.inner.enable_interrupt(true);
439
    }
440

            
441
    /// Unlistens for interrupt.
442
    pub fn unlisten(&mut self) {
443
        self.inner.enable_interrupt(false);
444
    }
445

            
446
    /// Clears the interrupt flag.
447
    pub fn clear_interrupt(&mut self) {
448
        self.inner.clear_interrupt();
449
    }
450
}
451

            
452
impl<Dm> crate::private::Sealed for PeriodicTimer<'_, Dm> where Dm: DriverMode {}
453

            
454
impl<Dm> InterruptConfigurable for PeriodicTimer<'_, Dm>
455
where
456
    Dm: DriverMode,
457
{
458
    fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) {
459
        PeriodicTimer::set_interrupt_handler(self, handler);
460
    }
461
}
462

            
463
crate::any_peripheral! {
464
    /// Any Timer peripheral.
465
    pub peripheral AnyTimer<'d> {
466
        #[cfg(timergroup_driver_supported)]
467
        TimgTimer(timg::Timer<'d>),
468
        #[cfg(systimer_driver_supported)]
469
        SystimerAlarm(systimer::Alarm<'d>),
470
    }
471
}
472

            
473
impl Timer for AnyTimer<'_> {
474
524
    delegate::delegate! {
475
128
        to match &self.0 {
476
            #[cfg(timergroup_driver_supported)]
477
88
            any::Inner::TimgTimer(inner) => inner,
478
            #[cfg(systimer_driver_supported)]
479
14
            any::Inner::SystimerAlarm(inner) => inner,
480
        } {
481
            fn start(&self);
482
            fn stop(&self);
483
            fn reset(&self);
484
            fn is_running(&self) -> bool;
485
            fn now(&self) -> Instant;
486
            fn load_value(&self, value: Duration) -> Result<(), Error>;
487
            fn enable_auto_reload(&self, auto_reload: bool);
488
            fn enable_interrupt(&self, state: bool);
489
            fn clear_interrupt(&self);
490
            fn is_interrupt_set(&self) -> bool;
491
            fn async_interrupt_handler(&self) -> InterruptHandler;
492
            fn peripheral_interrupt(&self) -> Interrupt;
493
            fn set_interrupt_handler(&self, handler: InterruptHandler);
494
            fn waker(&self) -> &AtomicWaker;
495
        }
496
    }
497
}