|
1 | 1 | //! Delays
|
2 | 2 |
|
3 |
| -use cast::u32; |
| 3 | +use cast::{u16, u32}; |
4 | 4 | use cortex_m::peripheral::syst::SystClkSource;
|
5 | 5 | use cortex_m::peripheral::SYST;
|
6 | 6 |
|
@@ -28,36 +28,58 @@ impl Delay {
|
28 | 28 | }
|
29 | 29 |
|
30 | 30 | impl DelayMs<u32> for Delay {
|
31 |
| - fn delay_ms(&mut self, ms: u32) { |
32 |
| - self.delay_us(ms * 1_000); |
| 31 | + // At 48 MHz, calling delay_us with ms * 1_000 directly overflows at 0x15D868 (just over the max u16 value) |
| 32 | + fn delay_ms(&mut self, mut ms: u32) { |
| 33 | + const MAX_MS: u32 = 0x0000_FFFF; |
| 34 | + while ms != 0 { |
| 35 | + let current_ms = if ms <= MAX_MS { ms } else { MAX_MS }; |
| 36 | + self.delay_us(current_ms * 1_000); |
| 37 | + ms -= current_ms; |
| 38 | + } |
33 | 39 | }
|
34 | 40 | }
|
35 | 41 |
|
36 | 42 | impl DelayMs<u16> for Delay {
|
37 | 43 | fn delay_ms(&mut self, ms: u16) {
|
38 |
| - self.delay_ms(u32(ms)); |
| 44 | + self.delay_us(ms as u32 * 1_000); |
39 | 45 | }
|
40 | 46 | }
|
41 | 47 |
|
42 | 48 | impl DelayMs<u8> for Delay {
|
43 | 49 | fn delay_ms(&mut self, ms: u8) {
|
44 |
| - self.delay_ms(u32(ms)); |
| 50 | + self.delay_ms(u16(ms)); |
45 | 51 | }
|
46 | 52 | }
|
47 | 53 |
|
48 | 54 | impl DelayUs<u32> for Delay {
|
49 | 55 | fn delay_us(&mut self, us: u32) {
|
50 |
| - let rvr = us * (self.clocks.sysclk().0 / 1_000_000); |
| 56 | + // The SysTick Reload Value register supports values between 1 and 0x00FFFFFF. |
| 57 | + const MAX_RVR: u32 = 0x00FF_FFFF; |
51 | 58 |
|
52 |
| - assert!(rvr < (1 << 24)); |
| 59 | + let mut total_rvr = if self.clocks.sysclk().0 < 1_000_000 { |
| 60 | + us / (1_000_00 / self.clocks.sysclk().0) |
| 61 | + } else { |
| 62 | + us * (self.clocks.sysclk().0 / 1_000_000) |
| 63 | + }; |
53 | 64 |
|
54 |
| - self.syst.set_reload(rvr); |
55 |
| - self.syst.clear_current(); |
56 |
| - self.syst.enable_counter(); |
| 65 | + while total_rvr != 0 { |
| 66 | + let current_rvr = if total_rvr <= MAX_RVR { |
| 67 | + total_rvr |
| 68 | + } else { |
| 69 | + MAX_RVR |
| 70 | + }; |
57 | 71 |
|
58 |
| - while !self.syst.has_wrapped() {} |
| 72 | + self.syst.set_reload(current_rvr); |
| 73 | + self.syst.clear_current(); |
| 74 | + self.syst.enable_counter(); |
59 | 75 |
|
60 |
| - self.syst.disable_counter(); |
| 76 | + // Update the tracking variable while we are waiting... |
| 77 | + total_rvr -= current_rvr; |
| 78 | + |
| 79 | + while !self.syst.has_wrapped() {} |
| 80 | + |
| 81 | + self.syst.disable_counter(); |
| 82 | + } |
61 | 83 | }
|
62 | 84 | }
|
63 | 85 |
|
|
0 commit comments