aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-nrf/src/buffered_uarte.rs225
-rw-r--r--embassy-nrf/src/uarte.rs85
-rw-r--r--examples/nrf52840/src/bin/buffered_uart.rs11
-rw-r--r--examples/nrf52840/src/bin/uart.rs9
-rw-r--r--examples/nrf52840/src/bin/uart_idle.rs10
-rw-r--r--examples/nrf52840/src/bin/uart_split.rs9
-rw-r--r--examples/nrf5340/src/bin/uart.rs10
-rw-r--r--tests/nrf/src/bin/buffered_uart.rs10
-rw-r--r--tests/nrf/src/bin/buffered_uart_spam.rs13
9 files changed, 206 insertions, 176 deletions
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs
index ab639aeea..75f93f904 100644
--- a/embassy-nrf/src/buffered_uarte.rs
+++ b/embassy-nrf/src/buffered_uarte.rs
@@ -10,6 +10,7 @@
10 10
11use core::cmp::min; 11use core::cmp::min;
12use core::future::poll_fn; 12use core::future::poll_fn;
13use core::marker::PhantomData;
13use core::slice; 14use core::slice;
14use core::sync::atomic::{compiler_fence, AtomicU8, AtomicUsize, Ordering}; 15use core::sync::atomic::{compiler_fence, AtomicU8, AtomicUsize, Ordering};
15use core::task::Poll; 16use core::task::Poll;
@@ -23,7 +24,7 @@ pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Pari
23 24
24use crate::gpio::sealed::Pin; 25use crate::gpio::sealed::Pin;
25use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits}; 26use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits};
26use crate::interrupt::InterruptExt; 27use crate::interrupt::{self, InterruptExt};
27use crate::ppi::{ 28use crate::ppi::{
28 self, AnyConfigurableChannel, AnyGroup, Channel, ConfigurableChannel, Event, Group, Ppi, PpiGroup, Task, 29 self, AnyConfigurableChannel, AnyGroup, Channel, ConfigurableChannel, Event, Group, Ppi, PpiGroup, Task,
29}; 30};
@@ -71,6 +72,113 @@ impl State {
71 } 72 }
72} 73}
73 74
75/// Interrupt handler.
76pub struct InterruptHandler<U: UarteInstance> {
77 _phantom: PhantomData<U>,
78}
79
80impl<U: UarteInstance> interrupt::Handler<U::Interrupt> for InterruptHandler<U> {
81 unsafe fn on_interrupt() {
82 //trace!("irq: start");
83 let r = U::regs();
84 let s = U::buffered_state();
85
86 let buf_len = s.rx_buf.len();
87 let half_len = buf_len / 2;
88 let mut tx = unsafe { s.tx_buf.reader() };
89 let mut rx = unsafe { s.rx_buf.writer() };
90
91 if r.events_error.read().bits() != 0 {
92 r.events_error.reset();
93 let errs = r.errorsrc.read();
94 r.errorsrc.write(|w| unsafe { w.bits(errs.bits()) });
95
96 if errs.overrun().bit() {
97 panic!("BufferedUarte overrun");
98 }
99 }
100
101 // Received some bytes, wake task.
102 if r.inten.read().rxdrdy().bit_is_set() && r.events_rxdrdy.read().bits() != 0 {
103 r.intenclr.write(|w| w.rxdrdy().clear());
104 r.events_rxdrdy.reset();
105 s.rx_waker.wake();
106 }
107
108 // If not RXing, start.
109 if s.rx_bufs.load(Ordering::Relaxed) == 0 {
110 let (ptr, len) = rx.push_buf();
111 if len >= half_len {
112 //trace!(" irq_rx: starting {:?}", half_len);
113 s.rx_bufs.store(1, Ordering::Relaxed);
114
115 // Set up the DMA read
116 r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) });
117 r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(half_len as _) });
118
119 // Start UARTE Receive transaction
120 r.tasks_startrx.write(|w| unsafe { w.bits(1) });
121 rx.push_done(half_len);
122 r.intenset.write(|w| w.rxstarted().set());
123 }
124 }
125
126 if r.events_rxstarted.read().bits() != 0 {
127 //trace!(" irq_rx: rxstarted");
128 let (ptr, len) = rx.push_buf();
129 if len >= half_len {
130 //trace!(" irq_rx: starting second {:?}", half_len);
131
132 // Set up the DMA read
133 r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) });
134 r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(half_len as _) });
135
136 let chn = s.rx_ppi_ch.load(Ordering::Relaxed);
137
138 ppi::regs().chenset.write(|w| unsafe { w.bits(1 << chn) });
139
140 rx.push_done(half_len);
141
142 r.events_rxstarted.reset();
143 } else {
144 //trace!(" irq_rx: rxstarted no buf");
145 r.intenclr.write(|w| w.rxstarted().clear());
146 }
147 }
148
149 // =============================
150
151 // TX end
152 if r.events_endtx.read().bits() != 0 {
153 r.events_endtx.reset();
154
155 let n = s.tx_count.load(Ordering::Relaxed);
156 //trace!(" irq_tx: endtx {:?}", n);
157 tx.pop_done(n);
158 s.tx_waker.wake();
159 s.tx_count.store(0, Ordering::Relaxed);
160 }
161
162 // If not TXing, start.
163 if s.tx_count.load(Ordering::Relaxed) == 0 {
164 let (ptr, len) = tx.pop_buf();
165 if len != 0 {
166 //trace!(" irq_tx: starting {:?}", len);
167 s.tx_count.store(len, Ordering::Relaxed);
168
169 // Set up the DMA write
170 r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) });
171 r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) });
172
173 // Start UARTE Transmit transaction
174 r.tasks_starttx.write(|w| unsafe { w.bits(1) });
175 }
176 }
177
178 //trace!("irq: end");
179 }
180}
181
74/// Buffered UARTE driver. 182/// Buffered UARTE driver.
75pub struct BufferedUarte<'d, U: UarteInstance, T: TimerInstance> { 183pub struct BufferedUarte<'d, U: UarteInstance, T: TimerInstance> {
76 _peri: PeripheralRef<'d, U>, 184 _peri: PeripheralRef<'d, U>,
@@ -94,7 +202,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
94 ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd, 202 ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd,
95 ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd, 203 ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd,
96 ppi_group: impl Peripheral<P = impl Group> + 'd, 204 ppi_group: impl Peripheral<P = impl Group> + 'd,
97 irq: impl Peripheral<P = U::Interrupt> + 'd, 205 _irq: impl interrupt::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
98 rxd: impl Peripheral<P = impl GpioPin> + 'd, 206 rxd: impl Peripheral<P = impl GpioPin> + 'd,
99 txd: impl Peripheral<P = impl GpioPin> + 'd, 207 txd: impl Peripheral<P = impl GpioPin> + 'd,
100 config: Config, 208 config: Config,
@@ -108,7 +216,6 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
108 ppi_ch1.map_into(), 216 ppi_ch1.map_into(),
109 ppi_ch2.map_into(), 217 ppi_ch2.map_into(),
110 ppi_group.map_into(), 218 ppi_group.map_into(),
111 irq,
112 rxd.map_into(), 219 rxd.map_into(),
113 txd.map_into(), 220 txd.map_into(),
114 None, 221 None,
@@ -130,7 +237,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
130 ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd, 237 ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd,
131 ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd, 238 ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd,
132 ppi_group: impl Peripheral<P = impl Group> + 'd, 239 ppi_group: impl Peripheral<P = impl Group> + 'd,
133 irq: impl Peripheral<P = U::Interrupt> + 'd, 240 _irq: impl interrupt::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
134 rxd: impl Peripheral<P = impl GpioPin> + 'd, 241 rxd: impl Peripheral<P = impl GpioPin> + 'd,
135 txd: impl Peripheral<P = impl GpioPin> + 'd, 242 txd: impl Peripheral<P = impl GpioPin> + 'd,
136 cts: impl Peripheral<P = impl GpioPin> + 'd, 243 cts: impl Peripheral<P = impl GpioPin> + 'd,
@@ -146,7 +253,6 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
146 ppi_ch1.map_into(), 253 ppi_ch1.map_into(),
147 ppi_ch2.map_into(), 254 ppi_ch2.map_into(),
148 ppi_group.map_into(), 255 ppi_group.map_into(),
149 irq,
150 rxd.map_into(), 256 rxd.map_into(),
151 txd.map_into(), 257 txd.map_into(),
152 Some(cts.map_into()), 258 Some(cts.map_into()),
@@ -163,7 +269,6 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
163 ppi_ch1: PeripheralRef<'d, AnyConfigurableChannel>, 269 ppi_ch1: PeripheralRef<'d, AnyConfigurableChannel>,
164 ppi_ch2: PeripheralRef<'d, AnyConfigurableChannel>, 270 ppi_ch2: PeripheralRef<'d, AnyConfigurableChannel>,
165 ppi_group: PeripheralRef<'d, AnyGroup>, 271 ppi_group: PeripheralRef<'d, AnyGroup>,
166 irq: impl Peripheral<P = U::Interrupt> + 'd,
167 rxd: PeripheralRef<'d, AnyPin>, 272 rxd: PeripheralRef<'d, AnyPin>,
168 txd: PeripheralRef<'d, AnyPin>, 273 txd: PeripheralRef<'d, AnyPin>,
169 cts: Option<PeripheralRef<'d, AnyPin>>, 274 cts: Option<PeripheralRef<'d, AnyPin>>,
@@ -172,7 +277,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
172 rx_buffer: &'d mut [u8], 277 rx_buffer: &'d mut [u8],
173 tx_buffer: &'d mut [u8], 278 tx_buffer: &'d mut [u8],
174 ) -> Self { 279 ) -> Self {
175 into_ref!(peri, timer, irq); 280 into_ref!(peri, timer);
176 281
177 assert!(rx_buffer.len() % 2 == 0); 282 assert!(rx_buffer.len() % 2 == 0);
178 283
@@ -257,10 +362,8 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
257 ppi_ch2.disable(); 362 ppi_ch2.disable();
258 ppi_group.add_channel(&ppi_ch2); 363 ppi_group.add_channel(&ppi_ch2);
259 364
260 irq.disable(); 365 unsafe { U::Interrupt::steal() }.pend();
261 irq.set_handler(Self::on_interrupt); 366 unsafe { U::Interrupt::steal() }.enable();
262 irq.pend();
263 irq.enable();
264 367
265 Self { 368 Self {
266 _peri: peri, 369 _peri: peri,
@@ -275,106 +378,6 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
275 unsafe { <U::Interrupt as Interrupt>::steal() }.pend() 378 unsafe { <U::Interrupt as Interrupt>::steal() }.pend()
276 } 379 }
277 380
278 fn on_interrupt(_: *mut ()) {
279 //trace!("irq: start");
280 let r = U::regs();
281 let s = U::buffered_state();
282
283 let buf_len = s.rx_buf.len();
284 let half_len = buf_len / 2;
285 let mut tx = unsafe { s.tx_buf.reader() };
286 let mut rx = unsafe { s.rx_buf.writer() };
287
288 if r.events_error.read().bits() != 0 {
289 r.events_error.reset();
290 let errs = r.errorsrc.read();
291 r.errorsrc.write(|w| unsafe { w.bits(errs.bits()) });
292
293 if errs.overrun().bit() {
294 panic!("BufferedUarte overrun");
295 }
296 }
297
298 // Received some bytes, wake task.
299 if r.inten.read().rxdrdy().bit_is_set() && r.events_rxdrdy.read().bits() != 0 {
300 r.intenclr.write(|w| w.rxdrdy().clear());
301 r.events_rxdrdy.reset();
302 s.rx_waker.wake();
303 }
304
305 // If not RXing, start.
306 if s.rx_bufs.load(Ordering::Relaxed) == 0 {
307 let (ptr, len) = rx.push_buf();
308 if len >= half_len {
309 //trace!(" irq_rx: starting {:?}", half_len);
310 s.rx_bufs.store(1, Ordering::Relaxed);
311
312 // Set up the DMA read
313 r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) });
314 r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(half_len as _) });
315
316 // Start UARTE Receive transaction
317 r.tasks_startrx.write(|w| unsafe { w.bits(1) });
318 rx.push_done(half_len);
319 r.intenset.write(|w| w.rxstarted().set());
320 }
321 }
322
323 if r.events_rxstarted.read().bits() != 0 {
324 //trace!(" irq_rx: rxstarted");
325 let (ptr, len) = rx.push_buf();
326 if len >= half_len {
327 //trace!(" irq_rx: starting second {:?}", half_len);
328
329 // Set up the DMA read
330 r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) });
331 r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(half_len as _) });
332
333 let chn = s.rx_ppi_ch.load(Ordering::Relaxed);
334
335 ppi::regs().chenset.write(|w| unsafe { w.bits(1 << chn) });
336
337 rx.push_done(half_len);
338
339 r.events_rxstarted.reset();
340 } else {
341 //trace!(" irq_rx: rxstarted no buf");
342 r.intenclr.write(|w| w.rxstarted().clear());
343 }
344 }
345
346 // =============================
347
348 // TX end
349 if r.events_endtx.read().bits() != 0 {
350 r.events_endtx.reset();
351
352 let n = s.tx_count.load(Ordering::Relaxed);
353 //trace!(" irq_tx: endtx {:?}", n);
354 tx.pop_done(n);
355 s.tx_waker.wake();
356 s.tx_count.store(0, Ordering::Relaxed);
357 }
358
359 // If not TXing, start.
360 if s.tx_count.load(Ordering::Relaxed) == 0 {
361 let (ptr, len) = tx.pop_buf();
362 if len != 0 {
363 //trace!(" irq_tx: starting {:?}", len);
364 s.tx_count.store(len, Ordering::Relaxed);
365
366 // Set up the DMA write
367 r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) });
368 r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) });
369
370 // Start UARTE Transmit transaction
371 r.tasks_starttx.write(|w| unsafe { w.bits(1) });
372 }
373 }
374
375 //trace!("irq: end");
376 }
377
378 /// Adjust the baud rate to the provided value. 381 /// Adjust the baud rate to the provided value.
379 pub fn set_baudrate(&mut self, baudrate: Baudrate) { 382 pub fn set_baudrate(&mut self, baudrate: Baudrate) {
380 let r = U::regs(); 383 let r = U::regs();
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs
index 00afbd059..3934d1b55 100644
--- a/embassy-nrf/src/uarte.rs
+++ b/embassy-nrf/src/uarte.rs
@@ -14,6 +14,7 @@
14#![macro_use] 14#![macro_use]
15 15
16use core::future::poll_fn; 16use core::future::poll_fn;
17use core::marker::PhantomData;
17use core::sync::atomic::{compiler_fence, Ordering}; 18use core::sync::atomic::{compiler_fence, Ordering};
18use core::task::Poll; 19use core::task::Poll;
19 20
@@ -26,7 +27,7 @@ pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Pari
26use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; 27use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE};
27use crate::gpio::sealed::Pin as _; 28use crate::gpio::sealed::Pin as _;
28use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits}; 29use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits};
29use crate::interrupt::{Interrupt, InterruptExt}; 30use crate::interrupt::{self, Interrupt, InterruptExt};
30use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; 31use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task};
31use crate::timer::{Frequency, Instance as TimerInstance, Timer}; 32use crate::timer::{Frequency, Instance as TimerInstance, Timer};
32use crate::util::slice_in_ram_or; 33use crate::util::slice_in_ram_or;
@@ -62,6 +63,27 @@ pub enum Error {
62 BufferNotInRAM, 63 BufferNotInRAM,
63} 64}
64 65
66/// Interrupt handler.
67pub struct InterruptHandler<T: Instance> {
68 _phantom: PhantomData<T>,
69}
70
71impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> {
72 unsafe fn on_interrupt() {
73 let r = T::regs();
74 let s = T::state();
75
76 if r.events_endrx.read().bits() != 0 {
77 s.endrx_waker.wake();
78 r.intenclr.write(|w| w.endrx().clear());
79 }
80 if r.events_endtx.read().bits() != 0 {
81 s.endtx_waker.wake();
82 r.intenclr.write(|w| w.endtx().clear());
83 }
84 }
85}
86
65/// UARTE driver. 87/// UARTE driver.
66pub struct Uarte<'d, T: Instance> { 88pub struct Uarte<'d, T: Instance> {
67 tx: UarteTx<'d, T>, 89 tx: UarteTx<'d, T>,
@@ -86,19 +108,19 @@ impl<'d, T: Instance> Uarte<'d, T> {
86 /// Create a new UARTE without hardware flow control 108 /// Create a new UARTE without hardware flow control
87 pub fn new( 109 pub fn new(
88 uarte: impl Peripheral<P = T> + 'd, 110 uarte: impl Peripheral<P = T> + 'd,
89 irq: impl Peripheral<P = T::Interrupt> + 'd, 111 _irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
90 rxd: impl Peripheral<P = impl GpioPin> + 'd, 112 rxd: impl Peripheral<P = impl GpioPin> + 'd,
91 txd: impl Peripheral<P = impl GpioPin> + 'd, 113 txd: impl Peripheral<P = impl GpioPin> + 'd,
92 config: Config, 114 config: Config,
93 ) -> Self { 115 ) -> Self {
94 into_ref!(rxd, txd); 116 into_ref!(rxd, txd);
95 Self::new_inner(uarte, irq, rxd.map_into(), txd.map_into(), None, None, config) 117 Self::new_inner(uarte, rxd.map_into(), txd.map_into(), None, None, config)
96 } 118 }
97 119
98 /// Create a new UARTE with hardware flow control (RTS/CTS) 120 /// Create a new UARTE with hardware flow control (RTS/CTS)
99 pub fn new_with_rtscts( 121 pub fn new_with_rtscts(
100 uarte: impl Peripheral<P = T> + 'd, 122 uarte: impl Peripheral<P = T> + 'd,
101 irq: impl Peripheral<P = T::Interrupt> + 'd, 123 _irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
102 rxd: impl Peripheral<P = impl GpioPin> + 'd, 124 rxd: impl Peripheral<P = impl GpioPin> + 'd,
103 txd: impl Peripheral<P = impl GpioPin> + 'd, 125 txd: impl Peripheral<P = impl GpioPin> + 'd,
104 cts: impl Peripheral<P = impl GpioPin> + 'd, 126 cts: impl Peripheral<P = impl GpioPin> + 'd,
@@ -108,7 +130,6 @@ impl<'d, T: Instance> Uarte<'d, T> {
108 into_ref!(rxd, txd, cts, rts); 130 into_ref!(rxd, txd, cts, rts);
109 Self::new_inner( 131 Self::new_inner(
110 uarte, 132 uarte,
111 irq,
112 rxd.map_into(), 133 rxd.map_into(),
113 txd.map_into(), 134 txd.map_into(),
114 Some(cts.map_into()), 135 Some(cts.map_into()),
@@ -119,14 +140,13 @@ impl<'d, T: Instance> Uarte<'d, T> {
119 140
120 fn new_inner( 141 fn new_inner(
121 uarte: impl Peripheral<P = T> + 'd, 142 uarte: impl Peripheral<P = T> + 'd,
122 irq: impl Peripheral<P = T::Interrupt> + 'd,
123 rxd: PeripheralRef<'d, AnyPin>, 143 rxd: PeripheralRef<'d, AnyPin>,
124 txd: PeripheralRef<'d, AnyPin>, 144 txd: PeripheralRef<'d, AnyPin>,
125 cts: Option<PeripheralRef<'d, AnyPin>>, 145 cts: Option<PeripheralRef<'d, AnyPin>>,
126 rts: Option<PeripheralRef<'d, AnyPin>>, 146 rts: Option<PeripheralRef<'d, AnyPin>>,
127 config: Config, 147 config: Config,
128 ) -> Self { 148 ) -> Self {
129 into_ref!(uarte, irq); 149 into_ref!(uarte);
130 150
131 let r = T::regs(); 151 let r = T::regs();
132 152
@@ -148,9 +168,8 @@ impl<'d, T: Instance> Uarte<'d, T> {
148 } 168 }
149 r.psel.rts.write(|w| unsafe { w.bits(rts.psel_bits()) }); 169 r.psel.rts.write(|w| unsafe { w.bits(rts.psel_bits()) });
150 170
151 irq.set_handler(Self::on_interrupt); 171 unsafe { T::Interrupt::steal() }.unpend();
152 irq.unpend(); 172 unsafe { T::Interrupt::steal() }.enable();
153 irq.enable();
154 173
155 let hardware_flow_control = match (rts.is_some(), cts.is_some()) { 174 let hardware_flow_control = match (rts.is_some(), cts.is_some()) {
156 (false, false) => false, 175 (false, false) => false,
@@ -238,20 +257,6 @@ impl<'d, T: Instance> Uarte<'d, T> {
238 Event::from_reg(&r.events_endtx) 257 Event::from_reg(&r.events_endtx)
239 } 258 }
240 259
241 fn on_interrupt(_: *mut ()) {
242 let r = T::regs();
243 let s = T::state();
244
245 if r.events_endrx.read().bits() != 0 {
246 s.endrx_waker.wake();
247 r.intenclr.write(|w| w.endrx().clear());
248 }
249 if r.events_endtx.read().bits() != 0 {
250 s.endtx_waker.wake();
251 r.intenclr.write(|w| w.endtx().clear());
252 }
253 }
254
255 /// Read bytes until the buffer is filled. 260 /// Read bytes until the buffer is filled.
256 pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { 261 pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
257 self.rx.read(buffer).await 262 self.rx.read(buffer).await
@@ -308,34 +313,33 @@ impl<'d, T: Instance> UarteTx<'d, T> {
308 /// Create a new tx-only UARTE without hardware flow control 313 /// Create a new tx-only UARTE without hardware flow control
309 pub fn new( 314 pub fn new(
310 uarte: impl Peripheral<P = T> + 'd, 315 uarte: impl Peripheral<P = T> + 'd,
311 irq: impl Peripheral<P = T::Interrupt> + 'd, 316 _irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
312 txd: impl Peripheral<P = impl GpioPin> + 'd, 317 txd: impl Peripheral<P = impl GpioPin> + 'd,
313 config: Config, 318 config: Config,
314 ) -> Self { 319 ) -> Self {
315 into_ref!(txd); 320 into_ref!(txd);
316 Self::new_inner(uarte, irq, txd.map_into(), None, config) 321 Self::new_inner(uarte, txd.map_into(), None, config)
317 } 322 }
318 323
319 /// Create a new tx-only UARTE with hardware flow control (RTS/CTS) 324 /// Create a new tx-only UARTE with hardware flow control (RTS/CTS)
320 pub fn new_with_rtscts( 325 pub fn new_with_rtscts(
321 uarte: impl Peripheral<P = T> + 'd, 326 uarte: impl Peripheral<P = T> + 'd,
322 irq: impl Peripheral<P = T::Interrupt> + 'd, 327 _irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
323 txd: impl Peripheral<P = impl GpioPin> + 'd, 328 txd: impl Peripheral<P = impl GpioPin> + 'd,
324 cts: impl Peripheral<P = impl GpioPin> + 'd, 329 cts: impl Peripheral<P = impl GpioPin> + 'd,
325 config: Config, 330 config: Config,
326 ) -> Self { 331 ) -> Self {
327 into_ref!(txd, cts); 332 into_ref!(txd, cts);
328 Self::new_inner(uarte, irq, txd.map_into(), Some(cts.map_into()), config) 333 Self::new_inner(uarte, txd.map_into(), Some(cts.map_into()), config)
329 } 334 }
330 335
331 fn new_inner( 336 fn new_inner(
332 uarte: impl Peripheral<P = T> + 'd, 337 uarte: impl Peripheral<P = T> + 'd,
333 irq: impl Peripheral<P = T::Interrupt> + 'd,
334 txd: PeripheralRef<'d, AnyPin>, 338 txd: PeripheralRef<'d, AnyPin>,
335 cts: Option<PeripheralRef<'d, AnyPin>>, 339 cts: Option<PeripheralRef<'d, AnyPin>>,
336 config: Config, 340 config: Config,
337 ) -> Self { 341 ) -> Self {
338 into_ref!(uarte, irq); 342 into_ref!(uarte);
339 343
340 let r = T::regs(); 344 let r = T::regs();
341 345
@@ -354,9 +358,8 @@ impl<'d, T: Instance> UarteTx<'d, T> {
354 let hardware_flow_control = cts.is_some(); 358 let hardware_flow_control = cts.is_some();
355 configure(r, config, hardware_flow_control); 359 configure(r, config, hardware_flow_control);
356 360
357 irq.set_handler(Uarte::<T>::on_interrupt); 361 unsafe { T::Interrupt::steal() }.unpend();
358 irq.unpend(); 362 unsafe { T::Interrupt::steal() }.enable();
359 irq.enable();
360 363
361 let s = T::state(); 364 let s = T::state();
362 s.tx_rx_refcount.store(1, Ordering::Relaxed); 365 s.tx_rx_refcount.store(1, Ordering::Relaxed);
@@ -506,34 +509,33 @@ impl<'d, T: Instance> UarteRx<'d, T> {
506 /// Create a new rx-only UARTE without hardware flow control 509 /// Create a new rx-only UARTE without hardware flow control
507 pub fn new( 510 pub fn new(
508 uarte: impl Peripheral<P = T> + 'd, 511 uarte: impl Peripheral<P = T> + 'd,
509 irq: impl Peripheral<P = T::Interrupt> + 'd, 512 _irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
510 rxd: impl Peripheral<P = impl GpioPin> + 'd, 513 rxd: impl Peripheral<P = impl GpioPin> + 'd,
511 config: Config, 514 config: Config,
512 ) -> Self { 515 ) -> Self {
513 into_ref!(rxd); 516 into_ref!(rxd);
514 Self::new_inner(uarte, irq, rxd.map_into(), None, config) 517 Self::new_inner(uarte, rxd.map_into(), None, config)
515 } 518 }
516 519
517 /// Create a new rx-only UARTE with hardware flow control (RTS/CTS) 520 /// Create a new rx-only UARTE with hardware flow control (RTS/CTS)
518 pub fn new_with_rtscts( 521 pub fn new_with_rtscts(
519 uarte: impl Peripheral<P = T> + 'd, 522 uarte: impl Peripheral<P = T> + 'd,
520 irq: impl Peripheral<P = T::Interrupt> + 'd, 523 _irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
521 rxd: impl Peripheral<P = impl GpioPin> + 'd, 524 rxd: impl Peripheral<P = impl GpioPin> + 'd,
522 rts: impl Peripheral<P = impl GpioPin> + 'd, 525 rts: impl Peripheral<P = impl GpioPin> + 'd,
523 config: Config, 526 config: Config,
524 ) -> Self { 527 ) -> Self {
525 into_ref!(rxd, rts); 528 into_ref!(rxd, rts);
526 Self::new_inner(uarte, irq, rxd.map_into(), Some(rts.map_into()), config) 529 Self::new_inner(uarte, rxd.map_into(), Some(rts.map_into()), config)
527 } 530 }
528 531
529 fn new_inner( 532 fn new_inner(
530 uarte: impl Peripheral<P = T> + 'd, 533 uarte: impl Peripheral<P = T> + 'd,
531 irq: impl Peripheral<P = T::Interrupt> + 'd,
532 rxd: PeripheralRef<'d, AnyPin>, 534 rxd: PeripheralRef<'d, AnyPin>,
533 rts: Option<PeripheralRef<'d, AnyPin>>, 535 rts: Option<PeripheralRef<'d, AnyPin>>,
534 config: Config, 536 config: Config,
535 ) -> Self { 537 ) -> Self {
536 into_ref!(uarte, irq); 538 into_ref!(uarte);
537 539
538 let r = T::regs(); 540 let r = T::regs();
539 541
@@ -549,9 +551,8 @@ impl<'d, T: Instance> UarteRx<'d, T> {
549 r.psel.txd.write(|w| w.connect().disconnected()); 551 r.psel.txd.write(|w| w.connect().disconnected());
550 r.psel.cts.write(|w| w.connect().disconnected()); 552 r.psel.cts.write(|w| w.connect().disconnected());
551 553
552 irq.set_handler(Uarte::<T>::on_interrupt); 554 unsafe { T::Interrupt::steal() }.unpend();
553 irq.unpend(); 555 unsafe { T::Interrupt::steal() }.enable();
554 irq.enable();
555 556
556 let hardware_flow_control = rts.is_some(); 557 let hardware_flow_control = rts.is_some();
557 configure(r, config, hardware_flow_control); 558 configure(r, config, hardware_flow_control);
diff --git a/examples/nrf52840/src/bin/buffered_uart.rs b/examples/nrf52840/src/bin/buffered_uart.rs
index 5b934b7d6..238695371 100644
--- a/examples/nrf52840/src/bin/buffered_uart.rs
+++ b/examples/nrf52840/src/bin/buffered_uart.rs
@@ -4,11 +4,15 @@
4 4
5use defmt::*; 5use defmt::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_nrf::buffered_uarte::BufferedUarte; 7use embassy_nrf::buffered_uarte::{self, BufferedUarte};
8use embassy_nrf::{interrupt, uarte}; 8use embassy_nrf::{bind_interrupts, peripherals, uarte};
9use embedded_io::asynch::Write; 9use embedded_io::asynch::Write;
10use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
11 11
12bind_interrupts!(struct Irqs {
13 UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;
14});
15
12#[embassy_executor::main] 16#[embassy_executor::main]
13async fn main(_spawner: Spawner) { 17async fn main(_spawner: Spawner) {
14 let p = embassy_nrf::init(Default::default()); 18 let p = embassy_nrf::init(Default::default());
@@ -19,14 +23,13 @@ async fn main(_spawner: Spawner) {
19 let mut tx_buffer = [0u8; 4096]; 23 let mut tx_buffer = [0u8; 4096];
20 let mut rx_buffer = [0u8; 4096]; 24 let mut rx_buffer = [0u8; 4096];
21 25
22 let irq = interrupt::take!(UARTE0_UART0);
23 let mut u = BufferedUarte::new( 26 let mut u = BufferedUarte::new(
24 p.UARTE0, 27 p.UARTE0,
25 p.TIMER0, 28 p.TIMER0,
26 p.PPI_CH0, 29 p.PPI_CH0,
27 p.PPI_CH1, 30 p.PPI_CH1,
28 p.PPI_GROUP0, 31 p.PPI_GROUP0,
29 irq, 32 Irqs,
30 p.P0_08, 33 p.P0_08,
31 p.P0_06, 34 p.P0_06,
32 config, 35 config,
diff --git a/examples/nrf52840/src/bin/uart.rs b/examples/nrf52840/src/bin/uart.rs
index 600f7a6ef..50d5cab8c 100644
--- a/examples/nrf52840/src/bin/uart.rs
+++ b/examples/nrf52840/src/bin/uart.rs
@@ -4,9 +4,13 @@
4 4
5use defmt::*; 5use defmt::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_nrf::{interrupt, uarte}; 7use embassy_nrf::{bind_interrupts, peripherals, uarte};
8use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
9 9
10bind_interrupts!(struct Irqs {
11 UARTE0_UART0 => uarte::InterruptHandler<peripherals::UARTE0>;
12});
13
10#[embassy_executor::main] 14#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 15async fn main(_spawner: Spawner) {
12 let p = embassy_nrf::init(Default::default()); 16 let p = embassy_nrf::init(Default::default());
@@ -14,8 +18,7 @@ async fn main(_spawner: Spawner) {
14 config.parity = uarte::Parity::EXCLUDED; 18 config.parity = uarte::Parity::EXCLUDED;
15 config.baudrate = uarte::Baudrate::BAUD115200; 19 config.baudrate = uarte::Baudrate::BAUD115200;
16 20
17 let irq = interrupt::take!(UARTE0_UART0); 21 let mut uart = uarte::Uarte::new(p.UARTE0, Irqs, p.P0_08, p.P0_06, config);
18 let mut uart = uarte::Uarte::new(p.UARTE0, irq, p.P0_08, p.P0_06, config);
19 22
20 info!("uarte initialized!"); 23 info!("uarte initialized!");
21 24
diff --git a/examples/nrf52840/src/bin/uart_idle.rs b/examples/nrf52840/src/bin/uart_idle.rs
index 6af4f7097..e1f42fa6c 100644
--- a/examples/nrf52840/src/bin/uart_idle.rs
+++ b/examples/nrf52840/src/bin/uart_idle.rs
@@ -4,9 +4,14 @@
4 4
5use defmt::*; 5use defmt::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_nrf::{interrupt, uarte}; 7use embassy_nrf::peripherals::UARTE0;
8use embassy_nrf::{bind_interrupts, uarte};
8use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
9 10
11bind_interrupts!(struct Irqs {
12 UARTE0_UART0 => uarte::InterruptHandler<UARTE0>;
13});
14
10#[embassy_executor::main] 15#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 16async fn main(_spawner: Spawner) {
12 let p = embassy_nrf::init(Default::default()); 17 let p = embassy_nrf::init(Default::default());
@@ -14,8 +19,7 @@ async fn main(_spawner: Spawner) {
14 config.parity = uarte::Parity::EXCLUDED; 19 config.parity = uarte::Parity::EXCLUDED;
15 config.baudrate = uarte::Baudrate::BAUD115200; 20 config.baudrate = uarte::Baudrate::BAUD115200;
16 21
17 let irq = interrupt::take!(UARTE0_UART0); 22 let uart = uarte::Uarte::new(p.UARTE0, Irqs, p.P0_08, p.P0_06, config);
18 let uart = uarte::Uarte::new(p.UARTE0, irq, p.P0_08, p.P0_06, config);
19 let (mut tx, mut rx) = uart.split_with_idle(p.TIMER0, p.PPI_CH0, p.PPI_CH1); 23 let (mut tx, mut rx) = uart.split_with_idle(p.TIMER0, p.PPI_CH0, p.PPI_CH1);
20 24
21 info!("uarte initialized!"); 25 info!("uarte initialized!");
diff --git a/examples/nrf52840/src/bin/uart_split.rs b/examples/nrf52840/src/bin/uart_split.rs
index 1adaf53fd..9979a1d53 100644
--- a/examples/nrf52840/src/bin/uart_split.rs
+++ b/examples/nrf52840/src/bin/uart_split.rs
@@ -6,13 +6,17 @@ use defmt::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_nrf::peripherals::UARTE0; 7use embassy_nrf::peripherals::UARTE0;
8use embassy_nrf::uarte::UarteRx; 8use embassy_nrf::uarte::UarteRx;
9use embassy_nrf::{interrupt, uarte}; 9use embassy_nrf::{bind_interrupts, uarte};
10use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; 10use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
11use embassy_sync::channel::Channel; 11use embassy_sync::channel::Channel;
12use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
13 13
14static CHANNEL: Channel<ThreadModeRawMutex, [u8; 8], 1> = Channel::new(); 14static CHANNEL: Channel<ThreadModeRawMutex, [u8; 8], 1> = Channel::new();
15 15
16bind_interrupts!(struct Irqs {
17 UARTE0_UART0 => uarte::InterruptHandler<UARTE0>;
18});
19
16#[embassy_executor::main] 20#[embassy_executor::main]
17async fn main(spawner: Spawner) { 21async fn main(spawner: Spawner) {
18 let p = embassy_nrf::init(Default::default()); 22 let p = embassy_nrf::init(Default::default());
@@ -20,8 +24,7 @@ async fn main(spawner: Spawner) {
20 config.parity = uarte::Parity::EXCLUDED; 24 config.parity = uarte::Parity::EXCLUDED;
21 config.baudrate = uarte::Baudrate::BAUD115200; 25 config.baudrate = uarte::Baudrate::BAUD115200;
22 26
23 let irq = interrupt::take!(UARTE0_UART0); 27 let uart = uarte::Uarte::new(p.UARTE0, Irqs, p.P0_08, p.P0_06, config);
24 let uart = uarte::Uarte::new(p.UARTE0, irq, p.P0_08, p.P0_06, config);
25 let (mut tx, rx) = uart.split(); 28 let (mut tx, rx) = uart.split();
26 29
27 info!("uarte initialized!"); 30 info!("uarte initialized!");
diff --git a/examples/nrf5340/src/bin/uart.rs b/examples/nrf5340/src/bin/uart.rs
index 5f448c2ba..d68539702 100644
--- a/examples/nrf5340/src/bin/uart.rs
+++ b/examples/nrf5340/src/bin/uart.rs
@@ -4,9 +4,14 @@
4 4
5use defmt::*; 5use defmt::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_nrf::{interrupt, uarte}; 7use embassy_nrf::peripherals::SERIAL0;
8use embassy_nrf::{bind_interrupts, uarte};
8use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
9 10
11bind_interrupts!(struct Irqs {
12 SERIAL0 => uarte::InterruptHandler<SERIAL0>;
13});
14
10#[embassy_executor::main] 15#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 16async fn main(_spawner: Spawner) {
12 let p = embassy_nrf::init(Default::default()); 17 let p = embassy_nrf::init(Default::default());
@@ -14,8 +19,7 @@ async fn main(_spawner: Spawner) {
14 config.parity = uarte::Parity::EXCLUDED; 19 config.parity = uarte::Parity::EXCLUDED;
15 config.baudrate = uarte::Baudrate::BAUD115200; 20 config.baudrate = uarte::Baudrate::BAUD115200;
16 21
17 let irq = interrupt::take!(SERIAL0); 22 let mut uart = uarte::Uarte::new(p.SERIAL0, Irqs, p.P1_00, p.P1_01, config);
18 let mut uart = uarte::Uarte::new(p.SERIAL0, irq, p.P1_00, p.P1_01, config);
19 23
20 info!("uarte initialized!"); 24 info!("uarte initialized!");
21 25
diff --git a/tests/nrf/src/bin/buffered_uart.rs b/tests/nrf/src/bin/buffered_uart.rs
index 0550b0bb7..e73d4f0b0 100644
--- a/tests/nrf/src/bin/buffered_uart.rs
+++ b/tests/nrf/src/bin/buffered_uart.rs
@@ -5,10 +5,14 @@
5use defmt::{assert_eq, *}; 5use defmt::{assert_eq, *};
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_futures::join::join; 7use embassy_futures::join::join;
8use embassy_nrf::buffered_uarte::BufferedUarte; 8use embassy_nrf::buffered_uarte::{self, BufferedUarte};
9use embassy_nrf::{interrupt, uarte}; 9use embassy_nrf::{bind_interrupts, peripherals, uarte};
10use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
11 11
12bind_interrupts!(struct Irqs {
13 UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;
14});
15
12#[embassy_executor::main] 16#[embassy_executor::main]
13async fn main(_spawner: Spawner) { 17async fn main(_spawner: Spawner) {
14 let p = embassy_nrf::init(Default::default()); 18 let p = embassy_nrf::init(Default::default());
@@ -25,7 +29,7 @@ async fn main(_spawner: Spawner) {
25 p.PPI_CH0, 29 p.PPI_CH0,
26 p.PPI_CH1, 30 p.PPI_CH1,
27 p.PPI_GROUP0, 31 p.PPI_GROUP0,
28 interrupt::take!(UARTE0_UART0), 32 Irqs,
29 p.P1_03, 33 p.P1_03,
30 p.P1_02, 34 p.P1_02,
31 config.clone(), 35 config.clone(),
diff --git a/tests/nrf/src/bin/buffered_uart_spam.rs b/tests/nrf/src/bin/buffered_uart_spam.rs
index 57aaeca45..74eda6d01 100644
--- a/tests/nrf/src/bin/buffered_uart_spam.rs
+++ b/tests/nrf/src/bin/buffered_uart_spam.rs
@@ -7,14 +7,19 @@ use core::ptr::NonNull;
7 7
8use defmt::{assert_eq, *}; 8use defmt::{assert_eq, *};
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_nrf::buffered_uarte::BufferedUarte; 10use embassy_nrf::buffered_uarte::{self, BufferedUarte};
11use embassy_nrf::gpio::{Level, Output, OutputDrive}; 11use embassy_nrf::gpio::{Level, Output, OutputDrive};
12use embassy_nrf::ppi::{Event, Ppi, Task}; 12use embassy_nrf::ppi::{Event, Ppi, Task};
13use embassy_nrf::uarte::Uarte; 13use embassy_nrf::uarte::Uarte;
14use embassy_nrf::{interrupt, pac, uarte}; 14use embassy_nrf::{bind_interrupts, pac, peripherals, uarte};
15use embassy_time::{Duration, Timer}; 15use embassy_time::{Duration, Timer};
16use {defmt_rtt as _, panic_probe as _}; 16use {defmt_rtt as _, panic_probe as _};
17 17
18bind_interrupts!(struct Irqs {
19 UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;
20 UARTE1 => uarte::InterruptHandler<peripherals::UARTE1>;
21});
22
18#[embassy_executor::main] 23#[embassy_executor::main]
19async fn main(_spawner: Spawner) { 24async fn main(_spawner: Spawner) {
20 let mut p = embassy_nrf::init(Default::default()); 25 let mut p = embassy_nrf::init(Default::default());
@@ -33,7 +38,7 @@ async fn main(_spawner: Spawner) {
33 p.PPI_CH0, 38 p.PPI_CH0,
34 p.PPI_CH1, 39 p.PPI_CH1,
35 p.PPI_GROUP0, 40 p.PPI_GROUP0,
36 interrupt::take!(UARTE0_UART0), 41 Irqs,
37 p.P1_03, 42 p.P1_03,
38 p.P1_04, 43 p.P1_04,
39 config.clone(), 44 config.clone(),
@@ -49,7 +54,7 @@ async fn main(_spawner: Spawner) {
49 // Tx spam in a loop. 54 // Tx spam in a loop.
50 const NSPAM: usize = 17; 55 const NSPAM: usize = 17;
51 static mut TX_BUF: [u8; NSPAM] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; 56 static mut TX_BUF: [u8; NSPAM] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
52 let _spam = Uarte::new(p.UARTE1, interrupt::take!(UARTE1), p.P1_01, p.P1_02, config.clone()); 57 let _spam = Uarte::new(p.UARTE1, Irqs, p.P1_01, p.P1_02, config.clone());
53 let spam_peri: pac::UARTE1 = unsafe { mem::transmute(()) }; 58 let spam_peri: pac::UARTE1 = unsafe { mem::transmute(()) };
54 let event = unsafe { Event::new_unchecked(NonNull::new_unchecked(&spam_peri.events_endtx as *const _ as _)) }; 59 let event = unsafe { Event::new_unchecked(NonNull::new_unchecked(&spam_peri.events_endtx as *const _ as _)) };
55 let task = unsafe { Task::new_unchecked(NonNull::new_unchecked(&spam_peri.tasks_starttx as *const _ as _)) }; 60 let task = unsafe { Task::new_unchecked(NonNull::new_unchecked(&spam_peri.tasks_starttx as *const _ as _)) };