From 91d0ad81bb69042a184a379db725d076b37838b4 Mon Sep 17 00:00:00 2001 From: Patryk Wychowaniec Date: Sun, 24 Apr 2022 18:45:00 +0200 Subject: [PATCH] Add support for `asm!()` --- Cargo.toml | 3 +++ README.md | 2 +- build.rs | 16 ++++++++++++++++ src/asm.rs | 15 ++++++++++++--- src/interrupt.rs | 24 ++++++++++++++++++++++-- src/lib.rs | 7 ++++--- 6 files changed, 58 insertions(+), 9 deletions(-) create mode 100644 build.rs diff --git a/Cargo.toml b/Cargo.toml index 32b8622..b277823 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,3 +59,6 @@ cfg-if = "0.1.10" path = "macros/" version = "=0.3.2" optional = true + +[build-dependencies] +rustversion = "1.0" diff --git a/README.md b/README.md index 2b0673f..80ddc92 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ The version on `crates.io` is pre-built. The following is only necessary when t You need to have [atdf2svd][] (= 0.3.1), [svd2rust][] (= 0.19), [form][] (>= 0.8), [rustfmt][](for the *nightly* toolchain) and [svdtools][] (>= 0.1.9) installed: ```bash cargo install atdf2svd --version 0.3.1 -cargo install svd2rust --version 0.19 +cargo install svd2rust --version 0.19.0 cargo install form rustup component add --toolchain nightly rustfmt pip3 install --user svdtools diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..352e458 --- /dev/null +++ b/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_device_asm_macro"); +} diff --git a/src/asm.rs b/src/asm.rs index b8f0e37..f859d89 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -1,10 +1,15 @@ //! Assembly instructions +#[cfg(all(target_arch = "avr", avr_device_asm_macro))] +use core::arch::asm; + /// No Operation #[inline(always)] pub fn nop() { cfg_if::cfg_if! { - if #[cfg(target_arch = "avr")] { + if #[cfg(all(target_arch = "avr", avr_device_asm_macro))] { + unsafe { asm!("nop") } + } else if #[cfg(target_arch = "avr")] { unsafe { llvm_asm!("nop") } } else { unimplemented!() @@ -16,7 +21,9 @@ pub fn nop() { #[inline(always)] pub fn sleep() { cfg_if::cfg_if! { - if #[cfg(target_arch = "avr")] { + if #[cfg(all(target_arch = "avr", avr_device_asm_macro))] { + unsafe { asm!("sleep") } + } else if #[cfg(target_arch = "avr")] { unsafe { llvm_asm!("sleep") } } else { unimplemented!() @@ -28,7 +35,9 @@ pub fn sleep() { #[inline(always)] pub fn wdr() { cfg_if::cfg_if! { - if #[cfg(target_arch = "avr")] { + if #[cfg(all(target_arch = "avr", avr_device_asm_macro))] { + unsafe { asm!("wdr") } + } else if #[cfg(target_arch = "avr")] { unsafe { llvm_asm!("wdr") } } else { unimplemented!() diff --git a/src/interrupt.rs b/src/interrupt.rs index e615aa1..6734b4e 100644 --- a/src/interrupt.rs +++ b/src/interrupt.rs @@ -10,13 +10,31 @@ pub use bare_metal::{CriticalSection, Mutex, Nr}; +#[cfg(all(target_arch = "avr", avr_device_asm_macro))] +use core::arch::asm; + #[inline] /// Disables all interrupts /// /// Returns a bool, reflecting whether interrupts were enabled prior to calling this method. pub fn disable() -> bool { cfg_if::cfg_if! { - if #[cfg(target_arch = "avr")] { + if #[cfg(all(target_arch = "avr", avr_device_asm_macro))] { + // Store current state + let sreg: u8; + + unsafe { + asm!( + "in {sreg}, 0x3F", + sreg = out(reg) sreg, + ) + }; + + // Disable interrupts + unsafe { asm!("cli") }; + + sreg & 0x80 == 0x80 + } else if #[cfg(target_arch = "avr")] { // Store current state let sreg: u8; unsafe { llvm_asm!("in $0,0x3F" :"=r"(sreg) ::: "volatile") }; @@ -39,7 +57,9 @@ pub fn disable() -> bool { /// - Do not call this function inside an [crate::interrupt::free] critical section pub unsafe fn enable() { cfg_if::cfg_if! { - if #[cfg(target_arch = "avr")] { + if #[cfg(all(target_arch = "avr", avr_device_asm_macro))] { + asm!("sei"); + } else if #[cfg(target_arch = "avr")] { llvm_asm!("sei" :::: "volatile"); } else { unimplemented!() diff --git a/src/lib.rs b/src/lib.rs index f6fc9de..2ccbed7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -56,7 +56,8 @@ //! * `attiny861` //! * `attiny88` #![no_std] -#![feature(llvm_asm)] +#![cfg_attr(avr_device_asm_macro, feature(asm_experimental_arch))] +#![cfg_attr(not(avr_device_asm_macro), feature(llvm_asm))] pub mod asm; pub mod interrupt; @@ -167,10 +168,10 @@ pub use crate::devices::atmega644; pub use crate::devices::atmega8; #[cfg(feature = "atmega8u2")] pub use crate::devices::atmega8u2; -#[cfg(feature = "attiny167")] -pub use crate::devices::attiny167; #[cfg(feature = "attiny1614")] pub use crate::devices::attiny1614; +#[cfg(feature = "attiny167")] +pub use crate::devices::attiny167; #[cfg(feature = "attiny202")] pub use crate::devices::attiny202; #[cfg(feature = "attiny2313")]