stm32/dma: make lowlevel api take ptrs instead of slices.
This commit is contained in:
parent
97ab859f00
commit
3d27a0e7cb
3 changed files with 48 additions and 29 deletions
|
@ -89,7 +89,8 @@ 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 W) {
|
unsafe fn start_write<W: Word>(&mut self, request: Request, buf: *const[W], reg_addr: *mut W) {
|
||||||
|
let (ptr, len) = super::slice_ptr_parts(buf);
|
||||||
low_level_api::start_transfer(
|
low_level_api::start_transfer(
|
||||||
pac::$dma_peri,
|
pac::$dma_peri,
|
||||||
$channel_num,
|
$channel_num,
|
||||||
|
@ -97,8 +98,8 @@ pac::dma_channels! {
|
||||||
request,
|
request,
|
||||||
vals::Dir::FROMMEMORY,
|
vals::Dir::FROMMEMORY,
|
||||||
reg_addr as *const u32,
|
reg_addr as *const u32,
|
||||||
buf.as_ptr() as *mut u32,
|
ptr as *mut u32,
|
||||||
buf.len(),
|
len,
|
||||||
true,
|
true,
|
||||||
vals::Size::from(W::bits()),
|
vals::Size::from(W::bits()),
|
||||||
#[cfg(dmamux)]
|
#[cfg(dmamux)]
|
||||||
|
@ -129,7 +130,8 @@ pac::dma_channels! {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn start_read<W: Word>(&mut self, request: Request, reg_addr: *mut W, buf: &mut [W]) {
|
unsafe fn start_read<W: Word>(&mut self, request: Request, reg_addr: *const W, buf: *mut [W]) {
|
||||||
|
let (ptr, len) = super::slice_ptr_parts_mut(buf);
|
||||||
low_level_api::start_transfer(
|
low_level_api::start_transfer(
|
||||||
pac::$dma_peri,
|
pac::$dma_peri,
|
||||||
$channel_num,
|
$channel_num,
|
||||||
|
@ -137,8 +139,8 @@ pac::dma_channels! {
|
||||||
request,
|
request,
|
||||||
vals::Dir::FROMPERIPHERAL,
|
vals::Dir::FROMPERIPHERAL,
|
||||||
reg_addr as *const u32,
|
reg_addr as *const u32,
|
||||||
buf.as_ptr() as *mut u32,
|
ptr as *mut u32,
|
||||||
buf.len(),
|
len,
|
||||||
true,
|
true,
|
||||||
vals::Size::from(W::bits()),
|
vals::Size::from(W::bits()),
|
||||||
#[cfg(dmamux)]
|
#[cfg(dmamux)]
|
||||||
|
|
|
@ -84,15 +84,16 @@ 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 W) {
|
unsafe fn start_write<W: Word>(&mut self, request: Request, buf: *const [W], reg_addr: *mut W) {
|
||||||
|
let (ptr, len) = super::slice_ptr_parts(buf);
|
||||||
low_level_api::start_transfer(
|
low_level_api::start_transfer(
|
||||||
pac::$dma_peri,
|
pac::$dma_peri,
|
||||||
$channel_num,
|
$channel_num,
|
||||||
request,
|
request,
|
||||||
vals::Dir::MEMORYTOPERIPHERAL,
|
vals::Dir::MEMORYTOPERIPHERAL,
|
||||||
reg_addr as *const u32,
|
reg_addr as *const u32,
|
||||||
buf.as_ptr() as *mut u32,
|
ptr as *mut u32,
|
||||||
buf.len(),
|
len,
|
||||||
true,
|
true,
|
||||||
vals::Size::from(W::bits()),
|
vals::Size::from(W::bits()),
|
||||||
#[cfg(dmamux)]
|
#[cfg(dmamux)]
|
||||||
|
@ -121,15 +122,16 @@ pac::dma_channels! {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn start_read<W: Word>(&mut self, request: Request, reg_addr: *mut W, buf: &mut [W]) {
|
unsafe fn start_read<W: Word>(&mut self, request: Request, reg_addr: *const W, buf: *mut [W]) {
|
||||||
|
let (ptr, len) = super::slice_ptr_parts_mut(buf);
|
||||||
low_level_api::start_transfer(
|
low_level_api::start_transfer(
|
||||||
pac::$dma_peri,
|
pac::$dma_peri,
|
||||||
$channel_num,
|
$channel_num,
|
||||||
request,
|
request,
|
||||||
vals::Dir::PERIPHERALTOMEMORY,
|
vals::Dir::PERIPHERALTOMEMORY,
|
||||||
reg_addr as *const u32,
|
reg_addr as *const u32,
|
||||||
buf.as_ptr() as *mut u32,
|
ptr as *mut u32,
|
||||||
buf.len(),
|
len,
|
||||||
true,
|
true,
|
||||||
vals::Size::from(W::bits()),
|
vals::Size::from(W::bits()),
|
||||||
#[cfg(dmamux)]
|
#[cfg(dmamux)]
|
||||||
|
|
|
@ -10,6 +10,7 @@ pub use dmamux::*;
|
||||||
|
|
||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
use core::mem;
|
||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
use core::task::Waker;
|
use core::task::Waker;
|
||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
|
@ -36,12 +37,13 @@ pub(crate) mod sealed {
|
||||||
/// Starts this channel for writing a stream of words.
|
/// Starts this channel for writing a stream of words.
|
||||||
///
|
///
|
||||||
/// Safety:
|
/// Safety:
|
||||||
|
/// - `buf` must point to a valid buffer for DMA reading.
|
||||||
/// - `buf` must be alive for the entire duration of the DMA transfer.
|
/// - `buf` must be alive for the entire duration of the DMA transfer.
|
||||||
/// - `reg_addr` must be a valid peripheral register address to write to.
|
/// - `reg_addr` must be a valid peripheral register address to write to.
|
||||||
unsafe fn start_write<W: super::Word>(
|
unsafe fn start_write<W: super::Word>(
|
||||||
&mut self,
|
&mut self,
|
||||||
request: Request,
|
request: Request,
|
||||||
buf: &[W],
|
buf: *const [W],
|
||||||
reg_addr: *mut W,
|
reg_addr: *mut W,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -60,13 +62,14 @@ pub(crate) mod sealed {
|
||||||
/// Starts this channel for reading a stream of words.
|
/// Starts this channel for reading a stream of words.
|
||||||
///
|
///
|
||||||
/// Safety:
|
/// Safety:
|
||||||
|
/// - `buf` must point to a valid buffer for DMA writing.
|
||||||
/// - `buf` must be alive for the entire duration of the DMA transfer.
|
/// - `buf` must be alive for the entire duration of the DMA transfer.
|
||||||
/// - `reg_addr` must be a valid peripheral register address to write to.
|
/// - `reg_addr` must be a valid peripheral register address to read from.
|
||||||
unsafe fn start_read<W: super::Word>(
|
unsafe fn start_read<W: super::Word>(
|
||||||
&mut self,
|
&mut self,
|
||||||
request: Request,
|
request: Request,
|
||||||
reg_addr: *mut W,
|
reg_addr: *const W,
|
||||||
buf: &mut [W],
|
buf: *mut [W],
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Requests the channel to stop.
|
/// Requests the channel to stop.
|
||||||
|
@ -132,10 +135,7 @@ mod transfers {
|
||||||
|
|
||||||
unsafe { channel.start_read::<W>(request, reg_addr, buf) };
|
unsafe { channel.start_read::<W>(request, reg_addr, buf) };
|
||||||
|
|
||||||
Transfer {
|
Transfer::new(channel)
|
||||||
channel,
|
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
|
@ -150,10 +150,7 @@ mod transfers {
|
||||||
|
|
||||||
unsafe { channel.start_write::<W>(request, buf, reg_addr) };
|
unsafe { channel.start_write::<W>(request, buf, reg_addr) };
|
||||||
|
|
||||||
Transfer {
|
Transfer::new(channel)
|
||||||
channel,
|
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
|
@ -168,17 +165,24 @@ mod transfers {
|
||||||
|
|
||||||
unsafe { channel.start_write_repeated::<W>(request, repeated, count, reg_addr) };
|
unsafe { channel.start_write_repeated::<W>(request, repeated, count, reg_addr) };
|
||||||
|
|
||||||
Transfer {
|
Transfer::new(channel)
|
||||||
channel,
|
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Transfer<'a, C: Channel> {
|
pub(crate) struct Transfer<'a, C: Channel> {
|
||||||
channel: C,
|
channel: C,
|
||||||
_phantom: PhantomData<&'a mut C>,
|
_phantom: PhantomData<&'a mut C>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, C: Channel> Transfer<'a, C> {
|
||||||
|
pub(crate) fn new(channel: impl Unborrow<Target = C> + 'a) -> Self {
|
||||||
|
unborrow!(channel);
|
||||||
|
Self {
|
||||||
|
channel,
|
||||||
|
_phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, C: Channel> Drop for Transfer<'a, C> {
|
impl<'a, C: Channel> Drop for Transfer<'a, C> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.channel.request_stop();
|
self.channel.request_stop();
|
||||||
|
@ -221,3 +225,14 @@ pub(crate) unsafe fn init() {
|
||||||
#[cfg(dmamux)]
|
#[cfg(dmamux)]
|
||||||
dmamux::init();
|
dmamux::init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: replace transmutes with core::ptr::metadata once it's stable
|
||||||
|
#[allow(unused)]
|
||||||
|
pub(crate) fn slice_ptr_parts<T>(slice: *const [T]) -> (usize, usize) {
|
||||||
|
unsafe { mem::transmute(slice) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
pub(crate) fn slice_ptr_parts_mut<T>(slice: *mut [T]) -> (usize, usize) {
|
||||||
|
unsafe { mem::transmute(slice) }
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue