aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-macros/src/lib.rs15
-rw-r--r--embassy-nrf/src/gpiote.rs4
-rw-r--r--embassy-nrf/src/qspi.rs4
-rw-r--r--embassy-nrf/src/rtc.rs6
-rw-r--r--embassy-nrf/src/uarte.rs4
-rw-r--r--embassy-nrf/src/util/peripheral.rs19
-rw-r--r--embassy/src/interrupt.rs31
7 files changed, 57 insertions, 26 deletions
diff --git a/embassy-macros/src/lib.rs b/embassy-macros/src/lib.rs
index c46f114a0..861406393 100644
--- a/embassy-macros/src/lib.rs
+++ b/embassy-macros/src/lib.rs
@@ -117,9 +117,9 @@ pub fn interrupt_declare(item: TokenStream) -> TokenStream {
117 fn number(&self) -> u8 { 117 fn number(&self) -> u8 {
118 Interrupt::#name as u8 118 Interrupt::#name as u8
119 } 119 }
120 unsafe fn __handler(&self) -> &'static ::core::sync::atomic::AtomicPtr<u32> { 120 unsafe fn __handler(&self) -> &'static ::embassy::interrupt::Handler {
121 #[export_name = #name_handler] 121 #[export_name = #name_handler]
122 static HANDLER: ::core::sync::atomic::AtomicPtr<u32> = ::core::sync::atomic::AtomicPtr::new(::core::ptr::null_mut()); 122 static HANDLER: ::embassy::interrupt::Handler = ::embassy::interrupt::Handler::new();
123 &HANDLER 123 &HANDLER
124 } 124 }
125 } 125 }
@@ -141,13 +141,14 @@ pub fn interrupt_take(item: TokenStream) -> TokenStream {
141 pub unsafe extern "C" fn trampoline() { 141 pub unsafe extern "C" fn trampoline() {
142 extern "C" { 142 extern "C" {
143 #[link_name = #name_handler] 143 #[link_name = #name_handler]
144 static HANDLER: ::core::sync::atomic::AtomicPtr<u32>; 144 static HANDLER: ::embassy::interrupt::Handler;
145 } 145 }
146 146
147 let p = HANDLER.load(::core::sync::atomic::Ordering::Acquire); 147 let func = HANDLER.func.load(::core::sync::atomic::Ordering::Acquire);
148 if !p.is_null() { 148 let ctx = HANDLER.ctx.load(::core::sync::atomic::Ordering::Acquire);
149 let f: fn() = ::core::mem::transmute(p); 149 if !func.is_null() {
150 f() 150 let func: fn(*mut ()) = ::core::mem::transmute(func);
151 func(ctx)
151 } 152 }
152 } 153 }
153 154
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs
index 353f6a94c..65a584c78 100644
--- a/embassy-nrf/src/gpiote.rs
+++ b/embassy-nrf/src/gpiote.rs
@@ -75,7 +75,7 @@ impl Gpiote {
75 // Enable interrupts 75 // Enable interrupts
76 gpiote.events_port.write(|w| w); 76 gpiote.events_port.write(|w| w);
77 gpiote.intenset.write(|w| w.port().set()); 77 gpiote.intenset.write(|w| w.port().set());
78 irq.set_handler(Self::on_irq); 78 irq.set_handler(Self::on_irq, core::ptr::null_mut());
79 irq.unpend(); 79 irq.unpend();
80 irq.enable(); 80 irq.enable();
81 81
@@ -296,7 +296,7 @@ impl Gpiote {
296 }) 296 })
297 } 297 }
298 298
299 unsafe fn on_irq() { 299 unsafe fn on_irq(_ctx: *mut ()) {
300 let s = &(*INSTANCE); 300 let s = &(*INSTANCE);
301 301
302 for i in 0..8 { 302 for i in 0..8 {
diff --git a/embassy-nrf/src/qspi.rs b/embassy-nrf/src/qspi.rs
index c9c907cd1..753a5985b 100644
--- a/embassy-nrf/src/qspi.rs
+++ b/embassy-nrf/src/qspi.rs
@@ -146,7 +146,7 @@ impl Qspi {
146 SIGNAL.reset(); 146 SIGNAL.reset();
147 qspi.intenset.write(|w| w.ready().set()); 147 qspi.intenset.write(|w| w.ready().set());
148 148
149 irq.set_handler(irq_handler); 149 irq.set_handler(irq_handler, core::ptr::null_mut());
150 irq.unpend(); 150 irq.unpend();
151 irq.enable(); 151 irq.enable();
152 152
@@ -347,7 +347,7 @@ impl Flash for Qspi {
347 347
348static SIGNAL: Signal<()> = Signal::new(); 348static SIGNAL: Signal<()> = Signal::new();
349 349
350unsafe fn irq_handler() { 350unsafe fn irq_handler(_ctx: *mut ()) {
351 let p = crate::pac::Peripherals::steal().QSPI; 351 let p = crate::pac::Peripherals::steal().QSPI;
352 if p.events_ready.read().events_ready().bit_is_set() { 352 if p.events_ready.read().events_ready().bit_is_set() {
353 p.events_ready.reset(); 353 p.events_ready.reset();
diff --git a/embassy-nrf/src/rtc.rs b/embassy-nrf/src/rtc.rs
index d65b8d472..fb59faa31 100644
--- a/embassy-nrf/src/rtc.rs
+++ b/embassy-nrf/src/rtc.rs
@@ -105,8 +105,10 @@ impl<T: Instance> RTC<T> {
105 while self.rtc.counter.read().bits() != 0 {} 105 while self.rtc.counter.read().bits() != 0 {}
106 106
107 T::set_rtc_instance(self); 107 T::set_rtc_instance(self);
108 self.irq 108 self.irq.set_handler(
109 .set_handler(|| T::get_rtc_instance().on_interrupt()); 109 |_| T::get_rtc_instance().on_interrupt(),
110 core::ptr::null_mut(),
111 );
110 self.irq.unpend(); 112 self.irq.unpend();
111 self.irq.enable(); 113 self.irq.enable();
112 } 114 }
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs
index 648298b84..8aee11c47 100644
--- a/embassy-nrf/src/uarte.rs
+++ b/embassy-nrf/src/uarte.rs
@@ -119,7 +119,7 @@ where
119 .write(|w| w.endtx().set().txstopped().set().endrx().set().rxto().set()); 119 .write(|w| w.endtx().set().txstopped().set().endrx().set().rxto().set());
120 120
121 // Register ISR 121 // Register ISR
122 irq.set_handler(Self::on_irq); 122 irq.set_handler(Self::on_irq, core::ptr::null_mut());
123 irq.unpend(); 123 irq.unpend();
124 irq.enable(); 124 irq.enable();
125 125
@@ -147,7 +147,7 @@ where
147 self.instance.events_rxstarted.read().bits() != 0 147 self.instance.events_rxstarted.read().bits() != 0
148 } 148 }
149 149
150 unsafe fn on_irq() { 150 unsafe fn on_irq(_ctx: *mut ()) {
151 let uarte = &*pac::UARTE0::ptr(); 151 let uarte = &*pac::UARTE0::ptr();
152 152
153 let mut try_disable = false; 153 let mut try_disable = false;
diff --git a/embassy-nrf/src/util/peripheral.rs b/embassy-nrf/src/util/peripheral.rs
index 85de3419e..9b3384e5d 100644
--- a/embassy-nrf/src/util/peripheral.rs
+++ b/embassy-nrf/src/util/peripheral.rs
@@ -55,12 +55,15 @@ impl<P: State> Registration<P> {
55 // - therefore it's safe to overwrite it without dropping the previous contents 55 // - therefore it's safe to overwrite it without dropping the previous contents
56 unsafe { P::store().write(state) } 56 unsafe { P::store().write(state) }
57 57
58 irq.set_handler(|| { 58 irq.set_handler(
59 // safety: 59 |_| {
60 // - If a PeripheralRegistration instance exists, P::storage() is initialized. 60 // safety:
61 // - It's OK to get a &mut to it since the irq is disabled. 61 // - If a PeripheralRegistration instance exists, P::storage() is initialized.
62 unsafe { P::store().as_mut() }.on_interrupt(); 62 // - It's OK to get a &mut to it since the irq is disabled.
63 }); 63 unsafe { P::store().as_mut() }.on_interrupt();
64 },
65 core::ptr::null_mut(),
66 );
64 67
65 compiler_fence(Ordering::SeqCst); 68 compiler_fence(Ordering::SeqCst);
66 irq.enable(); 69 irq.enable();
@@ -89,7 +92,7 @@ impl<P: State> Registration<P> {
89 pub fn free(self) -> (P::Interrupt, P) { 92 pub fn free(self) -> (P::Interrupt, P) {
90 let irq = unsafe { ptr::read(&self.irq) }; 93 let irq = unsafe { ptr::read(&self.irq) };
91 irq.disable(); 94 irq.disable();
92 irq.set_handler(|| ()); 95 irq.remove_handler();
93 mem::forget(self); 96 mem::forget(self);
94 let storage = P::store(); 97 let storage = P::store();
95 (irq, unsafe { storage.read() }) 98 (irq, unsafe { storage.read() })
@@ -99,7 +102,7 @@ impl<P: State> Registration<P> {
99impl<P: State> Drop for Registration<P> { 102impl<P: State> Drop for Registration<P> {
100 fn drop(&mut self) { 103 fn drop(&mut self) {
101 self.irq.disable(); 104 self.irq.disable();
102 self.irq.set_handler(|| ()); 105 self.irq.remove_handler();
103 106
104 let storage = P::store(); 107 let storage = P::store();
105 unsafe { storage.drop_in_place() }; 108 unsafe { storage.drop_in_place() };
diff --git a/embassy/src/interrupt.rs b/embassy/src/interrupt.rs
index fee52b326..7690bea0c 100644
--- a/embassy/src/interrupt.rs
+++ b/embassy/src/interrupt.rs
@@ -6,6 +6,22 @@ use cortex_m::peripheral::NVIC;
6pub use embassy_macros::interrupt_declare as declare; 6pub use embassy_macros::interrupt_declare as declare;
7pub use embassy_macros::interrupt_take as take; 7pub use embassy_macros::interrupt_take as take;
8 8
9/// Implementation detail, do not use outside embassy crates.
10#[doc(hidden)]
11pub struct Handler {
12 pub func: AtomicPtr<()>,
13 pub ctx: AtomicPtr<()>,
14}
15
16impl Handler {
17 pub const fn new() -> Self {
18 Self {
19 func: AtomicPtr::new(ptr::null_mut()),
20 ctx: AtomicPtr::new(ptr::null_mut()),
21 }
22 }
23}
24
9struct NrWrap(u8); 25struct NrWrap(u8);
10unsafe impl cortex_m::interrupt::Nr for NrWrap { 26unsafe impl cortex_m::interrupt::Nr for NrWrap {
11 fn nr(&self) -> u8 { 27 fn nr(&self) -> u8 {
@@ -16,11 +32,20 @@ unsafe impl cortex_m::interrupt::Nr for NrWrap {
16pub unsafe trait OwnedInterrupt { 32pub unsafe trait OwnedInterrupt {
17 type Priority: From<u8> + Into<u8> + Copy; 33 type Priority: From<u8> + Into<u8> + Copy;
18 fn number(&self) -> u8; 34 fn number(&self) -> u8;
35
36 /// Implementation detail, do not use outside embassy crates.
19 #[doc(hidden)] 37 #[doc(hidden)]
20 unsafe fn __handler(&self) -> &'static AtomicPtr<u32>; 38 unsafe fn __handler(&self) -> &'static Handler;
39
40 fn set_handler(&self, func: unsafe fn(*mut ()), ctx: *mut ()) {
41 let handler = unsafe { self.__handler() };
42 handler.func.store(func as *mut (), Ordering::Release);
43 handler.ctx.store(ctx, Ordering::Release);
44 }
21 45
22 fn set_handler(&self, handler: unsafe fn()) { 46 fn remove_handler(&self) {
23 unsafe { self.__handler() }.store(handler as *mut u32, Ordering::Release); 47 let handler = unsafe { self.__handler() };
48 handler.func.store(ptr::null_mut(), Ordering::Release);
24 } 49 }
25 50
26 #[inline] 51 #[inline]