From c6207c0f591263a271e2b909f646856a8f5d6cc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Quentin?= Date: Thu, 25 Jul 2024 15:55:02 +0200 Subject: [PATCH] Lift `static` requirement on DMA buffers (#1837) * Lift `static` requirement on DMA buffers * Seal `Word`, use `size_of_val` * Fix * CHANGELOG.md * Use Clippy's safety comment style * Top-level docs regarding mem::forget --- esp-hal/CHANGELOG.md | 1 + esp-hal/Cargo.toml | 1 - esp-hal/src/aes/mod.rs | 8 +- esp-hal/src/dma/gdma.rs | 8 +- esp-hal/src/dma/mod.rs | 186 ++++++++++++++++++++++++-- esp-hal/src/i2s.rs | 35 ++--- esp-hal/src/lcd_cam/cam.rs | 9 +- esp-hal/src/lcd_cam/lcd/i8080.rs | 6 +- esp-hal/src/lib.rs | 11 ++ esp-hal/src/parl_io.rs | 7 +- esp-hal/src/prelude.rs | 7 - esp-hal/src/spi/master.rs | 32 ++--- esp-hal/src/spi/slave.rs | 12 +- hil-test/tests/spi_full_duplex_dma.rs | 14 +- 14 files changed, 255 insertions(+), 82 deletions(-) diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index 60ab17404..e255d1922 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Use the peripheral ref pattern for `OneShotTimer` and `PeriodicTimer` (#1855) - Allow DMA to/from psram for esp32s3 (#1827) +- DMA buffers now don't require a static lifetime. Make sure to never `mem::forget` an in-progress DMA transfer (consider using `#[deny(clippy::mem_forget)]`) (#1837) ### Fixed diff --git a/esp-hal/Cargo.toml b/esp-hal/Cargo.toml index 62f911358..71ae27291 100644 --- a/esp-hal/Cargo.toml +++ b/esp-hal/Cargo.toml @@ -28,7 +28,6 @@ embassy-sync = { version = "0.6.0", optional = true } embassy-usb-driver = { version = "0.1.0", optional = true } embassy-usb-synopsys-otg = { version = "0.1.0", optional = true } embedded-can = { version = "0.4.1", optional = true } -embedded-dma = "0.2.0" embedded-hal-02 = { version = "0.2.7", optional = true, features = ["unproven"], package = "embedded-hal" } embedded-hal = { version = "1.0.0", optional = true } embedded-hal-async = { version = "1.0.0", optional = true } diff --git a/esp-hal/src/aes/mod.rs b/esp-hal/src/aes/mod.rs index 99363307f..794357bc4 100644 --- a/esp-hal/src/aes/mod.rs +++ b/esp-hal/src/aes/mod.rs @@ -220,8 +220,6 @@ pub enum Endianness { /// CTR, CFB8, and CFB128. #[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))] pub mod dma { - use embedded_dma::{ReadBuffer, WriteBuffer}; - use crate::{ aes::{Key, Mode}, dma::{ @@ -235,8 +233,10 @@ pub mod dma { DmaDescriptor, DmaPeripheral, DmaTransferTxRx, + ReadBuffer, RxPrivate, TxPrivate, + WriteBuffer, }, }; @@ -409,8 +409,8 @@ pub mod dma { ) -> Result, crate::dma::DmaError> where K: Into, - TXBUF: ReadBuffer, - RXBUF: WriteBuffer, + TXBUF: ReadBuffer, + RXBUF: WriteBuffer, { let (write_ptr, write_len) = unsafe { words.read_buffer() }; let (read_ptr, read_len) = unsafe { read_buffer.write_buffer() }; diff --git a/esp-hal/src/dma/gdma.rs b/esp-hal/src/dma/gdma.rs index ebdb7af2c..4f5a6c58d 100644 --- a/esp-hal/src/dma/gdma.rs +++ b/esp-hal/src/dma/gdma.rs @@ -638,8 +638,6 @@ impl<'d> Dma<'d> { pub use m2m::*; mod m2m { - use embedded_dma::{ReadBuffer, WriteBuffer}; - #[cfg(esp32s3)] use crate::dma::DmaExtMemBKSize; use crate::dma::{ @@ -653,8 +651,10 @@ mod m2m { DmaError, DmaPeripheral, DmaTransferRx, + ReadBuffer, RxPrivate, TxPrivate, + WriteBuffer, }; /// DMA Memory to Memory pseudo-Peripheral @@ -751,8 +751,8 @@ mod m2m { rx_buffer: &'t mut RXBUF, ) -> Result, DmaError> where - TXBUF: ReadBuffer, - RXBUF: WriteBuffer, + TXBUF: ReadBuffer, + RXBUF: WriteBuffer, { let (tx_ptr, tx_len) = unsafe { tx_buffer.read_buffer() }; let (rx_ptr, rx_len) = unsafe { rx_buffer.write_buffer() }; diff --git a/esp-hal/src/dma/mod.rs b/esp-hal/src/dma/mod.rs index 3d26f6ddc..535c35335 100644 --- a/esp-hal/src/dma/mod.rs +++ b/esp-hal/src/dma/mod.rs @@ -54,6 +54,135 @@ use core::{fmt::Debug, marker::PhantomData, ptr::addr_of_mut, sync::atomic::compiler_fence}; +trait Word: crate::private::Sealed {} + +macro_rules! impl_word { + ($w:ty) => { + impl $crate::private::Sealed for $w {} + impl Word for $w {} + }; +} + +impl_word!(u8); +impl_word!(u16); +impl_word!(u32); +impl_word!(i8); +impl_word!(i16); +impl_word!(i32); + +impl crate::private::Sealed for [W; S] where W: Word {} + +impl crate::private::Sealed for &[W; S] where W: Word {} + +impl crate::private::Sealed for &[W] where W: Word {} + +impl crate::private::Sealed for &mut [W] where W: Word {} + +/// Trait for buffers that can be given to DMA for reading. +pub trait ReadBuffer: crate::private::Sealed { + /// Provide a buffer usable for DMA reads. + /// + /// The return value is: + /// + /// - pointer to the start of the buffer + /// - buffer size in bytes + /// + /// # Safety + /// + /// Once this method has been called, it is unsafe to call any `&mut self` + /// methods on this object as long as the returned value is in use (by DMA). + unsafe fn read_buffer(&self) -> (*const u8, usize); +} + +impl ReadBuffer for [W; S] +where + W: Word, +{ + unsafe fn read_buffer(&self) -> (*const u8, usize) { + (self.as_ptr() as *const u8, core::mem::size_of_val(self)) + } +} + +impl ReadBuffer for &[W; S] +where + W: Word, +{ + unsafe fn read_buffer(&self) -> (*const u8, usize) { + (self.as_ptr() as *const u8, core::mem::size_of_val(*self)) + } +} + +impl ReadBuffer for &mut [W; S] +where + W: Word, +{ + unsafe fn read_buffer(&self) -> (*const u8, usize) { + (self.as_ptr() as *const u8, core::mem::size_of_val(*self)) + } +} + +impl ReadBuffer for &[W] +where + W: Word, +{ + unsafe fn read_buffer(&self) -> (*const u8, usize) { + (self.as_ptr() as *const u8, core::mem::size_of_val(*self)) + } +} + +impl ReadBuffer for &mut [W] +where + W: Word, +{ + unsafe fn read_buffer(&self) -> (*const u8, usize) { + (self.as_ptr() as *const u8, core::mem::size_of_val(*self)) + } +} + +/// Trait for buffers that can be given to DMA for writing. +pub trait WriteBuffer: crate::private::Sealed { + /// Provide a buffer usable for DMA writes. + /// + /// The return value is: + /// + /// - pointer to the start of the buffer + /// - buffer size in bytes + /// + /// # Safety + /// + /// Once this method has been called, it is unsafe to call any `&mut self` + /// methods, except for `write_buffer`, on this object as long as the + /// returned value is in use (by DMA). + unsafe fn write_buffer(&mut self) -> (*mut u8, usize); +} + +impl WriteBuffer for [W; S] +where + W: Word, +{ + unsafe fn write_buffer(&mut self) -> (*mut u8, usize) { + (self.as_mut_ptr() as *mut u8, core::mem::size_of_val(self)) + } +} + +impl WriteBuffer for &mut [W; S] +where + W: Word, +{ + unsafe fn write_buffer(&mut self) -> (*mut u8, usize) { + (self.as_mut_ptr() as *mut u8, core::mem::size_of_val(*self)) + } +} + +impl WriteBuffer for &mut [W] +where + W: Word, +{ + unsafe fn write_buffer(&mut self) -> (*mut u8, usize) { + (self.as_mut_ptr() as *mut u8, core::mem::size_of_val(*self)) + } +} + bitfield::bitfield! { #[doc(hidden)] #[derive(Clone, Copy)] @@ -130,7 +259,6 @@ impl DmaDescriptor { } } -use embedded_dma::{ReadBuffer, WriteBuffer}; use enumset::{EnumSet, EnumSetType}; #[cfg(gdma)] @@ -1741,6 +1869,10 @@ pub(crate) mod dma_private { } /// DMA transaction for TX only transfers +/// +/// # Safety +/// +/// Never use [core::mem::forget] on an in-progress transfer #[non_exhaustive] #[must_use] pub struct DmaTransferTx<'a, I> @@ -1785,6 +1917,10 @@ where } /// DMA transaction for RX only transfers +/// +/// # Safety +/// +/// Never use [core::mem::forget] on an in-progress transfer #[non_exhaustive] #[must_use] pub struct DmaTransferRx<'a, I> @@ -1829,6 +1965,10 @@ where } /// DMA transaction for TX+RX transfers +/// +/// # Safety +/// +/// Never use [core::mem::forget] on an in-progress transfer #[non_exhaustive] #[must_use] pub struct DmaTransferTxRx<'a, I> @@ -1874,12 +2014,16 @@ where /// DMA transaction for TX transfers with moved-in/moved-out peripheral and /// buffer +/// +/// # Safety +/// +/// Never use [core::mem::forget] on an in-progress transfer #[non_exhaustive] #[must_use] pub struct DmaTransferTxOwned where I: dma_private::DmaSupportTx, - T: ReadBuffer, + T: ReadBuffer, { instance: I, tx_buffer: T, @@ -1888,7 +2032,7 @@ where impl DmaTransferTxOwned where I: dma_private::DmaSupportTx, - T: ReadBuffer, + T: ReadBuffer, { pub(crate) fn new(instance: I, tx_buffer: T) -> Self { Self { @@ -1936,7 +2080,7 @@ where impl Drop for DmaTransferTxOwned where I: dma_private::DmaSupportTx, - T: ReadBuffer, + T: ReadBuffer, { fn drop(&mut self) { self.instance.peripheral_wait_dma(true, false); @@ -1945,12 +2089,16 @@ where /// DMA transaction for RX transfers with moved-in/moved-out peripheral and /// buffer +/// +/// # Safety +/// +/// Never use [core::mem::forget] on an in-progress transfer #[non_exhaustive] #[must_use] pub struct DmaTransferRxOwned where I: dma_private::DmaSupportRx, - R: WriteBuffer, + R: WriteBuffer, { instance: I, rx_buffer: R, @@ -1959,7 +2107,7 @@ where impl DmaTransferRxOwned where I: dma_private::DmaSupportRx, - R: WriteBuffer, + R: WriteBuffer, { pub(crate) fn new(instance: I, rx_buffer: R) -> Self { Self { @@ -2007,7 +2155,7 @@ where impl Drop for DmaTransferRxOwned where I: dma_private::DmaSupportRx, - R: WriteBuffer, + R: WriteBuffer, { fn drop(&mut self) { self.instance.peripheral_wait_dma(false, true); @@ -2016,13 +2164,17 @@ where /// DMA transaction for TX+RX transfers with moved-in/moved-out peripheral and /// buffers +/// +/// # Safety +/// +/// Never use [core::mem::forget] on an in-progress transfer #[non_exhaustive] #[must_use] pub struct DmaTransferTxRxOwned where I: dma_private::DmaSupportTx + dma_private::DmaSupportRx, - T: ReadBuffer, - R: WriteBuffer, + T: ReadBuffer, + R: WriteBuffer, { instance: I, tx_buffer: T, @@ -2032,8 +2184,8 @@ where impl DmaTransferTxRxOwned where I: dma_private::DmaSupportTx + dma_private::DmaSupportRx, - T: ReadBuffer, - R: WriteBuffer, + T: ReadBuffer, + R: WriteBuffer, { pub(crate) fn new(instance: I, tx_buffer: T, rx_buffer: R) -> Self { Self { @@ -2084,8 +2236,8 @@ where impl Drop for DmaTransferTxRxOwned where I: dma_private::DmaSupportTx + dma_private::DmaSupportRx, - T: ReadBuffer, - R: WriteBuffer, + T: ReadBuffer, + R: WriteBuffer, { fn drop(&mut self) { self.instance.peripheral_wait_dma(true, true); @@ -2093,6 +2245,10 @@ where } /// DMA transaction for TX only circular transfers +/// +/// # Safety +/// +/// Never use [core::mem::forget] on an in-progress transfer #[non_exhaustive] #[must_use] pub struct DmaTransferTxCircular<'a, I> @@ -2157,6 +2313,10 @@ where } /// DMA transaction for RX only circular transfers +/// +/// # Safety +/// +/// Never use [core::mem::forget] on an in-progress transfer #[non_exhaustive] #[must_use] pub struct DmaTransferRxCircular<'a, I> diff --git a/esp-hal/src/i2s.rs b/esp-hal/src/i2s.rs index 5c12e69b3..ee8cac44d 100644 --- a/esp-hal/src/i2s.rs +++ b/esp-hal/src/i2s.rs @@ -82,7 +82,6 @@ use core::marker::PhantomData; -use embedded_dma::{ReadBuffer, WriteBuffer}; use enumset::{EnumSet, EnumSetType}; use private::*; @@ -105,8 +104,10 @@ use crate::{ DmaTransferTxCircular, I2s0Peripheral, I2sPeripheral, + ReadBuffer, RxPrivate, TxPrivate, + WriteBuffer, }, gpio::OutputPin, interrupt::InterruptHandler, @@ -252,7 +253,7 @@ where /// transfer fn write_dma<'t>(&'t mut self, words: &'t TXBUF) -> Result, Error> where - TXBUF: ReadBuffer; + TXBUF: ReadBuffer; /// Continuously write to I2S. Returns [DmaTransferTxCircular] which /// represents the in-progress DMA transfer @@ -261,7 +262,7 @@ where words: &'t TXBUF, ) -> Result, Error> where - TXBUF: ReadBuffer; + TXBUF: ReadBuffer; } /// Blocking I2S Read @@ -282,7 +283,7 @@ where /// transfer fn read_dma<'t>(&'t mut self, words: &'t mut RXBUF) -> Result, Error> where - RXBUF: WriteBuffer; + RXBUF: WriteBuffer; /// Continuously read from I2S. /// Returns [DmaTransferRxCircular] which represents the in-progress DMA @@ -292,7 +293,7 @@ where words: &'t mut RXBUF, ) -> Result, Error> where - RXBUF: WriteBuffer; + RXBUF: WriteBuffer; } /// Instance of the I2S peripheral driver @@ -588,7 +589,7 @@ where circular: bool, ) -> Result<(), Error> where - TXBUF: ReadBuffer, + TXBUF: ReadBuffer, DmaMode: Mode, { let (ptr, len) = unsafe { words.read_buffer() }; @@ -647,7 +648,7 @@ where { fn write_dma<'t>(&'t mut self, words: &'t TXBUF) -> Result, Error> where - TXBUF: ReadBuffer, + TXBUF: ReadBuffer, { self.start_tx_transfer(words, false)?; Ok(DmaTransferTx::new(self)) @@ -658,7 +659,7 @@ where words: &'t TXBUF, ) -> Result, Error> where - TXBUF: ReadBuffer, + TXBUF: ReadBuffer, { self.start_tx_transfer(words, true)?; Ok(DmaTransferTxCircular::new(self)) @@ -769,7 +770,7 @@ where circular: bool, ) -> Result<(), Error> where - RXBUF: WriteBuffer, + RXBUF: WriteBuffer, { let (ptr, len) = unsafe { words.write_buffer() }; @@ -828,7 +829,7 @@ where { fn read_dma<'t>(&'t mut self, words: &'t mut RXBUF) -> Result, Error> where - RXBUF: WriteBuffer, + RXBUF: WriteBuffer, { self.start_rx_transfer(words, false)?; Ok(DmaTransferRx::new(self)) @@ -839,7 +840,7 @@ where words: &'t mut RXBUF, ) -> Result, Error> where - RXBUF: WriteBuffer, + RXBUF: WriteBuffer, { self.start_rx_transfer(words, true)?; Ok(DmaTransferRxCircular::new(self)) @@ -2151,17 +2152,17 @@ mod private { #[cfg(feature = "async")] pub mod asynch { - use embedded_dma::{ReadBuffer, WriteBuffer}; - use super::{Error, I2sRx, I2sTx, RegisterAccess}; use crate::{ dma::{ asynch::{DmaRxDoneChFuture, DmaRxFuture, DmaTxDoneChFuture, DmaTxFuture}, DmaChannel, + ReadBuffer, RxCircularState, RxPrivate, TxCircularState, TxPrivate, + WriteBuffer, }, Async, }; @@ -2181,7 +2182,7 @@ pub mod asynch { words: TXBUF, ) -> Result, Error> where - TXBUF: ReadBuffer; + TXBUF: ReadBuffer; } impl<'d, T, CH> I2sWriteDmaAsync<'d, T, CH> for super::I2sTx<'d, T, CH, Async> @@ -2215,7 +2216,7 @@ pub mod asynch { words: TXBUF, ) -> Result, Error> where - TXBUF: ReadBuffer, + TXBUF: ReadBuffer, { let (ptr, len) = unsafe { words.read_buffer() }; @@ -2315,7 +2316,7 @@ pub mod asynch { words: RXBUF, ) -> Result, Error> where - RXBUF: WriteBuffer; + RXBUF: WriteBuffer; } impl<'d, T, CH> I2sReadDmaAsync<'d, T, CH> for super::I2sRx<'d, T, CH, Async> @@ -2363,7 +2364,7 @@ pub mod asynch { mut words: RXBUF, ) -> Result, Error> where - RXBUF: WriteBuffer, + RXBUF: WriteBuffer, { let (ptr, len) = unsafe { words.write_buffer() }; diff --git a/esp-hal/src/lcd_cam/cam.rs b/esp-hal/src/lcd_cam/cam.rs index 328e9aaa8..90cacf692 100644 --- a/esp-hal/src/lcd_cam/cam.rs +++ b/esp-hal/src/lcd_cam/cam.rs @@ -64,9 +64,6 @@ //! # } //! ``` -use core::mem::size_of; - -use embedded_dma::WriteBuffer; use fugit::HertzU32; use crate::{ @@ -83,6 +80,7 @@ use crate::{ DmaTransferRxCircular, LcdCamPeripheral, RxPrivate, + WriteBuffer, }, gpio::{InputPin, InputSignal, OutputPin, OutputSignal}, lcd_cam::{cam::private::RxPins, private::calculate_clkm, BitOrder, ByteOrder}, @@ -380,11 +378,10 @@ impl<'d, CH: DmaChannel> Camera<'d, CH> { ) -> Result<(), DmaError> { let (ptr, len) = unsafe { buf.write_buffer() }; - assert_eq!(self.bus_width, size_of::()); + assert!(len % self.bus_width == 0); unsafe { - self.rx_chain - .fill_for_rx(circular, ptr as _, len * size_of::())?; + self.rx_chain.fill_for_rx(circular, ptr as _, len)?; self.rx_channel .prepare_transfer_without_start(DmaPeripheral::LcdCam, &self.rx_chain)?; } diff --git a/esp-hal/src/lcd_cam/lcd/i8080.rs b/esp-hal/src/lcd_cam/lcd/i8080.rs index c7845e88a..f2413ee17 100644 --- a/esp-hal/src/lcd_cam/lcd/i8080.rs +++ b/esp-hal/src/lcd_cam/lcd/i8080.rs @@ -59,7 +59,6 @@ use core::{fmt::Formatter, mem::size_of}; -use embedded_dma::ReadBuffer; use fugit::HertzU32; use crate::{ @@ -74,6 +73,7 @@ use crate::{ DmaPeripheral, DmaTransferTx, LcdCamPeripheral, + ReadBuffer, TxPrivate, }, gpio::{OutputPin, OutputSignal}, @@ -352,12 +352,12 @@ where data: &'t TXBUF, ) -> Result, DmaError> where - TXBUF: ReadBuffer, + TXBUF: ReadBuffer, { let (ptr, len) = unsafe { data.read_buffer() }; self.setup_send(cmd.into(), dummy); - self.start_write_bytes_dma(ptr as _, len * size_of::())?; + self.start_write_bytes_dma(ptr as _, len)?; self.start_send(); Ok(DmaTransferTx::new(self)) diff --git a/esp-hal/src/lib.rs b/esp-hal/src/lib.rs index d7ddc5f44..e9ae04b8f 100644 --- a/esp-hal/src/lib.rs +++ b/esp-hal/src/lib.rs @@ -115,6 +115,17 @@ //! dropped. Then it's possible to reuse the pin/peripheral for a different //! purpose. //! +//! ## Don't use [core::mem::forget] +//! +//! In general drivers are _NOT_ safe to use with [core::mem::forget] +//! +//! You should never use [core::mem::forget] on any type defined in the HAL. +//! +//! Some types heavily rely on their [Drop] implementation to not leave the +//! hardware in undefined state and causing UB. +//! +//! You might want to consider using [`#[deny(clippy::mem_forget)`](https://rust-lang.github.io/rust-clippy/v0.0.212/index.html#mem_forget) in your project. +//! //! [documentation]: https://docs.esp-rs.org/esp-hal //! [examples]: https://github.com/esp-rs/esp-hal/tree/main/examples //! [embedded-hal]: https://github.com/rust-embedded/embedded-hal/tree/master/embedded-hal diff --git a/esp-hal/src/parl_io.rs b/esp-hal/src/parl_io.rs index 8f8b185fc..253a7f181 100644 --- a/esp-hal/src/parl_io.rs +++ b/esp-hal/src/parl_io.rs @@ -27,7 +27,6 @@ use core::marker::PhantomData; -use embedded_dma::{ReadBuffer, WriteBuffer}; use enumset::{EnumSet, EnumSetType}; use fugit::HertzU32; use peripheral::PeripheralRef; @@ -48,8 +47,10 @@ use crate::{ DmaTransferRx, DmaTransferTx, ParlIoPeripheral, + ReadBuffer, RxPrivate, TxPrivate, + WriteBuffer, }, gpio::{InputPin, OutputPin}, interrupt::InterruptHandler, @@ -1431,7 +1432,7 @@ where words: &'t TXBUF, ) -> Result, Error> where - TXBUF: ReadBuffer, + TXBUF: ReadBuffer, { let (ptr, len) = unsafe { words.read_buffer() }; @@ -1527,7 +1528,7 @@ where words: &'t mut RXBUF, ) -> Result, Error> where - RXBUF: WriteBuffer, + RXBUF: WriteBuffer, { let (ptr, len) = unsafe { words.write_buffer() }; diff --git a/esp-hal/src/prelude.rs b/esp-hal/src/prelude.rs index 5a5679fe6..32c9a1cd8 100644 --- a/esp-hal/src/prelude.rs +++ b/esp-hal/src/prelude.rs @@ -6,13 +6,6 @@ //! things, particularly traits, which are used in almost every single Rust //! program. -pub use embedded_dma::{ - ReadBuffer as _embedded_dma_ReadBuffer, - ReadTarget as _embedded_dma_ReadTarget, - Word as _embedded_dma_Word, - WriteBuffer as _embedded_dma_WriteBuffer, - WriteTarget as _embedded_dma_WriteTarget, -}; pub use fugit::{ExtU64 as _fugit_ExtU64, RateExtU32 as _fugit_RateExtU32}; pub use nb; diff --git a/esp-hal/src/spi/master.rs b/esp-hal/src/spi/master.rs index 63579dfc2..3b83851d7 100644 --- a/esp-hal/src/spi/master.rs +++ b/esp-hal/src/spi/master.rs @@ -839,8 +839,6 @@ where } pub mod dma { - use embedded_dma::{ReadBuffer, WriteBuffer}; - use super::*; #[cfg(spi3)] use crate::dma::Spi3Peripheral; @@ -859,9 +857,11 @@ pub mod dma { DmaTransferTxOwned, DmaTransferTxRx, DmaTransferTxRxOwned, + ReadBuffer, Spi2Peripheral, SpiPeripheral, TxPrivate, + WriteBuffer, }, InterruptConfigurable, Mode, @@ -1125,7 +1125,7 @@ pub mod dma { words: &'t TXBUF, ) -> Result, super::Error> where - TXBUF: ReadBuffer, + TXBUF: ReadBuffer, { self.dma_write_start(words)?; Ok(DmaTransferTx::new(self)) @@ -1142,7 +1142,7 @@ pub mod dma { words: TXBUF, ) -> Result, super::Error> where - TXBUF: ReadBuffer, + TXBUF: ReadBuffer, { self.dma_write_start(&words)?; Ok(DmaTransferTxOwned::new(self, words)) @@ -1151,7 +1151,7 @@ pub mod dma { #[cfg_attr(feature = "place-spi-driver-in-ram", ram)] fn dma_write_start<'t, TXBUF>(&'t mut self, words: &'t TXBUF) -> Result<(), super::Error> where - TXBUF: ReadBuffer, + TXBUF: ReadBuffer, { let (ptr, len) = unsafe { words.read_buffer() }; @@ -1180,7 +1180,7 @@ pub mod dma { words: &'t mut RXBUF, ) -> Result, super::Error> where - RXBUF: WriteBuffer, + RXBUF: WriteBuffer, { self.dma_read_start(words)?; Ok(DmaTransferRx::new(self)) @@ -1197,7 +1197,7 @@ pub mod dma { mut words: RXBUF, ) -> Result, super::Error> where - RXBUF: WriteBuffer, + RXBUF: WriteBuffer, { self.dma_read_start(&mut words)?; Ok(DmaTransferRxOwned::new(self, words)) @@ -1206,7 +1206,7 @@ pub mod dma { #[cfg_attr(feature = "place-spi-driver-in-ram", ram)] fn dma_read_start<'t, RXBUF>(&'t mut self, words: &'t mut RXBUF) -> Result<(), super::Error> where - RXBUF: WriteBuffer, + RXBUF: WriteBuffer, { let (ptr, len) = unsafe { words.write_buffer() }; @@ -1236,8 +1236,8 @@ pub mod dma { read_buffer: &'t mut RXBUF, ) -> Result, super::Error> where - TXBUF: ReadBuffer, - RXBUF: WriteBuffer, + TXBUF: ReadBuffer, + RXBUF: WriteBuffer, { self.dma_transfer_start(words, read_buffer)?; Ok(DmaTransferTxRx::new(self)) @@ -1254,8 +1254,8 @@ pub mod dma { mut read_buffer: RXBUF, ) -> Result, super::Error> where - TXBUF: ReadBuffer, - RXBUF: WriteBuffer, + TXBUF: ReadBuffer, + RXBUF: WriteBuffer, { self.dma_transfer_start(&words, &mut read_buffer)?; Ok(DmaTransferTxRxOwned::new(self, words, read_buffer)) @@ -1267,8 +1267,8 @@ pub mod dma { read_buffer: &'t mut RXBUF, ) -> Result<(), super::Error> where - TXBUF: ReadBuffer, - RXBUF: WriteBuffer, + TXBUF: ReadBuffer, + RXBUF: WriteBuffer, { let (write_ptr, write_len) = unsafe { words.read_buffer() }; let (read_ptr, read_len) = unsafe { read_buffer.write_buffer() }; @@ -1312,7 +1312,7 @@ pub mod dma { buffer: &'t mut RXBUF, ) -> Result, super::Error> where - RXBUF: WriteBuffer, + RXBUF: WriteBuffer, { let (ptr, len) = unsafe { buffer.write_buffer() }; @@ -1391,7 +1391,7 @@ pub mod dma { buffer: &'t TXBUF, ) -> Result, super::Error> where - TXBUF: ReadBuffer, + TXBUF: ReadBuffer, { let (ptr, len) = unsafe { buffer.read_buffer() }; diff --git a/esp-hal/src/spi/slave.rs b/esp-hal/src/spi/slave.rs index 60862bbe9..876af4d5f 100644 --- a/esp-hal/src/spi/slave.rs +++ b/esp-hal/src/spi/slave.rs @@ -144,8 +144,6 @@ where } pub mod dma { - use embedded_dma::{ReadBuffer, WriteBuffer}; - use super::*; #[cfg(spi3)] use crate::dma::Spi3Peripheral; @@ -161,10 +159,12 @@ pub mod dma { DmaTransferRx, DmaTransferTx, DmaTransferTxRx, + ReadBuffer, RxPrivate, Spi2Peripheral, SpiPeripheral, TxPrivate, + WriteBuffer, }, Mode, }; @@ -346,7 +346,7 @@ pub mod dma { words: &'t TXBUF, ) -> Result, Error> where - TXBUF: ReadBuffer, + TXBUF: ReadBuffer, { let (ptr, len) = unsafe { words.read_buffer() }; @@ -372,7 +372,7 @@ pub mod dma { words: &'t mut RXBUF, ) -> Result, Error> where - RXBUF: WriteBuffer, + RXBUF: WriteBuffer, { let (ptr, len) = unsafe { words.write_buffer() }; @@ -400,8 +400,8 @@ pub mod dma { read_buffer: &'t mut RXBUF, ) -> Result, Error> where - TXBUF: ReadBuffer, - RXBUF: WriteBuffer, + TXBUF: ReadBuffer, + RXBUF: WriteBuffer, { let (write_ptr, write_len) = unsafe { words.read_buffer() }; let (read_ptr, read_len) = unsafe { read_buffer.write_buffer() }; diff --git a/hil-test/tests/spi_full_duplex_dma.rs b/hil-test/tests/spi_full_duplex_dma.rs index 15d2b2510..f57f377fa 100644 --- a/hil-test/tests/spi_full_duplex_dma.rs +++ b/hil-test/tests/spi_full_duplex_dma.rs @@ -193,7 +193,12 @@ mod tests { let tx_buffer = { // using `static`, not `static mut`, places the array in .rodata static TX_BUFFER: [u8; DMA_BUFFER_SIZE] = [42u8; DMA_BUFFER_SIZE]; - unsafe { &mut *(core::ptr::addr_of!(TX_BUFFER) as *mut u8) } + unsafe { + core::slice::from_raw_parts( + &mut *(core::ptr::addr_of!(TX_BUFFER) as *mut u8), + DMA_BUFFER_SIZE, + ) + } }; let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks) @@ -241,7 +246,12 @@ mod tests { let rx_buffer = { // using `static`, not `static mut`, places the array in .rodata static RX_BUFFER: [u8; DMA_BUFFER_SIZE] = [42u8; DMA_BUFFER_SIZE]; - unsafe { &mut *(core::ptr::addr_of!(RX_BUFFER) as *mut u8) } + unsafe { + core::slice::from_raw_parts_mut( + &mut *(core::ptr::addr_of!(RX_BUFFER) as *mut u8), + DMA_BUFFER_SIZE, + ) + } }; let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)