aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-macros/src/lib.rs62
-rw-r--r--embassy-nrf/src/buffered_uarte.rs50
-rw-r--r--embassy-nrf/src/gpiote.rs75
-rw-r--r--embassy-nrf/src/interrupt.rs250
-rw-r--r--embassy-nrf/src/qspi.rs15
-rw-r--r--embassy-nrf/src/rtc.rs36
-rw-r--r--embassy/src/interrupt.rs76
-rw-r--r--embassy/src/lib.rs1
-rw-r--r--examples/src/bin/gpiote.rs4
-rw-r--r--examples/src/bin/gpiote_port.rs4
-rw-r--r--examples/src/bin/multiprio.rs19
-rw-r--r--examples/src/bin/qspi.rs5
-rw-r--r--examples/src/bin/rtc_async.rs8
-rw-r--r--examples/src/bin/rtc_raw.rs7
-rw-r--r--examples/src/bin/uart.rs4
15 files changed, 460 insertions, 156 deletions
diff --git a/embassy-macros/src/lib.rs b/embassy-macros/src/lib.rs
index b11fc4ae9..091e08cfa 100644
--- a/embassy-macros/src/lib.rs
+++ b/embassy-macros/src/lib.rs
@@ -98,3 +98,65 @@ pub fn task(args: TokenStream, item: TokenStream) -> TokenStream {
98 }; 98 };
99 result.into() 99 result.into()
100} 100}
101
102#[proc_macro]
103pub fn interrupt_declare(item: TokenStream) -> TokenStream {
104 let name = syn::parse_macro_input!(item as syn::Ident);
105 let name = format_ident!("{}", name);
106 let name_interrupt = format_ident!("{}Interrupt", name);
107 let name_handler = format!("__EMBASSY_{}_HANDLER", name);
108
109 let result = quote! {
110 #[allow(non_camel_case_types)]
111 pub struct #name_interrupt(());
112 unsafe impl OwnedInterrupt for #name_interrupt {
113 type Priority = Priority;
114 fn number(&self) -> u8 {
115 Interrupt::#name as u8
116 }
117 unsafe fn __handler(&self) -> &'static ::core::sync::atomic::AtomicPtr<u32> {
118 #[export_name = #name_handler]
119 static HANDLER: ::core::sync::atomic::AtomicPtr<u32> = ::core::sync::atomic::AtomicPtr::new(::core::ptr::null_mut());
120 &HANDLER
121 }
122 }
123 };
124 result.into()
125}
126
127#[proc_macro]
128pub fn interrupt_take(item: TokenStream) -> TokenStream {
129 let name = syn::parse_macro_input!(item as syn::Ident);
130 let name = format!("{}", name);
131 let name_interrupt = format_ident!("{}Interrupt", name);
132 let name_handler = format!("__EMBASSY_{}_HANDLER", name);
133
134 let result = quote! {
135 {
136 #[allow(non_snake_case)]
137 #[export_name = #name]
138 pub unsafe extern "C" fn trampoline() {
139 extern "C" {
140 #[link_name = #name_handler]
141 static HANDLER: ::core::sync::atomic::AtomicPtr<u32>;
142 }
143
144 let p = HANDLER.load(::core::sync::atomic::Ordering::Acquire);
145 if !p.is_null() {
146 let f: fn() = ::core::mem::transmute(p);
147 f()
148 }
149 }
150
151 static TAKEN: ::core::sync::atomic::AtomicBool = ::core::sync::atomic::AtomicBool::new(false);
152
153 if TAKEN.compare_and_swap(false, true, ::core::sync::atomic::Ordering::AcqRel) {
154 panic!("IRQ Already taken");
155 }
156
157 let irq: interrupt::#name_interrupt = unsafe { ::core::mem::transmute(()) };
158 irq
159 }
160 };
161 result.into()
162}
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs
index 9e138ad4f..db6a83fb4 100644
--- a/embassy-nrf/src/buffered_uarte.rs
+++ b/embassy-nrf/src/buffered_uarte.rs
@@ -17,10 +17,10 @@ use embedded_hal::digital::v2::OutputPin;
17 17
18use crate::hal::gpio::{Floating, Input, Output, Pin as GpioPin, Port as GpioPort, PushPull}; 18use crate::hal::gpio::{Floating, Input, Output, Pin as GpioPin, Port as GpioPort, PushPull};
19use crate::interrupt; 19use crate::interrupt;
20use crate::interrupt::CriticalSection; 20use crate::interrupt::{CriticalSection, OwnedInterrupt};
21#[cfg(any(feature = "52833", feature = "52840", feature = "9160"))] 21#[cfg(any(feature = "52833", feature = "52840", feature = "9160"))]
22use crate::pac::UARTE1; 22use crate::pac::UARTE1;
23use crate::pac::{uarte0, Interrupt, UARTE0}; 23use crate::pac::{uarte0, UARTE0};
24 24
25// Re-export SVD variants to allow user to directly set values 25// Re-export SVD variants to allow user to directly set values
26pub use uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; 26pub use uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity};
@@ -141,8 +141,9 @@ pub struct BufferedUarte<T: Instance> {
141// public because it needs to be used in Instance::{get_state, set_state}, but 141// public because it needs to be used in Instance::{get_state, set_state}, but
142// should not be used outside the module 142// should not be used outside the module
143#[doc(hidden)] 143#[doc(hidden)]
144pub struct UarteState<T> { 144pub struct UarteState<T: Instance> {
145 inner: T, 145 inner: T,
146 irq: T::Interrupt,
146 147
147 rx: RingBuf, 148 rx: RingBuf,
148 rx_state: RxState, 149 rx_state: RxState,
@@ -164,7 +165,13 @@ fn port_bit(port: GpioPort) -> bool {
164} 165}
165 166
166impl<T: Instance> BufferedUarte<T> { 167impl<T: Instance> BufferedUarte<T> {
167 pub fn new(uarte: T, mut pins: Pins, parity: Parity, baudrate: Baudrate) -> Self { 168 pub fn new(
169 uarte: T,
170 irq: T::Interrupt,
171 mut pins: Pins,
172 parity: Parity,
173 baudrate: Baudrate,
174 ) -> Self {
168 // Select pins 175 // Select pins
169 uarte.psel.rxd.write(|w| { 176 uarte.psel.rxd.write(|w| {
170 let w = unsafe { w.pin().bits(pins.rxd.pin()) }; 177 let w = unsafe { w.pin().bits(pins.rxd.pin()) };
@@ -222,6 +229,7 @@ impl<T: Instance> BufferedUarte<T> {
222 started: false, 229 started: false,
223 state: UnsafeCell::new(UarteState { 230 state: UnsafeCell::new(UarteState {
224 inner: uarte, 231 inner: uarte,
232 irq,
225 233
226 rx: RingBuf::new(), 234 rx: RingBuf::new(),
227 rx_state: RxState::Idle, 235 rx_state: RxState::Idle,
@@ -287,9 +295,12 @@ impl<T: Instance> AsyncWrite for BufferedUarte<T> {
287 295
288impl<T: Instance> UarteState<T> { 296impl<T: Instance> UarteState<T> {
289 pub fn start(self: Pin<&mut Self>) { 297 pub fn start(self: Pin<&mut Self>) {
290 interrupt::set_priority(T::interrupt(), interrupt::Priority::Level7); 298 self.irq.set_handler(|| unsafe {
291 interrupt::enable(T::interrupt()); 299 interrupt::free(|cs| T::get_state(cs).as_mut().unwrap().on_interrupt());
292 interrupt::pend(T::interrupt()); 300 });
301
302 self.irq.pend();
303 self.irq.enable();
293 } 304 }
294 305
295 fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>> { 306 fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>> {
@@ -324,7 +335,7 @@ impl<T: Instance> UarteState<T> {
324 let this = unsafe { self.get_unchecked_mut() }; 335 let this = unsafe { self.get_unchecked_mut() };
325 trace!("consume {:?}", amt); 336 trace!("consume {:?}", amt);
326 this.rx.pop(amt); 337 this.rx.pop(amt);
327 interrupt::pend(T::interrupt()); 338 this.irq.pend();
328 } 339 }
329 340
330 fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize>> { 341 fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize>> {
@@ -350,7 +361,7 @@ impl<T: Instance> UarteState<T> {
350 // before any DMA action has started 361 // before any DMA action has started
351 compiler_fence(Ordering::SeqCst); 362 compiler_fence(Ordering::SeqCst);
352 363
353 interrupt::pend(T::interrupt()); 364 this.irq.pend();
354 365
355 Poll::Ready(Ok(n)) 366 Poll::Ready(Ok(n))
356 } 367 }
@@ -509,7 +520,7 @@ mod private {
509} 520}
510 521
511pub trait Instance: Deref<Target = uarte0::RegisterBlock> + Sized + private::Sealed { 522pub trait Instance: Deref<Target = uarte0::RegisterBlock> + Sized + private::Sealed {
512 fn interrupt() -> Interrupt; 523 type Interrupt: OwnedInterrupt;
513 524
514 #[doc(hidden)] 525 #[doc(hidden)]
515 fn get_state(_cs: &CriticalSection) -> *mut UarteState<Self>; 526 fn get_state(_cs: &CriticalSection) -> *mut UarteState<Self>;
@@ -518,25 +529,12 @@ pub trait Instance: Deref<Target = uarte0::RegisterBlock> + Sized + private::Sea
518 fn set_state(_cs: &CriticalSection, state: *mut UarteState<Self>); 529 fn set_state(_cs: &CriticalSection, state: *mut UarteState<Self>);
519} 530}
520 531
521#[interrupt]
522unsafe fn UARTE0_UART0() {
523 interrupt::free(|cs| UARTE0::get_state(cs).as_mut().unwrap().on_interrupt());
524}
525
526#[cfg(any(feature = "52833", feature = "52840", feature = "9160"))]
527#[interrupt]
528unsafe fn UARTE1() {
529 interrupt::free(|cs| UARTE1::get_state(cs).as_mut().unwrap().on_interrupt());
530}
531
532static mut UARTE0_STATE: *mut UarteState<UARTE0> = ptr::null_mut(); 532static mut UARTE0_STATE: *mut UarteState<UARTE0> = ptr::null_mut();
533#[cfg(any(feature = "52833", feature = "52840", feature = "9160"))] 533#[cfg(any(feature = "52833", feature = "52840", feature = "9160"))]
534static mut UARTE1_STATE: *mut UarteState<UARTE1> = ptr::null_mut(); 534static mut UARTE1_STATE: *mut UarteState<UARTE1> = ptr::null_mut();
535 535
536impl Instance for UARTE0 { 536impl Instance for UARTE0 {
537 fn interrupt() -> Interrupt { 537 type Interrupt = interrupt::UARTE0_UART0Interrupt;
538 Interrupt::UARTE0_UART0
539 }
540 538
541 fn get_state(_cs: &CriticalSection) -> *mut UarteState<Self> { 539 fn get_state(_cs: &CriticalSection) -> *mut UarteState<Self> {
542 unsafe { UARTE0_STATE } // Safe because of CriticalSection 540 unsafe { UARTE0_STATE } // Safe because of CriticalSection
@@ -548,9 +546,7 @@ impl Instance for UARTE0 {
548 546
549#[cfg(any(feature = "52833", feature = "52840", feature = "9160"))] 547#[cfg(any(feature = "52833", feature = "52840", feature = "9160"))]
550impl Instance for UARTE1 { 548impl Instance for UARTE1 {
551 fn interrupt() -> Interrupt { 549 type Interrupt = interrupt::UARTE1Interrupt;
552 Interrupt::UARTE1
553 }
554 550
555 fn get_state(_cs: &CriticalSection) -> *mut UarteState<Self> { 551 fn get_state(_cs: &CriticalSection) -> *mut UarteState<Self> {
556 unsafe { UARTE1_STATE } // Safe because of CriticalSection 552 unsafe { UARTE1_STATE } // Safe because of CriticalSection
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs
index 069e9140b..353f6a94c 100644
--- a/embassy-nrf/src/gpiote.rs
+++ b/embassy-nrf/src/gpiote.rs
@@ -7,6 +7,7 @@ use embassy::util::Signal;
7 7
8use crate::hal::gpio::{Input, Level, Output, Pin, Port}; 8use crate::hal::gpio::{Input, Level, Output, Pin, Port};
9use crate::interrupt; 9use crate::interrupt;
10use crate::interrupt::OwnedInterrupt;
10use crate::pac::generic::Reg; 11use crate::pac::generic::Reg;
11use crate::pac::gpiote::_TASKS_OUT; 12use crate::pac::gpiote::_TASKS_OUT;
12#[cfg(any(feature = "52833", feature = "52840"))] 13#[cfg(any(feature = "52833", feature = "52840"))]
@@ -58,7 +59,7 @@ pub enum NewChannelError {
58} 59}
59 60
60impl Gpiote { 61impl Gpiote {
61 pub fn new(gpiote: GPIOTE) -> Self { 62 pub fn new(gpiote: GPIOTE, irq: interrupt::GPIOTEInterrupt) -> Self {
62 #[cfg(any(feature = "52833", feature = "52840"))] 63 #[cfg(any(feature = "52833", feature = "52840"))]
63 let ports = unsafe { &[&*P0::ptr(), &*P1::ptr()] }; 64 let ports = unsafe { &[&*P0::ptr(), &*P1::ptr()] };
64 #[cfg(not(any(feature = "52833", feature = "52840")))] 65 #[cfg(not(any(feature = "52833", feature = "52840")))]
@@ -74,8 +75,9 @@ impl Gpiote {
74 // Enable interrupts 75 // Enable interrupts
75 gpiote.events_port.write(|w| w); 76 gpiote.events_port.write(|w| w);
76 gpiote.intenset.write(|w| w.port().set()); 77 gpiote.intenset.write(|w| w.port().set());
77 interrupt::unpend(interrupt::GPIOTE); 78 irq.set_handler(Self::on_irq);
78 interrupt::enable(interrupt::GPIOTE); 79 irq.unpend();
80 irq.enable();
79 81
80 Self { 82 Self {
81 inner: gpiote, 83 inner: gpiote,
@@ -293,6 +295,39 @@ impl Gpiote {
293 }) 295 })
294 }) 296 })
295 } 297 }
298
299 unsafe fn on_irq() {
300 let s = &(*INSTANCE);
301
302 for i in 0..8 {
303 if s.inner.events_in[i].read().bits() != 0 {
304 s.inner.events_in[i].write(|w| w);
305 s.channel_signals[i].signal(());
306 }
307 }
308
309 if s.inner.events_port.read().bits() != 0 {
310 s.inner.events_port.write(|w| w);
311
312 #[cfg(any(feature = "52833", feature = "52840"))]
313 let ports = &[&*P0::ptr(), &*P1::ptr()];
314 #[cfg(not(any(feature = "52833", feature = "52840")))]
315 let ports = &[&*P0::ptr()];
316
317 let mut work = true;
318 while work {
319 work = false;
320 for (port, &p) in ports.iter().enumerate() {
321 for pin in BitIter(p.latch.read().bits()) {
322 work = true;
323 p.pin_cnf[pin as usize].modify(|_, w| w.sense().disabled());
324 p.latch.write(|w| w.bits(1 << pin));
325 s.port_signals[port * 32 + pin as usize].signal(());
326 }
327 }
328 }
329 }
330 }
296} 331}
297 332
298pub struct PortInputFuture<'a, T> { 333pub struct PortInputFuture<'a, T> {
@@ -413,40 +448,6 @@ impl<'a> OutputChannel<'a> {
413 } 448 }
414} 449}
415 450
416#[interrupt]
417unsafe fn GPIOTE() {
418 let s = &(*INSTANCE);
419
420 for i in 0..8 {
421 if s.inner.events_in[i].read().bits() != 0 {
422 s.inner.events_in[i].write(|w| w);
423 s.channel_signals[i].signal(());
424 }
425 }
426
427 if s.inner.events_port.read().bits() != 0 {
428 s.inner.events_port.write(|w| w);
429
430 #[cfg(any(feature = "52833", feature = "52840"))]
431 let ports = &[&*P0::ptr(), &*P1::ptr()];
432 #[cfg(not(any(feature = "52833", feature = "52840")))]
433 let ports = &[&*P0::ptr()];
434
435 let mut work = true;
436 while work {
437 work = false;
438 for (port, &p) in ports.iter().enumerate() {
439 for pin in BitIter(p.latch.read().bits()) {
440 work = true;
441 p.pin_cnf[pin as usize].modify(|_, w| w.sense().disabled());
442 p.latch.write(|w| w.bits(1 << pin));
443 s.port_signals[port * 32 + pin as usize].signal(());
444 }
445 }
446 }
447 }
448}
449
450struct BitIter(u32); 451struct BitIter(u32);
451 452
452impl Iterator for BitIter { 453impl Iterator for BitIter {
diff --git a/embassy-nrf/src/interrupt.rs b/embassy-nrf/src/interrupt.rs
index 17fc9ab34..90b568573 100644
--- a/embassy-nrf/src/interrupt.rs
+++ b/embassy-nrf/src/interrupt.rs
@@ -5,12 +5,13 @@
5 5
6use core::sync::atomic::{compiler_fence, Ordering}; 6use core::sync::atomic::{compiler_fence, Ordering};
7 7
8use crate::pac::{NVIC, NVIC_PRIO_BITS}; 8use crate::pac::NVIC_PRIO_BITS;
9 9
10// Re-exports 10// Re-exports
11pub use crate::pac::Interrupt; 11pub use crate::pac::Interrupt;
12pub use crate::pac::Interrupt::*; // needed for cortex-m-rt #[interrupt] 12pub use crate::pac::Interrupt::*; // needed for cortex-m-rt #[interrupt]
13pub use cortex_m::interrupt::{CriticalSection, Mutex}; 13pub use cortex_m::interrupt::{CriticalSection, Mutex};
14pub use embassy::interrupt::{declare, take, OwnedInterrupt};
14 15
15#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] 16#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
16#[cfg_attr(feature = "defmt", derive(defmt::Format))] 17#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -26,14 +27,8 @@ pub enum Priority {
26 Level7 = 7, 27 Level7 = 7,
27} 28}
28 29
29impl Priority { 30impl From<u8> for Priority {
30 #[inline] 31 fn from(priority: u8) -> Self {
31 fn to_nvic(self) -> u8 {
32 (self as u8) << (8 - NVIC_PRIO_BITS)
33 }
34
35 #[inline]
36 fn from_nvic(priority: u8) -> Self {
37 match priority >> (8 - NVIC_PRIO_BITS) { 32 match priority >> (8 - NVIC_PRIO_BITS) {
38 0 => Self::Level0, 33 0 => Self::Level0,
39 1 => Self::Level1, 34 1 => Self::Level1,
@@ -48,6 +43,12 @@ impl Priority {
48 } 43 }
49} 44}
50 45
46impl From<Priority> for u8 {
47 fn from(p: Priority) -> Self {
48 (p as u8) << (8 - NVIC_PRIO_BITS)
49 }
50}
51
51#[inline] 52#[inline]
52pub fn free<F, R>(f: F) -> R 53pub fn free<F, R>(f: F) -> R
53where 54where
@@ -77,53 +78,204 @@ where
77 } 78 }
78} 79}
79 80
80#[inline] 81#[cfg(feature = "52810")]
81pub fn enable(irq: Interrupt) { 82mod irqs {
82 unsafe { 83 use super::*;
83 NVIC::unmask(irq); 84 declare!(POWER_CLOCK);
84 } 85 declare!(RADIO);
86 declare!(UARTE0_UART0);
87 declare!(TWIM0_TWIS0_TWI0);
88 declare!(SPIM0_SPIS0_SPI0);
89 declare!(GPIOTE);
90 declare!(SAADC);
91 declare!(TIMER0);
92 declare!(TIMER1);
93 declare!(TIMER2);
94 declare!(RTC0);
95 declare!(TEMP);
96 declare!(RNG);
97 declare!(ECB);
98 declare!(CCM_AAR);
99 declare!(WDT);
100 declare!(RTC1);
101 declare!(QDEC);
102 declare!(COMP);
103 declare!(SWI0_EGU0);
104 declare!(SWI1_EGU1);
105 declare!(SWI2);
106 declare!(SWI3);
107 declare!(SWI4);
108 declare!(SWI5);
109 declare!(PWM0);
110 declare!(PDM);
85} 111}
86 112
87#[inline] 113#[cfg(feature = "52811")]
88pub fn disable(irq: Interrupt) { 114mod irqs {
89 NVIC::mask(irq); 115 use super::*;
116 declare!(POWER_CLOCK);
117 declare!(RADIO);
118 declare!(UARTE0_UART0);
119 declare!(TWIM0_TWIS0_TWI0_SPIM1_SPIS1_SPI1);
120 declare!(SPIM0_SPIS0_SPI0);
121 declare!(GPIOTE);
122 declare!(SAADC);
123 declare!(TIMER0);
124 declare!(TIMER1);
125 declare!(TIMER2);
126 declare!(RTC0);
127 declare!(TEMP);
128 declare!(RNG);
129 declare!(ECB);
130 declare!(CCM_AAR);
131 declare!(WDT);
132 declare!(RTC1);
133 declare!(QDEC);
134 declare!(COMP);
135 declare!(SWI0_EGU0);
136 declare!(SWI1_EGU1);
137 declare!(SWI2);
138 declare!(SWI3);
139 declare!(SWI4);
140 declare!(SWI5);
141 declare!(PWM0);
142 declare!(PDM);
90} 143}
91 144
92#[inline] 145#[cfg(feature = "52832")]
93pub fn is_active(irq: Interrupt) -> bool { 146mod irqs {
94 NVIC::is_active(irq) 147 use super::*;
148 declare!(POWER_CLOCK);
149 declare!(RADIO);
150 declare!(UARTE0_UART0);
151 declare!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0);
152 declare!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1);
153 declare!(NFCT);
154 declare!(GPIOTE);
155 declare!(SAADC);
156 declare!(TIMER0);
157 declare!(TIMER1);
158 declare!(TIMER2);
159 declare!(RTC0);
160 declare!(TEMP);
161 declare!(RNG);
162 declare!(ECB);
163 declare!(CCM_AAR);
164 declare!(WDT);
165 declare!(RTC1);
166 declare!(QDEC);
167 declare!(COMP_LPCOMP);
168 declare!(SWI0_EGU0);
169 declare!(SWI1_EGU1);
170 declare!(SWI2_EGU2);
171 declare!(SWI3_EGU3);
172 declare!(SWI4_EGU4);
173 declare!(SWI5_EGU5);
174 declare!(TIMER3);
175 declare!(TIMER4);
176 declare!(PWM0);
177 declare!(PDM);
178 declare!(MWU);
179 declare!(PWM1);
180 declare!(PWM2);
181 declare!(SPIM2_SPIS2_SPI2);
182 declare!(RTC2);
183 declare!(I2S);
184 declare!(FPU);
95} 185}
96 186
97#[inline] 187#[cfg(feature = "52833")]
98pub fn is_enabled(irq: Interrupt) -> bool { 188mod irqs {
99 NVIC::is_enabled(irq) 189 use super::*;
190 declare!(POWER_CLOCK);
191 declare!(RADIO);
192 declare!(UARTE0_UART0);
193 declare!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0);
194 declare!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1);
195 declare!(NFCT);
196 declare!(GPIOTE);
197 declare!(SAADC);
198 declare!(TIMER0);
199 declare!(TIMER1);
200 declare!(TIMER2);
201 declare!(RTC0);
202 declare!(TEMP);
203 declare!(RNG);
204 declare!(ECB);
205 declare!(CCM_AAR);
206 declare!(WDT);
207 declare!(RTC1);
208 declare!(QDEC);
209 declare!(COMP_LPCOMP);
210 declare!(SWI0_EGU0);
211 declare!(SWI1_EGU1);
212 declare!(SWI2_EGU2);
213 declare!(SWI3_EGU3);
214 declare!(SWI4_EGU4);
215 declare!(SWI5_EGU5);
216 declare!(TIMER3);
217 declare!(TIMER4);
218 declare!(PWM0);
219 declare!(PDM);
220 declare!(MWU);
221 declare!(PWM1);
222 declare!(PWM2);
223 declare!(SPIM2_SPIS2_SPI2);
224 declare!(RTC2);
225 declare!(I2S);
226 declare!(FPU);
227 declare!(USBD);
228 declare!(UARTE1);
229 declare!(PWM3);
230 declare!(SPIM3);
100} 231}
101 232
102#[inline] 233#[cfg(feature = "52840")]
103pub fn is_pending(irq: Interrupt) -> bool { 234mod irqs {
104 NVIC::is_pending(irq) 235 use super::*;
236 declare!(POWER_CLOCK);
237 declare!(RADIO);
238 declare!(UARTE0_UART0);
239 declare!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0);
240 declare!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1);
241 declare!(NFCT);
242 declare!(GPIOTE);
243 declare!(SAADC);
244 declare!(TIMER0);
245 declare!(TIMER1);
246 declare!(TIMER2);
247 declare!(RTC0);
248 declare!(TEMP);
249 declare!(RNG);
250 declare!(ECB);
251 declare!(CCM_AAR);
252 declare!(WDT);
253 declare!(RTC1);
254 declare!(QDEC);
255 declare!(COMP_LPCOMP);
256 declare!(SWI0_EGU0);
257 declare!(SWI1_EGU1);
258 declare!(SWI2_EGU2);
259 declare!(SWI3_EGU3);
260 declare!(SWI4_EGU4);
261 declare!(SWI5_EGU5);
262 declare!(TIMER3);
263 declare!(TIMER4);
264 declare!(PWM0);
265 declare!(PDM);
266 declare!(MWU);
267 declare!(PWM1);
268 declare!(PWM2);
269 declare!(SPIM2_SPIS2_SPI2);
270 declare!(RTC2);
271 declare!(I2S);
272 declare!(FPU);
273 declare!(USBD);
274 declare!(UARTE1);
275 declare!(QSPI);
276 declare!(CRYPTOCELL);
277 declare!(PWM3);
278 declare!(SPIM3);
105} 279}
106 280
107#[inline] 281pub use irqs::*;
108pub fn pend(irq: Interrupt) {
109 NVIC::pend(irq)
110}
111
112#[inline]
113pub fn unpend(irq: Interrupt) {
114 NVIC::unpend(irq)
115}
116
117#[inline]
118pub fn get_priority(irq: Interrupt) -> Priority {
119 Priority::from_nvic(NVIC::get_priority(irq))
120}
121
122#[inline]
123pub fn set_priority(irq: Interrupt, prio: Priority) {
124 unsafe {
125 cortex_m::peripheral::Peripherals::steal()
126 .NVIC
127 .set_priority(irq, prio.to_nvic())
128 }
129}
diff --git a/embassy-nrf/src/qspi.rs b/embassy-nrf/src/qspi.rs
index 79fc7029c..c9c907cd1 100644
--- a/embassy-nrf/src/qspi.rs
+++ b/embassy-nrf/src/qspi.rs
@@ -2,6 +2,7 @@ use crate::fmt::{assert, assert_eq, panic, *};
2use core::future::Future; 2use core::future::Future;
3 3
4use crate::hal::gpio::{Output, Pin as GpioPin, Port as GpioPort, PushPull}; 4use crate::hal::gpio::{Output, Pin as GpioPin, Port as GpioPort, PushPull};
5use crate::interrupt::{OwnedInterrupt, QSPIInterrupt};
5use crate::pac::{Interrupt, QSPI}; 6use crate::pac::{Interrupt, QSPI};
6 7
7pub use crate::pac::qspi::ifconfig0::ADDRMODE_A as AddressMode; 8pub use crate::pac::qspi::ifconfig0::ADDRMODE_A as AddressMode;
@@ -22,8 +23,6 @@ pub use crate::pac::qspi::ifconfig0::WRITEOC_A as WriteOpcode;
22use embassy::flash::{Error, Flash}; 23use embassy::flash::{Error, Flash};
23use embassy::util::{DropBomb, Signal}; 24use embassy::util::{DropBomb, Signal};
24 25
25use crate::interrupt;
26
27pub struct Pins { 26pub struct Pins {
28 pub sck: GpioPin<Output<PushPull>>, 27 pub sck: GpioPin<Output<PushPull>>,
29 pub csn: GpioPin<Output<PushPull>>, 28 pub csn: GpioPin<Output<PushPull>>,
@@ -59,7 +58,7 @@ fn port_bit(port: GpioPort) -> bool {
59} 58}
60 59
61impl Qspi { 60impl Qspi {
62 pub fn new(qspi: QSPI, config: Config) -> Self { 61 pub fn new(qspi: QSPI, irq: QSPIInterrupt, config: Config) -> Self {
63 qspi.psel.sck.write(|w| { 62 qspi.psel.sck.write(|w| {
64 let pin = &config.pins.sck; 63 let pin = &config.pins.sck;
65 let w = unsafe { w.pin().bits(pin.pin()) }; 64 let w = unsafe { w.pin().bits(pin.pin()) };
@@ -146,9 +145,10 @@ impl Qspi {
146 // Enable READY interrupt 145 // Enable READY interrupt
147 SIGNAL.reset(); 146 SIGNAL.reset();
148 qspi.intenset.write(|w| w.ready().set()); 147 qspi.intenset.write(|w| w.ready().set());
149 interrupt::set_priority(Interrupt::QSPI, interrupt::Priority::Level7); 148
150 interrupt::unpend(Interrupt::QSPI); 149 irq.set_handler(irq_handler);
151 interrupt::enable(Interrupt::QSPI); 150 irq.unpend();
151 irq.enable();
152 152
153 Self { inner: qspi } 153 Self { inner: qspi }
154 } 154 }
@@ -347,8 +347,7 @@ impl Flash for Qspi {
347 347
348static SIGNAL: Signal<()> = Signal::new(); 348static SIGNAL: Signal<()> = Signal::new();
349 349
350#[interrupt] 350unsafe fn irq_handler() {
351unsafe fn QSPI() {
352 let p = crate::pac::Peripherals::steal().QSPI; 351 let p = crate::pac::Peripherals::steal().QSPI;
353 if p.events_ready.read().events_ready().bit_is_set() { 352 if p.events_ready.read().events_ready().bit_is_set() {
354 p.events_ready.reset(); 353 p.events_ready.reset();
diff --git a/embassy-nrf/src/rtc.rs b/embassy-nrf/src/rtc.rs
index 66e2f552d..d65b8d472 100644
--- a/embassy-nrf/src/rtc.rs
+++ b/embassy-nrf/src/rtc.rs
@@ -2,10 +2,10 @@ use core::cell::Cell;
2use core::ops::Deref; 2use core::ops::Deref;
3use core::sync::atomic::{AtomicU32, Ordering}; 3use core::sync::atomic::{AtomicU32, Ordering};
4 4
5use embassy::time::Clock; 5use embassy::time::{Clock, Instant};
6 6
7use crate::interrupt; 7use crate::interrupt;
8use crate::interrupt::{CriticalSection, Mutex}; 8use crate::interrupt::{CriticalSection, Mutex, OwnedInterrupt};
9use crate::pac::{rtc0, Interrupt, RTC0, RTC1}; 9use crate::pac::{rtc0, Interrupt, RTC0, RTC1};
10 10
11#[cfg(any(feature = "52832", feature = "52833", feature = "52840"))] 11#[cfg(any(feature = "52832", feature = "52833", feature = "52840"))]
@@ -56,8 +56,9 @@ impl AlarmState {
56 56
57const ALARM_COUNT: usize = 3; 57const ALARM_COUNT: usize = 3;
58 58
59pub struct RTC<T> { 59pub struct RTC<T: Instance> {
60 rtc: T, 60 rtc: T,
61 irq: T::Interrupt,
61 62
62 /// Number of 2^23 periods elapsed since boot. 63 /// Number of 2^23 periods elapsed since boot.
63 /// 64 ///
@@ -75,13 +76,14 @@ pub struct RTC<T> {
75 alarms: Mutex<[AlarmState; ALARM_COUNT]>, 76 alarms: Mutex<[AlarmState; ALARM_COUNT]>,
76} 77}
77 78
78unsafe impl<T> Send for RTC<T> {} 79unsafe impl<T: Instance> Send for RTC<T> {}
79unsafe impl<T> Sync for RTC<T> {} 80unsafe impl<T: Instance> Sync for RTC<T> {}
80 81
81impl<T: Instance> RTC<T> { 82impl<T: Instance> RTC<T> {
82 pub fn new(rtc: T) -> Self { 83 pub fn new(rtc: T, irq: T::Interrupt) -> Self {
83 Self { 84 Self {
84 rtc, 85 rtc,
86 irq,
85 period: AtomicU32::new(0), 87 period: AtomicU32::new(0),
86 alarms: Mutex::new([AlarmState::new(), AlarmState::new(), AlarmState::new()]), 88 alarms: Mutex::new([AlarmState::new(), AlarmState::new(), AlarmState::new()]),
87 } 89 }
@@ -103,7 +105,10 @@ impl<T: Instance> RTC<T> {
103 while self.rtc.counter.read().bits() != 0 {} 105 while self.rtc.counter.read().bits() != 0 {}
104 106
105 T::set_rtc_instance(self); 107 T::set_rtc_instance(self);
106 interrupt::enable(T::INTERRUPT); 108 self.irq
109 .set_handler(|| T::get_rtc_instance().on_interrupt());
110 self.irq.unpend();
111 self.irq.enable();
107 } 112 }
108 113
109 fn on_interrupt(&self) { 114 fn on_interrupt(&self) {
@@ -234,18 +239,18 @@ impl<T: Instance> embassy::time::Alarm for Alarm<T> {
234/// Implemented by all RTC instances. 239/// Implemented by all RTC instances.
235pub trait Instance: Deref<Target = rtc0::RegisterBlock> + Sized + 'static { 240pub trait Instance: Deref<Target = rtc0::RegisterBlock> + Sized + 'static {
236 /// The interrupt associated with this RTC instance. 241 /// The interrupt associated with this RTC instance.
237 const INTERRUPT: Interrupt; 242 type Interrupt: OwnedInterrupt;
238 243
239 fn set_rtc_instance(rtc: &'static RTC<Self>); 244 fn set_rtc_instance(rtc: &'static RTC<Self>);
240 fn get_rtc_instance() -> &'static RTC<Self>; 245 fn get_rtc_instance() -> &'static RTC<Self>;
241} 246}
242 247
243macro_rules! impl_instance { 248macro_rules! impl_instance {
244 ($name:ident, $static_name:ident) => { 249 ($name:ident, $irq_name:path, $static_name:ident) => {
245 static mut $static_name: Option<&'static RTC<$name>> = None; 250 static mut $static_name: Option<&'static RTC<$name>> = None;
246 251
247 impl Instance for $name { 252 impl Instance for $name {
248 const INTERRUPT: Interrupt = Interrupt::$name; 253 type Interrupt = $irq_name;
249 fn set_rtc_instance(rtc: &'static RTC<Self>) { 254 fn set_rtc_instance(rtc: &'static RTC<Self>) {
250 unsafe { $static_name = Some(rtc) } 255 unsafe { $static_name = Some(rtc) }
251 } 256 }
@@ -253,16 +258,11 @@ macro_rules! impl_instance {
253 unsafe { $static_name.unwrap() } 258 unsafe { $static_name.unwrap() }
254 } 259 }
255 } 260 }
256
257 #[interrupt]
258 fn $name() {
259 $name::get_rtc_instance().on_interrupt();
260 }
261 }; 261 };
262} 262}
263 263
264impl_instance!(RTC0, RTC0_INSTANCE); 264impl_instance!(RTC0, interrupt::RTC0Interrupt, RTC0_INSTANCE);
265impl_instance!(RTC1, RTC1_INSTANCE); 265impl_instance!(RTC1, interrupt::RTC1Interrupt, RTC1_INSTANCE);
266 266
267#[cfg(any(feature = "52832", feature = "52833", feature = "52840"))] 267#[cfg(any(feature = "52832", feature = "52833", feature = "52840"))]
268impl_instance!(RTC2, RTC2_INSTANCE); 268impl_instance!(RTC2, interrupt::RTC2Interrupt, RTC2_INSTANCE);
diff --git a/embassy/src/interrupt.rs b/embassy/src/interrupt.rs
new file mode 100644
index 000000000..fee52b326
--- /dev/null
+++ b/embassy/src/interrupt.rs
@@ -0,0 +1,76 @@
1use core::mem;
2use core::ptr;
3use core::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
4use cortex_m::peripheral::NVIC;
5
6pub use embassy_macros::interrupt_declare as declare;
7pub use embassy_macros::interrupt_take as take;
8
9struct NrWrap(u8);
10unsafe impl cortex_m::interrupt::Nr for NrWrap {
11 fn nr(&self) -> u8 {
12 self.0
13 }
14}
15
16pub unsafe trait OwnedInterrupt {
17 type Priority: From<u8> + Into<u8> + Copy;
18 fn number(&self) -> u8;
19 #[doc(hidden)]
20 unsafe fn __handler(&self) -> &'static AtomicPtr<u32>;
21
22 fn set_handler(&self, handler: unsafe fn()) {
23 unsafe { self.__handler() }.store(handler as *mut u32, Ordering::Release);
24 }
25
26 #[inline]
27 fn enable(&self) {
28 unsafe {
29 NVIC::unmask(NrWrap(self.number()));
30 }
31 }
32
33 #[inline]
34 fn disable(&self) {
35 NVIC::mask(NrWrap(self.number()));
36 }
37
38 #[inline]
39 fn is_active(&self) -> bool {
40 NVIC::is_active(NrWrap(self.number()))
41 }
42
43 #[inline]
44 fn is_enabled(&self) -> bool {
45 NVIC::is_enabled(NrWrap(self.number()))
46 }
47
48 #[inline]
49 fn is_pending(&self) -> bool {
50 NVIC::is_pending(NrWrap(self.number()))
51 }
52
53 #[inline]
54 fn pend(&self) {
55 NVIC::pend(NrWrap(self.number()))
56 }
57
58 #[inline]
59 fn unpend(&self) {
60 NVIC::unpend(NrWrap(self.number()))
61 }
62
63 #[inline]
64 fn get_priority(&self) -> Self::Priority {
65 Self::Priority::from(NVIC::get_priority(NrWrap(self.number())))
66 }
67
68 #[inline]
69 fn set_priority(&self, prio: Self::Priority) {
70 unsafe {
71 cortex_m::peripheral::Peripherals::steal()
72 .NVIC
73 .set_priority(NrWrap(self.number()), prio.into())
74 }
75 }
76}
diff --git a/embassy/src/lib.rs b/embassy/src/lib.rs
index 49ba8eea8..bc06ebd13 100644
--- a/embassy/src/lib.rs
+++ b/embassy/src/lib.rs
@@ -9,6 +9,7 @@ pub(crate) mod fmt;
9 9
10pub mod executor; 10pub mod executor;
11pub mod flash; 11pub mod flash;
12pub mod interrupt;
12pub mod io; 13pub mod io;
13pub mod rand; 14pub mod rand;
14pub mod time; 15pub mod time;
diff --git a/examples/src/bin/gpiote.rs b/examples/src/bin/gpiote.rs
index edc3f5ef1..afa1b85d5 100644
--- a/examples/src/bin/gpiote.rs
+++ b/examples/src/bin/gpiote.rs
@@ -7,18 +7,20 @@ mod example_common;
7use example_common::*; 7use example_common::*;
8 8
9use cortex_m_rt::entry; 9use cortex_m_rt::entry;
10use defmt::panic;
10use nrf52840_hal::gpio; 11use nrf52840_hal::gpio;
11 12
12use embassy::executor::{task, Executor}; 13use embassy::executor::{task, Executor};
13use embassy::util::Forever; 14use embassy::util::Forever;
14use embassy_nrf::gpiote; 15use embassy_nrf::gpiote;
16use embassy_nrf::interrupt;
15 17
16#[task] 18#[task]
17async fn run() { 19async fn run() {
18 let p = unwrap!(embassy_nrf::pac::Peripherals::take()); 20 let p = unwrap!(embassy_nrf::pac::Peripherals::take());
19 let port0 = gpio::p0::Parts::new(p.P0); 21 let port0 = gpio::p0::Parts::new(p.P0);
20 22
21 let g = gpiote::Gpiote::new(p.GPIOTE); 23 let g = gpiote::Gpiote::new(p.GPIOTE, interrupt::take!(GPIOTE));
22 24
23 info!("Starting!"); 25 info!("Starting!");
24 26
diff --git a/examples/src/bin/gpiote_port.rs b/examples/src/bin/gpiote_port.rs
index 585317642..f5aa81322 100644
--- a/examples/src/bin/gpiote_port.rs
+++ b/examples/src/bin/gpiote_port.rs
@@ -8,11 +8,13 @@ use example_common::*;
8 8
9use core::mem; 9use core::mem;
10use cortex_m_rt::entry; 10use cortex_m_rt::entry;
11use defmt::panic;
11use nrf52840_hal::gpio; 12use nrf52840_hal::gpio;
12 13
13use embassy::executor::{task, Executor}; 14use embassy::executor::{task, Executor};
14use embassy::util::Forever; 15use embassy::util::Forever;
15use embassy_nrf::gpiote::{Gpiote, PortInputPolarity}; 16use embassy_nrf::gpiote::{Gpiote, PortInputPolarity};
17use embassy_nrf::interrupt;
16 18
17async fn button(g: &Gpiote, n: usize, pin: gpio::Pin<gpio::Input<gpio::PullUp>>) { 19async fn button(g: &Gpiote, n: usize, pin: gpio::Pin<gpio::Input<gpio::PullUp>>) {
18 loop { 20 loop {
@@ -28,7 +30,7 @@ async fn run() {
28 let p = unwrap!(embassy_nrf::pac::Peripherals::take()); 30 let p = unwrap!(embassy_nrf::pac::Peripherals::take());
29 let port0 = gpio::p0::Parts::new(p.P0); 31 let port0 = gpio::p0::Parts::new(p.P0);
30 32
31 let g = Gpiote::new(p.GPIOTE); 33 let g = Gpiote::new(p.GPIOTE, interrupt::take!(GPIOTE));
32 info!( 34 info!(
33 "sizeof Signal<()> = {:usize}", 35 "sizeof Signal<()> = {:usize}",
34 mem::size_of::<embassy::util::Signal<()>>() 36 mem::size_of::<embassy::util::Signal<()>>()
diff --git a/examples/src/bin/multiprio.rs b/examples/src/bin/multiprio.rs
index be7e91a9d..c821e3dba 100644
--- a/examples/src/bin/multiprio.rs
+++ b/examples/src/bin/multiprio.rs
@@ -61,7 +61,9 @@
61mod example_common; 61mod example_common;
62use example_common::*; 62use example_common::*;
63 63
64use cortex_m::peripheral::NVIC;
64use cortex_m_rt::entry; 65use cortex_m_rt::entry;
66use defmt::panic;
65use nrf52840_hal::clocks; 67use nrf52840_hal::clocks;
66 68
67use embassy::executor::{task, Executor}; 69use embassy::executor::{task, Executor};
@@ -130,7 +132,7 @@ fn main() -> ! {
130 .set_lfclk_src_external(clocks::LfOscConfiguration::NoExternalNoBypass) 132 .set_lfclk_src_external(clocks::LfOscConfiguration::NoExternalNoBypass)
131 .start_lfclk(); 133 .start_lfclk();
132 134
133 let rtc = RTC.put(rtc::RTC::new(p.RTC1)); 135 let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1)));
134 rtc.start(); 136 rtc.start();
135 unsafe { embassy::time::set_clock(rtc) }; 137 unsafe { embassy::time::set_clock(rtc) };
136 138
@@ -138,17 +140,20 @@ fn main() -> ! {
138 let executor_low = EXECUTOR_LOW.put(Executor::new_with_alarm(alarm_low, cortex_m::asm::sev)); 140 let executor_low = EXECUTOR_LOW.put(Executor::new_with_alarm(alarm_low, cortex_m::asm::sev));
139 let alarm_med = ALARM_MED.put(rtc.alarm1()); 141 let alarm_med = ALARM_MED.put(rtc.alarm1());
140 let executor_med = EXECUTOR_MED.put(Executor::new_with_alarm(alarm_med, || { 142 let executor_med = EXECUTOR_MED.put(Executor::new_with_alarm(alarm_med, || {
141 interrupt::pend(interrupt::SWI0_EGU0) 143 NVIC::pend(interrupt::SWI0_EGU0)
142 })); 144 }));
143 let alarm_high = ALARM_HIGH.put(rtc.alarm2()); 145 let alarm_high = ALARM_HIGH.put(rtc.alarm2());
144 let executor_high = EXECUTOR_HIGH.put(Executor::new_with_alarm(alarm_high, || { 146 let executor_high = EXECUTOR_HIGH.put(Executor::new_with_alarm(alarm_high, || {
145 interrupt::pend(interrupt::SWI1_EGU1) 147 NVIC::pend(interrupt::SWI1_EGU1)
146 })); 148 }));
147 149
148 interrupt::set_priority(interrupt::SWI0_EGU0, interrupt::Priority::Level7); 150 unsafe {
149 interrupt::set_priority(interrupt::SWI1_EGU1, interrupt::Priority::Level6); 151 let mut nvic: NVIC = core::mem::transmute(());
150 interrupt::enable(interrupt::SWI0_EGU0); 152 nvic.set_priority(interrupt::SWI0_EGU0, 7 << 5);
151 interrupt::enable(interrupt::SWI1_EGU1); 153 nvic.set_priority(interrupt::SWI1_EGU1, 6 << 5);
154 NVIC::unmask(interrupt::SWI0_EGU0);
155 NVIC::unmask(interrupt::SWI1_EGU1);
156 }
152 157
153 unwrap!(executor_low.spawn(run_low())); 158 unwrap!(executor_low.spawn(run_low()));
154 unwrap!(executor_med.spawn(run_med())); 159 unwrap!(executor_med.spawn(run_med()));
diff --git a/examples/src/bin/qspi.rs b/examples/src/bin/qspi.rs
index 644018e2d..a7d47f79c 100644
--- a/examples/src/bin/qspi.rs
+++ b/examples/src/bin/qspi.rs
@@ -13,7 +13,7 @@ use nrf52840_hal::gpio;
13use embassy::executor::{task, Executor}; 13use embassy::executor::{task, Executor};
14use embassy::flash::Flash; 14use embassy::flash::Flash;
15use embassy::util::Forever; 15use embassy::util::Forever;
16use embassy_nrf::qspi; 16use embassy_nrf::{interrupt, qspi};
17 17
18const PAGE_SIZE: usize = 4096; 18const PAGE_SIZE: usize = 4096;
19 19
@@ -68,7 +68,8 @@ async fn run() {
68 deep_power_down: None, 68 deep_power_down: None,
69 }; 69 };
70 70
71 let mut q = qspi::Qspi::new(p.QSPI, config); 71 let irq = interrupt::take!(QSPI);
72 let mut q = qspi::Qspi::new(p.QSPI, irq, config);
72 73
73 let mut id = [1; 3]; 74 let mut id = [1; 3];
74 q.custom_instruction(0x9F, &[], &mut id).await.unwrap(); 75 q.custom_instruction(0x9F, &[], &mut id).await.unwrap();
diff --git a/examples/src/bin/rtc_async.rs b/examples/src/bin/rtc_async.rs
index aec70a072..dcdeb7049 100644
--- a/examples/src/bin/rtc_async.rs
+++ b/examples/src/bin/rtc_async.rs
@@ -8,13 +8,13 @@ use example_common::*;
8 8
9use core::mem::MaybeUninit; 9use core::mem::MaybeUninit;
10use cortex_m_rt::entry; 10use cortex_m_rt::entry;
11use nrf52840_hal::clocks; 11use defmt::panic;
12
13use embassy::executor::{task, Executor}; 12use embassy::executor::{task, Executor};
14use embassy::time::{Clock, Duration, Timer}; 13use embassy::time::{Clock, Duration, Timer};
15use embassy::util::Forever; 14use embassy::util::Forever;
16use embassy_nrf::pac; 15use embassy_nrf::pac;
17use embassy_nrf::rtc; 16use embassy_nrf::{interrupt, rtc};
17use nrf52840_hal::clocks;
18 18
19#[task] 19#[task]
20async fn run1() { 20async fn run1() {
@@ -47,7 +47,7 @@ fn main() -> ! {
47 .set_lfclk_src_external(clocks::LfOscConfiguration::NoExternalNoBypass) 47 .set_lfclk_src_external(clocks::LfOscConfiguration::NoExternalNoBypass)
48 .start_lfclk(); 48 .start_lfclk();
49 49
50 let rtc = RTC.put(rtc::RTC::new(p.RTC1)); 50 let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1)));
51 rtc.start(); 51 rtc.start();
52 52
53 unsafe { embassy::time::set_clock(rtc) }; 53 unsafe { embassy::time::set_clock(rtc) };
diff --git a/examples/src/bin/rtc_raw.rs b/examples/src/bin/rtc_raw.rs
index ad5fab246..438585460 100644
--- a/examples/src/bin/rtc_raw.rs
+++ b/examples/src/bin/rtc_raw.rs
@@ -8,8 +8,9 @@ use example_common::*;
8 8
9use core::mem::MaybeUninit; 9use core::mem::MaybeUninit;
10use cortex_m_rt::entry; 10use cortex_m_rt::entry;
11use defmt::panic;
11use embassy::time::{Alarm, Clock}; 12use embassy::time::{Alarm, Clock};
12use embassy_nrf::rtc; 13use embassy_nrf::{interrupt, rtc};
13use nrf52840_hal::clocks; 14use nrf52840_hal::clocks;
14 15
15static mut RTC: MaybeUninit<rtc::RTC<embassy_nrf::pac::RTC1>> = MaybeUninit::uninit(); 16static mut RTC: MaybeUninit<rtc::RTC<embassy_nrf::pac::RTC1>> = MaybeUninit::uninit();
@@ -25,9 +26,11 @@ fn main() -> ! {
25 .set_lfclk_src_external(clocks::LfOscConfiguration::NoExternalNoBypass) 26 .set_lfclk_src_external(clocks::LfOscConfiguration::NoExternalNoBypass)
26 .start_lfclk(); 27 .start_lfclk();
27 28
29 let irq = interrupt::take!(RTC1);
30
28 let rtc: &'static _ = unsafe { 31 let rtc: &'static _ = unsafe {
29 let ptr = RTC.as_mut_ptr(); 32 let ptr = RTC.as_mut_ptr();
30 ptr.write(rtc::RTC::new(p.RTC1)); 33 ptr.write(rtc::RTC::new(p.RTC1, irq));
31 &*ptr 34 &*ptr
32 }; 35 };
33 36
diff --git a/examples/src/bin/uart.rs b/examples/src/bin/uart.rs
index e664fcef2..6e15fbcfa 100644
--- a/examples/src/bin/uart.rs
+++ b/examples/src/bin/uart.rs
@@ -7,6 +7,7 @@ mod example_common;
7use example_common::*; 7use example_common::*;
8 8
9use cortex_m_rt::entry; 9use cortex_m_rt::entry;
10use defmt::panic;
10use futures::pin_mut; 11use futures::pin_mut;
11use nrf52840_hal::gpio; 12use nrf52840_hal::gpio;
12 13
@@ -14,6 +15,7 @@ use embassy::executor::{task, Executor};
14use embassy::io::{AsyncBufRead, AsyncBufReadExt, AsyncWrite, AsyncWriteExt}; 15use embassy::io::{AsyncBufRead, AsyncBufReadExt, AsyncWrite, AsyncWriteExt};
15use embassy::util::Forever; 16use embassy::util::Forever;
16use embassy_nrf::buffered_uarte; 17use embassy_nrf::buffered_uarte;
18use embassy_nrf::interrupt;
17 19
18#[task] 20#[task]
19async fn run() { 21async fn run() {
@@ -31,8 +33,10 @@ async fn run() {
31 rts: None, 33 rts: None,
32 }; 34 };
33 35
36 let irq = interrupt::take!(UARTE0_UART0);
34 let u = buffered_uarte::BufferedUarte::new( 37 let u = buffered_uarte::BufferedUarte::new(
35 p.UARTE0, 38 p.UARTE0,
39 irq,
36 pins, 40 pins,
37 buffered_uarte::Parity::EXCLUDED, 41 buffered_uarte::Parity::EXCLUDED,
38 buffered_uarte::Baudrate::BAUD115200, 42 buffered_uarte::Baudrate::BAUD115200,