From 8bd420ca7e197cbe9f56660fc4f950ee9a1365e3 Mon Sep 17 00:00:00 2001 From: Dominic Fischer Date: Mon, 30 Sep 2024 21:45:09 +0100 Subject: [PATCH] comments --- esp-hal/CHANGELOG.md | 1 + esp-hal/src/lcd_cam/lcd/i8080.rs | 61 +++++++++++++++++++------------- examples/src/bin/lcd_i8080.rs | 5 ++- 3 files changed, 40 insertions(+), 27 deletions(-) diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index 92197d4e50d..bb42965668e 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -89,6 +89,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Removed the following functions from `GpioPin`: `is_high`, `is_low`, `set_high`, `set_low`, `set_state`, `is_set_high`, `is_set_low`, `toggle`. (#2094) - Removed `Rtc::get_time_raw` (#1883) - Removed `_with_default_pins` UART constructors (#2132) +- Removed transfer methods `send`, `send_dma` and `send_dma_async` from `I8080` (#2191) - Removed `uart::{DefaultRxPin, DefaultTxPin}` (#2132) - Removed `PcntSource` and `PcntInputConfig`. (#2134) - Removed the `place-spi-driver-in-ram` feature, this is now enabled via [esp-config](https://docs.rs/esp-config) (#2156) diff --git a/esp-hal/src/lcd_cam/lcd/i8080.rs b/esp-hal/src/lcd_cam/lcd/i8080.rs index dbd4d3fa32c..45fd953a12e 100644 --- a/esp-hal/src/lcd_cam/lcd/i8080.rs +++ b/esp-hal/src/lcd_cam/lcd/i8080.rs @@ -17,15 +17,14 @@ #![doc = crate::before_snippet!()] //! # use esp_hal::gpio::Io; //! # use esp_hal::lcd_cam::{LcdCam, lcd::i8080::{Config, I8080, TxEightBits}}; -//! # use esp_hal::dma_buffers; +//! # use esp_hal::dma_tx_buffer; //! # use esp_hal::dma::{Dma, DmaPriority, DmaTxBuf}; //! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); //! //! # let dma = Dma::new(peripherals.DMA); //! # let channel = dma.channel0; //! -//! # let (_, _, tx_buffer, tx_descriptors) = dma_buffers!(0, 32678); -//! # let mut dma_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap(); +//! # let mut dma_buf = dma_tx_buffer!(32678).unwrap(); //! //! # let channel = channel.configure( //! # false, @@ -59,7 +58,11 @@ //! # } //! ``` -use core::{fmt::Formatter, marker::PhantomData, mem::size_of}; +use core::{ + fmt::Formatter, + marker::PhantomData, + mem::{size_of, ManuallyDrop}, +}; use fugit::HertzU32; @@ -266,7 +269,7 @@ impl<'d, CH: DmaChannel, DM: Mode> I8080<'d, CH, DM> { cmd: impl Into>, dummy: u8, mut data: BUF, - ) -> Result, (DmaError, Self, BUF)> { + ) -> Result, (DmaError, Self, BUF)> { let cmd = cmd.into(); // Reset LCD control unit and Async Tx FIFO @@ -356,8 +359,8 @@ impl<'d, CH: DmaChannel, DM: Mode> I8080<'d, CH, DM> { }); Ok(I8080Transfer { - i8080: self, - tx_buf: data, + i8080: ManuallyDrop::new(self), + tx_buf: ManuallyDrop::new(data), }) } } @@ -370,12 +373,12 @@ impl<'d, CH: DmaChannel, DM: Mode> core::fmt::Debug for I8080<'d, CH, DM> { /// Represents an ongoing (or potentially finished) transfer using the I8080 LCD /// interface -pub struct I8080Transfer<'d, CH: DmaChannel, DM: Mode, BUF> { - i8080: I8080<'d, CH, DM>, - tx_buf: BUF, +pub struct I8080Transfer<'d, BUF, CH: DmaChannel, DM: Mode> { + i8080: ManuallyDrop>, + tx_buf: ManuallyDrop, } -impl<'d, CH: DmaChannel, DM: Mode, BUF> I8080Transfer<'d, CH, DM, BUF> { +impl<'d, BUF, CH: DmaChannel, DM: Mode> I8080Transfer<'d, BUF, CH, DM> { /// Returns true when [Self::wait] will not block. pub fn is_done(&self) -> bool { self.i8080 @@ -397,7 +400,7 @@ impl<'d, CH: DmaChannel, DM: Mode, BUF> I8080Transfer<'d, CH, DM, BUF> { /// /// Note: This also clears the transfer interrupt so it can be used in /// interrupt handlers to "handle" the interrupt. - pub fn wait(self) -> (Result<(), DmaError>, I8080<'d, CH, DM>, BUF) { + pub fn wait(mut self) -> (Result<(), DmaError>, I8080<'d, CH, DM>, BUF) { while !self.is_done() {} // Clear "done" interrupt. @@ -406,19 +409,22 @@ impl<'d, CH: DmaChannel, DM: Mode, BUF> I8080Transfer<'d, CH, DM, BUF> { .lc_dma_int_clr() .write(|w| w.lcd_trans_done_int_clr().set_bit()); - unsafe { - let i8080 = core::ptr::read(&self.i8080); - let tx_buf = core::ptr::read(&self.tx_buf); + // SAFETY: Since forget is called on self, we know that self.i8080 and + // self.tx_buf won't be touched again. + let (i8080, tx_buf) = unsafe { + let i8080 = ManuallyDrop::take(&mut self.i8080); + let tx_buf = ManuallyDrop::take(&mut self.tx_buf); core::mem::forget(self); + (i8080, tx_buf) + }; - let result = if i8080.tx_channel.has_error() { - Err(DmaError::DescriptorError) - } else { - Ok(()) - }; + let result = if i8080.tx_channel.has_error() { + Err(DmaError::DescriptorError) + } else { + Ok(()) + }; - (result, i8080, tx_buf) - } + (result, i8080, tx_buf) } fn stop_peripherals(&mut self) { @@ -433,7 +439,7 @@ impl<'d, CH: DmaChannel, DM: Mode, BUF> I8080Transfer<'d, CH, DM, BUF> { } } -impl<'d, CH: DmaChannel, BUF> I8080Transfer<'d, CH, crate::Async, BUF> { +impl<'d, BUF, CH: DmaChannel> I8080Transfer<'d, BUF, CH, crate::Async> { /// Waits for [Self::is_done] to return true. pub async fn wait_for_done(&mut self) { use core::{ @@ -472,9 +478,16 @@ impl<'d, CH: DmaChannel, BUF> I8080Transfer<'d, CH, crate::Async, BUF> { } } -impl<'d, CH: DmaChannel, DM: Mode, BUF> Drop for I8080Transfer<'d, CH, DM, BUF> { +impl<'d, BUF, CH: DmaChannel, DM: Mode> Drop for I8080Transfer<'d, BUF, CH, DM> { fn drop(&mut self) { self.stop_peripherals(); + + // SAFETY: This is Drop, we know that self.i8080 and self.tx_buf + // won't be touched again. + unsafe { + ManuallyDrop::drop(&mut self.i8080); + ManuallyDrop::drop(&mut self.tx_buf); + } } } diff --git a/examples/src/bin/lcd_i8080.rs b/examples/src/bin/lcd_i8080.rs index e71e43ff56b..a87c1a2ea72 100644 --- a/examples/src/bin/lcd_i8080.rs +++ b/examples/src/bin/lcd_i8080.rs @@ -26,7 +26,7 @@ use esp_backtrace as _; use esp_hal::{ delay::Delay, dma::{Dma, DmaChannel0, DmaPriority, DmaTxBuf}, - dma_buffers, + dma_tx_buffer, gpio::{Input, Io, Level, Output, Pull}, lcd_cam::{ lcd::i8080::{Config, TxEightBits, I8080}, @@ -52,8 +52,7 @@ fn main() -> ! { let dma = Dma::new(peripherals.DMA); let channel = dma.channel0; - let (_, _, tx_buffer, tx_descriptors) = dma_buffers!(0, 4000); - let dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap(); + let dma_tx_buf = dma_tx_buffer!(4000).unwrap(); let channel = channel.configure(false, DmaPriority::Priority0);