diff options
| -rw-r--r-- | embassy-macros/src/lib.rs | 15 | ||||
| -rw-r--r-- | embassy-nrf/src/gpiote.rs | 4 | ||||
| -rw-r--r-- | embassy-nrf/src/qspi.rs | 4 | ||||
| -rw-r--r-- | embassy-nrf/src/rtc.rs | 6 | ||||
| -rw-r--r-- | embassy-nrf/src/uarte.rs | 4 | ||||
| -rw-r--r-- | embassy-nrf/src/util/peripheral.rs | 19 | ||||
| -rw-r--r-- | embassy/src/interrupt.rs | 31 |
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 | ||
| 348 | static SIGNAL: Signal<()> = Signal::new(); | 348 | static SIGNAL: Signal<()> = Signal::new(); |
| 349 | 349 | ||
| 350 | unsafe fn irq_handler() { | 350 | unsafe 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> { | |||
| 99 | impl<P: State> Drop for Registration<P> { | 102 | impl<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; | |||
| 6 | pub use embassy_macros::interrupt_declare as declare; | 6 | pub use embassy_macros::interrupt_declare as declare; |
| 7 | pub use embassy_macros::interrupt_take as take; | 7 | pub use embassy_macros::interrupt_take as take; |
| 8 | 8 | ||
| 9 | /// Implementation detail, do not use outside embassy crates. | ||
| 10 | #[doc(hidden)] | ||
| 11 | pub struct Handler { | ||
| 12 | pub func: AtomicPtr<()>, | ||
| 13 | pub ctx: AtomicPtr<()>, | ||
| 14 | } | ||
| 15 | |||
| 16 | impl 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 | |||
| 9 | struct NrWrap(u8); | 25 | struct NrWrap(u8); |
| 10 | unsafe impl cortex_m::interrupt::Nr for NrWrap { | 26 | unsafe 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 { | |||
| 16 | pub unsafe trait OwnedInterrupt { | 32 | pub 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] |
