From 6ff0614cb63a6fd95bbb062bc15eeac9a24359f0 Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Tue, 3 Aug 2021 15:17:04 +0200 Subject: [PATCH 1/2] Add uart::Read DMA-based implementation * Rename existing read() to bread() (blocking) --- embassy-stm32/src/usart/v1.rs | 30 ++++++++++++++++++- embassy-stm32/src/usart/v2.rs | 30 ++++++++++++++++++- examples/stm32f4/src/bin/usart.rs | 2 +- examples/stm32h7/src/bin/usart.rs | 2 +- examples/stm32l0/src/bin/usart_dma.rs | 42 +++++++++++++++++++++++++++ examples/stm32l4/src/bin/usart.rs | 2 +- 6 files changed, 103 insertions(+), 5 deletions(-) create mode 100644 examples/stm32l0/src/bin/usart_dma.rs diff --git a/embassy-stm32/src/usart/v1.rs b/embassy-stm32/src/usart/v1.rs index d68215fea..245303542 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 bread(&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 6ce3a338e..63e849ba1 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 bread(&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 8f0e04e57..40e862f58 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.bread(&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 11e04f33c..88420ae3e 100644 --- a/examples/stm32h7/src/bin/usart.rs +++ b/examples/stm32h7/src/bin/usart.rs @@ -34,7 +34,7 @@ async fn main_task() { let mut buf = [0u8; 1]; loop { - usart.read(&mut buf).unwrap(); + usart.bread(&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 000000000..0a5859b75 --- /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 06abd41a2..c71825bf5 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.bread(&mut buf).unwrap(); usart.bwrite_all(&buf).unwrap(); } } From 0d02342b2d9fba686ae10caee8486141f20848c5 Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Wed, 4 Aug 2021 08:34:30 +0200 Subject: [PATCH 2/2] Rename bread -> read_blocking --- embassy-stm32/src/usart/v1.rs | 2 +- embassy-stm32/src/usart/v2.rs | 2 +- examples/stm32f4/src/bin/usart.rs | 2 +- examples/stm32h7/src/bin/usart.rs | 2 +- examples/stm32l4/src/bin/usart.rs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/embassy-stm32/src/usart/v1.rs b/embassy-stm32/src/usart/v1.rs index 245303542..9e9b49306 100644 --- a/embassy-stm32/src/usart/v1.rs +++ b/embassy-stm32/src/usart/v1.rs @@ -96,7 +96,7 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { Ok(()) } - pub fn bread(&mut self, buffer: &mut [u8]) -> Result<(), Error> { + pub fn read_blocking(&mut self, buffer: &mut [u8]) -> Result<(), Error> { unsafe { let r = self.inner.regs(); for b in buffer { diff --git a/embassy-stm32/src/usart/v2.rs b/embassy-stm32/src/usart/v2.rs index 63e849ba1..694b16185 100644 --- a/embassy-stm32/src/usart/v2.rs +++ b/embassy-stm32/src/usart/v2.rs @@ -100,7 +100,7 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { Ok(()) } - pub fn bread(&mut self, buffer: &mut [u8]) -> Result<(), Error> { + pub fn read_blocking(&mut self, buffer: &mut [u8]) -> Result<(), Error> { unsafe { let r = self.inner.regs(); for b in buffer { diff --git a/examples/stm32f4/src/bin/usart.rs b/examples/stm32f4/src/bin/usart.rs index 40e862f58..a068df520 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.bread(&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 88420ae3e..7bdd3f000 100644 --- a/examples/stm32h7/src/bin/usart.rs +++ b/examples/stm32h7/src/bin/usart.rs @@ -34,7 +34,7 @@ async fn main_task() { let mut buf = [0u8; 1]; loop { - usart.bread(&mut buf).unwrap(); + usart.read_blocking(&mut buf).unwrap(); usart.bwrite_all(&buf).unwrap(); } } diff --git a/examples/stm32l4/src/bin/usart.rs b/examples/stm32l4/src/bin/usart.rs index c71825bf5..ebe06dc26 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.bread(&mut buf).unwrap(); + usart.read_blocking(&mut buf).unwrap(); usart.bwrite_all(&buf).unwrap(); } }