aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/dma_traits.rs15
-rw-r--r--embassy-stm32/src/usart/v3.rs42
-rw-r--r--examples/stm32l4/src/bin/usart_dma.rs11
3 files changed, 58 insertions, 10 deletions
diff --git a/embassy-stm32/src/dma_traits.rs b/embassy-stm32/src/dma_traits.rs
index 8f1a9f40e..518e10dcb 100644
--- a/embassy-stm32/src/dma_traits.rs
+++ b/embassy-stm32/src/dma_traits.rs
@@ -1,4 +1,5 @@
1use core::future::Future; 1use core::future::Future;
2use embassy::util::Unborrow;
2 3
3pub trait WriteDma<T> { 4pub trait WriteDma<T> {
4 type WriteDmaFuture<'a>: Future<Output = ()> + 'a 5 type WriteDmaFuture<'a>: Future<Output = ()> + 'a
@@ -19,3 +20,17 @@ pub trait ReadDma<T> {
19 where 20 where
20 T: 'a; 21 T: 'a;
21} 22}
23
24pub trait NoDmaMarker {}
25
26pub struct NoDma;
27
28impl NoDmaMarker for NoDma {}
29
30unsafe impl Unborrow for NoDma {
31 type Target = NoDma;
32
33 unsafe fn unborrow(self) -> Self::Target {
34 self
35 }
36}
diff --git a/embassy-stm32/src/usart/v3.rs b/embassy-stm32/src/usart/v3.rs
index 0071c597a..6c9696c71 100644
--- a/embassy-stm32/src/usart/v3.rs
+++ b/embassy-stm32/src/usart/v3.rs
@@ -6,20 +6,30 @@ use embassy_extras::unborrow;
6use crate::pac::usart::{regs, vals}; 6use crate::pac::usart::{regs, vals};
7 7
8use super::*; 8use super::*;
9use core::future::Future;
10use futures::TryFutureExt;
9 11
10pub struct Uart<'d, T: Instance> { 12use crate::dma_traits::NoDma;
13use crate::dma_traits::NoDmaMarker;
14
15#[allow(dead_code)]
16pub struct Uart<'d, T: Instance, TxDma = NoDma, RxDma = NoDma> {
11 inner: T, 17 inner: T,
12 phantom: PhantomData<&'d mut T>, 18 phantom: PhantomData<&'d mut T>,
19 tx_dma: TxDma,
20 rx_dma: RxDma,
13} 21}
14 22
15impl<'d, T: Instance> Uart<'d, T> { 23impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
16 pub fn new( 24 pub fn new(
17 inner: impl Unborrow<Target = T>, 25 inner: impl Unborrow<Target = T>,
18 rx: impl Unborrow<Target = impl RxPin<T>>, 26 rx: impl Unborrow<Target = impl RxPin<T>>,
19 tx: impl Unborrow<Target = impl TxPin<T>>, 27 tx: impl Unborrow<Target = impl TxPin<T>>,
28 tx_dma: impl Unborrow<Target = TxDma>,
29 rx_dma: impl Unborrow<Target = RxDma>,
20 config: Config, 30 config: Config,
21 ) -> Self { 31 ) -> Self {
22 unborrow!(inner, rx, tx); 32 unborrow!(inner, rx, tx, tx_dma, rx_dma);
23 33
24 // Uncomment once we find all of the H7's UART clocks. 34 // Uncomment once we find all of the H7's UART clocks.
25 T::enable(); 35 T::enable();
@@ -54,11 +64,17 @@ impl<'d, T: Instance> Uart<'d, T> {
54 Self { 64 Self {
55 inner, 65 inner,
56 phantom: PhantomData, 66 phantom: PhantomData,
67 tx_dma,
68 rx_dma,
57 } 69 }
58 } 70 }
59 71
60 #[cfg(any(dma, dmamux))] 72 #[cfg(any(dma, dmamux))]
61 pub async fn write_dma(&mut self, ch: &mut impl TxDma<T>, buffer: &[u8]) -> Result<(), Error> { 73 pub async fn write_dma(&mut self, buffer: &[u8]) -> Result<(), Error>
74 where
75 TxDma: crate::usart::TxDma<T>,
76 {
77 let ch = &mut self.tx_dma;
62 unsafe { 78 unsafe {
63 self.inner.regs().cr3().modify(|reg| { 79 self.inner.regs().cr3().modify(|reg| {
64 reg.set_dmat(true); 80 reg.set_dmat(true);
@@ -99,7 +115,11 @@ impl<'d, T: Instance> Uart<'d, T> {
99 } 115 }
100} 116}
101 117
102impl<'d, T: Instance> embedded_hal::blocking::serial::Write<u8> for Uart<'d, T> { 118impl<'d, T: Instance, TxDma, RxDma> embedded_hal::blocking::serial::Write<u8>
119 for Uart<'d, T, TxDma, RxDma>
120where
121 TxDma: NoDmaMarker,
122{
103 type Error = Error; 123 type Error = Error;
104 fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { 124 fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
105 unsafe { 125 unsafe {
@@ -119,3 +139,15 @@ impl<'d, T: Instance> embedded_hal::blocking::serial::Write<u8> for Uart<'d, T>
119 Ok(()) 139 Ok(())
120 } 140 }
121} 141}
142
143// rustfmt::skip because intellij removes the 'where' claus on the associated type.
144#[rustfmt::skip]
145impl<'d, T: Instance, TxDma, RxDma> embassy_traits::uart::Write for Uart<'d, T, TxDma, RxDma>
146 where TxDma: crate::usart::TxDma<T>
147{
148 type WriteFuture<'a> where Self: 'a = impl Future<Output = Result<(), embassy_traits::uart::Error>>;
149
150 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
151 self.write_dma(buf).map_err(|_| embassy_traits::uart::Error::Other)
152 }
153}
diff --git a/examples/stm32l4/src/bin/usart_dma.rs b/examples/stm32l4/src/bin/usart_dma.rs
index cc630e0df..1239bf9c2 100644
--- a/examples/stm32l4/src/bin/usart_dma.rs
+++ b/examples/stm32l4/src/bin/usart_dma.rs
@@ -17,22 +17,23 @@ use embassy_stm32::usart::{Config, Uart};
17use example_common::*; 17use example_common::*;
18use heapless::String; 18use heapless::String;
19use stm32l4::stm32l4x5 as pac; 19use stm32l4::stm32l4x5 as pac;
20use embassy_stm32::dma_traits::NoDma;
21use embassy_traits::uart::Write as AsyncWrite;
22use embassy::io::AsyncWriteExt;
20 23
21#[embassy::task] 24#[embassy::task]
22async fn main_task() { 25async fn main_task() {
23 let mut p = embassy_stm32::init(Default::default()); 26 let mut p = embassy_stm32::init(Default::default());
24 27
25 let config = Config::default(); 28 let config = Config::default();
26 let mut usart = Uart::new(p.UART4, p.PA1, p.PA0, config); 29 let mut usart = Uart::new(p.UART4, p.PA1, p.PA0, p.DMA1_3, NoDma, config);
27 30
28 for n in 0u32.. { 31 for n in 0u32.. {
29 let mut s: String<128> = String::new(); 32 let mut s: String<128> = String::new();
30 core::write!(&mut s, "Hello DMA World {}!\r\n", n).unwrap(); 33 core::write!(&mut s, "Hello DMA World {}!\r\n", n).unwrap();
31 34
32 usart 35 usart.write( s.as_bytes() ).await;
33 .write_dma(&mut p.DMA1_3, s.as_bytes()) 36
34 .await
35 .unwrap();
36 info!("wrote DMA"); 37 info!("wrote DMA");
37 } 38 }
38} 39}