aboutsummaryrefslogtreecommitdiff
path: root/embassy-rp/src/uart/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-rp/src/uart/mod.rs')
-rw-r--r--embassy-rp/src/uart/mod.rs168
1 files changed, 71 insertions, 97 deletions
diff --git a/embassy-rp/src/uart/mod.rs b/embassy-rp/src/uart/mod.rs
index 8d12aeef6..90c7655be 100644
--- a/embassy-rp/src/uart/mod.rs
+++ b/embassy-rp/src/uart/mod.rs
@@ -5,7 +5,7 @@ use core::task::Poll;
5 5
6use atomic_polyfill::{AtomicU16, Ordering}; 6use atomic_polyfill::{AtomicU16, Ordering};
7use embassy_futures::select::{select, Either}; 7use embassy_futures::select::{select, Either};
8use embassy_hal_internal::{into_ref, PeripheralRef}; 8use embassy_hal_internal::{Peri, PeripheralType};
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10use embassy_time::{Delay, Timer}; 10use embassy_time::{Delay, Timer};
11use pac::uart::regs::Uartris; 11use pac::uart::regs::Uartris;
@@ -15,7 +15,7 @@ use crate::dma::{AnyChannel, Channel};
15use crate::gpio::{AnyPin, SealedPin}; 15use crate::gpio::{AnyPin, SealedPin};
16use crate::interrupt::typelevel::{Binding, Interrupt}; 16use crate::interrupt::typelevel::{Binding, Interrupt};
17use crate::pac::io::vals::{Inover, Outover}; 17use crate::pac::io::vals::{Inover, Outover};
18use crate::{interrupt, pac, peripherals, Peripheral, RegExt}; 18use crate::{interrupt, pac, peripherals, RegExt};
19 19
20mod buffered; 20mod buffered;
21pub use buffered::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, BufferedUartTx}; 21pub use buffered::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, BufferedUartTx};
@@ -142,30 +142,29 @@ pub struct Uart<'d, T: Instance, M: Mode> {
142 142
143/// UART TX driver. 143/// UART TX driver.
144pub struct UartTx<'d, T: Instance, M: Mode> { 144pub struct UartTx<'d, T: Instance, M: Mode> {
145 tx_dma: Option<PeripheralRef<'d, AnyChannel>>, 145 tx_dma: Option<Peri<'d, AnyChannel>>,
146 phantom: PhantomData<(&'d mut T, M)>, 146 phantom: PhantomData<(&'d mut T, M)>,
147} 147}
148 148
149/// UART RX driver. 149/// UART RX driver.
150pub struct UartRx<'d, T: Instance, M: Mode> { 150pub struct UartRx<'d, T: Instance, M: Mode> {
151 rx_dma: Option<PeripheralRef<'d, AnyChannel>>, 151 rx_dma: Option<Peri<'d, AnyChannel>>,
152 phantom: PhantomData<(&'d mut T, M)>, 152 phantom: PhantomData<(&'d mut T, M)>,
153} 153}
154 154
155impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> { 155impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> {
156 /// Create a new DMA-enabled UART which can only send data 156 /// Create a new DMA-enabled UART which can only send data
157 pub fn new( 157 pub fn new(
158 _uart: impl Peripheral<P = T> + 'd, 158 _uart: Peri<'d, T>,
159 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 159 tx: Peri<'d, impl TxPin<T>>,
160 tx_dma: impl Peripheral<P = impl Channel> + 'd, 160 tx_dma: Peri<'d, impl Channel>,
161 config: Config, 161 config: Config,
162 ) -> Self { 162 ) -> Self {
163 into_ref!(tx, tx_dma); 163 Uart::<T, M>::init(Some(tx.into()), None, None, None, config);
164 Uart::<T, M>::init(Some(tx.map_into()), None, None, None, config); 164 Self::new_inner(Some(tx_dma.into()))
165 Self::new_inner(Some(tx_dma.map_into()))
166 } 165 }
167 166
168 fn new_inner(tx_dma: Option<PeripheralRef<'d, AnyChannel>>) -> Self { 167 fn new_inner(tx_dma: Option<Peri<'d, AnyChannel>>) -> Self {
169 Self { 168 Self {
170 tx_dma, 169 tx_dma,
171 phantom: PhantomData, 170 phantom: PhantomData,
@@ -225,13 +224,8 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> {
225 224
226impl<'d, T: Instance> UartTx<'d, T, Blocking> { 225impl<'d, T: Instance> UartTx<'d, T, Blocking> {
227 /// Create a new UART TX instance for blocking mode operations. 226 /// Create a new UART TX instance for blocking mode operations.
228 pub fn new_blocking( 227 pub fn new_blocking(_uart: Peri<'d, T>, tx: Peri<'d, impl TxPin<T>>, config: Config) -> Self {
229 _uart: impl Peripheral<P = T> + 'd, 228 Uart::<T, Blocking>::init(Some(tx.into()), None, None, None, config);
230 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
231 config: Config,
232 ) -> Self {
233 into_ref!(tx);
234 Uart::<T, Blocking>::init(Some(tx.map_into()), None, None, None, config);
235 Self::new_inner(None) 229 Self::new_inner(None)
236 } 230 }
237 231
@@ -251,7 +245,7 @@ impl<'d, T: Instance> UartTx<'d, T, Blocking> {
251impl<'d, T: Instance> UartTx<'d, T, Async> { 245impl<'d, T: Instance> UartTx<'d, T, Async> {
252 /// Write to UART TX from the provided buffer using DMA. 246 /// Write to UART TX from the provided buffer using DMA.
253 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { 247 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
254 let ch = self.tx_dma.as_mut().unwrap(); 248 let ch = self.tx_dma.as_mut().unwrap().reborrow();
255 let transfer = unsafe { 249 let transfer = unsafe {
256 T::regs().uartdmacr().write_set(|reg| { 250 T::regs().uartdmacr().write_set(|reg| {
257 reg.set_txdmae(true); 251 reg.set_txdmae(true);
@@ -268,18 +262,17 @@ impl<'d, T: Instance> UartTx<'d, T, Async> {
268impl<'d, T: Instance, M: Mode> UartRx<'d, T, M> { 262impl<'d, T: Instance, M: Mode> UartRx<'d, T, M> {
269 /// Create a new DMA-enabled UART which can only receive data 263 /// Create a new DMA-enabled UART which can only receive data
270 pub fn new( 264 pub fn new(
271 _uart: impl Peripheral<P = T> + 'd, 265 _uart: Peri<'d, T>,
272 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 266 rx: Peri<'d, impl RxPin<T>>,
273 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>, 267 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
274 rx_dma: impl Peripheral<P = impl Channel> + 'd, 268 rx_dma: Peri<'d, impl Channel>,
275 config: Config, 269 config: Config,
276 ) -> Self { 270 ) -> Self {
277 into_ref!(rx, rx_dma); 271 Uart::<T, M>::init(None, Some(rx.into()), None, None, config);
278 Uart::<T, M>::init(None, Some(rx.map_into()), None, None, config); 272 Self::new_inner(true, Some(rx_dma.into()))
279 Self::new_inner(true, Some(rx_dma.map_into()))
280 } 273 }
281 274
282 fn new_inner(has_irq: bool, rx_dma: Option<PeripheralRef<'d, AnyChannel>>) -> Self { 275 fn new_inner(has_irq: bool, rx_dma: Option<Peri<'d, AnyChannel>>) -> Self {
283 debug_assert_eq!(has_irq, rx_dma.is_some()); 276 debug_assert_eq!(has_irq, rx_dma.is_some());
284 if has_irq { 277 if has_irq {
285 // disable all error interrupts initially 278 // disable all error interrupts initially
@@ -346,13 +339,8 @@ impl<'d, T: Instance, M: Mode> Drop for UartRx<'d, T, M> {
346 339
347impl<'d, T: Instance> UartRx<'d, T, Blocking> { 340impl<'d, T: Instance> UartRx<'d, T, Blocking> {
348 /// Create a new UART RX instance for blocking mode operations. 341 /// Create a new UART RX instance for blocking mode operations.
349 pub fn new_blocking( 342 pub fn new_blocking(_uart: Peri<'d, T>, rx: Peri<'d, impl RxPin<T>>, config: Config) -> Self {
350 _uart: impl Peripheral<P = T> + 'd, 343 Uart::<T, Blocking>::init(None, Some(rx.into()), None, None, config);
351 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
352 config: Config,
353 ) -> Self {
354 into_ref!(rx);
355 Uart::<T, Blocking>::init(None, Some(rx.map_into()), None, None, config);
356 Self::new_inner(false, None) 344 Self::new_inner(false, None)
357 } 345 }
358 346
@@ -419,7 +407,7 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
419 // start a dma transfer. if errors have happened in the interim some error 407 // start a dma transfer. if errors have happened in the interim some error
420 // interrupt flags will have been raised, and those will be picked up immediately 408 // interrupt flags will have been raised, and those will be picked up immediately
421 // by the interrupt handler. 409 // by the interrupt handler.
422 let ch = self.rx_dma.as_mut().unwrap(); 410 let ch = self.rx_dma.as_mut().unwrap().reborrow();
423 T::regs().uartimsc().write_set(|w| { 411 T::regs().uartimsc().write_set(|w| {
424 w.set_oeim(true); 412 w.set_oeim(true);
425 w.set_beim(true); 413 w.set_beim(true);
@@ -566,7 +554,7 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
566 // start a dma transfer. if errors have happened in the interim some error 554 // start a dma transfer. if errors have happened in the interim some error
567 // interrupt flags will have been raised, and those will be picked up immediately 555 // interrupt flags will have been raised, and those will be picked up immediately
568 // by the interrupt handler. 556 // by the interrupt handler.
569 let mut ch = self.rx_dma.as_mut().unwrap(); 557 let ch = self.rx_dma.as_mut().unwrap();
570 T::regs().uartimsc().write_set(|w| { 558 T::regs().uartimsc().write_set(|w| {
571 w.set_oeim(true); 559 w.set_oeim(true);
572 w.set_beim(true); 560 w.set_beim(true);
@@ -583,7 +571,7 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
583 // If we don't assign future to a variable, the data register pointer 571 // If we don't assign future to a variable, the data register pointer
584 // is held across an await and makes the future non-Send. 572 // is held across an await and makes the future non-Send.
585 crate::dma::read( 573 crate::dma::read(
586 &mut ch, 574 ch.reborrow(),
587 T::regs().uartdr().as_ptr() as *const _, 575 T::regs().uartdr().as_ptr() as *const _,
588 sbuffer, 576 sbuffer,
589 T::RX_DREQ.into(), 577 T::RX_DREQ.into(),
@@ -700,41 +688,29 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
700impl<'d, T: Instance> Uart<'d, T, Blocking> { 688impl<'d, T: Instance> Uart<'d, T, Blocking> {
701 /// Create a new UART without hardware flow control 689 /// Create a new UART without hardware flow control
702 pub fn new_blocking( 690 pub fn new_blocking(
703 uart: impl Peripheral<P = T> + 'd, 691 uart: Peri<'d, T>,
704 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 692 tx: Peri<'d, impl TxPin<T>>,
705 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 693 rx: Peri<'d, impl RxPin<T>>,
706 config: Config, 694 config: Config,
707 ) -> Self { 695 ) -> Self {
708 into_ref!(tx, rx); 696 Self::new_inner(uart, tx.into(), rx.into(), None, None, false, None, None, config)
709 Self::new_inner(
710 uart,
711 tx.map_into(),
712 rx.map_into(),
713 None,
714 None,
715 false,
716 None,
717 None,
718 config,
719 )
720 } 697 }
721 698
722 /// Create a new UART with hardware flow control (RTS/CTS) 699 /// Create a new UART with hardware flow control (RTS/CTS)
723 pub fn new_with_rtscts_blocking( 700 pub fn new_with_rtscts_blocking(
724 uart: impl Peripheral<P = T> + 'd, 701 uart: Peri<'d, T>,
725 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 702 tx: Peri<'d, impl TxPin<T>>,
726 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 703 rx: Peri<'d, impl RxPin<T>>,
727 rts: impl Peripheral<P = impl RtsPin<T>> + 'd, 704 rts: Peri<'d, impl RtsPin<T>>,
728 cts: impl Peripheral<P = impl CtsPin<T>> + 'd, 705 cts: Peri<'d, impl CtsPin<T>>,
729 config: Config, 706 config: Config,
730 ) -> Self { 707 ) -> Self {
731 into_ref!(tx, rx, cts, rts);
732 Self::new_inner( 708 Self::new_inner(
733 uart, 709 uart,
734 tx.map_into(), 710 tx.into(),
735 rx.map_into(), 711 rx.into(),
736 Some(rts.map_into()), 712 Some(rts.into()),
737 Some(cts.map_into()), 713 Some(cts.into()),
738 false, 714 false,
739 None, 715 None,
740 None, 716 None,
@@ -762,50 +738,48 @@ impl<'d, T: Instance> Uart<'d, T, Blocking> {
762impl<'d, T: Instance> Uart<'d, T, Async> { 738impl<'d, T: Instance> Uart<'d, T, Async> {
763 /// Create a new DMA enabled UART without hardware flow control 739 /// Create a new DMA enabled UART without hardware flow control
764 pub fn new( 740 pub fn new(
765 uart: impl Peripheral<P = T> + 'd, 741 uart: Peri<'d, T>,
766 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 742 tx: Peri<'d, impl TxPin<T>>,
767 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 743 rx: Peri<'d, impl RxPin<T>>,
768 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>, 744 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
769 tx_dma: impl Peripheral<P = impl Channel> + 'd, 745 tx_dma: Peri<'d, impl Channel>,
770 rx_dma: impl Peripheral<P = impl Channel> + 'd, 746 rx_dma: Peri<'d, impl Channel>,
771 config: Config, 747 config: Config,
772 ) -> Self { 748 ) -> Self {
773 into_ref!(tx, rx, tx_dma, rx_dma);
774 Self::new_inner( 749 Self::new_inner(
775 uart, 750 uart,
776 tx.map_into(), 751 tx.into(),
777 rx.map_into(), 752 rx.into(),
778 None, 753 None,
779 None, 754 None,
780 true, 755 true,
781 Some(tx_dma.map_into()), 756 Some(tx_dma.into()),
782 Some(rx_dma.map_into()), 757 Some(rx_dma.into()),
783 config, 758 config,
784 ) 759 )
785 } 760 }
786 761
787 /// Create a new DMA enabled UART with hardware flow control (RTS/CTS) 762 /// Create a new DMA enabled UART with hardware flow control (RTS/CTS)
788 pub fn new_with_rtscts( 763 pub fn new_with_rtscts(
789 uart: impl Peripheral<P = T> + 'd, 764 uart: Peri<'d, T>,
790 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 765 tx: Peri<'d, impl TxPin<T>>,
791 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 766 rx: Peri<'d, impl RxPin<T>>,
792 rts: impl Peripheral<P = impl RtsPin<T>> + 'd, 767 rts: Peri<'d, impl RtsPin<T>>,
793 cts: impl Peripheral<P = impl CtsPin<T>> + 'd, 768 cts: Peri<'d, impl CtsPin<T>>,
794 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>, 769 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
795 tx_dma: impl Peripheral<P = impl Channel> + 'd, 770 tx_dma: Peri<'d, impl Channel>,
796 rx_dma: impl Peripheral<P = impl Channel> + 'd, 771 rx_dma: Peri<'d, impl Channel>,
797 config: Config, 772 config: Config,
798 ) -> Self { 773 ) -> Self {
799 into_ref!(tx, rx, cts, rts, tx_dma, rx_dma);
800 Self::new_inner( 774 Self::new_inner(
801 uart, 775 uart,
802 tx.map_into(), 776 tx.into(),
803 rx.map_into(), 777 rx.into(),
804 Some(rts.map_into()), 778 Some(rts.into()),
805 Some(cts.map_into()), 779 Some(cts.into()),
806 true, 780 true,
807 Some(tx_dma.map_into()), 781 Some(tx_dma.into()),
808 Some(rx_dma.map_into()), 782 Some(rx_dma.into()),
809 config, 783 config,
810 ) 784 )
811 } 785 }
@@ -813,14 +787,14 @@ impl<'d, T: Instance> Uart<'d, T, Async> {
813 787
814impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> { 788impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> {
815 fn new_inner( 789 fn new_inner(
816 _uart: impl Peripheral<P = T> + 'd, 790 _uart: Peri<'d, T>,
817 mut tx: PeripheralRef<'d, AnyPin>, 791 mut tx: Peri<'d, AnyPin>,
818 mut rx: PeripheralRef<'d, AnyPin>, 792 mut rx: Peri<'d, AnyPin>,
819 mut rts: Option<PeripheralRef<'d, AnyPin>>, 793 mut rts: Option<Peri<'d, AnyPin>>,
820 mut cts: Option<PeripheralRef<'d, AnyPin>>, 794 mut cts: Option<Peri<'d, AnyPin>>,
821 has_irq: bool, 795 has_irq: bool,
822 tx_dma: Option<PeripheralRef<'d, AnyChannel>>, 796 tx_dma: Option<Peri<'d, AnyChannel>>,
823 rx_dma: Option<PeripheralRef<'d, AnyChannel>>, 797 rx_dma: Option<Peri<'d, AnyChannel>>,
824 config: Config, 798 config: Config,
825 ) -> Self { 799 ) -> Self {
826 Self::init( 800 Self::init(
@@ -838,10 +812,10 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> {
838 } 812 }
839 813
840 fn init( 814 fn init(
841 tx: Option<PeripheralRef<'_, AnyPin>>, 815 tx: Option<Peri<'_, AnyPin>>,
842 rx: Option<PeripheralRef<'_, AnyPin>>, 816 rx: Option<Peri<'_, AnyPin>>,
843 rts: Option<PeripheralRef<'_, AnyPin>>, 817 rts: Option<Peri<'_, AnyPin>>,
844 cts: Option<PeripheralRef<'_, AnyPin>>, 818 cts: Option<Peri<'_, AnyPin>>,
845 config: Config, 819 config: Config,
846 ) { 820 ) {
847 let r = T::regs(); 821 let r = T::regs();
@@ -1326,7 +1300,7 @@ impl_mode!(Async);
1326 1300
1327/// UART instance. 1301/// UART instance.
1328#[allow(private_bounds)] 1302#[allow(private_bounds)]
1329pub trait Instance: SealedInstance { 1303pub trait Instance: SealedInstance + PeripheralType {
1330 /// Interrupt for this instance. 1304 /// Interrupt for this instance.
1331 type Interrupt: interrupt::typelevel::Interrupt; 1305 type Interrupt: interrupt::typelevel::Interrupt;
1332} 1306}