diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs index 3d06b635..29c9fd59 100644 --- a/embassy-stm32/src/dma/bdma.rs +++ b/embassy-stm32/src/dma/bdma.rs @@ -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(&mut self, request: Request, buf: &[W], reg_addr: *mut u32) { + unsafe fn start_write(&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(&mut self, request: Request, repeated: W, count: usize, reg_addr: *mut u32) { + unsafe fn start_write_repeated(&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(&mut self, request: Request, reg_addr: *mut u32, buf: &mut [W]) { + unsafe fn start_read(&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, diff --git a/embassy-stm32/src/dma/dma.rs b/embassy-stm32/src/dma/dma.rs index baed2460..05d62ef8 100644 --- a/embassy-stm32/src/dma/dma.rs +++ b/embassy-stm32/src/dma/dma.rs @@ -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(&mut self, request: Request, buf: &[W], reg_addr: *mut u32) { + unsafe fn start_write(&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(&mut self, request: Request, repeated: W, count: usize, reg_addr: *mut u32) { + unsafe fn start_write_repeated(&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(&mut self, request: Request, reg_addr: *mut u32, buf: &mut [W]) { + unsafe fn start_read(&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); diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs index 5e4b5d3d..accc5565 100644 --- a/embassy-stm32/src/dma/mod.rs +++ b/embassy-stm32/src/dma/mod.rs @@ -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(&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( + &mut self, + request: Request, + buf: &[W], + reg_addr: *mut W, + ); /// Starts this channel for writing a word repeatedly. - unsafe fn start_write_repeated( + /// + /// Safety: + /// - `reg_addr` must be a valid peripheral register address to write to. + unsafe fn start_write_repeated( &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( + /// + /// 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( &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 + 'a, request: Request, - reg_addr: *mut u32, + reg_addr: *mut W, buf: &'a mut [W], ) -> impl Future + 'a { assert!(buf.len() <= 0xFFFF); @@ -117,7 +143,7 @@ mod transfers { channel: impl Unborrow + 'a, request: Request, buf: &'a [W], - reg_addr: *mut u32, + reg_addr: *mut W, ) -> impl Future + '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 + 'a { unborrow!(channel); diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index af3ac74b..94c4d9a7 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -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(); diff --git a/embassy-stm32/src/usart/v1.rs b/embassy-stm32/src/usart/v1.rs index 3a8c1d34..10f87f2d 100644 --- a/embassy-stm32/src/usart/v1.rs +++ b/embassy-stm32/src/usart/v1.rs @@ -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(()) } diff --git a/embassy-stm32/src/usart/v2.rs b/embassy-stm32/src/usart/v2.rs index cd70afec..697adf45 100644 --- a/embassy-stm32/src/usart/v2.rs +++ b/embassy-stm32/src/usart/v2.rs @@ -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(())