stm32/dma: improve trait docs, seal Word.
This commit is contained in:
parent
6179da6b9c
commit
b316d2620c
6 changed files with 50 additions and 24 deletions
|
@ -89,7 +89,7 @@ pac::dma_channels! {
|
|||
($channel_peri:ident, $dma_peri:ident, bdma, $channel_num:expr, $dmamux:tt) => {
|
||||
impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri {
|
||||
|
||||
unsafe fn start_write<W: Word>(&mut self, request: Request, buf: &[W], reg_addr: *mut u32) {
|
||||
unsafe fn start_write<W: Word>(&mut self, request: Request, buf: &[W], reg_addr: *mut W) {
|
||||
low_level_api::reset_status(crate::pac::$dma_peri, $channel_num);
|
||||
low_level_api::start_transfer(
|
||||
crate::pac::$dma_peri,
|
||||
|
@ -110,7 +110,7 @@ pac::dma_channels! {
|
|||
}
|
||||
|
||||
|
||||
unsafe fn start_write_repeated<W: Word>(&mut self, request: Request, repeated: W, count: usize, reg_addr: *mut u32) {
|
||||
unsafe fn start_write_repeated<W: Word>(&mut self, request: Request, repeated: W, count: usize, reg_addr: *mut W) {
|
||||
let buf = [repeated];
|
||||
low_level_api::reset_status(crate::pac::$dma_peri, $channel_num);
|
||||
low_level_api::start_transfer(
|
||||
|
@ -131,7 +131,7 @@ pac::dma_channels! {
|
|||
)
|
||||
}
|
||||
|
||||
unsafe fn start_read<W: Word>(&mut self, request: Request, reg_addr: *mut u32, buf: &mut [W]) {
|
||||
unsafe fn start_read<W: Word>(&mut self, request: Request, reg_addr: *mut W, buf: &mut [W]) {
|
||||
low_level_api::reset_status(crate::pac::$dma_peri, $channel_num);
|
||||
low_level_api::start_transfer(
|
||||
crate::pac::$dma_peri,
|
||||
|
|
|
@ -84,7 +84,7 @@ pub(crate) unsafe fn init() {
|
|||
pac::dma_channels! {
|
||||
($channel_peri:ident, $dma_peri:ident, dma, $channel_num:expr, $dmamux:tt) => {
|
||||
impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri {
|
||||
unsafe fn start_write<W: Word>(&mut self, request: Request, buf: &[W], reg_addr: *mut u32) {
|
||||
unsafe fn start_write<W: Word>(&mut self, request: Request, buf: &[W], reg_addr: *mut W) {
|
||||
let isrn = $channel_num as usize / 4;
|
||||
let isrbit = $channel_num as usize % 4;
|
||||
low_level_api::reset_status(&crate::pac::$dma_peri, isrn, isrbit);
|
||||
|
@ -104,7 +104,7 @@ pac::dma_channels! {
|
|||
)
|
||||
}
|
||||
|
||||
unsafe fn start_write_repeated<W: Word>(&mut self, request: Request, repeated: W, count: usize, reg_addr: *mut u32) {
|
||||
unsafe fn start_write_repeated<W: Word>(&mut self, request: Request, repeated: W, count: usize, reg_addr: *mut W) {
|
||||
let buf = [repeated];
|
||||
let isrn = $channel_num as usize / 4;
|
||||
let isrbit = $channel_num as usize % 4;
|
||||
|
@ -125,7 +125,7 @@ pac::dma_channels! {
|
|||
)
|
||||
}
|
||||
|
||||
unsafe fn start_read<W: Word>(&mut self, request: Request, reg_addr: *mut u32, buf: &mut [W]) {
|
||||
unsafe fn start_read<W: Word>(&mut self, request: Request, reg_addr: *mut W, buf: &mut [W]) {
|
||||
let isrn = $channel_num as usize / 4;
|
||||
let isrbit = $channel_num as usize % 4;
|
||||
low_level_api::reset_status(&crate::pac::$dma_peri, isrn, isrbit);
|
||||
|
|
|
@ -30,37 +30,59 @@ pub type Request = ();
|
|||
pub(crate) mod sealed {
|
||||
use super::*;
|
||||
|
||||
pub trait Word {}
|
||||
|
||||
pub trait Channel {
|
||||
/// Starts this channel for writing a stream of words.
|
||||
unsafe fn start_write<W: Word>(&mut self, request: Request, buf: &[W], reg_addr: *mut u32);
|
||||
///
|
||||
/// Safety:
|
||||
/// - `buf` must be alive for the entire duration of the DMA transfer.
|
||||
/// - `reg_addr` must be a valid peripheral register address to write to.
|
||||
unsafe fn start_write<W: super::Word>(
|
||||
&mut self,
|
||||
request: Request,
|
||||
buf: &[W],
|
||||
reg_addr: *mut W,
|
||||
);
|
||||
|
||||
/// Starts this channel for writing a word repeatedly.
|
||||
unsafe fn start_write_repeated<W: Word>(
|
||||
///
|
||||
/// Safety:
|
||||
/// - `reg_addr` must be a valid peripheral register address to write to.
|
||||
unsafe fn start_write_repeated<W: super::Word>(
|
||||
&mut self,
|
||||
request: Request,
|
||||
repeated: W,
|
||||
count: usize,
|
||||
reg_addr: *mut u32,
|
||||
reg_addr: *mut W,
|
||||
);
|
||||
|
||||
/// Starts this channel for reading a stream of words.
|
||||
unsafe fn start_read<W: Word>(
|
||||
///
|
||||
/// Safety:
|
||||
/// - `buf` must be alive for the entire duration of the DMA transfer.
|
||||
/// - `reg_addr` must be a valid peripheral register address to write to.
|
||||
unsafe fn start_read<W: super::Word>(
|
||||
&mut self,
|
||||
request: Request,
|
||||
reg_addr: *mut u32,
|
||||
reg_addr: *mut W,
|
||||
buf: &mut [W],
|
||||
);
|
||||
|
||||
/// Stops this channel.
|
||||
/// Requests the channel to stop.
|
||||
/// NOTE: The channel does not immediately stop, you have to wait
|
||||
/// for `is_running() = false`.
|
||||
fn request_stop(&mut self);
|
||||
|
||||
/// Returns whether this channel is active or stopped.
|
||||
/// Returns whether this channel is running or stopped.
|
||||
///
|
||||
/// The channel stops running when it either completes or is manually stopped.
|
||||
fn is_running(&self) -> bool;
|
||||
|
||||
/// Returns the total number of remaining transfers.
|
||||
fn remaining_transfers(&mut self) -> u16;
|
||||
|
||||
/// Sets the waker that is called when this channel completes.
|
||||
/// Sets the waker that is called when this channel stops (either completed or manually stopped)
|
||||
fn set_waker(&mut self, waker: &Waker);
|
||||
}
|
||||
}
|
||||
|
@ -70,21 +92,25 @@ pub enum WordSize {
|
|||
TwoBytes,
|
||||
FourBytes,
|
||||
}
|
||||
pub trait Word {
|
||||
pub trait Word: sealed::Word {
|
||||
fn bits() -> WordSize;
|
||||
}
|
||||
|
||||
impl sealed::Word for u8 {}
|
||||
impl Word for u8 {
|
||||
fn bits() -> WordSize {
|
||||
WordSize::OneByte
|
||||
}
|
||||
}
|
||||
|
||||
impl sealed::Word for u16 {}
|
||||
impl Word for u16 {
|
||||
fn bits() -> WordSize {
|
||||
WordSize::TwoBytes
|
||||
}
|
||||
}
|
||||
|
||||
impl sealed::Word for u32 {}
|
||||
impl Word for u32 {
|
||||
fn bits() -> WordSize {
|
||||
WordSize::FourBytes
|
||||
|
@ -98,7 +124,7 @@ mod transfers {
|
|||
pub fn read<'a, W: Word>(
|
||||
channel: impl Unborrow<Target = impl Channel> + 'a,
|
||||
request: Request,
|
||||
reg_addr: *mut u32,
|
||||
reg_addr: *mut W,
|
||||
buf: &'a mut [W],
|
||||
) -> impl Future<Output = ()> + 'a {
|
||||
assert!(buf.len() <= 0xFFFF);
|
||||
|
@ -117,7 +143,7 @@ mod transfers {
|
|||
channel: impl Unborrow<Target = impl Channel> + 'a,
|
||||
request: Request,
|
||||
buf: &'a [W],
|
||||
reg_addr: *mut u32,
|
||||
reg_addr: *mut W,
|
||||
) -> impl Future<Output = ()> + 'a {
|
||||
assert!(buf.len() <= 0xFFFF);
|
||||
unborrow!(channel);
|
||||
|
@ -136,7 +162,7 @@ mod transfers {
|
|||
request: Request,
|
||||
repeated: W,
|
||||
count: usize,
|
||||
reg_addr: *mut u32,
|
||||
reg_addr: *mut W,
|
||||
) -> impl Future<Output = ()> + 'a {
|
||||
unborrow!(channel);
|
||||
|
||||
|
|
|
@ -415,7 +415,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
|
|||
w.set_tcie(true);
|
||||
}
|
||||
});
|
||||
let dst = regs.txdr().ptr() as *mut u32;
|
||||
let dst = regs.txdr().ptr() as *mut u8;
|
||||
|
||||
let ch = &mut self.tx_dma;
|
||||
let request = ch.request();
|
||||
|
@ -508,7 +508,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
|
|||
w.set_rxdmaen(true);
|
||||
w.set_tcie(true);
|
||||
});
|
||||
let src = regs.rxdr().ptr() as *mut u32;
|
||||
let src = regs.rxdr().ptr() as *mut u8;
|
||||
|
||||
let ch = &mut self.rx_dma;
|
||||
let request = ch.request();
|
||||
|
|
|
@ -77,7 +77,7 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
|
|||
});
|
||||
}
|
||||
let r = self.inner.regs();
|
||||
let dst = r.dr().ptr() as *mut u32;
|
||||
let dst = r.dr().ptr() as *mut u8;
|
||||
crate::dma::write(ch, request, buffer, dst).await;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
|
|||
});
|
||||
}
|
||||
let r = self.inner.regs();
|
||||
let src = r.dr().ptr() as *mut u32;
|
||||
let src = r.dr().ptr() as *mut u8;
|
||||
crate::dma::read(ch, request, src, buffer).await;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
|
|||
});
|
||||
}
|
||||
let r = self.inner.regs();
|
||||
let dst = r.tdr().ptr() as *mut u32;
|
||||
let dst = r.tdr().ptr() as *mut u8;
|
||||
crate::dma::write(ch, request, buffer, dst).await;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
|
|||
});
|
||||
}
|
||||
let r = self.inner.regs();
|
||||
let src = r.rdr().ptr() as *mut u32;
|
||||
let src = r.rdr().ptr() as *mut u8;
|
||||
|
||||
crate::dma::read(ch, request, src, buffer).await;
|
||||
Ok(())
|
||||
|
|
Loading…
Reference in a new issue