stm32/dma: improve trait docs, seal Word.
This commit is contained in:
parent
6179da6b9c
commit
b316d2620c
@ -89,7 +89,7 @@ pac::dma_channels! {
|
|||||||
($channel_peri:ident, $dma_peri:ident, bdma, $channel_num:expr, $dmamux:tt) => {
|
($channel_peri:ident, $dma_peri:ident, bdma, $channel_num:expr, $dmamux:tt) => {
|
||||||
impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri {
|
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::reset_status(crate::pac::$dma_peri, $channel_num);
|
||||||
low_level_api::start_transfer(
|
low_level_api::start_transfer(
|
||||||
crate::pac::$dma_peri,
|
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];
|
let buf = [repeated];
|
||||||
low_level_api::reset_status(crate::pac::$dma_peri, $channel_num);
|
low_level_api::reset_status(crate::pac::$dma_peri, $channel_num);
|
||||||
low_level_api::start_transfer(
|
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::reset_status(crate::pac::$dma_peri, $channel_num);
|
||||||
low_level_api::start_transfer(
|
low_level_api::start_transfer(
|
||||||
crate::pac::$dma_peri,
|
crate::pac::$dma_peri,
|
||||||
|
@ -84,7 +84,7 @@ pub(crate) unsafe fn init() {
|
|||||||
pac::dma_channels! {
|
pac::dma_channels! {
|
||||||
($channel_peri:ident, $dma_peri:ident, dma, $channel_num:expr, $dmamux:tt) => {
|
($channel_peri:ident, $dma_peri:ident, dma, $channel_num:expr, $dmamux:tt) => {
|
||||||
impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri {
|
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 isrn = $channel_num as usize / 4;
|
||||||
let isrbit = $channel_num as usize % 4;
|
let isrbit = $channel_num as usize % 4;
|
||||||
low_level_api::reset_status(&crate::pac::$dma_peri, isrn, isrbit);
|
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 buf = [repeated];
|
||||||
let isrn = $channel_num as usize / 4;
|
let isrn = $channel_num as usize / 4;
|
||||||
let isrbit = $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 isrn = $channel_num as usize / 4;
|
||||||
let isrbit = $channel_num as usize % 4;
|
let isrbit = $channel_num as usize % 4;
|
||||||
low_level_api::reset_status(&crate::pac::$dma_peri, isrn, isrbit);
|
low_level_api::reset_status(&crate::pac::$dma_peri, isrn, isrbit);
|
||||||
|
@ -30,37 +30,59 @@ pub type Request = ();
|
|||||||
pub(crate) mod sealed {
|
pub(crate) mod sealed {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
pub trait Word {}
|
||||||
|
|
||||||
pub trait Channel {
|
pub trait Channel {
|
||||||
/// Starts this channel for writing a stream of words.
|
/// 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.
|
/// 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,
|
&mut self,
|
||||||
request: Request,
|
request: Request,
|
||||||
repeated: W,
|
repeated: W,
|
||||||
count: usize,
|
count: usize,
|
||||||
reg_addr: *mut u32,
|
reg_addr: *mut W,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Starts this channel for reading a stream of words.
|
/// 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,
|
&mut self,
|
||||||
request: Request,
|
request: Request,
|
||||||
reg_addr: *mut u32,
|
reg_addr: *mut W,
|
||||||
buf: &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);
|
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;
|
fn is_running(&self) -> bool;
|
||||||
|
|
||||||
/// Returns the total number of remaining transfers.
|
/// Returns the total number of remaining transfers.
|
||||||
fn remaining_transfers(&mut self) -> u16;
|
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);
|
fn set_waker(&mut self, waker: &Waker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,21 +92,25 @@ pub enum WordSize {
|
|||||||
TwoBytes,
|
TwoBytes,
|
||||||
FourBytes,
|
FourBytes,
|
||||||
}
|
}
|
||||||
pub trait Word {
|
pub trait Word: sealed::Word {
|
||||||
fn bits() -> WordSize;
|
fn bits() -> WordSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl sealed::Word for u8 {}
|
||||||
impl Word for u8 {
|
impl Word for u8 {
|
||||||
fn bits() -> WordSize {
|
fn bits() -> WordSize {
|
||||||
WordSize::OneByte
|
WordSize::OneByte
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl sealed::Word for u16 {}
|
||||||
impl Word for u16 {
|
impl Word for u16 {
|
||||||
fn bits() -> WordSize {
|
fn bits() -> WordSize {
|
||||||
WordSize::TwoBytes
|
WordSize::TwoBytes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl sealed::Word for u32 {}
|
||||||
impl Word for u32 {
|
impl Word for u32 {
|
||||||
fn bits() -> WordSize {
|
fn bits() -> WordSize {
|
||||||
WordSize::FourBytes
|
WordSize::FourBytes
|
||||||
@ -98,7 +124,7 @@ mod transfers {
|
|||||||
pub fn read<'a, W: Word>(
|
pub fn read<'a, W: Word>(
|
||||||
channel: impl Unborrow<Target = impl Channel> + 'a,
|
channel: impl Unborrow<Target = impl Channel> + 'a,
|
||||||
request: Request,
|
request: Request,
|
||||||
reg_addr: *mut u32,
|
reg_addr: *mut W,
|
||||||
buf: &'a mut [W],
|
buf: &'a mut [W],
|
||||||
) -> impl Future<Output = ()> + 'a {
|
) -> impl Future<Output = ()> + 'a {
|
||||||
assert!(buf.len() <= 0xFFFF);
|
assert!(buf.len() <= 0xFFFF);
|
||||||
@ -117,7 +143,7 @@ mod transfers {
|
|||||||
channel: impl Unborrow<Target = impl Channel> + 'a,
|
channel: impl Unborrow<Target = impl Channel> + 'a,
|
||||||
request: Request,
|
request: Request,
|
||||||
buf: &'a [W],
|
buf: &'a [W],
|
||||||
reg_addr: *mut u32,
|
reg_addr: *mut W,
|
||||||
) -> impl Future<Output = ()> + 'a {
|
) -> impl Future<Output = ()> + 'a {
|
||||||
assert!(buf.len() <= 0xFFFF);
|
assert!(buf.len() <= 0xFFFF);
|
||||||
unborrow!(channel);
|
unborrow!(channel);
|
||||||
@ -136,7 +162,7 @@ mod transfers {
|
|||||||
request: Request,
|
request: Request,
|
||||||
repeated: W,
|
repeated: W,
|
||||||
count: usize,
|
count: usize,
|
||||||
reg_addr: *mut u32,
|
reg_addr: *mut W,
|
||||||
) -> impl Future<Output = ()> + 'a {
|
) -> impl Future<Output = ()> + 'a {
|
||||||
unborrow!(channel);
|
unborrow!(channel);
|
||||||
|
|
||||||
|
@ -415,7 +415,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
|
|||||||
w.set_tcie(true);
|
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 ch = &mut self.tx_dma;
|
||||||
let request = ch.request();
|
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_rxdmaen(true);
|
||||||
w.set_tcie(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 ch = &mut self.rx_dma;
|
||||||
let request = ch.request();
|
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 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;
|
crate::dma::write(ch, request, buffer, dst).await;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -94,7 +94,7 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
let r = self.inner.regs();
|
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;
|
crate::dma::read(ch, request, src, buffer).await;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
let r = self.inner.regs();
|
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;
|
crate::dma::write(ch, request, buffer, dst).await;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -104,7 +104,7 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
let r = self.inner.regs();
|
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;
|
crate::dma::read(ch, request, src, buffer).await;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user