stm32/dma: impl all variants
This commit is contained in:
committed by
Bob McWhirter
parent
69fb1b5418
commit
3d1391ef2d
@ -3,7 +3,7 @@
|
||||
#[cfg_attr(usart_v1, path = "v1.rs")]
|
||||
#[cfg_attr(usart_v2, path = "v2.rs")]
|
||||
mod _version;
|
||||
use crate::peripherals;
|
||||
use crate::{dma, peripherals};
|
||||
pub use _version::*;
|
||||
|
||||
use crate::gpio::Pin;
|
||||
@ -72,9 +72,6 @@ pub enum Error {
|
||||
pub(crate) mod sealed {
|
||||
use super::*;
|
||||
|
||||
#[cfg(any(dma, bdma, dmamux))]
|
||||
use crate::dma_traits::WriteDma;
|
||||
|
||||
pub trait Instance {
|
||||
fn regs(&self) -> crate::pac::usart::Usart;
|
||||
}
|
||||
@ -94,11 +91,13 @@ pub(crate) mod sealed {
|
||||
fn af_num(&self) -> u8;
|
||||
}
|
||||
|
||||
#[cfg(any(bdma, dma, dmamux))]
|
||||
pub trait RxDma<T: Instance> {}
|
||||
pub trait RxDma<T: Instance> {
|
||||
fn request(&self) -> dma::Request;
|
||||
}
|
||||
|
||||
#[cfg(any(bdma, dma, dmamux))]
|
||||
pub trait TxDma<T: Instance>: WriteDma<T> {}
|
||||
pub trait TxDma<T: Instance> {
|
||||
fn request(&self) -> dma::Request;
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Instance: sealed::Instance + RccPeripheral {}
|
||||
@ -107,12 +106,8 @@ pub trait TxPin<T: Instance>: sealed::TxPin<T> {}
|
||||
pub trait CtsPin<T: Instance>: sealed::CtsPin<T> {}
|
||||
pub trait RtsPin<T: Instance>: sealed::RtsPin<T> {}
|
||||
pub trait CkPin<T: Instance>: sealed::CkPin<T> {}
|
||||
|
||||
#[cfg(any(bdma, dma, dmamux))]
|
||||
pub trait RxDma<T: Instance>: sealed::RxDma<T> {}
|
||||
|
||||
#[cfg(any(bdma, dma, dmamux))]
|
||||
pub trait TxDma<T: Instance>: sealed::TxDma<T> {}
|
||||
pub trait RxDma<T: Instance>: sealed::RxDma<T> + dma::Channel {}
|
||||
pub trait TxDma<T: Instance>: sealed::TxDma<T> + dma::Channel {}
|
||||
|
||||
crate::pac::peripherals!(
|
||||
(usart, $inst:ident) => {
|
||||
@ -141,46 +136,86 @@ macro_rules! impl_pin {
|
||||
crate::pac::peripheral_pins!(
|
||||
|
||||
// USART
|
||||
|
||||
($inst:ident, usart, USART, $pin:ident, TX, $af:expr) => {
|
||||
impl_pin!($inst, $pin, TxPin, $af);
|
||||
};
|
||||
|
||||
($inst:ident, usart, USART, $pin:ident, RX, $af:expr) => {
|
||||
impl_pin!($inst, $pin, RxPin, $af);
|
||||
};
|
||||
|
||||
($inst:ident, usart, USART, $pin:ident, CTS, $af:expr) => {
|
||||
impl_pin!($inst, $pin, CtsPin, $af);
|
||||
};
|
||||
|
||||
($inst:ident, usart, USART, $pin:ident, RTS, $af:expr) => {
|
||||
impl_pin!($inst, $pin, RtsPin, $af);
|
||||
};
|
||||
|
||||
($inst:ident, usart, USART, $pin:ident, CK, $af:expr) => {
|
||||
impl_pin!($inst, $pin, CkPin, $af);
|
||||
};
|
||||
|
||||
// UART
|
||||
|
||||
($inst:ident, uart, UART, $pin:ident, TX, $af:expr) => {
|
||||
impl_pin!($inst, $pin, TxPin, $af);
|
||||
};
|
||||
|
||||
($inst:ident, uart, UART, $pin:ident, RX, $af:expr) => {
|
||||
impl_pin!($inst, $pin, RxPin, $af);
|
||||
};
|
||||
|
||||
($inst:ident, uart, UART, $pin:ident, CTS, $af:expr) => {
|
||||
impl_pin!($inst, $pin, CtsPin, $af);
|
||||
};
|
||||
|
||||
($inst:ident, uart, UART, $pin:ident, RTS, $af:expr) => {
|
||||
impl_pin!($inst, $pin, RtsPin, $af);
|
||||
};
|
||||
|
||||
($inst:ident, uart, UART, $pin:ident, CK, $af:expr) => {
|
||||
impl_pin!($inst, $pin, CkPin, $af);
|
||||
};
|
||||
);
|
||||
|
||||
macro_rules! impl_dma {
|
||||
($inst:ident, ALL, $signal:ident, $request:expr) => {
|
||||
impl<T: crate::dma::Channel> sealed::$signal<peripherals::$inst> for T {
|
||||
fn request(&self) -> dma::Request {
|
||||
$request
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: crate::dma::Channel> $signal<peripherals::$inst> for T {}
|
||||
};
|
||||
($inst:ident, $channel:ident, $signal:ident, $request:expr) => {
|
||||
impl sealed::$signal<peripherals::$inst> for peripherals::$channel {
|
||||
fn request(&self) -> dma::Request {
|
||||
$request
|
||||
}
|
||||
}
|
||||
|
||||
impl $signal<peripherals::$inst> for peripherals::$channel {}
|
||||
};
|
||||
}
|
||||
|
||||
crate::pac::peripheral_dma_channels! {
|
||||
($peri:ident, usart, $kind:ident, RX, $channel:ident, $dma_peri:ident, $channel_num:expr, $request:expr) => {
|
||||
impl_dma!($peri, $channel, RxDma, $request);
|
||||
};
|
||||
($peri:ident, usart, $kind:ident, TX, $channel:ident, $dma_peri:ident, $channel_num:expr, $request:expr) => {
|
||||
impl_dma!($peri, $channel, TxDma, $request);
|
||||
};
|
||||
($peri:ident, uart, $kind:ident, RX, $channel:ident, $dma_peri:ident, $channel_num:expr, $request:expr) => {
|
||||
impl_dma!($peri, $channel, RxDma, $request);
|
||||
};
|
||||
($peri:ident, uart, $kind:ident, TX, $channel:ident, $dma_peri:ident, $channel_num:expr, $request:expr) => {
|
||||
impl_dma!($peri, $channel, TxDma, $request);
|
||||
};
|
||||
}
|
||||
crate::pac::dma_requests! {
|
||||
(usart, $peri:ident, RX, $request:expr) => {
|
||||
impl_dma!($peri, ALL, RxDma, $request);
|
||||
};
|
||||
(usart, $peri:ident, TX, $request:expr) => {
|
||||
impl_dma!($peri, ALL, TxDma, $request);
|
||||
};
|
||||
(uart, $peri:ident, RX, $request:expr) => {
|
||||
impl_dma!($peri, ALL, RxDma, $request);
|
||||
};
|
||||
(uart, $peri:ident, TX, $request:expr) => {
|
||||
impl_dma!($peri, ALL, TxDma, $request);
|
||||
};
|
||||
}
|
||||
|
@ -1,25 +1,31 @@
|
||||
use core::future::Future;
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy::util::Unborrow;
|
||||
use embassy_extras::unborrow;
|
||||
|
||||
use crate::pac::usart::{regs, vals};
|
||||
use futures::TryFutureExt;
|
||||
|
||||
use super::*;
|
||||
use crate::dma::NoDma;
|
||||
use crate::pac::usart::{regs, vals};
|
||||
|
||||
pub struct Uart<'d, T: Instance> {
|
||||
pub struct Uart<'d, T: Instance, TxDma = NoDma, RxDma = NoDma> {
|
||||
inner: T,
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
tx_dma: TxDma,
|
||||
#[allow(dead_code)]
|
||||
rx_dma: RxDma,
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> Uart<'d, T> {
|
||||
impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
|
||||
pub fn new(
|
||||
inner: impl Unborrow<Target = T>,
|
||||
rx: impl Unborrow<Target = impl RxPin<T>>,
|
||||
tx: impl Unborrow<Target = impl TxPin<T>>,
|
||||
tx_dma: impl Unborrow<Target = TxDma>,
|
||||
rx_dma: impl Unborrow<Target = RxDma>,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(inner, rx, tx);
|
||||
unborrow!(inner, rx, tx, tx_dma, rx_dma);
|
||||
|
||||
T::enable();
|
||||
let pclk_freq = T::frequency();
|
||||
@ -53,11 +59,16 @@ impl<'d, T: Instance> Uart<'d, T> {
|
||||
Self {
|
||||
inner,
|
||||
phantom: PhantomData,
|
||||
tx_dma,
|
||||
rx_dma,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(dma)]
|
||||
pub async fn write_dma(&mut self, ch: &mut impl TxDma<T>, buffer: &[u8]) -> Result<(), Error> {
|
||||
async fn write_dma(&mut self, buffer: &[u8]) -> Result<(), Error>
|
||||
where
|
||||
TxDma: crate::usart::TxDma<T>,
|
||||
{
|
||||
let ch = &mut self.tx_dma;
|
||||
unsafe {
|
||||
self.inner.regs().cr3().modify(|reg| {
|
||||
reg.set_dmat(true);
|
||||
@ -65,7 +76,7 @@ impl<'d, T: Instance> Uart<'d, T> {
|
||||
}
|
||||
let r = self.inner.regs();
|
||||
let dst = r.dr().ptr() as *mut u8;
|
||||
ch.transfer(buffer, dst).await;
|
||||
ch.write(ch.request(), buffer, dst).await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -98,7 +109,9 @@ impl<'d, T: Instance> Uart<'d, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> embedded_hal::blocking::serial::Write<u8> for Uart<'d, T> {
|
||||
impl<'d, T: Instance, RxDma> embedded_hal::blocking::serial::Write<u8>
|
||||
for Uart<'d, T, NoDma, RxDma>
|
||||
{
|
||||
type Error = Error;
|
||||
fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
|
||||
unsafe {
|
||||
@ -118,3 +131,15 @@ impl<'d, T: Instance> embedded_hal::blocking::serial::Write<u8> for Uart<'d, T>
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// rustfmt::skip because intellij removes the 'where' claus on the associated type.
|
||||
#[rustfmt::skip]
|
||||
impl<'d, T: Instance, TxDma, RxDma> embassy_traits::uart::Write for Uart<'d, T, TxDma, RxDma>
|
||||
where TxDma: crate::usart::TxDma<T>
|
||||
{
|
||||
type WriteFuture<'a> where Self: 'a = impl Future<Output = Result<(), embassy_traits::uart::Error>>;
|
||||
|
||||
fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
|
||||
self.write_dma(buf).map_err(|_| embassy_traits::uart::Error::Other)
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +1,18 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use core::future::Future;
|
||||
use futures::TryFutureExt;
|
||||
use embassy::util::Unborrow;
|
||||
use embassy_extras::unborrow;
|
||||
|
||||
use crate::pac::usart::{regs, vals};
|
||||
|
||||
use super::*;
|
||||
use core::future::Future;
|
||||
use futures::TryFutureExt;
|
||||
use crate::dma::NoDma;
|
||||
|
||||
use crate::dma_traits::NoDma;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct Uart<'d, T: Instance, TxDma = NoDma, RxDma = NoDma> {
|
||||
inner: T,
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
tx_dma: TxDma,
|
||||
#[allow(dead_code)]
|
||||
rx_dma: RxDma,
|
||||
}
|
||||
|
||||
@ -83,7 +80,7 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
|
||||
}
|
||||
let r = self.inner.regs();
|
||||
let dst = r.tdr().ptr() as *mut u8;
|
||||
ch.transfer(buffer, dst).await;
|
||||
ch.write(ch.request(), buffer, dst).await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user