aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf/src/buffered_uarte.rs
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-03-05 20:17:52 +0100
committerDario Nieuwenhuis <[email protected]>2023-03-06 00:17:51 +0100
commit9cf000ef4edd8f230b348ede8d7ce015045a0035 (patch)
treeed3db0facdb024479843691292121daa04f0975f /embassy-nrf/src/buffered_uarte.rs
parent42c13c8c3d9514866c2842009f76e88e8cb01b22 (diff)
nrf/uart: switch to new interrupt binding.
Diffstat (limited to 'embassy-nrf/src/buffered_uarte.rs')
-rw-r--r--embassy-nrf/src/buffered_uarte.rs225
1 files changed, 114 insertions, 111 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();