From bbba98677d5bd679d8075cec448d729abd14f553 Mon Sep 17 00:00:00 2001 From: Tray Torrance Date: Sun, 3 Oct 2021 09:45:59 -0700 Subject: [PATCH] Return the previous interrupt status upon disabling interrupts This commit addresses #88 by returning a boolean which reflects the previous state of the GIE flag upon disabling interrupts. This allows `critical-section` to implement itself for AVR, while not breaking the existing `avr-device` API. --- src/interrupt.rs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/interrupt.rs b/src/interrupt.rs index de8652e..e615aa1 100644 --- a/src/interrupt.rs +++ b/src/interrupt.rs @@ -12,10 +12,19 @@ pub use bare_metal::{CriticalSection, Mutex, Nr}; #[inline] /// Disables all interrupts -pub fn disable() { +/// +/// 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")] { + // Store current state + let sreg: u8; + unsafe { llvm_asm!("in $0,0x3F" :"=r"(sreg) ::: "volatile") }; + + // Disable interrupts unsafe { llvm_asm!("cli" :::: "volatile") }; + + sreg & 0x80 == 0x80 } else { unimplemented!() } @@ -47,20 +56,13 @@ where { cfg_if::cfg_if! { if #[cfg(target_arch = "avr")] { - let sreg: u8; - - // Store current state - unsafe { - llvm_asm!("in $0,0x3F" :"=r"(sreg) ::: "volatile"); - } - // Disable interrupts - disable(); + let interrupts_enabled = disable(); let r = f(unsafe { &CriticalSection::new() }); // Restore interrupt state - if sreg & 0x80 != 0x00 { + if interrupts_enabled { unsafe { enable(); } } -- 2.49.0