Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix timing of asm-based delay implementation #312

Merged
merged 1 commit into from
Jan 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions asm/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
);
}

Expand Down
Binary file modified bin/thumbv6m-none-eabi-lto.a
Binary file not shown.
Binary file modified bin/thumbv6m-none-eabi.a
Binary file not shown.
Binary file modified bin/thumbv7em-none-eabi-lto.a
Binary file not shown.
Binary file modified bin/thumbv7em-none-eabi.a
Binary file not shown.
Binary file modified bin/thumbv7em-none-eabihf-lto.a
Binary file not shown.
Binary file modified bin/thumbv7em-none-eabihf.a
Binary file not shown.
Binary file modified bin/thumbv7m-none-eabi-lto.a
Binary file not shown.
Binary file modified bin/thumbv7m-none-eabi.a
Binary file not shown.
Binary file modified bin/thumbv8m.base-none-eabi-lto.a
Binary file not shown.
Binary file modified bin/thumbv8m.base-none-eabi.a
Binary file not shown.
Binary file modified bin/thumbv8m.main-none-eabi-lto.a
Binary file not shown.
Binary file modified bin/thumbv8m.main-none-eabi.a
Binary file not shown.
Binary file modified bin/thumbv8m.main-none-eabihf-lto.a
Binary file not shown.
Binary file modified bin/thumbv8m.main-none-eabihf.a
Binary file not shown.
8 changes: 3 additions & 5 deletions src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub fn bkpt() {
call_asm!(__bkpt());
}

/// Blocks the program for *at least* `n` instruction cycles
/// Blocks the program for *at least* `cycles` CPU cycles.
///
/// This is implemented in assembly so its execution time is independent of the optimization
/// level, however it is dependent on the specific architecture and core configuration.
Expand All @@ -25,10 +25,8 @@ pub fn bkpt() {
/// timer-less initialization of peripherals if and only if accurate timing is not essential. In
/// any other case please use a more accurate method to produce a delay.
#[inline]
pub fn delay(n: u32) {
// NOTE(divide by 4) is easier to compute than `/ 3` because it's just a shift (`>> 2`).
let real_cyc = n / 4 + 1;
call_asm!(__delay(real_cyc: u32));
pub fn delay(cycles: u32) {
call_asm!(__delay(cycles: u32));
}

/// A no-operation. Useful to prevent delay loops from being optimized away.
Expand Down