Skip to content

Commit 0daa4df

Browse files
authored
Merge pull request #14 from david-sawatzke/delay
Allow larger systick delays
2 parents b07a488 + 9cd3f37 commit 0daa4df

File tree

3 files changed

+65
-14
lines changed

3 files changed

+65
-14
lines changed

CHANGELOG.md

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

1212
- Added Sync & Send ability to Pin
13+
- Added overflow guards to delay
1314

1415
## [v0.10.0] - 2018-12-23
1516

src/delay.rs

Lines changed: 61 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,31 @@
1-
//! Delays
2-
3-
use cast::u32;
1+
//! API for delays with the systick timer
2+
//!
3+
//! Please be aware of potential overflows.
4+
//! For example, the maximum delay with 48MHz is around 89 seconds
5+
//!
6+
//! Consider using the timers api as a more flexible interface
7+
//!
8+
//! # Example
9+
//!
10+
//! ``` no_run
11+
//! use stm32f0xx_hal as hal;
12+
//!
13+
//! use crate::hal::stm32;
14+
//! use crate::hal::prelude::*;
15+
//! use crate::hal::delay::Delay;
16+
//! use cortex_m::peripheral::Peripherals;
17+
//!
18+
//! let mut p = stm32::Peripherals::take().unwrap();
19+
//! let mut cp = cortex_m::Peripherals::take().unwrap();
20+
//!
21+
//! let clocks = p.RCC.constrain().cfgr.freeze();
22+
//! let mut delay = Delay::new(cp.SYST, clocks);
23+
//! loop {
24+
//! delay.delay_ms(1_000_u16);
25+
//! }
26+
//! ```
27+
28+
use cast::{u16, u32};
429
use cortex_m::peripheral::syst::SystClkSource;
530
use cortex_m::peripheral::SYST;
631

@@ -28,36 +53,58 @@ impl Delay {
2853
}
2954

3055
impl DelayMs<u32> for Delay {
31-
fn delay_ms(&mut self, ms: u32) {
32-
self.delay_us(ms * 1_000);
56+
// At 48 MHz, calling delay_us with ms * 1_000 directly overflows at 0x15D868 (just over the max u16 value)
57+
fn delay_ms(&mut self, mut ms: u32) {
58+
const MAX_MS: u32 = 0x0000_FFFF;
59+
while ms != 0 {
60+
let current_ms = if ms <= MAX_MS { ms } else { MAX_MS };
61+
self.delay_us(current_ms * 1_000);
62+
ms -= current_ms;
63+
}
3364
}
3465
}
3566

3667
impl DelayMs<u16> for Delay {
3768
fn delay_ms(&mut self, ms: u16) {
38-
self.delay_ms(u32(ms));
69+
self.delay_us(ms as u32 * 1_000);
3970
}
4071
}
4172

4273
impl DelayMs<u8> for Delay {
4374
fn delay_ms(&mut self, ms: u8) {
44-
self.delay_ms(u32(ms));
75+
self.delay_ms(u16(ms));
4576
}
4677
}
4778

4879
impl DelayUs<u32> for Delay {
4980
fn delay_us(&mut self, us: u32) {
50-
let rvr = us * (self.clocks.sysclk().0 / 1_000_000);
81+
// The SysTick Reload Value register supports values between 1 and 0x00FFFFFF.
82+
const MAX_RVR: u32 = 0x00FF_FFFF;
83+
84+
let mut total_rvr = if self.clocks.sysclk().0 < 1_000_000 {
85+
us / (1_000_00 / self.clocks.sysclk().0)
86+
} else {
87+
us * (self.clocks.sysclk().0 / 1_000_000)
88+
};
89+
90+
while total_rvr != 0 {
91+
let current_rvr = if total_rvr <= MAX_RVR {
92+
total_rvr
93+
} else {
94+
MAX_RVR
95+
};
5196

52-
assert!(rvr < (1 << 24));
97+
self.syst.set_reload(current_rvr);
98+
self.syst.clear_current();
99+
self.syst.enable_counter();
53100

54-
self.syst.set_reload(rvr);
55-
self.syst.clear_current();
56-
self.syst.enable_counter();
101+
// Update the tracking variable while we are waiting...
102+
total_rvr -= current_rvr;
57103

58-
while !self.syst.has_wrapped() {}
104+
while !self.syst.has_wrapped() {}
59105

60-
self.syst.disable_counter();
106+
self.syst.disable_counter();
107+
}
61108
}
62109
}
63110

src/timers.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ impl Timer<SYST> {
7373
}
7474
}
7575

76+
/// Use the systick as a timer
77+
///
78+
/// Be aware that intervals less than 4 Hertz may not function properly
7679
impl CountDown for Timer<SYST> {
7780
type Time = Hertz;
7881

0 commit comments

Comments
 (0)