mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-25 08:12:30 +00:00
stm32/dma: add ChannelAndRequest helper.
This commit is contained in:
parent
d66c054aae
commit
02da66aec8
@ -16,6 +16,9 @@ mod dmamux;
|
||||
#[cfg(dmamux)]
|
||||
pub use dmamux::*;
|
||||
|
||||
mod util;
|
||||
pub(crate) use util::*;
|
||||
|
||||
pub(crate) mod ringbuffer;
|
||||
pub mod word;
|
||||
|
||||
|
60
embassy-stm32/src/dma/util.rs
Normal file
60
embassy-stm32/src/dma/util.rs
Normal 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)
|
||||
}
|
||||
}
|
@ -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| {
|
||||
|
@ -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,
|
||||
})
|
||||
}};
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user