diff --git a/avr-hal-generic/Cargo.toml b/avr-hal-generic/Cargo.toml index fae3aeb010..81a940ac65 100644 --- a/avr-hal-generic/Cargo.toml +++ b/avr-hal-generic/Cargo.toml @@ -18,3 +18,6 @@ features = ["unproven"] [dependencies.void] version = "1.0.2" default-features = false + +[build-dependencies] +rustversion = "1.0" diff --git a/avr-hal-generic/build.rs b/avr-hal-generic/build.rs new file mode 100644 index 0000000000..b22938833f --- /dev/null +++ b/avr-hal-generic/build.rs @@ -0,0 +1,16 @@ +fn main() { + println!("cargo:rerun-if-changed=build.rs"); + + maybe_enable_asm(); +} + +#[rustversion::before(1.59.0)] +fn maybe_enable_asm() { + // +} + +#[rustversion::since(1.59.0)] +fn maybe_enable_asm() { + // https://github.com/rust-lang/rust/pull/92816 + println!("cargo:rustc-cfg=avr_hal_asm_macro"); +} diff --git a/avr-hal-generic/src/delay.rs b/avr-hal-generic/src/delay.rs index cac1df5c95..1e413eb6a1 100644 --- a/avr-hal-generic/src/delay.rs +++ b/avr-hal-generic/src/delay.rs @@ -3,6 +3,9 @@ use core::marker; use hal::blocking::delay; +#[cfg(all(target_arch = "avr", avr_hal_asm_macro))] +use core::arch::asm; + /// A busy-loop delay implementation /// /// # Example @@ -32,7 +35,18 @@ impl Delay { // based on https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/wiring.c cfg_if::cfg_if! { - if #[cfg(target_arch = "avr")] { + if #[cfg(all(target_arch = "avr", avr_hal_asm_macro))] { + fn busy_loop(c: u16) { + unsafe { + asm!( + "1:", + "sbiw {c}, 1", + "brne 1b", + c = in(reg_iw) c, + ); + } + } + } else if #[cfg(target_arch = "avr")] { #[allow(unused_assignments)] fn busy_loop(mut c: u16) { unsafe { @@ -81,9 +95,15 @@ impl delay::DelayUs for Delay { // for a one-microsecond delay, simply return. the overhead // of the function call takes 18 (20) cycles, which is 1us + #[cfg(all(target_arch = "avr", avr_hal_asm_macro))] + unsafe { + asm!("nop", "nop", "nop", "nop"); + } + + #[cfg(all(target_arch = "avr", not(avr_hal_asm_macro)))] unsafe { llvm_asm!("nop\nnop\nnop\nnop" :::: "volatile"); - } //just waiting 4 cycles + } if us <= 1 { return; @@ -238,7 +258,7 @@ where } } -impl delay::DelayMs for Delay +impl delay::DelayMs for Delay where Delay: delay::DelayMs, { diff --git a/avr-hal-generic/src/lib.rs b/avr-hal-generic/src/lib.rs index 590ef7d1a9..1814e80234 100644 --- a/avr-hal-generic/src/lib.rs +++ b/avr-hal-generic/src/lib.rs @@ -1,5 +1,6 @@ #![no_std] -#![feature(llvm_asm)] +#![cfg_attr(avr_hal_asm_macro, feature(asm_experimental_arch))] +#![cfg_attr(not(avr_hal_asm_macro), feature(llvm_asm))] pub extern crate embedded_hal as hal;