1#![cfg_attr(
9 not(feature = "esp32"),
10 doc = "See the [timg] and [systimer] modules for more information."
11)]
12#![cfg_attr(feature = "esp32", doc = "See the [timg] module for more information.")]
13#![doc = crate::before_snippet!()]
19#![doc = crate::before_snippet!()]
32use core::{
45 marker::PhantomData,
46 pin::Pin,
47 task::{Context, Poll},
48};
49
50use crate::{
51 asynch::AtomicWaker,
52 interrupt::{InterruptConfigurable, InterruptHandler},
53 peripheral::{Peripheral, PeripheralRef},
54 peripherals::Interrupt,
55 system::Cpu,
56 time::{Duration, Instant},
57 Async,
58 Blocking,
59 DriverMode,
60};
61
62#[cfg(systimer)]
63pub mod systimer;
64#[cfg(any(timg0, timg1))]
65pub mod timg;
66
67#[derive(Debug, Clone, Copy, PartialEq, Eq)]
69#[cfg_attr(feature = "defmt", derive(defmt::Format))]
70pub enum Error {
71 TimerActive,
73 TimerInactive,
75 AlarmInactive,
77 InvalidTimeout,
79}
80
81pub trait Timer: Into<AnyTimer> + 'static + crate::private::Sealed {
83 #[doc(hidden)]
85 fn start(&self);
86
87 #[doc(hidden)]
89 fn stop(&self);
90
91 #[doc(hidden)]
93 fn reset(&self);
94
95 #[doc(hidden)]
97 fn is_running(&self) -> bool;
98
99 #[doc(hidden)]
101 fn now(&self) -> Instant;
102
103 #[doc(hidden)]
105 fn load_value(&self, value: Duration) -> Result<(), Error>;
106
107 #[doc(hidden)]
109 fn enable_auto_reload(&self, auto_reload: bool);
110
111 #[doc(hidden)]
113 fn enable_interrupt(&self, state: bool);
114
115 fn clear_interrupt(&self);
117
118 fn is_interrupt_set(&self) -> bool;
120
121 #[doc(hidden)]
123 fn async_interrupt_handler(&self) -> InterruptHandler;
124
125 fn peripheral_interrupt(&self) -> Interrupt;
127
128 #[doc(hidden)]
130 fn set_interrupt_handler(&self, handler: InterruptHandler);
131
132 #[doc(hidden)]
133 fn waker(&self) -> &AtomicWaker;
134}
135
136pub struct OneShotTimer<'d, Dm: DriverMode> {
138 inner: PeripheralRef<'d, AnyTimer>,
139 _ph: PhantomData<Dm>,
140}
141
142impl<'d> OneShotTimer<'d, Blocking> {
143 pub fn new(inner: impl Peripheral<P = impl Timer> + 'd) -> OneShotTimer<'d, Blocking> {
145 crate::into_mapped_ref!(inner);
146 Self {
147 inner,
148 _ph: PhantomData,
149 }
150 }
151}
152
153impl<'d> OneShotTimer<'d, Blocking> {
154 pub fn into_async(self) -> OneShotTimer<'d, Async> {
156 let handler = self.inner.async_interrupt_handler();
157 self.inner.set_interrupt_handler(handler);
158 OneShotTimer {
159 inner: self.inner,
160 _ph: PhantomData,
161 }
162 }
163}
164
165impl OneShotTimer<'_, Async> {
166 pub fn into_blocking(self) -> Self {
168 crate::interrupt::disable(Cpu::current(), self.inner.peripheral_interrupt());
169 Self {
170 inner: self.inner,
171 _ph: PhantomData,
172 }
173 }
174
175 pub async fn delay_nanos_async(&mut self, ns: u32) {
177 self.delay_async(Duration::from_micros(ns.div_ceil(1000) as u64))
178 .await
179 }
180
181 pub async fn delay_millis_async(&mut self, ms: u32) {
183 self.delay_async(Duration::from_millis(ms as u64)).await;
184 }
185
186 pub async fn delay_micros_async(&mut self, us: u32) {
188 self.delay_async(Duration::from_micros(us as u64)).await;
189 }
190
191 async fn delay_async(&mut self, us: Duration) {
192 unwrap!(self.schedule(us));
193
194 WaitFuture::new(self.inner.reborrow()).await;
195
196 self.stop();
197 self.clear_interrupt();
198 }
199}
200
201#[must_use = "futures do nothing unless you `.await` or poll them"]
202struct WaitFuture<'d> {
203 timer: PeripheralRef<'d, AnyTimer>,
204}
205
206impl<'d> WaitFuture<'d> {
207 fn new(timer: impl Peripheral<P = AnyTimer> + 'd) -> Self {
208 crate::into_ref!(timer);
209 timer.enable_interrupt(true);
213 Self { timer }
214 }
215
216 fn is_done(&self) -> bool {
217 self.timer.is_interrupt_set()
218 }
219}
220
221impl core::future::Future for WaitFuture<'_> {
222 type Output = ();
223
224 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
225 self.timer.waker().register(ctx.waker());
228
229 if self.is_done() {
230 Poll::Ready(())
231 } else {
232 Poll::Pending
233 }
234 }
235}
236
237impl Drop for WaitFuture<'_> {
238 fn drop(&mut self) {
239 self.timer.enable_interrupt(false);
240 }
241}
242
243impl<Dm> OneShotTimer<'_, Dm>
244where
245 Dm: DriverMode,
246{
247 pub fn delay_millis(&mut self, ms: u32) {
249 self.delay(Duration::from_millis(ms as u64));
250 }
251
252 pub fn delay_micros(&mut self, us: u32) {
254 self.delay(Duration::from_micros(us as u64));
255 }
256
257 pub fn delay_nanos(&mut self, ns: u32) {
259 self.delay(Duration::from_micros(ns.div_ceil(1000) as u64))
260 }
261
262 fn delay(&mut self, us: Duration) {
263 self.schedule(us).unwrap();
264
265 while !self.inner.is_interrupt_set() {
266 }
268
269 self.stop();
270 self.clear_interrupt();
271 }
272
273 pub fn schedule(&mut self, timeout: Duration) -> Result<(), Error> {
275 if self.inner.is_running() {
276 self.inner.stop();
277 }
278
279 self.inner.clear_interrupt();
280 self.inner.reset();
281
282 self.inner.enable_auto_reload(false);
283 self.inner.load_value(timeout)?;
284 self.inner.start();
285
286 Ok(())
287 }
288
289 pub fn stop(&mut self) {
291 self.inner.stop();
292 }
293
294 #[instability::unstable]
298 pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
299 self.inner.set_interrupt_handler(handler);
300 }
301
302 pub fn enable_interrupt(&mut self, enable: bool) {
304 self.inner.enable_interrupt(enable);
305 }
306
307 pub fn clear_interrupt(&mut self) {
309 self.inner.clear_interrupt();
310 }
311}
312
313impl<Dm> crate::private::Sealed for OneShotTimer<'_, Dm> where Dm: DriverMode {}
314
315impl<Dm> InterruptConfigurable for OneShotTimer<'_, Dm>
316where
317 Dm: DriverMode,
318{
319 fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) {
320 OneShotTimer::set_interrupt_handler(self, handler);
321 }
322}
323
324impl embedded_hal::delay::DelayNs for OneShotTimer<'_, Blocking> {
325 fn delay_ns(&mut self, ns: u32) {
326 self.delay_nanos(ns);
327 }
328}
329
330impl embedded_hal_async::delay::DelayNs for OneShotTimer<'_, Async> {
331 async fn delay_ns(&mut self, ns: u32) {
332 self.delay_nanos_async(ns).await
333 }
334}
335
336pub struct PeriodicTimer<'d, Dm: DriverMode> {
338 inner: PeripheralRef<'d, AnyTimer>,
339 _ph: PhantomData<Dm>,
340}
341
342impl<'d> PeriodicTimer<'d, Blocking> {
343 pub fn new(inner: impl Peripheral<P = impl Timer> + 'd) -> PeriodicTimer<'d, Blocking> {
345 crate::into_mapped_ref!(inner);
346 Self {
347 inner,
348 _ph: PhantomData,
349 }
350 }
351}
352
353impl<Dm> PeriodicTimer<'_, Dm>
354where
355 Dm: DriverMode,
356{
357 pub fn start(&mut self, period: Duration) -> Result<(), Error> {
359 if self.inner.is_running() {
360 self.inner.stop();
361 }
362
363 self.inner.clear_interrupt();
364 self.inner.reset();
365
366 self.inner.enable_auto_reload(true);
367 self.inner.load_value(period)?;
368 self.inner.start();
369
370 Ok(())
371 }
372
373 pub fn wait(&mut self) {
375 while !self.inner.is_interrupt_set() {}
376 self.inner.clear_interrupt();
377 }
378
379 pub fn cancel(&mut self) -> Result<(), Error> {
381 if !self.inner.is_running() {
382 return Err(Error::TimerInactive);
383 }
384
385 self.inner.stop();
386
387 Ok(())
388 }
389
390 #[instability::unstable]
394 pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
395 self.inner.set_interrupt_handler(handler);
396 }
397
398 pub fn enable_interrupt(&mut self, enable: bool) {
400 self.inner.enable_interrupt(enable);
401 }
402
403 pub fn clear_interrupt(&mut self) {
405 self.inner.clear_interrupt();
406 }
407}
408
409impl<Dm> crate::private::Sealed for PeriodicTimer<'_, Dm> where Dm: DriverMode {}
410
411impl<Dm> InterruptConfigurable for PeriodicTimer<'_, Dm>
412where
413 Dm: DriverMode,
414{
415 fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) {
416 PeriodicTimer::set_interrupt_handler(self, handler);
417 }
418}
419
420crate::any_peripheral! {
421 pub peripheral AnyTimer {
423 TimgTimer(timg::Timer),
424 #[cfg(systimer)]
425 SystimerAlarm(systimer::Alarm),
426 }
427}
428
429impl Timer for AnyTimer {
430 delegate::delegate! {
431 to match &self.0 {
432 AnyTimerInner::TimgTimer(inner) => inner,
433 #[cfg(systimer)]
434 AnyTimerInner::SystimerAlarm(inner) => inner,
435 } {
436 fn start(&self);
437 fn stop(&self);
438 fn reset(&self);
439 fn is_running(&self) -> bool;
440 fn now(&self) -> Instant;
441 fn load_value(&self, value: Duration) -> Result<(), Error>;
442 fn enable_auto_reload(&self, auto_reload: bool);
443 fn enable_interrupt(&self, state: bool);
444 fn clear_interrupt(&self);
445 fn is_interrupt_set(&self) -> bool;
446 fn async_interrupt_handler(&self) -> InterruptHandler;
447 fn peripheral_interrupt(&self) -> Interrupt;
448 fn set_interrupt_handler(&self, handler: InterruptHandler);
449 fn waker(&self) -> &AtomicWaker;
450 }
451 }
452}