@@ -40,10 +40,12 @@ use crate::rcc::Clocks;
40
40
use crate :: time:: MicroSecond ;
41
41
pub use cortex_m:: delay:: * ;
42
42
use cortex_m:: peripheral:: SYST ;
43
+ use fugit:: ExtU32Ceil ;
43
44
44
45
use crate :: nb:: block;
45
46
use crate :: time:: ExtU32 ;
46
47
use embedded_hal:: blocking:: delay:: { DelayMs , DelayUs } ;
48
+ use embedded_hal_one:: delay:: DelayNs ;
47
49
48
50
pub trait CountDown : embedded_hal:: timer:: CountDown {
49
51
fn max_period ( & self ) -> MicroSecond ;
@@ -132,7 +134,7 @@ macro_rules! impl_delay_from_count_down_timer {
132
134
T : CountDown <Time = MicroSecond >,
133
135
{
134
136
fn $delay( & mut self , t: u16 ) {
135
- self . $ delay( t as u32 ) ;
137
+ $Delay :: $ delay( self , t as u32 ) ;
136
138
}
137
139
}
138
140
@@ -141,7 +143,7 @@ macro_rules! impl_delay_from_count_down_timer {
141
143
T : CountDown <Time = MicroSecond >,
142
144
{
143
145
fn $delay( & mut self , t: u8 ) {
144
- self . $ delay( t as u32 ) ;
146
+ $Delay :: $ delay( self , t as u32 ) ;
145
147
}
146
148
}
147
149
) +
@@ -152,3 +154,34 @@ impl_delay_from_count_down_timer! {
152
154
( DelayMs , delay_ms, 1_000 ) ,
153
155
( DelayUs , delay_us, 1 )
154
156
}
157
+
158
+ // TODO: decouple the timer API from embedded-hal 0.2, stm32f4xx-hal with constant timer
159
+ // frequencies looks like a good example
160
+ impl < T : CountDown < Time = MicroSecond > > DelayNs for DelayFromCountDownTimer < T > {
161
+ // From a quick look at the clock diagram timer resolution can go down to ~3ns on most timers
162
+ // 170MHz (PLL-R as SysClk) / 1 (AHB Prescaler) / 1 (APBx prescaler) * 2 = 340MHz timer clock
163
+ // TODO: the current fallback to 1us resolution is a stopgap until the module is reworked
164
+ fn delay_ns ( & mut self , ns : u32 ) {
165
+ DelayNs :: delay_us ( self , ns. div_ceil ( 1000 ) )
166
+ }
167
+ fn delay_us ( & mut self , mut us : u32 ) {
168
+ let max_sleep = self . 0 . max_period ( ) ;
169
+ let max_us = max_sleep. to_micros ( ) ;
170
+
171
+ while us > max_us {
172
+ self . 0 . start ( max_us. micros_at_least ( ) ) ;
173
+ let _ = nb:: block!( self . 0 . wait( ) ) ;
174
+ us -= max_us;
175
+ }
176
+ self . 0 . start ( us. micros_at_least ( ) ) ;
177
+ let _ = nb:: block!( self . 0 . wait( ) ) ;
178
+ }
179
+ fn delay_ms ( & mut self , mut ms : u32 ) {
180
+ const MAX_MILLIS : u32 = u32:: MAX / 1000 ;
181
+ while ms > MAX_MILLIS {
182
+ ms -= MAX_MILLIS ;
183
+ DelayNs :: delay_us ( self , MAX_MILLIS * 1000 ) ;
184
+ }
185
+ DelayNs :: delay_us ( self , ms * 1000 ) ;
186
+ }
187
+ }
0 commit comments