aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf/src/uarte.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-nrf/src/uarte.rs')
-rw-r--r--embassy-nrf/src/uarte.rs88
1 files changed, 44 insertions, 44 deletions
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 }