Merge pull request #341 from lulf/usart-dma-read
Add uart::Read DMA-based implementation
This commit is contained in:
commit
5d31dd328f
@ -80,7 +80,23 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
|
|||||||
Ok(())
|
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<T>,
|
||||||
|
{
|
||||||
|
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 {
|
unsafe {
|
||||||
let r = self.inner.regs();
|
let r = self.inner.regs();
|
||||||
for b in buffer {
|
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)
|
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<T>
|
||||||
|
{
|
||||||
|
type ReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), embassy_traits::uart::Error>>;
|
||||||
|
|
||||||
|
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
|
||||||
|
self.read_dma(buf).map_err(|_| embassy_traits::uart::Error::Other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -84,7 +84,23 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
|
|||||||
Ok(())
|
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<T>,
|
||||||
|
{
|
||||||
|
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 {
|
unsafe {
|
||||||
let r = self.inner.regs();
|
let r = self.inner.regs();
|
||||||
for b in buffer {
|
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)
|
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<T>
|
||||||
|
{
|
||||||
|
type ReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), embassy_traits::uart::Error>>;
|
||||||
|
|
||||||
|
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
|
||||||
|
self.read_dma(buf).map_err(|_| embassy_traits::uart::Error::Other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -33,7 +33,7 @@ fn main() -> ! {
|
|||||||
|
|
||||||
let mut buf = [0u8; 1];
|
let mut buf = [0u8; 1];
|
||||||
loop {
|
loop {
|
||||||
usart.read(&mut buf).unwrap();
|
usart.read_blocking(&mut buf).unwrap();
|
||||||
usart.bwrite_all(&buf).unwrap();
|
usart.bwrite_all(&buf).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ async fn main_task() {
|
|||||||
|
|
||||||
let mut buf = [0u8; 1];
|
let mut buf = [0u8; 1];
|
||||||
loop {
|
loop {
|
||||||
usart.read(&mut buf).unwrap();
|
usart.read_blocking(&mut buf).unwrap();
|
||||||
usart.bwrite_all(&buf).unwrap();
|
usart.bwrite_all(&buf).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
42
examples/stm32l0/src/bin/usart_dma.rs
Normal file
42
examples/stm32l0/src/bin/usart_dma.rs
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -33,7 +33,7 @@ fn main() -> ! {
|
|||||||
|
|
||||||
let mut buf = [0u8; 1];
|
let mut buf = [0u8; 1];
|
||||||
loop {
|
loop {
|
||||||
usart.read(&mut buf).unwrap();
|
usart.read_blocking(&mut buf).unwrap();
|
||||||
usart.bwrite_all(&buf).unwrap();
|
usart.bwrite_all(&buf).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user