aboutsummaryrefslogtreecommitdiff
path: root/src/interrupt.rs
diff options
context:
space:
mode:
authorGravatar Jorge Aparicio <japaricious@gmail.com> 2016-09-27 18:35:29 -0500
committerGravatar Jorge Aparicio <japaricious@gmail.com> 2016-09-27 18:35:29 -0500
commitddc7f255b57d0e6aeb9f3b1b7466b2e5c0c5fff0 (patch)
treeac8332c9d63b45082f81ce419045c9b16db1b270 /src/interrupt.rs
downloadcortex-m-ddc7f255b57d0e6aeb9f3b1b7466b2e5c0c5fff0.tar.gz
cortex-m-ddc7f255b57d0e6aeb9f3b1b7466b2e5c0c5fff0.tar.zst
cortex-m-ddc7f255b57d0e6aeb9f3b1b7466b2e5c0c5fff0.zip
initial commit
Diffstat (limited to 'src/interrupt.rs')
-rw-r--r--src/interrupt.rs47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/interrupt.rs b/src/interrupt.rs
new file mode 100644
index 0000000..6fb8aeb
--- /dev/null
+++ b/src/interrupt.rs
@@ -0,0 +1,47 @@
+//! Interrupts
+
+/// Disable interrupts, globally
+#[inline(always)]
+pub unsafe fn disable() {
+ match () {
+ #[cfg(target_arch = "arm")]
+ () => {
+ asm!("cpsid i" :::: "volatile");
+ }
+ #[cfg(not(target_arch = "arm"))]
+ () => {}
+ }
+}
+
+/// Enable interrupts, globally
+#[inline(always)]
+pub unsafe fn enable() {
+ match () {
+ #[cfg(target_arch = "arm")]
+ () => {
+ asm!("cpsie i" :::: "volatile");
+ }
+ #[cfg(not(target_arch = "arm"))]
+ () => {}
+ }
+}
+
+/// Execute closure `f` in an interrupt-free context.
+/// This as also known as a "critical section".
+pub unsafe fn free<F>(f: F)
+ where F: FnOnce()
+{
+ let primask = ::register::primask::read();
+
+ disable();
+
+ f();
+
+ // If the interrupts were enabled before our `disable` call, then re-enable them
+ // Otherwise, keep them disabled
+ // PRIMASK & 1 = 1 indicates that the interrupts were disabled
+ // PRIMASK & 1 = 0 indicates that they were enabled
+ if primask & 1 == 0 {
+ enable();
+ }
+}