1 | //! Delays. |
2 | |
3 | /// Nanoseconds per microsecond |
4 | const NANOS_PER_MICRO: u32 = 1_000; |
5 | /// Nanoseconds per millisecond |
6 | const NANOS_PER_MILLI: u32 = 1_000_000; |
7 | |
8 | /// Delay with up to nanosecond precision. |
9 | pub trait DelayNs { |
10 | /// Pauses execution for at minimum `ns` nanoseconds. Pause can be longer |
11 | /// if the implementation requires it due to precision/timing issues. |
12 | fn delay_ns(&mut self, ns: u32); |
13 | |
14 | /// Pauses execution for at minimum `us` microseconds. Pause can be longer |
15 | /// if the implementation requires it due to precision/timing issues. |
16 | fn delay_us(&mut self, mut us: u32) { |
17 | const MAX_MICROS: u32 = u32::MAX / NANOS_PER_MICRO; |
18 | |
19 | // Avoid potential overflow if micro -> nano conversion is too large |
20 | while us > MAX_MICROS { |
21 | us -= MAX_MICROS; |
22 | self.delay_ns(MAX_MICROS * NANOS_PER_MICRO); |
23 | } |
24 | |
25 | self.delay_ns(us * NANOS_PER_MICRO); |
26 | } |
27 | |
28 | /// Pauses execution for at minimum `ms` milliseconds. Pause can be longer |
29 | /// if the implementation requires it due to precision/timing issues. |
30 | #[inline ] |
31 | fn delay_ms(&mut self, mut ms: u32) { |
32 | const MAX_MILLIS: u32 = u32::MAX / NANOS_PER_MILLI; |
33 | |
34 | // Avoid potential overflow if milli -> nano conversion is too large |
35 | while ms > MAX_MILLIS { |
36 | ms -= MAX_MILLIS; |
37 | self.delay_ns(MAX_MILLIS * NANOS_PER_MILLI); |
38 | } |
39 | |
40 | self.delay_ns(ms * NANOS_PER_MILLI); |
41 | } |
42 | } |
43 | |
44 | impl<T> DelayNs for &mut T |
45 | where |
46 | T: DelayNs + ?Sized, |
47 | { |
48 | #[inline ] |
49 | fn delay_ns(&mut self, ns: u32) { |
50 | T::delay_ns(self, ns); |
51 | } |
52 | |
53 | #[inline ] |
54 | fn delay_us(&mut self, us: u32) { |
55 | T::delay_us(self, us); |
56 | } |
57 | |
58 | #[inline ] |
59 | fn delay_ms(&mut self, ms: u32) { |
60 | T::delay_ms(self, ms); |
61 | } |
62 | } |
63 | |