Skip to content

Commit f729f7e

Browse files
david-sawatzketherealprof
authored andcommitted
Allow multi delay instances for the systick timer (#23)
* Fix typo from #21 * Implement shareable systick * Fix it, so downcounting is expected & add overflow guards * Add changelog entry for multi-delay
1 parent f55163c commit f729f7e

File tree

2 files changed

+16
-19
lines changed

2 files changed

+16
-19
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1111

1212
- Added ADC helper functions to read more intuitive values (#22) - @HarkonenBade
1313
- Added interrupt enabling/disabling support to USART ports
14+
- Added the option to have multiple Delay instances by cloning it - @david-sawatzke
1415

1516
### Changed
1617

src/delay.rs

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,22 +33,24 @@ use crate::rcc::Clocks;
3333
use embedded_hal::blocking::delay::{DelayMs, DelayUs};
3434

3535
/// System timer (SysTick) as a delay provider
36+
#[derive(Clone)]
3637
pub struct Delay {
3738
clocks: Clocks,
38-
syst: SYST,
3939
}
4040

41+
const MAX_SYSTICK: u32 = 0x00FF_FFFF;
42+
4143
impl 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 {
7981
impl 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

Comments
 (0)