M Cargo.toml => Cargo.toml +3 -0
@@ 59,3 59,6 @@ cfg-if = "0.1.10"
path = "macros/"
version = "=0.3.2"
optional = true
+
+[build-dependencies]
+rustversion = "1.0"
M README.md => README.md +1 -1
@@ 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
A build.rs => build.rs +16 -0
@@ 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");
+}
M src/asm.rs => src/asm.rs +12 -3
@@ 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!()
M src/interrupt.rs => src/interrupt.rs +22 -2
@@ 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!()
M src/lib.rs => src/lib.rs +4 -3
@@ 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")]