@@ -33,22 +33,24 @@ use crate::rcc::Clocks;
3333use embedded_hal:: blocking:: delay:: { DelayMs , DelayUs } ;
3434
3535/// System timer (SysTick) as a delay provider
36+ #[ derive( Clone ) ]
3637pub struct Delay {
3738 clocks : Clocks ,
38- syst : SYST ,
3939}
4040
41+ const MAX_SYSTICK : u32 = 0x00FF_FFFF ;
42+
4143impl Delay {
4244 /// 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 {
4448 syst. set_clock_source ( SystClkSource :: Core ) ;
4549
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 }
5254 }
5355}
5456
@@ -79,10 +81,11 @@ impl DelayMs<u8> for Delay {
7981impl DelayUs < u32 > for Delay {
8082 fn delay_us ( & mut self , us : u32 ) {
8183 // 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 ;
8386
8487 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 )
8689 } else {
8790 us * ( self . clocks . sysclk ( ) . 0 / 1_000_000 )
8891 } ;
@@ -94,16 +97,9 @@ impl DelayUs<u32> for Delay {
9497 MAX_RVR
9598 } ;
9699
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 ( ) ;
102101 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 { }
107103 }
108104 }
109105}
0 commit comments