stm32/dma: make lowlevel api take ptrs instead of slices.
This commit is contained in:
		
							parent
							
								
									97ab859f00
								
							
						
					
					
						commit
						3d27a0e7cb
					
				@ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user