aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf/src/buffered_uarte.rs
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-10-24 13:31:53 +0200
committerDario Nieuwenhuis <[email protected]>2024-11-04 00:47:31 +0100
commit51f6b813e1a4311ffb4adf2e66ed3effb990d246 (patch)
tree66a175cc893b00dcd56bcaff0e6b90b4d0753732 /embassy-nrf/src/buffered_uarte.rs
parent650f97924ab540d3232b187cbde73d7a0104f734 (diff)
nrf: port to chiptool-based `nrf-pac`.
Diffstat (limited to 'embassy-nrf/src/buffered_uarte.rs')
-rw-r--r--embassy-nrf/src/buffered_uarte.rs157
1 files changed, 70 insertions, 87 deletions
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs
index 6d39597c6..b55e70a36 100644
--- a/embassy-nrf/src/buffered_uarte.rs
+++ b/embassy-nrf/src/buffered_uarte.rs
@@ -17,16 +17,17 @@ 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 pac::uarte::vals;
20// Re-export SVD variants to allow user to directly set values 21// Re-export SVD variants to allow user to directly set values
21pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; 22pub use pac::uarte::vals::{Baudrate, ConfigParity as Parity};
22 23
23use crate::gpio::{AnyPin, Pin as GpioPin, PselBits, SealedPin}; 24use crate::gpio::{AnyPin, Pin as GpioPin};
24use crate::interrupt::typelevel::Interrupt; 25use crate::interrupt::typelevel::Interrupt;
25use crate::ppi::{ 26use crate::ppi::{
26 self, AnyConfigurableChannel, AnyGroup, Channel, ConfigurableChannel, Event, Group, Ppi, PpiGroup, Task, 27 self, AnyConfigurableChannel, AnyGroup, Channel, ConfigurableChannel, Event, Group, Ppi, PpiGroup, Task,
27}; 28};
28use crate::timer::{Instance as TimerInstance, Timer}; 29use crate::timer::{Instance as TimerInstance, Timer};
29use crate::uarte::{configure, drop_tx_rx, Config, Instance as UarteInstance}; 30use crate::uarte::{configure, configure_rx_pins, configure_tx_pins, drop_tx_rx, Config, Instance as UarteInstance};
30use crate::{interrupt, pac, Peripheral, EASY_DMA_SIZE}; 31use crate::{interrupt, pac, Peripheral, EASY_DMA_SIZE};
31 32
32pub(crate) struct State { 33pub(crate) struct State {
@@ -79,57 +80,57 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt
79 let buf_len = s.rx_buf.len(); 80 let buf_len = s.rx_buf.len();
80 let half_len = buf_len / 2; 81 let half_len = buf_len / 2;
81 82
82 if r.events_error.read().bits() != 0 { 83 if r.events_error().read() != 0 {
83 r.events_error.reset(); 84 r.events_error().write_value(0);
84 let errs = r.errorsrc.read(); 85 let errs = r.errorsrc().read();
85 r.errorsrc.write(|w| unsafe { w.bits(errs.bits()) }); 86 r.errorsrc().write_value(errs);
86 87
87 if errs.overrun().bit() { 88 if errs.overrun() {
88 panic!("BufferedUarte overrun"); 89 panic!("BufferedUarte overrun");
89 } 90 }
90 } 91 }
91 92
92 // Received some bytes, wake task. 93 // Received some bytes, wake task.
93 if r.inten.read().rxdrdy().bit_is_set() && r.events_rxdrdy.read().bits() != 0 { 94 if r.inten().read().rxdrdy() && r.events_rxdrdy().read() != 0 {
94 r.intenclr.write(|w| w.rxdrdy().clear()); 95 r.intenclr().write(|w| w.set_rxdrdy(true));
95 r.events_rxdrdy.reset(); 96 r.events_rxdrdy().write_value(0);
96 ss.rx_waker.wake(); 97 ss.rx_waker.wake();
97 } 98 }
98 99
99 if r.events_endrx.read().bits() != 0 { 100 if r.events_endrx().read() != 0 {
100 //trace!(" irq_rx: endrx"); 101 //trace!(" irq_rx: endrx");
101 r.events_endrx.reset(); 102 r.events_endrx().write_value(0);
102 103
103 let val = s.rx_ended_count.load(Ordering::Relaxed); 104 let val = s.rx_ended_count.load(Ordering::Relaxed);
104 s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed); 105 s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed);
105 } 106 }
106 107
107 if r.events_rxstarted.read().bits() != 0 || !s.rx_started.load(Ordering::Relaxed) { 108 if r.events_rxstarted().read() != 0 || !s.rx_started.load(Ordering::Relaxed) {
108 //trace!(" irq_rx: rxstarted"); 109 //trace!(" irq_rx: rxstarted");
109 let (ptr, len) = rx.push_buf(); 110 let (ptr, len) = rx.push_buf();
110 if len >= half_len { 111 if len >= half_len {
111 r.events_rxstarted.reset(); 112 r.events_rxstarted().write_value(0);
112 113
113 //trace!(" irq_rx: starting second {:?}", half_len); 114 //trace!(" irq_rx: starting second {:?}", half_len);
114 115
115 // Set up the DMA read 116 // Set up the DMA read
116 r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); 117 r.rxd().ptr().write_value(ptr as u32);
117 r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(half_len as _) }); 118 r.rxd().maxcnt().write(|w| w.set_maxcnt(half_len as _));
118 119
119 let chn = s.rx_ppi_ch.load(Ordering::Relaxed); 120 let chn = s.rx_ppi_ch.load(Ordering::Relaxed);
120 121
121 // Enable endrx -> startrx PPI channel. 122 // Enable endrx -> startrx PPI channel.
122 // From this point on, if endrx happens, startrx is automatically fired. 123 // From this point on, if endrx happens, startrx is automatically fired.
123 ppi::regs().chenset.write(|w| unsafe { w.bits(1 << chn) }); 124 ppi::regs().chenset().write(|w| w.0 = 1 << chn);
124 125
125 // It is possible that endrx happened BEFORE enabling the PPI. In this case 126 // It is possible that endrx happened BEFORE enabling the PPI. In this case
126 // the PPI channel doesn't trigger, and we'd hang. We have to detect this 127 // the PPI channel doesn't trigger, and we'd hang. We have to detect this
127 // and manually start. 128 // and manually start.
128 129
129 // check again in case endrx has happened between the last check and now. 130 // check again in case endrx has happened between the last check and now.
130 if r.events_endrx.read().bits() != 0 { 131 if r.events_endrx().read() != 0 {
131 //trace!(" irq_rx: endrx"); 132 //trace!(" irq_rx: endrx");
132 r.events_endrx.reset(); 133 r.events_endrx().write_value(0);
133 134
134 let val = s.rx_ended_count.load(Ordering::Relaxed); 135 let val = s.rx_ended_count.load(Ordering::Relaxed);
135 s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed); 136 s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed);
@@ -144,7 +145,7 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt
144 145
145 // Check if the PPI channel is still enabled. The PPI channel disables itself 146 // Check if the PPI channel is still enabled. The PPI channel disables itself
146 // when it fires, so if it's still enabled it hasn't fired. 147 // when it fires, so if it's still enabled it hasn't fired.
147 let ppi_ch_enabled = ppi::regs().chen.read().bits() & (1 << chn) != 0; 148 let ppi_ch_enabled = ppi::regs().chen().read().ch(chn as _);
148 149
149 // if rxend happened, and the ppi channel hasn't fired yet, the rxend got missed. 150 // if rxend happened, and the ppi channel hasn't fired yet, the rxend got missed.
150 // this condition also naturally matches if `!started`, needed to kickstart the DMA. 151 // this condition also naturally matches if `!started`, needed to kickstart the DMA.
@@ -152,10 +153,10 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt
152 //trace!("manually starting."); 153 //trace!("manually starting.");
153 154
154 // disable the ppi ch, it's of no use anymore. 155 // disable the ppi ch, it's of no use anymore.
155 ppi::regs().chenclr.write(|w| unsafe { w.bits(1 << chn) }); 156 ppi::regs().chenclr().write(|w| w.set_ch(chn as _, true));
156 157
157 // manually start 158 // manually start
158 r.tasks_startrx.write(|w| unsafe { w.bits(1) }); 159 r.tasks_startrx().write_value(1);
159 } 160 }
160 161
161 rx.push_done(half_len); 162 rx.push_done(half_len);
@@ -164,7 +165,7 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt
164 s.rx_started.store(true, Ordering::Relaxed); 165 s.rx_started.store(true, Ordering::Relaxed);
165 } else { 166 } else {
166 //trace!(" irq_rx: rxstarted no buf"); 167 //trace!(" irq_rx: rxstarted no buf");
167 r.intenclr.write(|w| w.rxstarted().clear()); 168 r.intenclr().write(|w| w.set_rxstarted(true));
168 } 169 }
169 } 170 }
170 } 171 }
@@ -173,8 +174,8 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt
173 174
174 if let Some(mut tx) = unsafe { s.tx_buf.try_reader() } { 175 if let Some(mut tx) = unsafe { s.tx_buf.try_reader() } {
175 // TX end 176 // TX end
176 if r.events_endtx.read().bits() != 0 { 177 if r.events_endtx().read() != 0 {
177 r.events_endtx.reset(); 178 r.events_endtx().write_value(0);
178 179
179 let n = s.tx_count.load(Ordering::Relaxed); 180 let n = s.tx_count.load(Ordering::Relaxed);
180 //trace!(" irq_tx: endtx {:?}", n); 181 //trace!(" irq_tx: endtx {:?}", n);
@@ -192,11 +193,11 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt
192 s.tx_count.store(len, Ordering::Relaxed); 193 s.tx_count.store(len, Ordering::Relaxed);
193 194
194 // Set up the DMA write 195 // Set up the DMA write
195 r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); 196 r.txd().ptr().write_value(ptr as u32);
196 r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); 197 r.txd().maxcnt().write(|w| w.set_maxcnt(len as _));
197 198
198 // Start UARTE Transmit transaction 199 // Start UARTE Transmit transaction
199 r.tasks_starttx.write(|w| unsafe { w.bits(1) }); 200 r.tasks_starttx().write_value(1);
200 } 201 }
201 } 202 }
202 } 203 }
@@ -308,7 +309,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
308 let tx = BufferedUarteTx::new_innerer(unsafe { peri.clone_unchecked() }, txd, cts, tx_buffer); 309 let tx = BufferedUarteTx::new_innerer(unsafe { peri.clone_unchecked() }, txd, cts, tx_buffer);
309 let rx = BufferedUarteRx::new_innerer(peri, timer, ppi_ch1, ppi_ch2, ppi_group, rxd, rts, rx_buffer); 310 let rx = BufferedUarteRx::new_innerer(peri, timer, ppi_ch1, ppi_ch2, ppi_group, rxd, rts, rx_buffer);
310 311
311 U::regs().enable.write(|w| w.enable().enabled()); 312 U::regs().enable().write(|w| w.set_enable(vals::Enable::ENABLED));
312 U::Interrupt::pend(); 313 U::Interrupt::pend();
313 unsafe { U::Interrupt::enable() }; 314 unsafe { U::Interrupt::enable() };
314 315
@@ -320,7 +321,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
320 /// Adjust the baud rate to the provided value. 321 /// Adjust the baud rate to the provided value.
321 pub fn set_baudrate(&mut self, baudrate: Baudrate) { 322 pub fn set_baudrate(&mut self, baudrate: Baudrate) {
322 let r = U::regs(); 323 let r = U::regs();
323 r.baudrate.write(|w| w.baudrate().variant(baudrate)); 324 r.baudrate().write(|w| w.set_baudrate(baudrate));
324 } 325 }
325 326
326 /// Split the UART in reader and writer parts. 327 /// Split the UART in reader and writer parts.
@@ -415,7 +416,7 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> {
415 416
416 let this = Self::new_innerer(peri, txd, cts, tx_buffer); 417 let this = Self::new_innerer(peri, txd, cts, tx_buffer);
417 418
418 U::regs().enable.write(|w| w.enable().enabled()); 419 U::regs().enable().write(|w| w.set_enable(vals::Enable::ENABLED));
419 U::Interrupt::pend(); 420 U::Interrupt::pend();
420 unsafe { U::Interrupt::enable() }; 421 unsafe { U::Interrupt::enable() };
421 422
@@ -432,14 +433,7 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> {
432 ) -> Self { 433 ) -> Self {
433 let r = U::regs(); 434 let r = U::regs();
434 435
435 txd.set_high(); 436 configure_tx_pins(r, txd, cts);
436 txd.conf().write(|w| w.dir().output().drive().h0h1());
437 r.psel.txd.write(|w| unsafe { w.bits(txd.psel_bits()) });
438
439 if let Some(pin) = &cts {
440 pin.conf().write(|w| w.input().connect().drive().h0h1());
441 }
442 r.psel.cts.write(|w| unsafe { w.bits(cts.psel_bits()) });
443 437
444 // Initialize state 438 // Initialize state
445 let s = U::buffered_state(); 439 let s = U::buffered_state();
@@ -447,12 +441,11 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> {
447 let len = tx_buffer.len(); 441 let len = tx_buffer.len();
448 unsafe { s.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; 442 unsafe { s.tx_buf.init(tx_buffer.as_mut_ptr(), len) };
449 443
450 r.events_txstarted.reset(); 444 r.events_txstarted().write_value(0);
451 445
452 // Enable interrupts 446 // Enable interrupts
453 r.intenset.write(|w| { 447 r.intenset().write(|w| {
454 w.endtx().set(); 448 w.set_endtx(true);
455 w
456 }); 449 });
457 450
458 Self { _peri: peri } 451 Self { _peri: peri }
@@ -532,15 +525,14 @@ impl<'a, U: UarteInstance> Drop for BufferedUarteTx<'a, U> {
532 fn drop(&mut self) { 525 fn drop(&mut self) {
533 let r = U::regs(); 526 let r = U::regs();
534 527
535 r.intenclr.write(|w| { 528 r.intenclr().write(|w| {
536 w.txdrdy().set_bit(); 529 w.set_txdrdy(true);
537 w.txstarted().set_bit(); 530 w.set_txstarted(true);
538 w.txstopped().set_bit(); 531 w.set_txstopped(true);
539 w
540 }); 532 });
541 r.events_txstopped.reset(); 533 r.events_txstopped().write_value(0);
542 r.tasks_stoptx.write(|w| unsafe { w.bits(1) }); 534 r.tasks_stoptx().write_value(1);
543 while r.events_txstopped.read().bits() == 0 {} 535 while r.events_txstopped().read() == 0 {}
544 536
545 let s = U::buffered_state(); 537 let s = U::buffered_state();
546 unsafe { s.tx_buf.deinit() } 538 unsafe { s.tx_buf.deinit() }
@@ -639,7 +631,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
639 631
640 let this = Self::new_innerer(peri, timer, ppi_ch1, ppi_ch2, ppi_group, rxd, rts, rx_buffer); 632 let this = Self::new_innerer(peri, timer, ppi_ch1, ppi_ch2, ppi_group, rxd, rts, rx_buffer);
641 633
642 U::regs().enable.write(|w| w.enable().enabled()); 634 U::regs().enable().write(|w| w.set_enable(vals::Enable::ENABLED));
643 U::Interrupt::pend(); 635 U::Interrupt::pend();
644 unsafe { U::Interrupt::enable() }; 636 unsafe { U::Interrupt::enable() };
645 637
@@ -663,14 +655,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
663 655
664 let r = U::regs(); 656 let r = U::regs();
665 657
666 rxd.conf().write(|w| w.input().connect().drive().h0h1()); 658 configure_rx_pins(r, rxd, rts);
667 r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) });
668
669 if let Some(pin) = &rts {
670 pin.set_high();
671 pin.conf().write(|w| w.dir().output().drive().h0h1());
672 }
673 r.psel.rts.write(|w| unsafe { w.bits(rts.psel_bits()) });
674 659
675 // Initialize state 660 // Initialize state
676 let s = U::buffered_state(); 661 let s = U::buffered_state();
@@ -681,20 +666,19 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
681 unsafe { s.rx_buf.init(rx_buffer.as_mut_ptr(), rx_len) }; 666 unsafe { s.rx_buf.init(rx_buffer.as_mut_ptr(), rx_len) };
682 667
683 // clear errors 668 // clear errors
684 let errors = r.errorsrc.read().bits(); 669 let errors = r.errorsrc().read();
685 r.errorsrc.write(|w| unsafe { w.bits(errors) }); 670 r.errorsrc().write_value(errors);
686 671
687 r.events_rxstarted.reset(); 672 r.events_rxstarted().write_value(0);
688 r.events_error.reset(); 673 r.events_error().write_value(0);
689 r.events_endrx.reset(); 674 r.events_endrx().write_value(0);
690 675
691 // Enable interrupts 676 // Enable interrupts
692 r.intenset.write(|w| { 677 r.intenset().write(|w| {
693 w.endtx().set(); 678 w.set_endtx(true);
694 w.rxstarted().set(); 679 w.set_rxstarted(true);
695 w.error().set(); 680 w.set_error(true);
696 w.endrx().set(); 681 w.set_endrx(true);
697 w
698 }); 682 });
699 683
700 // Configure byte counter. 684 // Configure byte counter.
@@ -704,15 +688,15 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
704 timer.clear(); 688 timer.clear();
705 timer.start(); 689 timer.start();
706 690
707 let mut ppi_ch1 = Ppi::new_one_to_one(ppi_ch1, Event::from_reg(&r.events_rxdrdy), timer.task_count()); 691 let mut ppi_ch1 = Ppi::new_one_to_one(ppi_ch1, Event::from_reg(r.events_rxdrdy()), timer.task_count());
708 ppi_ch1.enable(); 692 ppi_ch1.enable();
709 693
710 s.rx_ppi_ch.store(ppi_ch2.number() as u8, Ordering::Relaxed); 694 s.rx_ppi_ch.store(ppi_ch2.number() as u8, Ordering::Relaxed);
711 let mut ppi_group = PpiGroup::new(ppi_group); 695 let mut ppi_group = PpiGroup::new(ppi_group);
712 let mut ppi_ch2 = Ppi::new_one_to_two( 696 let mut ppi_ch2 = Ppi::new_one_to_two(
713 ppi_ch2, 697 ppi_ch2,
714 Event::from_reg(&r.events_endrx), 698 Event::from_reg(r.events_endrx()),
715 Task::from_reg(&r.tasks_startrx), 699 Task::from_reg(r.tasks_startrx()),
716 ppi_group.task_disable_all(), 700 ppi_group.task_disable_all(),
717 ); 701 );
718 ppi_ch2.disable(); 702 ppi_ch2.disable();
@@ -747,8 +731,8 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
747 let ss = U::state(); 731 let ss = U::state();
748 732
749 // Read the RXDRDY counter. 733 // Read the RXDRDY counter.
750 T::regs().tasks_capture[0].write(|w| unsafe { w.bits(1) }); 734 T::regs().tasks_capture(0).write_value(1);
751 let mut end = T::regs().cc[0].read().bits() as usize; 735 let mut end = T::regs().cc(0).read() as usize;
752 //trace!(" rxdrdy count = {:?}", end); 736 //trace!(" rxdrdy count = {:?}", end);
753 737
754 // We've set a compare channel that resets the counter to 0 when it reaches `len*2`. 738 // We've set a compare channel that resets the counter to 0 when it reaches `len*2`.
@@ -769,7 +753,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
769 if start == end { 753 if start == end {
770 //trace!(" empty"); 754 //trace!(" empty");
771 ss.rx_waker.register(cx.waker()); 755 ss.rx_waker.register(cx.waker());
772 r.intenset.write(|w| w.rxdrdy().set_bit()); 756 r.intenset().write(|w| w.set_rxdrdy(true));
773 return Poll::Pending; 757 return Poll::Pending;
774 } 758 }
775 759
@@ -799,7 +783,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
799 let s = U::buffered_state(); 783 let s = U::buffered_state();
800 let mut rx = unsafe { s.rx_buf.reader() }; 784 let mut rx = unsafe { s.rx_buf.reader() };
801 rx.pop_done(amt); 785 rx.pop_done(amt);
802 U::regs().intenset.write(|w| w.rxstarted().set()); 786 U::regs().intenset().write(|w| w.set_rxstarted(true));
803 } 787 }
804 788
805 /// we are ready to read if there is data in the buffer 789 /// we are ready to read if there is data in the buffer
@@ -817,15 +801,14 @@ impl<'a, U: UarteInstance, T: TimerInstance> Drop for BufferedUarteRx<'a, U, T>
817 801
818 self.timer.stop(); 802 self.timer.stop();
819 803
820 r.intenclr.write(|w| { 804 r.intenclr().write(|w| {
821 w.rxdrdy().set_bit(); 805 w.set_rxdrdy(true);
822 w.rxstarted().set_bit(); 806 w.set_rxstarted(true);
823 w.rxto().set_bit(); 807 w.set_rxto(true);
824 w
825 }); 808 });
826 r.events_rxto.reset(); 809 r.events_rxto().write_value(0);
827 r.tasks_stoprx.write(|w| unsafe { w.bits(1) }); 810 r.tasks_stoprx().write_value(1);
828 while r.events_rxto.read().bits() == 0 {} 811 while r.events_rxto().read() == 0 {}
829 812
830 let s = U::buffered_state(); 813 let s = U::buffered_state();
831 unsafe { s.rx_buf.deinit() } 814 unsafe { s.rx_buf.deinit() }