aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf/src
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-nrf/src')
-rw-r--r--embassy-nrf/src/buffered_uarte.rs755
-rw-r--r--embassy-nrf/src/gpio.rs2
-rw-r--r--embassy-nrf/src/spim.rs23
-rw-r--r--embassy-nrf/src/uarte.rs88
4 files changed, 520 insertions, 348 deletions
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs
index fb72422bd..b04c96e09 100644
--- a/embassy-nrf/src/buffered_uarte.rs
+++ b/embassy-nrf/src/buffered_uarte.rs
@@ -17,29 +17,26 @@ use core::task::Poll;
17 17
18use embassy_hal_internal::atomic_ring_buffer::RingBuffer; 18use embassy_hal_internal::atomic_ring_buffer::RingBuffer;
19use embassy_hal_internal::{into_ref, PeripheralRef}; 19use embassy_hal_internal::{into_ref, PeripheralRef};
20use embassy_sync::waitqueue::AtomicWaker;
21// Re-export SVD variants to allow user to directly set values 20// Re-export SVD variants to allow user to directly set values
22pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; 21pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity};
23 22
24use crate::gpio::sealed::Pin; 23use crate::gpio::sealed::Pin;
25use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits}; 24use crate::gpio::{AnyPin, Pin as GpioPin, PselBits};
26use crate::interrupt::typelevel::Interrupt; 25use crate::interrupt::typelevel::Interrupt;
27use crate::ppi::{ 26use crate::ppi::{
28 self, AnyConfigurableChannel, AnyGroup, Channel, ConfigurableChannel, Event, Group, Ppi, PpiGroup, Task, 27 self, AnyConfigurableChannel, AnyGroup, Channel, ConfigurableChannel, Event, Group, Ppi, PpiGroup, Task,
29}; 28};
30use crate::timer::{Instance as TimerInstance, Timer}; 29use crate::timer::{Instance as TimerInstance, Timer};
31use crate::uarte::{apply_workaround_for_enable_anomaly, Config, Instance as UarteInstance}; 30use crate::uarte::{configure, drop_tx_rx, Config, Instance as UarteInstance};
32use crate::{interrupt, pac, Peripheral}; 31use crate::{interrupt, pac, Peripheral};
33 32
34mod sealed { 33mod sealed {
35 use super::*; 34 use super::*;
36 35
37 pub struct State { 36 pub struct State {
38 pub tx_waker: AtomicWaker,
39 pub tx_buf: RingBuffer, 37 pub tx_buf: RingBuffer,
40 pub tx_count: AtomicUsize, 38 pub tx_count: AtomicUsize,
41 39
42 pub rx_waker: AtomicWaker,
43 pub rx_buf: RingBuffer, 40 pub rx_buf: RingBuffer,
44 pub rx_started: AtomicBool, 41 pub rx_started: AtomicBool,
45 pub rx_started_count: AtomicU8, 42 pub rx_started_count: AtomicU8,
@@ -61,11 +58,9 @@ pub(crate) use sealed::State;
61impl State { 58impl State {
62 pub(crate) const fn new() -> Self { 59 pub(crate) const fn new() -> Self {
63 Self { 60 Self {
64 tx_waker: AtomicWaker::new(),
65 tx_buf: RingBuffer::new(), 61 tx_buf: RingBuffer::new(),
66 tx_count: AtomicUsize::new(0), 62 tx_count: AtomicUsize::new(0),
67 63
68 rx_waker: AtomicWaker::new(),
69 rx_buf: RingBuffer::new(), 64 rx_buf: RingBuffer::new(),
70 rx_started: AtomicBool::new(false), 65 rx_started: AtomicBool::new(false),
71 rx_started_count: AtomicU8::new(0), 66 rx_started_count: AtomicU8::new(0),
@@ -84,128 +79,131 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt
84 unsafe fn on_interrupt() { 79 unsafe fn on_interrupt() {
85 //trace!("irq: start"); 80 //trace!("irq: start");
86 let r = U::regs(); 81 let r = U::regs();
82 let ss = U::state();
87 let s = U::buffered_state(); 83 let s = U::buffered_state();
88 84
89 let buf_len = s.rx_buf.len(); 85 if let Some(mut rx) = unsafe { s.rx_buf.try_writer() } {
90 let half_len = buf_len / 2; 86 let buf_len = s.rx_buf.len();
91 let mut tx = unsafe { s.tx_buf.reader() }; 87 let half_len = buf_len / 2;
92 let mut rx = unsafe { s.rx_buf.writer() };
93 88
94 if r.events_error.read().bits() != 0 { 89 if r.events_error.read().bits() != 0 {
95 r.events_error.reset(); 90 r.events_error.reset();
96 let errs = r.errorsrc.read(); 91 let errs = r.errorsrc.read();
97 r.errorsrc.write(|w| unsafe { w.bits(errs.bits()) }); 92 r.errorsrc.write(|w| unsafe { w.bits(errs.bits()) });
98 93
99 if errs.overrun().bit() { 94 if errs.overrun().bit() {
100 panic!("BufferedUarte overrun"); 95 panic!("BufferedUarte overrun");
96 }
101 } 97 }
102 }
103 98
104 // Received some bytes, wake task. 99 // Received some bytes, wake task.
105 if r.inten.read().rxdrdy().bit_is_set() && r.events_rxdrdy.read().bits() != 0 { 100 if r.inten.read().rxdrdy().bit_is_set() && r.events_rxdrdy.read().bits() != 0 {
106 r.intenclr.write(|w| w.rxdrdy().clear()); 101 r.intenclr.write(|w| w.rxdrdy().clear());
107 r.events_rxdrdy.reset(); 102 r.events_rxdrdy.reset();
108 s.rx_waker.wake(); 103 ss.rx_waker.wake();
109 } 104 }
110 105
111 if r.events_endrx.read().bits() != 0 { 106 if r.events_endrx.read().bits() != 0 {
112 //trace!(" irq_rx: endrx"); 107 //trace!(" irq_rx: endrx");
113 r.events_endrx.reset(); 108 r.events_endrx.reset();
114 109
115 let val = s.rx_ended_count.load(Ordering::Relaxed); 110 let val = s.rx_ended_count.load(Ordering::Relaxed);
116 s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed); 111 s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed);
117 } 112 }
118 113
119 if r.events_rxstarted.read().bits() != 0 || !s.rx_started.load(Ordering::Relaxed) { 114 if r.events_rxstarted.read().bits() != 0 || !s.rx_started.load(Ordering::Relaxed) {
120 //trace!(" irq_rx: rxstarted"); 115 //trace!(" irq_rx: rxstarted");
121 let (ptr, len) = rx.push_buf(); 116 let (ptr, len) = rx.push_buf();
122 if len >= half_len { 117 if len >= half_len {
123 r.events_rxstarted.reset(); 118 r.events_rxstarted.reset();
124 119
125 //trace!(" irq_rx: starting second {:?}", half_len); 120 //trace!(" irq_rx: starting second {:?}", half_len);
126 121
127 // Set up the DMA read 122 // Set up the DMA read
128 r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); 123 r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) });
129 r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(half_len as _) }); 124 r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(half_len as _) });
130 125
131 let chn = s.rx_ppi_ch.load(Ordering::Relaxed); 126 let chn = s.rx_ppi_ch.load(Ordering::Relaxed);
132 127
133 // Enable endrx -> startrx PPI channel. 128 // Enable endrx -> startrx PPI channel.
134 // From this point on, if endrx happens, startrx is automatically fired. 129 // From this point on, if endrx happens, startrx is automatically fired.
135 ppi::regs().chenset.write(|w| unsafe { w.bits(1 << chn) }); 130 ppi::regs().chenset.write(|w| unsafe { w.bits(1 << chn) });
136 131
137 // It is possible that endrx happened BEFORE enabling the PPI. In this case 132 // It is possible that endrx happened BEFORE enabling the PPI. In this case
138 // the PPI channel doesn't trigger, and we'd hang. We have to detect this 133 // the PPI channel doesn't trigger, and we'd hang. We have to detect this
139 // and manually start. 134 // and manually start.
140 135
141 // check again in case endrx has happened between the last check and now. 136 // check again in case endrx has happened between the last check and now.
142 if r.events_endrx.read().bits() != 0 { 137 if r.events_endrx.read().bits() != 0 {
143 //trace!(" irq_rx: endrx"); 138 //trace!(" irq_rx: endrx");
144 r.events_endrx.reset(); 139 r.events_endrx.reset();
145 140
146 let val = s.rx_ended_count.load(Ordering::Relaxed); 141 let val = s.rx_ended_count.load(Ordering::Relaxed);
147 s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed); 142 s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed);
148 } 143 }
149 144
150 let rx_ended = s.rx_ended_count.load(Ordering::Relaxed); 145 let rx_ended = s.rx_ended_count.load(Ordering::Relaxed);
151 let rx_started = s.rx_started_count.load(Ordering::Relaxed); 146 let rx_started = s.rx_started_count.load(Ordering::Relaxed);
152 147
153 // If we started the same amount of transfers as ended, the last rxend has 148 // If we started the same amount of transfers as ended, the last rxend has
154 // already occured. 149 // already occured.
155 let rxend_happened = rx_started == rx_ended; 150 let rxend_happened = rx_started == rx_ended;
156 151
157 // Check if the PPI channel is still enabled. The PPI channel disables itself 152 // Check if the PPI channel is still enabled. The PPI channel disables itself
158 // when it fires, so if it's still enabled it hasn't fired. 153 // when it fires, so if it's still enabled it hasn't fired.
159 let ppi_ch_enabled = ppi::regs().chen.read().bits() & (1 << chn) != 0; 154 let ppi_ch_enabled = ppi::regs().chen.read().bits() & (1 << chn) != 0;
160 155
161 // if rxend happened, and the ppi channel hasn't fired yet, the rxend got missed. 156 // if rxend happened, and the ppi channel hasn't fired yet, the rxend got missed.
162 // this condition also naturally matches if `!started`, needed to kickstart the DMA. 157 // this condition also naturally matches if `!started`, needed to kickstart the DMA.
163 if rxend_happened && ppi_ch_enabled { 158 if rxend_happened && ppi_ch_enabled {
164 //trace!("manually starting."); 159 //trace!("manually starting.");
165 160
166 // disable the ppi ch, it's of no use anymore. 161 // disable the ppi ch, it's of no use anymore.
167 ppi::regs().chenclr.write(|w| unsafe { w.bits(1 << chn) }); 162 ppi::regs().chenclr.write(|w| unsafe { w.bits(1 << chn) });
168 163
169 // manually start 164 // manually start
170 r.tasks_startrx.write(|w| unsafe { w.bits(1) }); 165 r.tasks_startrx.write(|w| unsafe { w.bits(1) });
171 } 166 }
172 167
173 rx.push_done(half_len); 168 rx.push_done(half_len);
174 169
175 s.rx_started_count.store(rx_started.wrapping_add(1), Ordering::Relaxed); 170 s.rx_started_count.store(rx_started.wrapping_add(1), Ordering::Relaxed);
176 s.rx_started.store(true, Ordering::Relaxed); 171 s.rx_started.store(true, Ordering::Relaxed);
177 } else { 172 } else {
178 //trace!(" irq_rx: rxstarted no buf"); 173 //trace!(" irq_rx: rxstarted no buf");
179 r.intenclr.write(|w| w.rxstarted().clear()); 174 r.intenclr.write(|w| w.rxstarted().clear());
175 }
180 } 176 }
181 } 177 }
182 178
183 // ============================= 179 // =============================
184 180
185 // TX end 181 if let Some(mut tx) = unsafe { s.tx_buf.try_reader() } {
186 if r.events_endtx.read().bits() != 0 { 182 // TX end
187 r.events_endtx.reset(); 183 if r.events_endtx.read().bits() != 0 {
184 r.events_endtx.reset();
188 185
189 let n = s.tx_count.load(Ordering::Relaxed); 186 let n = s.tx_count.load(Ordering::Relaxed);
190 //trace!(" irq_tx: endtx {:?}", n); 187 //trace!(" irq_tx: endtx {:?}", n);
191 tx.pop_done(n); 188 tx.pop_done(n);
192 s.tx_waker.wake(); 189 ss.tx_waker.wake();
193 s.tx_count.store(0, Ordering::Relaxed); 190 s.tx_count.store(0, Ordering::Relaxed);
194 } 191 }
195 192
196 // If not TXing, start. 193 // If not TXing, start.
197 if s.tx_count.load(Ordering::Relaxed) == 0 { 194 if s.tx_count.load(Ordering::Relaxed) == 0 {
198 let (ptr, len) = tx.pop_buf(); 195 let (ptr, len) = tx.pop_buf();
199 if len != 0 { 196 if len != 0 {
200 //trace!(" irq_tx: starting {:?}", len); 197 //trace!(" irq_tx: starting {:?}", len);
201 s.tx_count.store(len, Ordering::Relaxed); 198 s.tx_count.store(len, Ordering::Relaxed);
202 199
203 // Set up the DMA write 200 // Set up the DMA write
204 r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); 201 r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) });
205 r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); 202 r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) });
206 203
207 // Start UARTE Transmit transaction 204 // Start UARTE Transmit transaction
208 r.tasks_starttx.write(|w| unsafe { w.bits(1) }); 205 r.tasks_starttx.write(|w| unsafe { w.bits(1) });
206 }
209 } 207 }
210 } 208 }
211 209
@@ -215,11 +213,8 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt
215 213
216/// Buffered UARTE driver. 214/// Buffered UARTE driver.
217pub struct BufferedUarte<'d, U: UarteInstance, T: TimerInstance> { 215pub struct BufferedUarte<'d, U: UarteInstance, T: TimerInstance> {
218 _peri: PeripheralRef<'d, U>, 216 tx: BufferedUarteTx<'d, U>,
219 timer: Timer<'d, T>, 217 rx: BufferedUarteRx<'d, U, T>,
220 _ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 1>,
221 _ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 2>,
222 _ppi_group: PpiGroup<'d, AnyGroup>,
223} 218}
224 219
225impl<'d, U: UarteInstance, T: TimerInstance> Unpin for BufferedUarte<'d, U, T> {} 220impl<'d, U: UarteInstance, T: TimerInstance> Unpin for BufferedUarte<'d, U, T> {}
@@ -243,7 +238,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
243 rx_buffer: &'d mut [u8], 238 rx_buffer: &'d mut [u8],
244 tx_buffer: &'d mut [u8], 239 tx_buffer: &'d mut [u8],
245 ) -> Self { 240 ) -> Self {
246 into_ref!(rxd, txd, ppi_ch1, ppi_ch2, ppi_group); 241 into_ref!(uarte, timer, rxd, txd, ppi_ch1, ppi_ch2, ppi_group);
247 Self::new_inner( 242 Self::new_inner(
248 uarte, 243 uarte,
249 timer, 244 timer,
@@ -280,7 +275,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
280 rx_buffer: &'d mut [u8], 275 rx_buffer: &'d mut [u8],
281 tx_buffer: &'d mut [u8], 276 tx_buffer: &'d mut [u8],
282 ) -> Self { 277 ) -> Self {
283 into_ref!(rxd, txd, cts, rts, ppi_ch1, ppi_ch2, ppi_group); 278 into_ref!(uarte, timer, rxd, txd, cts, rts, ppi_ch1, ppi_ch2, ppi_group);
284 Self::new_inner( 279 Self::new_inner(
285 uarte, 280 uarte,
286 timer, 281 timer,
@@ -298,8 +293,8 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
298 } 293 }
299 294
300 fn new_inner( 295 fn new_inner(
301 peri: impl Peripheral<P = U> + 'd, 296 peri: PeripheralRef<'d, U>,
302 timer: impl Peripheral<P = T> + 'd, 297 timer: PeripheralRef<'d, T>,
303 ppi_ch1: PeripheralRef<'d, AnyConfigurableChannel>, 298 ppi_ch1: PeripheralRef<'d, AnyConfigurableChannel>,
304 ppi_ch2: PeripheralRef<'d, AnyConfigurableChannel>, 299 ppi_ch2: PeripheralRef<'d, AnyConfigurableChannel>,
305 ppi_group: PeripheralRef<'d, AnyGroup>, 300 ppi_group: PeripheralRef<'d, AnyGroup>,
@@ -311,16 +306,127 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
311 rx_buffer: &'d mut [u8], 306 rx_buffer: &'d mut [u8],
312 tx_buffer: &'d mut [u8], 307 tx_buffer: &'d mut [u8],
313 ) -> Self { 308 ) -> Self {
314 into_ref!(peri, timer); 309 configure(U::regs(), config, cts.is_some());
315 310
316 assert!(rx_buffer.len() % 2 == 0); 311 let tx = BufferedUarteTx::new_innerer(unsafe { peri.clone_unchecked() }, txd, cts, tx_buffer);
312 let rx = BufferedUarteRx::new_innerer(peri, timer, ppi_ch1, ppi_ch2, ppi_group, rxd, rts, rx_buffer);
317 313
314 U::Interrupt::pend();
315 unsafe { U::Interrupt::enable() };
316
317 U::state().tx_rx_refcount.store(2, Ordering::Relaxed);
318
319 Self { tx, rx }
320 }
321
322 /// Adjust the baud rate to the provided value.
323 pub fn set_baudrate(&mut self, baudrate: Baudrate) {
318 let r = U::regs(); 324 let r = U::regs();
325 r.baudrate.write(|w| w.baudrate().variant(baudrate));
326 }
319 327
320 let hwfc = cts.is_some(); 328 /// Split the UART in reader and writer parts.
329 ///
330 /// This allows reading and writing concurrently from independent tasks.
331 pub fn split(self) -> (BufferedUarteRx<'d, U, T>, BufferedUarteTx<'d, U>) {
332 (self.rx, self.tx)
333 }
321 334
322 rxd.conf().write(|w| w.input().connect().drive().h0h1()); 335 /// Split the UART in reader and writer parts, by reference.
323 r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) }); 336 ///
337 /// The returned halves borrow from `self`, so you can drop them and go back to using
338 /// the "un-split" `self`. This allows temporarily splitting the UART.
339 pub fn split_by_ref(&mut self) -> (&mut BufferedUarteRx<'d, U, T>, &mut BufferedUarteTx<'d, U>) {
340 (&mut self.rx, &mut self.tx)
341 }
342
343 /// Pull some bytes from this source into the specified buffer, returning how many bytes were read.
344 pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
345 self.rx.read(buf).await
346 }
347
348 /// Return the contents of the internal buffer, filling it with more data from the inner reader if it is empty.
349 pub async fn fill_buf(&mut self) -> Result<&[u8], Error> {
350 self.rx.fill_buf().await
351 }
352
353 /// Tell this buffer that `amt` bytes have been consumed from the buffer, so they should no longer be returned in calls to `fill_buf`.
354 pub fn consume(&mut self, amt: usize) {
355 self.rx.consume(amt)
356 }
357
358 /// Write a buffer into this writer, returning how many bytes were written.
359 pub async fn write(&mut self, buf: &[u8]) -> Result<usize, Error> {
360 self.tx.write(buf).await
361 }
362
363 /// Flush this output stream, ensuring that all intermediately buffered contents reach their destination.
364 pub async fn flush(&mut self) -> Result<(), Error> {
365 self.tx.flush().await
366 }
367}
368
369/// Reader part of the buffered UARTE driver.
370pub struct BufferedUarteTx<'d, U: UarteInstance> {
371 _peri: PeripheralRef<'d, U>,
372}
373
374impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> {
375 /// Create a new BufferedUarteTx without hardware flow control.
376 pub fn new(
377 uarte: impl Peripheral<P = U> + 'd,
378 _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
379 txd: impl Peripheral<P = impl GpioPin> + 'd,
380 config: Config,
381 tx_buffer: &'d mut [u8],
382 ) -> Self {
383 into_ref!(uarte, txd);
384 Self::new_inner(uarte, txd.map_into(), None, config, tx_buffer)
385 }
386
387 /// Create a new BufferedUarte with hardware flow control (RTS/CTS)
388 ///
389 /// # Panics
390 ///
391 /// Panics if `rx_buffer.len()` is odd.
392 pub fn new_with_cts(
393 uarte: impl Peripheral<P = U> + 'd,
394 _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
395 txd: impl Peripheral<P = impl GpioPin> + 'd,
396 cts: impl Peripheral<P = impl GpioPin> + 'd,
397 config: Config,
398 tx_buffer: &'d mut [u8],
399 ) -> Self {
400 into_ref!(uarte, txd, cts);
401 Self::new_inner(uarte, txd.map_into(), Some(cts.map_into()), config, tx_buffer)
402 }
403
404 fn new_inner(
405 peri: PeripheralRef<'d, U>,
406 txd: PeripheralRef<'d, AnyPin>,
407 cts: Option<PeripheralRef<'d, AnyPin>>,
408 config: Config,
409 tx_buffer: &'d mut [u8],
410 ) -> Self {
411 configure(U::regs(), config, cts.is_some());
412
413 let this = Self::new_innerer(peri, txd, cts, tx_buffer);
414
415 U::Interrupt::pend();
416 unsafe { U::Interrupt::enable() };
417
418 U::state().tx_rx_refcount.store(1, Ordering::Relaxed);
419
420 this
421 }
422
423 fn new_innerer(
424 peri: PeripheralRef<'d, U>,
425 txd: PeripheralRef<'d, AnyPin>,
426 cts: Option<PeripheralRef<'d, AnyPin>>,
427 tx_buffer: &'d mut [u8],
428 ) -> Self {
429 let r = U::regs();
324 430
325 txd.set_high(); 431 txd.set_high();
326 txd.conf().write(|w| w.dir().output().drive().h0h1()); 432 txd.conf().write(|w| w.dir().output().drive().h0h1());
@@ -331,6 +437,203 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
331 } 437 }
332 r.psel.cts.write(|w| unsafe { w.bits(cts.psel_bits()) }); 438 r.psel.cts.write(|w| unsafe { w.bits(cts.psel_bits()) });
333 439
440 // Initialize state
441 let s = U::buffered_state();
442 s.tx_count.store(0, Ordering::Relaxed);
443 let len = tx_buffer.len();
444 unsafe { s.tx_buf.init(tx_buffer.as_mut_ptr(), len) };
445
446 r.events_txstarted.reset();
447
448 // Enable interrupts
449 r.intenset.write(|w| {
450 w.endtx().set();
451 w
452 });
453
454 Self { _peri: peri }
455 }
456
457 /// Write a buffer into this writer, returning how many bytes were written.
458 pub async fn write(&mut self, buf: &[u8]) -> Result<usize, Error> {
459 poll_fn(move |cx| {
460 //trace!("poll_write: {:?}", buf.len());
461 let ss = U::state();
462 let s = U::buffered_state();
463 let mut tx = unsafe { s.tx_buf.writer() };
464
465 let tx_buf = tx.push_slice();
466 if tx_buf.is_empty() {
467 //trace!("poll_write: pending");
468 ss.tx_waker.register(cx.waker());
469 return Poll::Pending;
470 }
471
472 let n = min(tx_buf.len(), buf.len());
473 tx_buf[..n].copy_from_slice(&buf[..n]);
474 tx.push_done(n);
475
476 //trace!("poll_write: queued {:?}", n);
477
478 compiler_fence(Ordering::SeqCst);
479 U::Interrupt::pend();
480
481 Poll::Ready(Ok(n))
482 })
483 .await
484 }
485
486 /// Flush this output stream, ensuring that all intermediately buffered contents reach their destination.
487 pub async fn flush(&mut self) -> Result<(), Error> {
488 poll_fn(move |cx| {
489 //trace!("poll_flush");
490 let ss = U::state();
491 let s = U::buffered_state();
492 if !s.tx_buf.is_empty() {
493 //trace!("poll_flush: pending");
494 ss.tx_waker.register(cx.waker());
495 return Poll::Pending;
496 }
497
498 Poll::Ready(Ok(()))
499 })
500 .await
501 }
502}
503
504impl<'a, U: UarteInstance> Drop for BufferedUarteTx<'a, U> {
505 fn drop(&mut self) {
506 let r = U::regs();
507
508 r.intenclr.write(|w| {
509 w.txdrdy().set_bit();
510 w.txstarted().set_bit();
511 w.txstopped().set_bit();
512 w
513 });
514 r.events_txstopped.reset();
515 r.tasks_stoptx.write(|w| unsafe { w.bits(1) });
516 while r.events_txstopped.read().bits() == 0 {}
517
518 let s = U::buffered_state();
519 unsafe { s.tx_buf.deinit() }
520
521 let s = U::state();
522 drop_tx_rx(r, s);
523 }
524}
525
526/// Reader part of the buffered UARTE driver.
527pub struct BufferedUarteRx<'d, U: UarteInstance, T: TimerInstance> {
528 _peri: PeripheralRef<'d, U>,
529 timer: Timer<'d, T>,
530 _ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 1>,
531 _ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 2>,
532 _ppi_group: PpiGroup<'d, AnyGroup>,
533}
534
535impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
536 /// Create a new BufferedUarte without hardware flow control.
537 ///
538 /// # Panics
539 ///
540 /// Panics if `rx_buffer.len()` is odd.
541 pub fn new(
542 uarte: impl Peripheral<P = U> + 'd,
543 timer: impl Peripheral<P = T> + 'd,
544 ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd,
545 ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd,
546 ppi_group: impl Peripheral<P = impl Group> + 'd,
547 _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
548 rxd: impl Peripheral<P = impl GpioPin> + 'd,
549 config: Config,
550 rx_buffer: &'d mut [u8],
551 ) -> Self {
552 into_ref!(uarte, timer, rxd, ppi_ch1, ppi_ch2, ppi_group);
553 Self::new_inner(
554 uarte,
555 timer,
556 ppi_ch1.map_into(),
557 ppi_ch2.map_into(),
558 ppi_group.map_into(),
559 rxd.map_into(),
560 None,
561 config,
562 rx_buffer,
563 )
564 }
565
566 /// Create a new BufferedUarte with hardware flow control (RTS/CTS)
567 ///
568 /// # Panics
569 ///
570 /// Panics if `rx_buffer.len()` is odd.
571 pub fn new_with_rts(
572 uarte: impl Peripheral<P = U> + 'd,
573 timer: impl Peripheral<P = T> + 'd,
574 ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd,
575 ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd,
576 ppi_group: impl Peripheral<P = impl Group> + 'd,
577 _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
578 rxd: impl Peripheral<P = impl GpioPin> + 'd,
579 rts: impl Peripheral<P = impl GpioPin> + 'd,
580 config: Config,
581 rx_buffer: &'d mut [u8],
582 ) -> Self {
583 into_ref!(uarte, timer, rxd, rts, ppi_ch1, ppi_ch2, ppi_group);
584 Self::new_inner(
585 uarte,
586 timer,
587 ppi_ch1.map_into(),
588 ppi_ch2.map_into(),
589 ppi_group.map_into(),
590 rxd.map_into(),
591 Some(rts.map_into()),
592 config,
593 rx_buffer,
594 )
595 }
596
597 fn new_inner(
598 peri: PeripheralRef<'d, U>,
599 timer: PeripheralRef<'d, T>,
600 ppi_ch1: PeripheralRef<'d, AnyConfigurableChannel>,
601 ppi_ch2: PeripheralRef<'d, AnyConfigurableChannel>,
602 ppi_group: PeripheralRef<'d, AnyGroup>,
603 rxd: PeripheralRef<'d, AnyPin>,
604 rts: Option<PeripheralRef<'d, AnyPin>>,
605 config: Config,
606 rx_buffer: &'d mut [u8],
607 ) -> Self {
608 configure(U::regs(), config, rts.is_some());
609
610 let this = Self::new_innerer(peri, timer, ppi_ch1, ppi_ch2, ppi_group, rxd, rts, rx_buffer);
611
612 U::Interrupt::pend();
613 unsafe { U::Interrupt::enable() };
614
615 U::state().tx_rx_refcount.store(1, Ordering::Relaxed);
616
617 this
618 }
619
620 fn new_innerer(
621 peri: PeripheralRef<'d, U>,
622 timer: PeripheralRef<'d, T>,
623 ppi_ch1: PeripheralRef<'d, AnyConfigurableChannel>,
624 ppi_ch2: PeripheralRef<'d, AnyConfigurableChannel>,
625 ppi_group: PeripheralRef<'d, AnyGroup>,
626 rxd: PeripheralRef<'d, AnyPin>,
627 rts: Option<PeripheralRef<'d, AnyPin>>,
628 rx_buffer: &'d mut [u8],
629 ) -> Self {
630 assert!(rx_buffer.len() % 2 == 0);
631
632 let r = U::regs();
633
634 rxd.conf().write(|w| w.input().connect().drive().h0h1());
635 r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) });
636
334 if let Some(pin) = &rts { 637 if let Some(pin) = &rts {
335 pin.set_high(); 638 pin.set_high();
336 pin.conf().write(|w| w.dir().output().drive().h0h1()); 639 pin.conf().write(|w| w.dir().output().drive().h0h1());
@@ -339,35 +642,21 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
339 642
340 // Initialize state 643 // Initialize state
341 let s = U::buffered_state(); 644 let s = U::buffered_state();
342 s.tx_count.store(0, Ordering::Relaxed);
343 s.rx_started_count.store(0, Ordering::Relaxed); 645 s.rx_started_count.store(0, Ordering::Relaxed);
344 s.rx_ended_count.store(0, Ordering::Relaxed); 646 s.rx_ended_count.store(0, Ordering::Relaxed);
345 s.rx_started.store(false, Ordering::Relaxed); 647 s.rx_started.store(false, Ordering::Relaxed);
346 let len = tx_buffer.len();
347 unsafe { s.tx_buf.init(tx_buffer.as_mut_ptr(), len) };
348 let len = rx_buffer.len(); 648 let len = rx_buffer.len();
349 unsafe { s.rx_buf.init(rx_buffer.as_mut_ptr(), len) }; 649 unsafe { s.rx_buf.init(rx_buffer.as_mut_ptr(), len) };
350 650
351 // Configure
352 r.config.write(|w| {
353 w.hwfc().bit(hwfc);
354 w.parity().variant(config.parity);
355 w
356 });
357 r.baudrate.write(|w| w.baudrate().variant(config.baudrate));
358
359 // clear errors 651 // clear errors
360 let errors = r.errorsrc.read().bits(); 652 let errors = r.errorsrc.read().bits();
361 r.errorsrc.write(|w| unsafe { w.bits(errors) }); 653 r.errorsrc.write(|w| unsafe { w.bits(errors) });
362 654
363 r.events_rxstarted.reset(); 655 r.events_rxstarted.reset();
364 r.events_txstarted.reset();
365 r.events_error.reset(); 656 r.events_error.reset();
366 r.events_endrx.reset(); 657 r.events_endrx.reset();
367 r.events_endtx.reset();
368 658
369 // Enable interrupts 659 // Enable interrupts
370 r.intenclr.write(|w| unsafe { w.bits(!0) });
371 r.intenset.write(|w| { 660 r.intenset.write(|w| {
372 w.endtx().set(); 661 w.endtx().set();
373 w.rxstarted().set(); 662 w.rxstarted().set();
@@ -376,10 +665,6 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
376 w 665 w
377 }); 666 });
378 667
379 // Enable UARTE instance
380 apply_workaround_for_enable_anomaly(r);
381 r.enable.write(|w| w.enable().enabled());
382
383 // Configure byte counter. 668 // Configure byte counter.
384 let timer = Timer::new_counter(timer); 669 let timer = Timer::new_counter(timer);
385 timer.cc(1).write(rx_buffer.len() as u32 * 2); 670 timer.cc(1).write(rx_buffer.len() as u32 * 2);
@@ -401,9 +686,6 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
401 ppi_ch2.disable(); 686 ppi_ch2.disable();
402 ppi_group.add_channel(&ppi_ch2); 687 ppi_group.add_channel(&ppi_ch2);
403 688
404 U::Interrupt::pend();
405 unsafe { U::Interrupt::enable() };
406
407 Self { 689 Self {
408 _peri: peri, 690 _peri: peri,
409 timer, 691 timer,
@@ -413,80 +695,24 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
413 } 695 }
414 } 696 }
415 697
416 fn pend_irq() { 698 /// Pull some bytes from this source into the specified buffer, returning how many bytes were read.
417 U::Interrupt::pend() 699 pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
418 } 700 let data = self.fill_buf().await?;
419
420 /// Adjust the baud rate to the provided value.
421 pub fn set_baudrate(&mut self, baudrate: Baudrate) {
422 let r = U::regs();
423 r.baudrate.write(|w| w.baudrate().variant(baudrate));
424 }
425
426 /// Split the UART in reader and writer parts.
427 ///
428 /// This allows reading and writing concurrently from independent tasks.
429 pub fn split<'u>(&'u mut self) -> (BufferedUarteRx<'u, 'd, U, T>, BufferedUarteTx<'u, 'd, U, T>) {
430 (BufferedUarteRx { inner: self }, BufferedUarteTx { inner: self })
431 }
432
433 async fn inner_read(&self, buf: &mut [u8]) -> Result<usize, Error> {
434 let data = self.inner_fill_buf().await?;
435 let n = data.len().min(buf.len()); 701 let n = data.len().min(buf.len());
436 buf[..n].copy_from_slice(&data[..n]); 702 buf[..n].copy_from_slice(&data[..n]);
437 self.inner_consume(n); 703 self.consume(n);
438 Ok(n) 704 Ok(n)
439 } 705 }
440 706
441 async fn inner_write<'a>(&'a self, buf: &'a [u8]) -> Result<usize, Error> { 707 /// Return the contents of the internal buffer, filling it with more data from the inner reader if it is empty.
442 poll_fn(move |cx| { 708 pub async fn fill_buf(&mut self) -> Result<&[u8], Error> {
443 //trace!("poll_write: {:?}", buf.len());
444 let s = U::buffered_state();
445 let mut tx = unsafe { s.tx_buf.writer() };
446
447 let tx_buf = tx.push_slice();
448 if tx_buf.is_empty() {
449 //trace!("poll_write: pending");
450 s.tx_waker.register(cx.waker());
451 return Poll::Pending;
452 }
453
454 let n = min(tx_buf.len(), buf.len());
455 tx_buf[..n].copy_from_slice(&buf[..n]);
456 tx.push_done(n);
457
458 //trace!("poll_write: queued {:?}", n);
459
460 compiler_fence(Ordering::SeqCst);
461 Self::pend_irq();
462
463 Poll::Ready(Ok(n))
464 })
465 .await
466 }
467
468 async fn inner_flush<'a>(&'a self) -> Result<(), Error> {
469 poll_fn(move |cx| {
470 //trace!("poll_flush");
471 let s = U::buffered_state();
472 if !s.tx_buf.is_empty() {
473 //trace!("poll_flush: pending");
474 s.tx_waker.register(cx.waker());
475 return Poll::Pending;
476 }
477
478 Poll::Ready(Ok(()))
479 })
480 .await
481 }
482
483 async fn inner_fill_buf<'a>(&'a self) -> Result<&'a [u8], Error> {
484 poll_fn(move |cx| { 709 poll_fn(move |cx| {
485 compiler_fence(Ordering::SeqCst); 710 compiler_fence(Ordering::SeqCst);
486 //trace!("poll_read"); 711 //trace!("poll_read");
487 712
488 let r = U::regs(); 713 let r = U::regs();
489 let s = U::buffered_state(); 714 let s = U::buffered_state();
715 let ss = U::state();
490 716
491 // Read the RXDRDY counter. 717 // Read the RXDRDY counter.
492 T::regs().tasks_capture[0].write(|w| unsafe { w.bits(1) }); 718 T::regs().tasks_capture[0].write(|w| unsafe { w.bits(1) });
@@ -510,7 +736,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
510 let len = s.rx_buf.len(); 736 let len = s.rx_buf.len();
511 if start == end { 737 if start == end {
512 //trace!(" empty"); 738 //trace!(" empty");
513 s.rx_waker.register(cx.waker()); 739 ss.rx_waker.register(cx.waker());
514 r.intenset.write(|w| w.rxdrdy().set_bit()); 740 r.intenset.write(|w| w.rxdrdy().set_bit());
515 return Poll::Pending; 741 return Poll::Pending;
516 } 742 }
@@ -532,7 +758,8 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
532 .await 758 .await
533 } 759 }
534 760
535 fn inner_consume(&self, amt: usize) { 761 /// Tell this buffer that `amt` bytes have been consumed from the buffer, so they should no longer be returned in calls to `fill_buf`.
762 pub fn consume(&mut self, amt: usize) {
536 if amt == 0 { 763 if amt == 0 {
537 return; 764 return;
538 } 765 }
@@ -542,69 +769,31 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
542 rx.pop_done(amt); 769 rx.pop_done(amt);
543 U::regs().intenset.write(|w| w.rxstarted().set()); 770 U::regs().intenset.write(|w| w.rxstarted().set());
544 } 771 }
545
546 /// Pull some bytes from this source into the specified buffer, returning how many bytes were read.
547 pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
548 self.inner_read(buf).await
549 }
550
551 /// Return the contents of the internal buffer, filling it with more data from the inner reader if it is empty.
552 pub async fn fill_buf(&mut self) -> Result<&[u8], Error> {
553 self.inner_fill_buf().await
554 }
555
556 /// Tell this buffer that `amt` bytes have been consumed from the buffer, so they should no longer be returned in calls to `fill_buf`.
557 pub fn consume(&mut self, amt: usize) {
558 self.inner_consume(amt)
559 }
560
561 /// Write a buffer into this writer, returning how many bytes were written.
562 pub async fn write(&mut self, buf: &[u8]) -> Result<usize, Error> {
563 self.inner_write(buf).await
564 }
565
566 /// Flush this output stream, ensuring that all intermediately buffered contents reach their destination.
567 pub async fn flush(&mut self) -> Result<(), Error> {
568 self.inner_flush().await
569 }
570} 772}
571 773
572/// Reader part of the buffered UARTE driver. 774impl<'a, U: UarteInstance, T: TimerInstance> Drop for BufferedUarteRx<'a, U, T> {
573pub struct BufferedUarteTx<'u, 'd, U: UarteInstance, T: TimerInstance> { 775 fn drop(&mut self) {
574 inner: &'u BufferedUarte<'d, U, T>, 776 self._ppi_group.disable_all();
575}
576
577impl<'u, 'd, U: UarteInstance, T: TimerInstance> BufferedUarteTx<'u, 'd, U, T> {
578 /// Write a buffer into this writer, returning how many bytes were written.
579 pub async fn write(&mut self, buf: &[u8]) -> Result<usize, Error> {
580 self.inner.inner_write(buf).await
581 }
582 777
583 /// Flush this output stream, ensuring that all intermediately buffered contents reach their destination. 778 let r = U::regs();
584 pub async fn flush(&mut self) -> Result<(), Error> {
585 self.inner.inner_flush().await
586 }
587}
588 779
589/// Writer part of the buffered UARTE driver. 780 self.timer.stop();
590pub struct BufferedUarteRx<'u, 'd, U: UarteInstance, T: TimerInstance> {
591 inner: &'u BufferedUarte<'d, U, T>,
592}
593 781
594impl<'u, 'd, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'u, 'd, U, T> { 782 r.intenclr.write(|w| {
595 /// Pull some bytes from this source into the specified buffer, returning how many bytes were read. 783 w.rxdrdy().set_bit();
596 pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { 784 w.rxstarted().set_bit();
597 self.inner.inner_read(buf).await 785 w.rxto().set_bit();
598 } 786 w
787 });
788 r.events_rxto.reset();
789 r.tasks_stoprx.write(|w| unsafe { w.bits(1) });
790 while r.events_rxto.read().bits() == 0 {}
599 791
600 /// Return the contents of the internal buffer, filling it with more data from the inner reader if it is empty. 792 let s = U::buffered_state();
601 pub async fn fill_buf(&mut self) -> Result<&[u8], Error> { 793 unsafe { s.rx_buf.deinit() }
602 self.inner.inner_fill_buf().await
603 }
604 794
605 /// Tell this buffer that `amt` bytes have been consumed from the buffer, so they should no longer be returned in calls to `fill_buf`. 795 let s = U::state();
606 pub fn consume(&mut self, amt: usize) { 796 drop_tx_rx(r, s);
607 self.inner.inner_consume(amt)
608 } 797 }
609} 798}
610 799
@@ -621,95 +810,63 @@ mod _embedded_io {
621 type Error = Error; 810 type Error = Error;
622 } 811 }
623 812
624 impl<'u, 'd, U: UarteInstance, T: TimerInstance> embedded_io_async::ErrorType for BufferedUarteRx<'u, 'd, U, T> { 813 impl<'d, U: UarteInstance, T: TimerInstance> embedded_io_async::ErrorType for BufferedUarteRx<'d, U, T> {
625 type Error = Error; 814 type Error = Error;
626 } 815 }
627 816
628 impl<'u, 'd, U: UarteInstance, T: TimerInstance> embedded_io_async::ErrorType for BufferedUarteTx<'u, 'd, U, T> { 817 impl<'d, U: UarteInstance> embedded_io_async::ErrorType for BufferedUarteTx<'d, U> {
629 type Error = Error; 818 type Error = Error;
630 } 819 }
631 820
632 impl<'d, U: UarteInstance, T: TimerInstance> embedded_io_async::Read for BufferedUarte<'d, U, T> { 821 impl<'d, U: UarteInstance, T: TimerInstance> embedded_io_async::Read for BufferedUarte<'d, U, T> {
633 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { 822 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
634 self.inner_read(buf).await 823 self.read(buf).await
635 } 824 }
636 } 825 }
637 826
638 impl<'u, 'd: 'u, U: UarteInstance, T: TimerInstance> embedded_io_async::Read for BufferedUarteRx<'u, 'd, U, T> { 827 impl<'d: 'd, U: UarteInstance, T: TimerInstance> embedded_io_async::Read for BufferedUarteRx<'d, U, T> {
639 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { 828 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
640 self.inner.inner_read(buf).await 829 self.read(buf).await
641 } 830 }
642 } 831 }
643 832
644 impl<'d, U: UarteInstance, T: TimerInstance> embedded_io_async::BufRead for BufferedUarte<'d, U, T> { 833 impl<'d, U: UarteInstance, T: TimerInstance> embedded_io_async::BufRead for BufferedUarte<'d, U, T> {
645 async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { 834 async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
646 self.inner_fill_buf().await 835 self.fill_buf().await
647 } 836 }
648 837
649 fn consume(&mut self, amt: usize) { 838 fn consume(&mut self, amt: usize) {
650 self.inner_consume(amt) 839 self.consume(amt)
651 } 840 }
652 } 841 }
653 842
654 impl<'u, 'd: 'u, U: UarteInstance, T: TimerInstance> embedded_io_async::BufRead for BufferedUarteRx<'u, 'd, U, T> { 843 impl<'d: 'd, U: UarteInstance, T: TimerInstance> embedded_io_async::BufRead for BufferedUarteRx<'d, U, T> {
655 async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { 844 async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
656 self.inner.inner_fill_buf().await 845 self.fill_buf().await
657 } 846 }
658 847
659 fn consume(&mut self, amt: usize) { 848 fn consume(&mut self, amt: usize) {
660 self.inner.inner_consume(amt) 849 self.consume(amt)
661 } 850 }
662 } 851 }
663 852
664 impl<'d, U: UarteInstance, T: TimerInstance> embedded_io_async::Write for BufferedUarte<'d, U, T> { 853 impl<'d, U: UarteInstance, T: TimerInstance> embedded_io_async::Write for BufferedUarte<'d, U, T> {
665 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { 854 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
666 self.inner_write(buf).await 855 self.write(buf).await
667 } 856 }
668 857
669 async fn flush(&mut self) -> Result<(), Self::Error> { 858 async fn flush(&mut self) -> Result<(), Self::Error> {
670 self.inner_flush().await 859 self.flush().await
671 } 860 }
672 } 861 }
673 862
674 impl<'u, 'd: 'u, U: UarteInstance, T: TimerInstance> embedded_io_async::Write for BufferedUarteTx<'u, 'd, U, T> { 863 impl<'d: 'd, U: UarteInstance> embedded_io_async::Write for BufferedUarteTx<'d, U> {
675 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { 864 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
676 self.inner.inner_write(buf).await 865 self.write(buf).await
677 } 866 }
678 867
679 async fn flush(&mut self) -> Result<(), Self::Error> { 868 async fn flush(&mut self) -> Result<(), Self::Error> {
680 self.inner.inner_flush().await 869 self.flush().await
681 }
682 }
683}
684
685impl<'a, U: UarteInstance, T: TimerInstance> Drop for BufferedUarte<'a, U, T> {
686 fn drop(&mut self) {
687 self._ppi_group.disable_all();
688
689 let r = U::regs();
690
691 self.timer.stop();
692
693 r.inten.reset();
694 r.events_rxto.reset();
695 r.tasks_stoprx.write(|w| unsafe { w.bits(1) });
696 r.events_txstopped.reset();
697 r.tasks_stoptx.write(|w| unsafe { w.bits(1) });
698
699 while r.events_txstopped.read().bits() == 0 {}
700 while r.events_rxto.read().bits() == 0 {}
701
702 r.enable.write(|w| w.enable().disabled());
703
704 gpio::deconfigure_pin(r.psel.rxd.read().bits());
705 gpio::deconfigure_pin(r.psel.txd.read().bits());
706 gpio::deconfigure_pin(r.psel.rts.read().bits());
707 gpio::deconfigure_pin(r.psel.cts.read().bits());
708
709 let s = U::buffered_state();
710 unsafe {
711 s.rx_buf.deinit();
712 s.tx_buf.deinit();
713 } 870 }
714 } 871 }
715} 872}
diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs
index b2f987109..3649ea61a 100644
--- a/embassy-nrf/src/gpio.rs
+++ b/embassy-nrf/src/gpio.rs
@@ -189,7 +189,7 @@ impl<'d> Output<'d> {
189 } 189 }
190} 190}
191 191
192fn convert_drive(drive: OutputDrive) -> DRIVE_A { 192pub(crate) fn convert_drive(drive: OutputDrive) -> DRIVE_A {
193 match drive { 193 match drive {
194 OutputDrive::Standard => DRIVE_A::S0S1, 194 OutputDrive::Standard => DRIVE_A::S0S1,
195 OutputDrive::HighDrive0Standard1 => DRIVE_A::H0S1, 195 OutputDrive::HighDrive0Standard1 => DRIVE_A::H0S1,
diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs
index 2d70732a8..3538afa2b 100644
--- a/embassy-nrf/src/spim.rs
+++ b/embassy-nrf/src/spim.rs
@@ -15,7 +15,7 @@ pub use pac::spim0::frequency::FREQUENCY_A as Frequency;
15 15
16use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; 16use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE};
17use crate::gpio::sealed::Pin as _; 17use crate::gpio::sealed::Pin as _;
18use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits}; 18use crate::gpio::{self, convert_drive, AnyPin, OutputDrive, Pin as GpioPin, PselBits};
19use crate::interrupt::typelevel::Interrupt; 19use crate::interrupt::typelevel::Interrupt;
20use crate::util::{slice_in_ram_or, slice_ptr_len, slice_ptr_parts, slice_ptr_parts_mut}; 20use crate::util::{slice_in_ram_or, slice_ptr_len, slice_ptr_parts, slice_ptr_parts_mut};
21use crate::{interrupt, pac, Peripheral}; 21use crate::{interrupt, pac, Peripheral};
@@ -46,6 +46,15 @@ pub struct Config {
46 /// When doing bidirectional transfers, if the TX buffer is shorter than the RX buffer, 46 /// When doing bidirectional transfers, if the TX buffer is shorter than the RX buffer,
47 /// this byte will be transmitted in the MOSI line for the left-over bytes. 47 /// this byte will be transmitted in the MOSI line for the left-over bytes.
48 pub orc: u8, 48 pub orc: u8,
49
50 /// Drive strength for the SCK line.
51 pub sck_drive: OutputDrive,
52
53 /// Drive strength for the MOSI line.
54 pub mosi_drive: OutputDrive,
55
56 /// Drive strength for the MISO line.
57 pub miso_drive: OutputDrive,
49} 58}
50 59
51impl Default for Config { 60impl Default for Config {
@@ -55,6 +64,9 @@ impl Default for Config {
55 mode: MODE_0, 64 mode: MODE_0,
56 bit_order: BitOrder::MSB_FIRST, 65 bit_order: BitOrder::MSB_FIRST,
57 orc: 0x00, 66 orc: 0x00,
67 sck_drive: OutputDrive::HighDrive,
68 mosi_drive: OutputDrive::HighDrive,
69 miso_drive: OutputDrive::HighDrive,
58 } 70 }
59 } 71 }
60} 72}
@@ -159,13 +171,16 @@ impl<'d, T: Instance> Spim<'d, T> {
159 171
160 // Configure pins 172 // Configure pins
161 if let Some(sck) = &sck { 173 if let Some(sck) = &sck {
162 sck.conf().write(|w| w.dir().output().drive().h0h1()); 174 sck.conf()
175 .write(|w| w.dir().output().drive().variant(convert_drive(config.sck_drive)));
163 } 176 }
164 if let Some(mosi) = &mosi { 177 if let Some(mosi) = &mosi {
165 mosi.conf().write(|w| w.dir().output().drive().h0h1()); 178 mosi.conf()
179 .write(|w| w.dir().output().drive().variant(convert_drive(config.mosi_drive)));
166 } 180 }
167 if let Some(miso) = &miso { 181 if let Some(miso) = &miso {
168 miso.conf().write(|w| w.input().connect().drive().h0h1()); 182 miso.conf()
183 .write(|w| w.input().connect().drive().variant(convert_drive(config.miso_drive)));
169 } 184 }
170 185
171 match config.mode.polarity { 186 match config.mode.polarity {
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs
index 9e5b85dea..cbd5dccbc 100644
--- a/embassy-nrf/src/uarte.rs
+++ b/embassy-nrf/src/uarte.rs
@@ -115,7 +115,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
115 let endrx = r.events_endrx.read().bits(); 115 let endrx = r.events_endrx.read().bits();
116 let error = r.events_error.read().bits(); 116 let error = r.events_error.read().bits();
117 if endrx != 0 || error != 0 { 117 if endrx != 0 || error != 0 {
118 s.endrx_waker.wake(); 118 s.rx_waker.wake();
119 if endrx != 0 { 119 if endrx != 0 {
120 r.intenclr.write(|w| w.endrx().clear()); 120 r.intenclr.write(|w| w.endrx().clear());
121 } 121 }
@@ -124,7 +124,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
124 } 124 }
125 } 125 }
126 if r.events_endtx.read().bits() != 0 { 126 if r.events_endtx.read().bits() != 0 {
127 s.endtx_waker.wake(); 127 s.tx_waker.wake();
128 r.intenclr.write(|w| w.endtx().clear()); 128 r.intenclr.write(|w| w.endtx().clear());
129 } 129 }
130 } 130 }
@@ -159,7 +159,7 @@ impl<'d, T: Instance> Uarte<'d, T> {
159 txd: impl Peripheral<P = impl GpioPin> + 'd, 159 txd: impl Peripheral<P = impl GpioPin> + 'd,
160 config: Config, 160 config: Config,
161 ) -> Self { 161 ) -> Self {
162 into_ref!(rxd, txd); 162 into_ref!(uarte, rxd, txd);
163 Self::new_inner(uarte, rxd.map_into(), txd.map_into(), None, None, config) 163 Self::new_inner(uarte, rxd.map_into(), txd.map_into(), None, None, config)
164 } 164 }
165 165
@@ -173,7 +173,7 @@ impl<'d, T: Instance> Uarte<'d, T> {
173 rts: impl Peripheral<P = impl GpioPin> + 'd, 173 rts: impl Peripheral<P = impl GpioPin> + 'd,
174 config: Config, 174 config: Config,
175 ) -> Self { 175 ) -> Self {
176 into_ref!(rxd, txd, cts, rts); 176 into_ref!(uarte, rxd, txd, cts, rts);
177 Self::new_inner( 177 Self::new_inner(
178 uarte, 178 uarte,
179 rxd.map_into(), 179 rxd.map_into(),
@@ -185,17 +185,22 @@ impl<'d, T: Instance> Uarte<'d, T> {
185 } 185 }
186 186
187 fn new_inner( 187 fn new_inner(
188 uarte: impl Peripheral<P = T> + 'd, 188 uarte: PeripheralRef<'d, T>,
189 rxd: PeripheralRef<'d, AnyPin>, 189 rxd: PeripheralRef<'d, AnyPin>,
190 txd: PeripheralRef<'d, AnyPin>, 190 txd: PeripheralRef<'d, AnyPin>,
191 cts: Option<PeripheralRef<'d, AnyPin>>, 191 cts: Option<PeripheralRef<'d, AnyPin>>,
192 rts: Option<PeripheralRef<'d, AnyPin>>, 192 rts: Option<PeripheralRef<'d, AnyPin>>,
193 config: Config, 193 config: Config,
194 ) -> Self { 194 ) -> Self {
195 into_ref!(uarte);
196
197 let r = T::regs(); 195 let r = T::regs();
198 196
197 let hardware_flow_control = match (rts.is_some(), cts.is_some()) {
198 (false, false) => false,
199 (true, true) => true,
200 _ => panic!("RTS and CTS pins must be either both set or none set."),
201 };
202 configure(r, config, hardware_flow_control);
203
199 rxd.conf().write(|w| w.input().connect().drive().h0h1()); 204 rxd.conf().write(|w| w.input().connect().drive().h0h1());
200 r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) }); 205 r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) });
201 206
@@ -217,13 +222,6 @@ impl<'d, T: Instance> Uarte<'d, T> {
217 T::Interrupt::unpend(); 222 T::Interrupt::unpend();
218 unsafe { T::Interrupt::enable() }; 223 unsafe { T::Interrupt::enable() };
219 224
220 let hardware_flow_control = match (rts.is_some(), cts.is_some()) {
221 (false, false) => false,
222 (true, true) => true,
223 _ => panic!("RTS and CTS pins must be either both set or none set."),
224 };
225 configure(r, config, hardware_flow_control);
226
227 let s = T::state(); 225 let s = T::state();
228 s.tx_rx_refcount.store(2, Ordering::Relaxed); 226 s.tx_rx_refcount.store(2, Ordering::Relaxed);
229 227
@@ -242,6 +240,14 @@ impl<'d, T: Instance> Uarte<'d, T> {
242 (self.tx, self.rx) 240 (self.tx, self.rx)
243 } 241 }
244 242
243 /// Split the UART in reader and writer parts, by reference.
244 ///
245 /// The returned halves borrow from `self`, so you can drop them and go back to using
246 /// the "un-split" `self`. This allows temporarily splitting the UART.
247 pub fn split_by_ref(&mut self) -> (&mut UarteTx<'d, T>, &mut UarteRx<'d, T>) {
248 (&mut self.tx, &mut self.rx)
249 }
250
245 /// Split the Uarte into the transmitter and receiver with idle support parts. 251 /// Split the Uarte into the transmitter and receiver with idle support parts.
246 /// 252 ///
247 /// This is useful to concurrently transmit and receive from independent tasks. 253 /// This is useful to concurrently transmit and receive from independent tasks.
@@ -291,7 +297,7 @@ impl<'d, T: Instance> Uarte<'d, T> {
291 } 297 }
292} 298}
293 299
294fn configure(r: &RegisterBlock, config: Config, hardware_flow_control: bool) { 300pub(crate) fn configure(r: &RegisterBlock, config: Config, hardware_flow_control: bool) {
295 r.config.write(|w| { 301 r.config.write(|w| {
296 w.hwfc().bit(hardware_flow_control); 302 w.hwfc().bit(hardware_flow_control);
297 w.parity().variant(config.parity); 303 w.parity().variant(config.parity);
@@ -307,6 +313,12 @@ fn configure(r: &RegisterBlock, config: Config, hardware_flow_control: bool) {
307 r.events_rxstarted.reset(); 313 r.events_rxstarted.reset();
308 r.events_txstarted.reset(); 314 r.events_txstarted.reset();
309 315
316 // reset all pins
317 r.psel.txd.write(|w| w.connect().disconnected());
318 r.psel.rxd.write(|w| w.connect().disconnected());
319 r.psel.cts.write(|w| w.connect().disconnected());
320 r.psel.rts.write(|w| w.connect().disconnected());
321
310 // Enable 322 // Enable
311 apply_workaround_for_enable_anomaly(r); 323 apply_workaround_for_enable_anomaly(r);
312 r.enable.write(|w| w.enable().enabled()); 324 r.enable.write(|w| w.enable().enabled());
@@ -320,7 +332,7 @@ impl<'d, T: Instance> UarteTx<'d, T> {
320 txd: impl Peripheral<P = impl GpioPin> + 'd, 332 txd: impl Peripheral<P = impl GpioPin> + 'd,
321 config: Config, 333 config: Config,
322 ) -> Self { 334 ) -> Self {
323 into_ref!(txd); 335 into_ref!(uarte, txd);
324 Self::new_inner(uarte, txd.map_into(), None, config) 336 Self::new_inner(uarte, txd.map_into(), None, config)
325 } 337 }
326 338
@@ -332,20 +344,20 @@ impl<'d, T: Instance> UarteTx<'d, T> {
332 cts: impl Peripheral<P = impl GpioPin> + 'd, 344 cts: impl Peripheral<P = impl GpioPin> + 'd,
333 config: Config, 345 config: Config,
334 ) -> Self { 346 ) -> Self {
335 into_ref!(txd, cts); 347 into_ref!(uarte, txd, cts);
336 Self::new_inner(uarte, txd.map_into(), Some(cts.map_into()), config) 348 Self::new_inner(uarte, txd.map_into(), Some(cts.map_into()), config)
337 } 349 }
338 350
339 fn new_inner( 351 fn new_inner(
340 uarte: impl Peripheral<P = T> + 'd, 352 uarte: PeripheralRef<'d, T>,
341 txd: PeripheralRef<'d, AnyPin>, 353 txd: PeripheralRef<'d, AnyPin>,
342 cts: Option<PeripheralRef<'d, AnyPin>>, 354 cts: Option<PeripheralRef<'d, AnyPin>>,
343 config: Config, 355 config: Config,
344 ) -> Self { 356 ) -> Self {
345 into_ref!(uarte);
346
347 let r = T::regs(); 357 let r = T::regs();
348 358
359 configure(r, config, cts.is_some());
360
349 txd.set_high(); 361 txd.set_high();
350 txd.conf().write(|w| w.dir().output().drive().s0s1()); 362 txd.conf().write(|w| w.dir().output().drive().s0s1());
351 r.psel.txd.write(|w| unsafe { w.bits(txd.psel_bits()) }); 363 r.psel.txd.write(|w| unsafe { w.bits(txd.psel_bits()) });
@@ -355,12 +367,6 @@ impl<'d, T: Instance> UarteTx<'d, T> {
355 } 367 }
356 r.psel.cts.write(|w| unsafe { w.bits(cts.psel_bits()) }); 368 r.psel.cts.write(|w| unsafe { w.bits(cts.psel_bits()) });
357 369
358 r.psel.rxd.write(|w| w.connect().disconnected());
359 r.psel.rts.write(|w| w.connect().disconnected());
360
361 let hardware_flow_control = cts.is_some();
362 configure(r, config, hardware_flow_control);
363
364 T::Interrupt::unpend(); 370 T::Interrupt::unpend();
365 unsafe { T::Interrupt::enable() }; 371 unsafe { T::Interrupt::enable() };
366 372
@@ -425,7 +431,7 @@ impl<'d, T: Instance> UarteTx<'d, T> {
425 r.tasks_starttx.write(|w| unsafe { w.bits(1) }); 431 r.tasks_starttx.write(|w| unsafe { w.bits(1) });
426 432
427 poll_fn(|cx| { 433 poll_fn(|cx| {
428 s.endtx_waker.register(cx.waker()); 434 s.tx_waker.register(cx.waker());
429 if r.events_endtx.read().bits() != 0 { 435 if r.events_endtx.read().bits() != 0 {
430 return Poll::Ready(()); 436 return Poll::Ready(());
431 } 437 }
@@ -516,7 +522,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
516 rxd: impl Peripheral<P = impl GpioPin> + 'd, 522 rxd: impl Peripheral<P = impl GpioPin> + 'd,
517 config: Config, 523 config: Config,
518 ) -> Self { 524 ) -> Self {
519 into_ref!(rxd); 525 into_ref!(uarte, rxd);
520 Self::new_inner(uarte, rxd.map_into(), None, config) 526 Self::new_inner(uarte, rxd.map_into(), None, config)
521 } 527 }
522 528
@@ -528,7 +534,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
528 rts: impl Peripheral<P = impl GpioPin> + 'd, 534 rts: impl Peripheral<P = impl GpioPin> + 'd,
529 config: Config, 535 config: Config,
530 ) -> Self { 536 ) -> Self {
531 into_ref!(rxd, rts); 537 into_ref!(uarte, rxd, rts);
532 Self::new_inner(uarte, rxd.map_into(), Some(rts.map_into()), config) 538 Self::new_inner(uarte, rxd.map_into(), Some(rts.map_into()), config)
533 } 539 }
534 540
@@ -541,15 +547,15 @@ impl<'d, T: Instance> UarteRx<'d, T> {
541 } 547 }
542 548
543 fn new_inner( 549 fn new_inner(
544 uarte: impl Peripheral<P = T> + 'd, 550 uarte: PeripheralRef<'d, T>,
545 rxd: PeripheralRef<'d, AnyPin>, 551 rxd: PeripheralRef<'d, AnyPin>,
546 rts: Option<PeripheralRef<'d, AnyPin>>, 552 rts: Option<PeripheralRef<'d, AnyPin>>,
547 config: Config, 553 config: Config,
548 ) -> Self { 554 ) -> Self {
549 into_ref!(uarte);
550
551 let r = T::regs(); 555 let r = T::regs();
552 556
557 configure(r, config, rts.is_some());
558
553 rxd.conf().write(|w| w.input().connect().drive().h0h1()); 559 rxd.conf().write(|w| w.input().connect().drive().h0h1());
554 r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) }); 560 r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) });
555 561
@@ -559,15 +565,9 @@ impl<'d, T: Instance> UarteRx<'d, T> {
559 } 565 }
560 r.psel.rts.write(|w| unsafe { w.bits(rts.psel_bits()) }); 566 r.psel.rts.write(|w| unsafe { w.bits(rts.psel_bits()) });
561 567
562 r.psel.txd.write(|w| w.connect().disconnected());
563 r.psel.cts.write(|w| w.connect().disconnected());
564
565 T::Interrupt::unpend(); 568 T::Interrupt::unpend();
566 unsafe { T::Interrupt::enable() }; 569 unsafe { T::Interrupt::enable() };
567 570
568 let hardware_flow_control = rts.is_some();
569 configure(r, config, hardware_flow_control);
570
571 let s = T::state(); 571 let s = T::state();
572 s.tx_rx_refcount.store(1, Ordering::Relaxed); 572 s.tx_rx_refcount.store(1, Ordering::Relaxed);
573 573
@@ -672,7 +672,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
672 r.tasks_startrx.write(|w| unsafe { w.bits(1) }); 672 r.tasks_startrx.write(|w| unsafe { w.bits(1) });
673 673
674 let result = poll_fn(|cx| { 674 let result = poll_fn(|cx| {
675 s.endrx_waker.register(cx.waker()); 675 s.rx_waker.register(cx.waker());
676 676
677 if let Err(e) = self.check_and_clear_errors() { 677 if let Err(e) = self.check_and_clear_errors() {
678 r.tasks_stoprx.write(|w| unsafe { w.bits(1) }); 678 r.tasks_stoprx.write(|w| unsafe { w.bits(1) });
@@ -819,7 +819,7 @@ impl<'d, T: Instance, U: TimerInstance> UarteRxWithIdle<'d, T, U> {
819 r.tasks_startrx.write(|w| unsafe { w.bits(1) }); 819 r.tasks_startrx.write(|w| unsafe { w.bits(1) });
820 820
821 let result = poll_fn(|cx| { 821 let result = poll_fn(|cx| {
822 s.endrx_waker.register(cx.waker()); 822 s.rx_waker.register(cx.waker());
823 823
824 if let Err(e) = self.rx.check_and_clear_errors() { 824 if let Err(e) = self.rx.check_and_clear_errors() {
825 r.tasks_stoprx.write(|w| unsafe { w.bits(1) }); 825 r.tasks_stoprx.write(|w| unsafe { w.bits(1) });
@@ -962,15 +962,15 @@ pub(crate) mod sealed {
962 use super::*; 962 use super::*;
963 963
964 pub struct State { 964 pub struct State {
965 pub endrx_waker: AtomicWaker, 965 pub rx_waker: AtomicWaker,
966 pub endtx_waker: AtomicWaker, 966 pub tx_waker: AtomicWaker,
967 pub tx_rx_refcount: AtomicU8, 967 pub tx_rx_refcount: AtomicU8,
968 } 968 }
969 impl State { 969 impl State {
970 pub const fn new() -> Self { 970 pub const fn new() -> Self {
971 Self { 971 Self {
972 endrx_waker: AtomicWaker::new(), 972 rx_waker: AtomicWaker::new(),
973 endtx_waker: AtomicWaker::new(), 973 tx_waker: AtomicWaker::new(),
974 tx_rx_refcount: AtomicU8::new(0), 974 tx_rx_refcount: AtomicU8::new(0),
975 } 975 }
976 } 976 }