diff --git a/embassy-stm32/src/usart/v1.rs b/embassy-stm32/src/usart/v1.rs index d68215fe..9e9b4930 100644 --- a/embassy-stm32/src/usart/v1.rs +++ b/embassy-stm32/src/usart/v1.rs @@ -80,7 +80,23 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { Ok(()) } - pub fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { + async fn read_dma(&mut self, buffer: &mut [u8]) -> Result<(), Error> + where + RxDma: crate::usart::RxDma, + { + let ch = &mut self.rx_dma; + unsafe { + self.inner.regs().cr3().modify(|reg| { + reg.set_dmar(true); + }); + } + let r = self.inner.regs(); + let src = r.dr().ptr() as *mut u8; + ch.read(ch.request(), src, buffer).await; + Ok(()) + } + + pub fn read_blocking(&mut self, buffer: &mut [u8]) -> Result<(), Error> { unsafe { let r = self.inner.regs(); for b in buffer { @@ -143,3 +159,15 @@ impl<'d, T: Instance, TxDma, RxDma> embassy_traits::uart::Write for Uart<'d, T, self.write_dma(buf).map_err(|_| embassy_traits::uart::Error::Other) } } + +// rustfmt::skip because intellij removes the 'where' claus on the associated type. +#[rustfmt::skip] +impl<'d, T: Instance, TxDma, RxDma> embassy_traits::uart::Read for Uart<'d, T, TxDma, RxDma> + where RxDma: crate::usart::RxDma +{ + type ReadFuture<'a> where Self: 'a = impl Future>; + + fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { + self.read_dma(buf).map_err(|_| embassy_traits::uart::Error::Other) + } +} diff --git a/embassy-stm32/src/usart/v2.rs b/embassy-stm32/src/usart/v2.rs index 6ce3a338..694b1618 100644 --- a/embassy-stm32/src/usart/v2.rs +++ b/embassy-stm32/src/usart/v2.rs @@ -84,7 +84,23 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { Ok(()) } - pub fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { + async fn read_dma(&mut self, buffer: &mut [u8]) -> Result<(), Error> + where + RxDma: crate::usart::RxDma, + { + let ch = &mut self.rx_dma; + unsafe { + self.inner.regs().cr3().modify(|reg| { + reg.set_dmar(true); + }); + } + let r = self.inner.regs(); + let src = r.rdr().ptr() as *mut u8; + ch.read(ch.request(), src, buffer).await; + Ok(()) + } + + pub fn read_blocking(&mut self, buffer: &mut [u8]) -> Result<(), Error> { unsafe { let r = self.inner.regs(); for b in buffer { @@ -147,3 +163,15 @@ impl<'d, T: Instance, TxDma, RxDma> embassy_traits::uart::Write for Uart<'d, T, self.write_dma(buf).map_err(|_| embassy_traits::uart::Error::Other) } } + +// rustfmt::skip because intellij removes the 'where' claus on the associated type. +#[rustfmt::skip] +impl<'d, T: Instance, TxDma, RxDma> embassy_traits::uart::Read for Uart<'d, T, TxDma, RxDma> + where RxDma: crate::usart::RxDma +{ + type ReadFuture<'a> where Self: 'a = impl Future>; + + fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { + self.read_dma(buf).map_err(|_| embassy_traits::uart::Error::Other) + } +} diff --git a/examples/stm32f4/src/bin/usart.rs b/examples/stm32f4/src/bin/usart.rs index 8f0e04e5..a068df52 100644 --- a/examples/stm32f4/src/bin/usart.rs +++ b/examples/stm32f4/src/bin/usart.rs @@ -33,7 +33,7 @@ fn main() -> ! { let mut buf = [0u8; 1]; loop { - usart.read(&mut buf).unwrap(); + usart.read_blocking(&mut buf).unwrap(); usart.bwrite_all(&buf).unwrap(); } } diff --git a/examples/stm32h7/src/bin/usart.rs b/examples/stm32h7/src/bin/usart.rs index ce33f201..3e3e5b16 100644 --- a/examples/stm32h7/src/bin/usart.rs +++ b/examples/stm32h7/src/bin/usart.rs @@ -31,7 +31,7 @@ async fn main_task() { let mut buf = [0u8; 1]; loop { - usart.read(&mut buf).unwrap(); + usart.read_blocking(&mut buf).unwrap(); usart.bwrite_all(&buf).unwrap(); } } diff --git a/examples/stm32l0/src/bin/usart_dma.rs b/examples/stm32l0/src/bin/usart_dma.rs new file mode 100644 index 00000000..0a5859b7 --- /dev/null +++ b/examples/stm32l0/src/bin/usart_dma.rs @@ -0,0 +1,42 @@ +#![no_std] +#![no_main] +#![feature(trait_alias)] +#![feature(min_type_alias_impl_trait)] +#![feature(impl_trait_in_bindings)] +#![feature(type_alias_impl_trait)] +#![allow(incomplete_features)] + +#[path = "../example_common.rs"] +mod example_common; + +use example_common::*; + +use defmt::panic; +use embassy::executor::Spawner; +use embassy_stm32::usart::{Config, Uart}; +use embassy_stm32::{rcc, Peripherals}; +use embassy_traits::uart::{Read, Write}; + +#[embassy::main] +async fn main(_spawner: Spawner, mut p: Peripherals) { + let mut rcc = rcc::Rcc::new(p.RCC); + rcc.enable_debug_wfe(&mut p.DBGMCU, true); + + let mut usart = Uart::new( + p.USART1, + p.PB7, + p.PB6, + p.DMA1_CH2, + p.DMA1_CH3, + Config::default(), + ); + + usart.write(b"Hello Embassy World!\r\n").await.unwrap(); + info!("wrote Hello, starting echo"); + + let mut buf = [0; 1]; + loop { + usart.read(&mut buf[..]).await.unwrap(); + usart.write(&buf[..]).await.unwrap(); + } +} diff --git a/examples/stm32l4/src/bin/usart.rs b/examples/stm32l4/src/bin/usart.rs index 06abd41a..ebe06dc2 100644 --- a/examples/stm32l4/src/bin/usart.rs +++ b/examples/stm32l4/src/bin/usart.rs @@ -33,7 +33,7 @@ fn main() -> ! { let mut buf = [0u8; 1]; loop { - usart.read(&mut buf).unwrap(); + usart.read_blocking(&mut buf).unwrap(); usart.bwrite_all(&buf).unwrap(); } }