3030//! [DelayUs]: embedded_hal_02::blocking::delay::DelayUs
3131//! [embedded-hal]: https://docs.rs/embedded-hal/1.0.0/embedded_hal/delay/index.html
3232
33- use fugit:: HertzU64 ;
3433pub use fugit:: MicrosDurationU64 ;
3534
35+ use crate :: clock:: Clocks ;
36+
3637/// Delay driver
3738///
3839/// Uses the `SYSTIMER` peripheral internally for RISC-V devices, and the
3940/// built-in Xtensa timer for Xtensa devices.
4041#[ derive( Clone , Copy ) ]
41- pub struct Delay {
42- freq : HertzU64 ,
43- }
44-
45- impl Delay {
46- /// Delay for the specified number of milliseconds
47- pub fn delay_millis ( & self , ms : u32 ) {
48- for _ in 0 ..ms {
49- self . delay_micros ( 1000 ) ;
50- }
51- }
52- }
42+ #[ non_exhaustive]
43+ pub struct Delay ;
5344
5445#[ cfg( feature = "embedded-hal-02" ) ]
5546impl < T > embedded_hal_02:: blocking:: delay:: DelayMs < T > for Delay
5647where
5748 T : Into < u32 > ,
5849{
5950 fn delay_ms ( & mut self , ms : T ) {
60- for _ in 0 ..ms. into ( ) {
61- self . delay_micros ( 1000 ) ;
62- }
51+ self . delay_millis ( ms. into ( ) ) ;
6352 }
6453}
6554
@@ -80,83 +69,48 @@ impl embedded_hal::delay::DelayNs for Delay {
8069 }
8170}
8271
83- #[ cfg( riscv) ]
84- mod implementation {
85- use super :: * ;
86- use crate :: { clock:: Clocks , timer:: systimer:: SystemTimer } ;
87-
88- impl Delay {
89- /// Create a new `Delay` instance
90- pub fn new ( clocks : & Clocks < ' _ > ) -> Self {
91- // The counters and comparators are driven using `XTAL_CLK`.
92- // The average clock frequency is fXTAL_CLK/2.5, which is 16 MHz.
93- // The timer counting is incremented by 1/16 μs on each `CNT_CLK` cycle.
94- Self {
95- #[ cfg( not( esp32h2) ) ]
96- freq : HertzU64 :: MHz ( clocks. xtal_clock . to_MHz ( ) as u64 * 10 / 25 ) ,
97- #[ cfg( esp32h2) ]
98- // esp32h2 TRM, section 11.2 Clock Source Selection
99- freq : HertzU64 :: MHz ( clocks. xtal_clock . to_MHz ( ) as u64 * 10 / 20 ) ,
100- }
101- }
102-
103- /// Delay for the specified time
104- pub fn delay ( & self , time : MicrosDurationU64 ) {
105- let t0 = SystemTimer :: now ( ) ;
106- let rate: HertzU64 = MicrosDurationU64 :: from_ticks ( 1 ) . into_rate ( ) ;
107- let clocks = time. ticks ( ) * ( self . freq / rate) ;
72+ impl Delay {
73+ /// Creates a new `Delay` instance.
74+ // Do not remove the argument, it makes sure that the clocks are initialized.
75+ pub fn new ( _clocks : & Clocks < ' _ > ) -> Self {
76+ Self { }
77+ }
10878
109- while SystemTimer :: now ( ) . wrapping_sub ( t0) & SystemTimer :: BIT_MASK <= clocks { }
110- }
79+ /// Delay for the specified time
80+ pub fn delay ( & self , delay : MicrosDurationU64 ) {
81+ let start = crate :: time:: current_time ( ) ;
11182
112- /// Delay for the specified number of microseconds
113- pub fn delay_micros ( & self , us : u32 ) {
114- let t0 = SystemTimer :: now ( ) ;
115- let clocks = us as u64 * ( self . freq / HertzU64 :: MHz ( 1 ) ) ;
83+ while elapsed_since ( start) < delay { }
84+ }
11685
117- while SystemTimer :: now ( ) . wrapping_sub ( t0) & SystemTimer :: BIT_MASK <= clocks { }
86+ /// Delay for the specified number of milliseconds
87+ pub fn delay_millis ( & self , ms : u32 ) {
88+ for _ in 0 ..ms {
89+ self . delay_micros ( 1000 ) ;
11890 }
91+ }
11992
120- /// Delay for the specified number of nanoseconds
121- pub fn delay_nanos ( & self , ns : u32 ) {
122- let t0 = SystemTimer :: now ( ) ;
123- let clocks = ns as u64 * ( self . freq / HertzU64 :: MHz ( 1 ) ) / 1000 ;
93+ /// Delay for the specified number of microseconds
94+ pub fn delay_micros ( & self , us : u32 ) {
95+ let delay = MicrosDurationU64 :: micros ( us as u64 ) ;
96+ self . delay ( delay) ;
97+ }
12498
125- while SystemTimer :: now ( ) . wrapping_sub ( t0) & SystemTimer :: BIT_MASK <= clocks { }
126- }
99+ /// Delay for the specified number of nanoseconds
100+ pub fn delay_nanos ( & self , ns : u32 ) {
101+ let delay = MicrosDurationU64 :: nanos ( ns as u64 ) ;
102+ self . delay ( delay) ;
127103 }
128104}
129105
130- #[ cfg( xtensa) ]
131- mod implementation {
132- use super :: * ;
133- use crate :: clock:: Clocks ;
134-
135- impl Delay {
136- /// Create a new `Delay` instance
137- pub fn new ( clocks : & Clocks < ' _ > ) -> Self {
138- Self {
139- freq : clocks. cpu_clock . into ( ) ,
140- }
141- }
142-
143- /// Delay for the specified time
144- pub fn delay ( & self , time : MicrosDurationU64 ) {
145- let rate: HertzU64 = MicrosDurationU64 :: from_ticks ( 1 ) . into_rate ( ) ;
146- let clocks = time. ticks ( ) * ( self . freq / rate) ;
147- xtensa_lx:: timer:: delay ( clocks as u32 ) ;
148- }
149-
150- /// Delay for the specified number of microseconds
151- pub fn delay_micros ( & self , us : u32 ) {
152- let clocks = us as u64 * ( self . freq / HertzU64 :: MHz ( 1 ) ) ;
153- xtensa_lx:: timer:: delay ( clocks as u32 ) ;
154- }
106+ fn elapsed_since ( start : fugit:: Instant < u64 , 1 , 1_000_000 > ) -> MicrosDurationU64 {
107+ let now = crate :: time:: current_time ( ) ;
155108
156- /// Delay for the specified number of nanoseconds
157- pub fn delay_nanos ( & self , ns : u32 ) {
158- let clocks = ns as u64 * ( self . freq / HertzU64 :: MHz ( 1 ) ) / 1000 ;
159- xtensa_lx:: timer:: delay ( clocks as u32 ) ;
160- }
109+ if start. ticks ( ) <= now. ticks ( ) {
110+ now - start
111+ } else {
112+ // current_time specifies at least 7 happy years, let's ignore this issue for
113+ // now.
114+ panic ! ( "Time has wrapped around, which we currently don't handle" ) ;
161115 }
162116}
0 commit comments