stm32/dma: add ChannelAndRequest helper.

This commit is contained in:
Dario Nieuwenhuis 2024-04-15 21:47:37 +02:00
parent d66c054aae
commit 02da66aec8
4 changed files with 86 additions and 24 deletions

View File

@ -16,6 +16,9 @@ mod dmamux;
#[cfg(dmamux)]
pub use dmamux::*;
mod util;
pub(crate) use util::*;
pub(crate) mod ringbuffer;
pub mod word;

View File

@ -0,0 +1,60 @@
use embassy_hal_internal::PeripheralRef;
use super::word::Word;
use super::{AnyChannel, Request, Transfer, TransferOptions};
/// Convenience wrapper, contains a channel and a request number.
///
/// Commonly used in peripheral drivers that own DMA channels.
pub(crate) struct ChannelAndRequest<'d> {
pub channel: PeripheralRef<'d, AnyChannel>,
pub request: Request,
}
impl<'d> ChannelAndRequest<'d> {
pub unsafe fn read<'a, W: Word>(
&'a mut self,
peri_addr: *mut W,
buf: &'a mut [W],
options: TransferOptions,
) -> Transfer<'a> {
Transfer::new_read(&mut self.channel, self.request, peri_addr, buf, options)
}
pub unsafe fn read_raw<'a, W: Word>(
&'a mut self,
peri_addr: *mut W,
buf: *mut [W],
options: TransferOptions,
) -> Transfer<'a> {
Transfer::new_read_raw(&mut self.channel, self.request, peri_addr, buf, options)
}
pub unsafe fn write<'a, W: Word>(
&'a mut self,
buf: &'a [W],
peri_addr: *mut W,
options: TransferOptions,
) -> Transfer<'a> {
Transfer::new_write(&mut self.channel, self.request, buf, peri_addr, options)
}
pub unsafe fn write_raw<'a, W: Word>(
&'a mut self,
buf: *const [W],
peri_addr: *mut W,
options: TransferOptions,
) -> Transfer<'a> {
Transfer::new_write_raw(&mut self.channel, self.request, buf, peri_addr, options)
}
pub unsafe fn write_repeated<'a, W: Word>(
&'a mut self,
repeated: &'a W,
count: usize,
peri_addr: *mut W,
options: TransferOptions,
) -> Transfer<'a> {
Transfer::new_write_repeated(&mut self.channel, self.request, repeated, count, peri_addr, options)
}
}

View File

@ -9,7 +9,7 @@ use embassy_futures::join::join;
use embassy_hal_internal::{into_ref, PeripheralRef};
pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
use crate::dma::{slice_ptr_parts, word, AnyChannel, Request, Transfer};
use crate::dma::{slice_ptr_parts, word, ChannelAndRequest};
use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed};
use crate::mode::{Async, Blocking, Mode as PeriMode};
use crate::pac::spi::{regs, vals, Spi as Regs};
@ -97,8 +97,8 @@ pub struct Spi<'d, T: Instance, M: PeriMode> {
sck: Option<PeripheralRef<'d, AnyPin>>,
mosi: Option<PeripheralRef<'d, AnyPin>>,
miso: Option<PeripheralRef<'d, AnyPin>>,
txdma: Option<(PeripheralRef<'d, AnyChannel>, Request)>,
rxdma: Option<(PeripheralRef<'d, AnyChannel>, Request)>,
txdma: Option<ChannelAndRequest<'d>>,
rxdma: Option<ChannelAndRequest<'d>>,
_phantom: PhantomData<M>,
current_word_size: word_impl::Config,
}
@ -109,8 +109,8 @@ impl<'d, T: Instance, M: PeriMode> Spi<'d, T, M> {
sck: Option<PeripheralRef<'d, AnyPin>>,
mosi: Option<PeripheralRef<'d, AnyPin>>,
miso: Option<PeripheralRef<'d, AnyPin>>,
txdma: Option<(PeripheralRef<'d, AnyChannel>, Request)>,
rxdma: Option<(PeripheralRef<'d, AnyChannel>, Request)>,
txdma: Option<ChannelAndRequest<'d>>,
rxdma: Option<ChannelAndRequest<'d>>,
config: Config,
) -> Self {
into_ref!(peri);
@ -593,9 +593,8 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
w.set_spe(false);
});
let (txdma, tx_request) = self.txdma.as_mut().unwrap();
let tx_dst = T::REGS.tx_ptr();
let tx_f = unsafe { Transfer::new_write(txdma, *tx_request, data, tx_dst, Default::default()) };
let tx_f = unsafe { self.txdma.as_mut().unwrap().write(data, tx_dst, Default::default()) };
set_txdmaen(T::REGS, true);
T::REGS.cr1().modify(|w| {
@ -632,22 +631,16 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
let clock_byte_count = data.len();
let (rxdma, rx_request) = self.rxdma.as_mut().unwrap();
let rx_src = T::REGS.rx_ptr();
let rx_f = unsafe { Transfer::new_read(rxdma, *rx_request, rx_src, data, Default::default()) };
let rx_f = unsafe { self.rxdma.as_mut().unwrap().read(rx_src, data, Default::default()) };
let (txdma, tx_request) = self.txdma.as_mut().unwrap();
let tx_dst = T::REGS.tx_ptr();
let clock_byte = 0x00u8;
let tx_f = unsafe {
Transfer::new_write_repeated(
txdma,
*tx_request,
&clock_byte,
clock_byte_count,
tx_dst,
Default::default(),
)
self.txdma
.as_mut()
.unwrap()
.write_repeated(&clock_byte, clock_byte_count, tx_dst, Default::default())
};
set_txdmaen(T::REGS, true);
@ -685,13 +678,16 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
set_rxdmaen(T::REGS, true);
let (rxdma, rx_request) = self.rxdma.as_mut().unwrap();
let rx_src = T::REGS.rx_ptr();
let rx_f = unsafe { Transfer::new_read_raw(rxdma, *rx_request, rx_src, read, Default::default()) };
let rx_f = unsafe { self.rxdma.as_mut().unwrap().read_raw(rx_src, read, Default::default()) };
let (txdma, tx_request) = self.txdma.as_mut().unwrap();
let tx_dst = T::REGS.tx_ptr();
let tx_f = unsafe { Transfer::new_write_raw(txdma, *tx_request, write, tx_dst, Default::default()) };
let tx_f = unsafe {
self.txdma
.as_mut()
.unwrap()
.write_raw(write, tx_dst, Default::default())
};
set_txdmaen(T::REGS, true);
T::REGS.cr1().modify(|w| {

View File

@ -73,8 +73,11 @@ macro_rules! dma_trait_impl {
macro_rules! new_dma {
($name:ident) => {{
let dma = $name.into_ref();
let req = dma.request();
Some((dma.map_into(), req))
let request = dma.request();
Some(crate::dma::ChannelAndRequest {
channel: dma.map_into(),
request,
})
}};
}