Browse Source

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
trying.tmp
david-sawatzke 4 years ago committed by Daniel Egger
parent
commit
f729f7e4df
  1. 1
      CHANGELOG.md
  2. 34
      src/delay.rs

1
CHANGELOG.md

@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Added ADC helper functions to read more intuitive values (#22) - @HarkonenBade
- Added interrupt enabling/disabling support to USART ports
- Added the option to have multiple Delay instances by cloning it - @david-sawatzke
### Changed

34
src/delay.rs

@ -33,22 +33,24 @@ use crate::rcc::Clocks;
use embedded_hal::blocking::delay::{DelayMs, DelayUs};
/// System timer (SysTick) as a delay provider
#[derive(Clone)]
pub struct Delay {
clocks: Clocks,
syst: SYST,
}
const MAX_SYSTICK: u32 = 0x00FF_FFFF;
impl Delay {
/// Configures the system timer (SysTick) as a delay provider
pub fn new(mut syst: SYST, clocks: Clocks) -> Self {
/// As access to the count register is possible without a reference, we can
/// just drop it
pub fn new(mut syst: SYST, clocks: Clocks) -> Delay {
syst.set_clock_source(SystClkSource::Core);
Delay { syst, clocks }
}
/// Releases the system timer (SysTick) resource
pub fn free(self) -> SYST {
self.syst
syst.set_reload(MAX_SYSTICK);
syst.clear_current();
syst.enable_counter();
Delay { clocks }
}
}
@ -79,10 +81,11 @@ impl DelayMs<u8> for Delay {
impl DelayUs<u32> for Delay {
fn delay_us(&mut self, us: u32) {
// The SysTick Reload Value register supports values between 1 and 0x00FFFFFF.
const MAX_RVR: u32 = 0x00FF_FFFF;
// Here less than maximum is used so we have some play if there's a long running interrupt.
const MAX_RVR: u32 = 0x007F_FFFF;
let mut total_rvr = if self.clocks.sysclk().0 < 1_000_000 {
us / (1_000_00 / self.clocks.sysclk().0)
us / (1_000_000 / self.clocks.sysclk().0)
} else {
us * (self.clocks.sysclk().0 / 1_000_000)
};
@ -94,16 +97,9 @@ impl DelayUs<u32> for Delay {
MAX_RVR
};
self.syst.set_reload(current_rvr);
self.syst.clear_current();
self.syst.enable_counter();
// Update the tracking variable while we are waiting...
let start_count = SYST::get_current();
total_rvr -= current_rvr;
while !self.syst.has_wrapped() {}
self.syst.disable_counter();
while ((start_count - SYST::get_current()) % MAX_SYSTICK) < current_rvr {}
}
}
}

Loading…
Cancel
Save