@@ -33,22 +33,24 @@ use crate::rcc::Clocks;
33
33
use embedded_hal:: blocking:: delay:: { DelayMs , DelayUs } ;
34
34
35
35
/// System timer (SysTick) as a delay provider
36
+ #[ derive( Clone ) ]
36
37
pub struct Delay {
37
38
clocks : Clocks ,
38
- syst : SYST ,
39
39
}
40
40
41
+ const MAX_SYSTICK : u32 = 0x00FF_FFFF ;
42
+
41
43
impl Delay {
42
44
/// Configures the system timer (SysTick) as a delay provider
43
- pub fn new ( mut syst : SYST , clocks : Clocks ) -> Self {
45
+ /// As access to the count register is possible without a reference, we can
46
+ /// just drop it
47
+ pub fn new ( mut syst : SYST , clocks : Clocks ) -> Delay {
44
48
syst. set_clock_source ( SystClkSource :: Core ) ;
45
49
46
- Delay { syst, clocks }
47
- }
48
-
49
- /// Releases the system timer (SysTick) resource
50
- pub fn free ( self ) -> SYST {
51
- self . syst
50
+ syst. set_reload ( MAX_SYSTICK ) ;
51
+ syst. clear_current ( ) ;
52
+ syst. enable_counter ( ) ;
53
+ Delay { clocks }
52
54
}
53
55
}
54
56
@@ -79,10 +81,11 @@ impl DelayMs<u8> for Delay {
79
81
impl DelayUs < u32 > for Delay {
80
82
fn delay_us ( & mut self , us : u32 ) {
81
83
// The SysTick Reload Value register supports values between 1 and 0x00FFFFFF.
82
- const MAX_RVR : u32 = 0x00FF_FFFF ;
84
+ // Here less than maximum is used so we have some play if there's a long running interrupt.
85
+ const MAX_RVR : u32 = 0x007F_FFFF ;
83
86
84
87
let mut total_rvr = if self . clocks . sysclk ( ) . 0 < 1_000_000 {
85
- us / ( 1_000_00 / self . clocks . sysclk ( ) . 0 )
88
+ us / ( 1_000_000 / self . clocks . sysclk ( ) . 0 )
86
89
} else {
87
90
us * ( self . clocks . sysclk ( ) . 0 / 1_000_000 )
88
91
} ;
@@ -94,16 +97,9 @@ impl DelayUs<u32> for Delay {
94
97
MAX_RVR
95
98
} ;
96
99
97
- self . syst . set_reload ( current_rvr) ;
98
- self . syst . clear_current ( ) ;
99
- self . syst . enable_counter ( ) ;
100
-
101
- // Update the tracking variable while we are waiting...
100
+ let start_count = SYST :: get_current ( ) ;
102
101
total_rvr -= current_rvr;
103
-
104
- while !self . syst . has_wrapped ( ) { }
105
-
106
- self . syst . disable_counter ( ) ;
102
+ while ( ( start_count - SYST :: get_current ( ) ) % MAX_SYSTICK ) < current_rvr { }
107
103
}
108
104
}
109
105
}
0 commit comments