stm32/dma: improve trait docs, seal Word.

This commit is contained in:
Dario Nieuwenhuis 2021-12-08 03:18:15 +01:00
parent 6179da6b9c
commit b316d2620c
6 changed files with 50 additions and 24 deletions

View file

@ -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,

View file

@ -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);

View file

@ -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);

View file

@ -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();

View file

@ -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(())
}

View file

@ -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(())