Skip to content

Commit

Permalink
Add support for asm!()
Browse files Browse the repository at this point in the history
  • Loading branch information
Patryk27 authored and Rahix committed Apr 26, 2022
1 parent 3d22b91 commit 5d75769
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 4 deletions.
3 changes: 3 additions & 0 deletions avr-hal-generic/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ features = ["unproven"]
[dependencies.void]
version = "1.0.2"
default-features = false

[build-dependencies]
rustversion = "1.0"
16 changes: 16 additions & 0 deletions avr-hal-generic/build.rs
Original file line number Diff line number Diff line change
@@ -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");
}
26 changes: 23 additions & 3 deletions avr-hal-generic/src/delay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -32,7 +35,18 @@ impl<SPEED> Delay<SPEED> {
// 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 {
Expand Down Expand Up @@ -81,9 +95,15 @@ impl delay::DelayUs<u16> for Delay<crate::clock::MHz20> {

// 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;
Expand Down Expand Up @@ -238,7 +258,7 @@ where
}
}

impl <SPEED> delay::DelayMs<u8> for Delay<SPEED>
impl<SPEED> delay::DelayMs<u8> for Delay<SPEED>
where
Delay<SPEED>: delay::DelayMs<u16>,
{
Expand Down
3 changes: 2 additions & 1 deletion avr-hal-generic/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down

0 comments on commit 5d75769

Please sign in to comment.