aboutsummaryrefslogtreecommitdiff
path: root/asm/inline.rs
diff options
context:
space:
mode:
authorGravatar Jonas Schievink <jonasschievink@gmail.com> 2021-01-07 18:40:03 +0100
committerGravatar Jonas Schievink <jonasschievink@gmail.com> 2021-01-07 18:40:03 +0100
commit5a43c6e7927efb2658183929c69dd774c5f8d2c1 (patch)
tree4ada31c00f8e44647975df3cf17ed601ed5a1e0b /asm/inline.rs
parent126165331e14f92809656a76dfa351e42dfa1a68 (diff)
downloadcortex-m-5a43c6e7927efb2658183929c69dd774c5f8d2c1.tar.gz
cortex-m-5a43c6e7927efb2658183929c69dd774c5f8d2c1.tar.zst
cortex-m-5a43c6e7927efb2658183929c69dd774c5f8d2c1.zip
Fix timing of asm-based delay implementation
Diffstat (limited to 'asm/inline.rs')
-rw-r--r--asm/inline.rs9
1 files changed, 6 insertions, 3 deletions
diff --git a/asm/inline.rs b/asm/inline.rs
index 9150c9c..5e2fbc1 100644
--- a/asm/inline.rs
+++ b/asm/inline.rs
@@ -52,13 +52,16 @@ pub unsafe fn __cpsie() {
#[inline(always)]
pub unsafe fn __delay(cyc: u32) {
- // Use local labels to avoid R_ARM_THM_JUMP8 relocations which fail on thumbv6m.
+ // The loop will normally take 3 to 4 CPU cycles per iteration, but superscalar cores
+ // (eg. Cortex-M7) can potentially do it in 2, so we use that as the lower bound, since delaying
+ // for more cycles is okay.
+ let real_cyc = cyc / 2;
asm!(
+ // Use local labels to avoid R_ARM_THM_JUMP8 relocations which fail on thumbv6m.
"1:",
- "nop",
"subs {}, #1",
"bne 1b",
- in(reg) cyc
+ in(reg) real_cyc
);
}