Skip to content

Commit 396b631

Browse files
committed
Fix RVR values
1 parent 0790a32 commit 396b631

File tree

1 file changed

+21
-14
lines changed

1 file changed

+21
-14
lines changed

src/delay.rs

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ pub struct Delay {
4141
hclk_hz: u32,
4242
syst: SYST,
4343
}
44-
fn calc_rvr(ns: u32, hclk: u32) -> u32 {
44+
45+
fn calc_ticks(ns: u32, hclk: u32) -> u32 {
4546
// Default is for SYSTICK to be fed by HCLK/8
4647
let ticks: u64 = (SecsDurationU64::secs(1) * SYSTICK_HCLK_DIV).to_nanos();
4748
((ns as u64 * hclk as u64) / ticks) as u32
@@ -69,21 +70,24 @@ impl DelayNs for Delay {
6970
// The SysTick Reload Value register supports values between 1 and 0x00FFFFFF.
7071
const MAX_RVR: u32 = 0x00FF_FFFF;
7172

72-
let mut total_rvr = calc_rvr(ns, self.hclk_hz);
73+
let mut total_ticks = calc_ticks(ns, self.hclk_hz);
7374

74-
while total_rvr != 0 {
75-
let current_rvr = if total_rvr <= MAX_RVR {
76-
total_rvr
75+
while total_ticks != 0 {
76+
let current_ticks = if total_ticks <= MAX_RVR {
77+
// To count N ticks, set RVR to N-1
78+
// (see ARM Cortex M33 Devices Generic User Guide section 4.3.2.1)
79+
core::cmp::max(total_ticks - 1, 1)
7780
} else {
7881
MAX_RVR
7982
};
8083

81-
self.syst.set_reload(current_rvr);
84+
self.syst.set_reload(current_ticks);
8285
self.syst.clear_current();
8386
self.syst.enable_counter();
8487

85-
// Update the tracking variable while we are waiting...
86-
total_rvr -= current_rvr;
88+
// For an RVR value of N, the SYSTICK counts N+1 ticks
89+
// (see ARM Cortex M33 Devices Generic User Guide section 4.3.2.1)
90+
total_ticks = total_ticks.saturating_sub(current_ticks + 1);
8791

8892
while !self.syst.has_wrapped() {}
8993

@@ -94,19 +98,22 @@ impl DelayNs for Delay {
9498

9599
#[cfg(test)]
96100
mod tests {
97-
use super::calc_rvr;
101+
use super::calc_ticks;
98102
#[test]
99103
fn test_calc_rvr() {
100-
let rvr = calc_rvr(1000, 8_000_000);
104+
let rvr = calc_ticks(1_000, 8_000_000);
101105
assert_eq!(rvr, 1);
102106

103-
let rvr = calc_rvr(1000_000, 8_000_000);
107+
let rvr = calc_ticks(1_000_000, 8_000_000);
104108
assert_eq!(rvr, 1000);
105109

106-
let rvr = calc_rvr(1000_000, 10_000_000);
110+
let rvr = calc_ticks(1_000_000, 10_000_000);
107111
assert_eq!(rvr, 1250);
108112

109-
let rvr = calc_rvr(1000_000, 250_000_000);
110-
assert_eq!(rvr, 31250);
113+
let rvr = calc_ticks(1_000_000_000, 250_000_000);
114+
assert_eq!(rvr, 31_250_000);
115+
116+
let rvr = calc_ticks(32, 250_000_000);
117+
assert_eq!(rvr, 1);
111118
}
112119
}

0 commit comments

Comments
 (0)