aboutsummaryrefslogtreecommitdiff
path: root/embassy-hal-internal/src/interrupt.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-hal-internal/src/interrupt.rs')
-rw-r--r--embassy-hal-internal/src/interrupt.rs32
1 files changed, 29 insertions, 3 deletions
diff --git a/embassy-hal-internal/src/interrupt.rs b/embassy-hal-internal/src/interrupt.rs
index b970aa2cd..19dabcf6f 100644
--- a/embassy-hal-internal/src/interrupt.rs
+++ b/embassy-hal-internal/src/interrupt.rs
@@ -4,6 +4,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
4 4
5use cortex_m::interrupt::InterruptNumber; 5use cortex_m::interrupt::InterruptNumber;
6use cortex_m::peripheral::NVIC; 6use cortex_m::peripheral::NVIC;
7use critical_section::CriticalSection;
7 8
8/// Generate a standard `mod interrupt` for a HAL. 9/// Generate a standard `mod interrupt` for a HAL.
9#[macro_export] 10#[macro_export]
@@ -91,6 +92,12 @@ macro_rules! interrupt_mod {
91 fn set_priority(prio: crate::interrupt::Priority) { 92 fn set_priority(prio: crate::interrupt::Priority) {
92 Self::IRQ.set_priority(prio) 93 Self::IRQ.set_priority(prio)
93 } 94 }
95
96 /// Set the interrupt priority with an already-acquired critical section
97 #[inline]
98 fn set_priority_with_cs(cs: critical_section::CriticalSection, prio: crate::interrupt::Priority) {
99 Self::IRQ.set_priority_with_cs(cs, prio)
100 }
94 } 101 }
95 102
96 $( 103 $(
@@ -195,10 +202,29 @@ pub unsafe trait InterruptExt: InterruptNumber + Copy {
195 /// Set the interrupt priority. 202 /// Set the interrupt priority.
196 #[inline] 203 #[inline]
197 fn set_priority(self, prio: Priority) { 204 fn set_priority(self, prio: Priority) {
198 critical_section::with(|_| unsafe { 205 unsafe {
206 let mut nvic: cortex_m::peripheral::NVIC = mem::transmute(());
207
208 // On thumbv6, set_priority must do a RMW to change 8bit in a 32bit reg.
209 #[cfg(armv6m)]
210 critical_section::with(|_| nvic.set_priority(self, prio.into()));
211 // On thumbv7+, set_priority does an atomic 8bit write, so no CS needed.
212 #[cfg(not(armv6m))]
213 nvic.set_priority(self, prio.into());
214 }
215 }
216
217 /// Set the interrupt priority with an already-acquired critical section
218 ///
219 /// Equivalent to `set_priority`, except you pass a `CriticalSection` to prove
220 /// you've already acquired a critical section. This prevents acquiring another
221 /// one, which saves code size.
222 #[inline]
223 fn set_priority_with_cs(self, _cs: CriticalSection, prio: Priority) {
224 unsafe {
199 let mut nvic: cortex_m::peripheral::NVIC = mem::transmute(()); 225 let mut nvic: cortex_m::peripheral::NVIC = mem::transmute(());
200 nvic.set_priority(self, prio.into()) 226 nvic.set_priority(self, prio.into());
201 }) 227 }
202 } 228 }
203} 229}
204 230