1#![cfg_attr(
9 systimer,
10 doc = "See the [timg] and [systimer] modules for more information."
11)]
12#![cfg_attr(not(systimer), 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 Async,
52 Blocking,
53 DriverMode,
54 asynch::AtomicWaker,
55 interrupt::{InterruptConfigurable, InterruptHandler},
56 peripherals::Interrupt,
57 system::Cpu,
58 time::{Duration, Instant},
59};
60
61#[cfg(systimer)]
62pub mod systimer;
63#[cfg(any(timg0, timg1))]
64pub mod timg;
65
66#[derive(Debug, Clone, Copy, PartialEq, Eq)]
68#[cfg_attr(feature = "defmt", derive(defmt::Format))]
69pub enum Error {
70 TimerActive,
72 TimerInactive,
74 AlarmInactive,
76 InvalidTimeout,
78}
79
80pub trait Timer: crate::private::Sealed {
82 #[doc(hidden)]
84 fn start(&self);
85
86 #[doc(hidden)]
88 fn stop(&self);
89
90 #[doc(hidden)]
92 fn reset(&self);
93
94 #[doc(hidden)]
96 fn is_running(&self) -> bool;
97
98 #[doc(hidden)]
100 fn now(&self) -> Instant;
101
102 #[doc(hidden)]
104 fn load_value(&self, value: Duration) -> Result<(), Error>;
105
106 #[doc(hidden)]
108 fn enable_auto_reload(&self, auto_reload: bool);
109
110 #[doc(hidden)]
112 fn enable_interrupt(&self, state: bool);
113
114 fn clear_interrupt(&self);
116
117 fn is_interrupt_set(&self) -> bool;
119
120 #[doc(hidden)]
122 fn async_interrupt_handler(&self) -> InterruptHandler;
123
124 fn peripheral_interrupt(&self) -> Interrupt;
126
127 #[doc(hidden)]
129 fn set_interrupt_handler(&self, handler: InterruptHandler);
130
131 #[doc(hidden)]
132 fn waker(&self) -> &AtomicWaker;
133}
134
135pub struct OneShotTimer<'d, Dm: DriverMode> {
137 inner: AnyTimer<'d>,
138 _ph: PhantomData<Dm>,
139}
140
141impl<'d> OneShotTimer<'d, Blocking> {
142 pub fn new(inner: impl Timer + Into<AnyTimer<'d>>) -> OneShotTimer<'d, Blocking> {
144 Self {
145 inner: inner.into(),
146 _ph: PhantomData,
147 }
148 }
149}
150
151impl<'d> OneShotTimer<'d, Blocking> {
152 pub fn into_async(self) -> OneShotTimer<'d, Async> {
154 let handler = self.inner.async_interrupt_handler();
155 self.inner.set_interrupt_handler(handler);
156 OneShotTimer {
157 inner: self.inner,
158 _ph: PhantomData,
159 }
160 }
161}
162
163impl OneShotTimer<'_, Async> {
164 pub fn into_blocking(self) -> Self {
166 crate::interrupt::disable(Cpu::current(), self.inner.peripheral_interrupt());
167 Self {
168 inner: self.inner,
169 _ph: PhantomData,
170 }
171 }
172
173 pub async fn delay_nanos_async(&mut self, ns: u32) {
175 self.delay_async(Duration::from_micros(ns.div_ceil(1000) as u64))
176 .await
177 }
178
179 pub async fn delay_millis_async(&mut self, ms: u32) {
181 self.delay_async(Duration::from_millis(ms as u64)).await;
182 }
183
184 pub async fn delay_micros_async(&mut self, us: u32) {
186 self.delay_async(Duration::from_micros(us as u64)).await;
187 }
188
189 async fn delay_async(&mut self, us: Duration) {
190 unwrap!(self.schedule(us));
191
192 WaitFuture::new(self.inner.reborrow()).await;
193
194 self.stop();
195 self.clear_interrupt();
196 }
197}
198
199#[must_use = "futures do nothing unless you `.await` or poll them"]
200struct WaitFuture<'d> {
201 timer: AnyTimer<'d>,
202}
203
204impl<'d> WaitFuture<'d> {
205 fn new(timer: AnyTimer<'d>) -> Self {
206 timer.enable_interrupt(true);
210 Self { timer }
211 }
212
213 fn is_done(&self) -> bool {
214 self.timer.is_interrupt_set()
215 }
216}
217
218impl core::future::Future for WaitFuture<'_> {
219 type Output = ();
220
221 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
222 self.timer.waker().register(ctx.waker());
225
226 if self.is_done() {
227 Poll::Ready(())
228 } else {
229 Poll::Pending
230 }
231 }
232}
233
234impl Drop for WaitFuture<'_> {
235 fn drop(&mut self) {
236 self.timer.enable_interrupt(false);
237 }
238}
239
240impl<Dm> OneShotTimer<'_, Dm>
241where
242 Dm: DriverMode,
243{
244 pub fn delay_millis(&mut self, ms: u32) {
246 self.delay(Duration::from_millis(ms as u64));
247 }
248
249 pub fn delay_micros(&mut self, us: u32) {
251 self.delay(Duration::from_micros(us as u64));
252 }
253
254 pub fn delay_nanos(&mut self, ns: u32) {
256 self.delay(Duration::from_micros(ns.div_ceil(1000) as u64))
257 }
258
259 fn delay(&mut self, us: Duration) {
260 self.schedule(us).unwrap();
261
262 while !self.inner.is_interrupt_set() {
263 }
265
266 self.stop();
267 self.clear_interrupt();
268 }
269
270 pub fn schedule(&mut self, timeout: Duration) -> Result<(), Error> {
272 if self.inner.is_running() {
273 self.inner.stop();
274 }
275
276 self.inner.clear_interrupt();
277 self.inner.reset();
278
279 self.inner.enable_auto_reload(false);
280 self.inner.load_value(timeout)?;
281 self.inner.start();
282
283 Ok(())
284 }
285
286 pub fn stop(&mut self) {
288 self.inner.stop();
289 }
290
291 #[instability::unstable]
295 pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
296 self.inner.set_interrupt_handler(handler);
297 }
298
299 pub fn enable_interrupt(&mut self, enable: bool) {
301 self.inner.enable_interrupt(enable);
302 }
303
304 pub fn clear_interrupt(&mut self) {
306 self.inner.clear_interrupt();
307 }
308}
309
310impl<Dm> crate::private::Sealed for OneShotTimer<'_, Dm> where Dm: DriverMode {}
311
312impl<Dm> InterruptConfigurable for OneShotTimer<'_, Dm>
313where
314 Dm: DriverMode,
315{
316 fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) {
317 OneShotTimer::set_interrupt_handler(self, handler);
318 }
319}
320
321impl embedded_hal::delay::DelayNs for OneShotTimer<'_, Blocking> {
322 fn delay_ns(&mut self, ns: u32) {
323 self.delay_nanos(ns);
324 }
325}
326
327impl embedded_hal_async::delay::DelayNs for OneShotTimer<'_, Async> {
328 async fn delay_ns(&mut self, ns: u32) {
329 self.delay_nanos_async(ns).await
330 }
331}
332
333pub struct PeriodicTimer<'d, Dm: DriverMode> {
335 inner: AnyTimer<'d>,
336 _ph: PhantomData<Dm>,
337}
338
339impl<'d> PeriodicTimer<'d, Blocking> {
340 pub fn new(inner: impl Timer + Into<AnyTimer<'d>>) -> PeriodicTimer<'d, Blocking> {
342 Self {
343 inner: inner.into(),
344 _ph: PhantomData,
345 }
346 }
347}
348
349impl<Dm> PeriodicTimer<'_, Dm>
350where
351 Dm: DriverMode,
352{
353 pub fn start(&mut self, period: Duration) -> Result<(), Error> {
355 if self.inner.is_running() {
356 self.inner.stop();
357 }
358
359 self.inner.clear_interrupt();
360 self.inner.reset();
361
362 self.inner.enable_auto_reload(true);
363 self.inner.load_value(period)?;
364 self.inner.start();
365
366 Ok(())
367 }
368
369 pub fn wait(&mut self) {
371 while !self.inner.is_interrupt_set() {}
372 self.inner.clear_interrupt();
373 }
374
375 pub fn cancel(&mut self) -> Result<(), Error> {
377 if !self.inner.is_running() {
378 return Err(Error::TimerInactive);
379 }
380
381 self.inner.stop();
382
383 Ok(())
384 }
385
386 #[instability::unstable]
390 pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
391 self.inner.set_interrupt_handler(handler);
392 }
393
394 pub fn enable_interrupt(&mut self, enable: bool) {
396 self.inner.enable_interrupt(enable);
397 }
398
399 pub fn clear_interrupt(&mut self) {
401 self.inner.clear_interrupt();
402 }
403}
404
405impl<Dm> crate::private::Sealed for PeriodicTimer<'_, Dm> where Dm: DriverMode {}
406
407impl<Dm> InterruptConfigurable for PeriodicTimer<'_, Dm>
408where
409 Dm: DriverMode,
410{
411 fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) {
412 PeriodicTimer::set_interrupt_handler(self, handler);
413 }
414}
415
416crate::any_peripheral! {
417 pub peripheral AnyTimer<'d> {
419 TimgTimer(timg::Timer<'d>),
420 #[cfg(systimer)]
421 SystimerAlarm(systimer::Alarm<'d>),
422 }
423}
424
425impl Timer for AnyTimer<'_> {
426 delegate::delegate! {
427 to match &self.0 {
428 AnyTimerInner::TimgTimer(inner) => inner,
429 #[cfg(systimer)]
430 AnyTimerInner::SystimerAlarm(inner) => inner,
431 } {
432 fn start(&self);
433 fn stop(&self);
434 fn reset(&self);
435 fn is_running(&self) -> bool;
436 fn now(&self) -> Instant;
437 fn load_value(&self, value: Duration) -> Result<(), Error>;
438 fn enable_auto_reload(&self, auto_reload: bool);
439 fn enable_interrupt(&self, state: bool);
440 fn clear_interrupt(&self);
441 fn is_interrupt_set(&self) -> bool;
442 fn async_interrupt_handler(&self) -> InterruptHandler;
443 fn peripheral_interrupt(&self) -> Interrupt;
444 fn set_interrupt_handler(&self, handler: InterruptHandler);
445 fn waker(&self) -> &AtomicWaker;
446 }
447 }
448}