From a8944a867c97ec8600cf543d91d82580219b5814 Mon Sep 17 00:00:00 2001 From: Dominic Fischer Date: Sun, 23 Jun 2024 00:33:27 +0100 Subject: [PATCH 1/2] Expose optional HSYNC input in LCD_CAM --- esp-hal/CHANGELOG.md | 1 + esp-hal/src/lcd_cam/cam.rs | 46 ++++++++++++++++++++++++++---- examples/src/bin/lcd_cam_ov2640.rs | 3 +- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index 3e34af3bff0..16608e529bd 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add new `DmaError::UnsupportedMemoryRegion` - used memory regions are checked when preparing a transfer now (#1670) - Add DmaTransactionTxOwned, DmaTransactionRxOwned, DmaTransactionTxRxOwned, functions to do owning transfers added to SPI half-duplex (#1672) - uart: Implement `embedded_io::ReadReady` for `Uart` and `UartRx` (#1702) +- ESP32-S3: Expose optional HSYNC input in LCD_CAM (#1707) ### Fixed diff --git a/esp-hal/src/lcd_cam/cam.rs b/esp-hal/src/lcd_cam/cam.rs index 6526ca12d67..8abda6e4b2e 100644 --- a/esp-hal/src/lcd_cam/cam.rs +++ b/esp-hal/src/lcd_cam/cam.rs @@ -52,7 +52,8 @@ //! let mut camera = //! Camera::new(lcd_cam.cam, channel.rx, data_pins, 20u32.MHz(), &clocks) //! .with_master_clock(mclk_pin) // Remove this for slave mode. -//! .with_ctrl_pins(vsync_pin, href_pin, pclk_pin); +//! .with_pixel_clock(pclk_pin) +//! .with_ctrl_pins(vsync_pin, href_pin); //! # } //! ``` @@ -274,22 +275,55 @@ impl<'d, RX: Rx> Camera<'d, RX> { self } - pub fn with_ctrl_pins( + pub fn with_pixel_clock(self, pclk: impl Peripheral

+ 'd) -> Self { + crate::into_ref!(pclk); + + pclk.set_to_input(crate::private::Internal); + pclk.connect_input_to_peripheral(InputSignal::CAM_PCLK, crate::private::Internal); + + self + } + + pub fn with_ctrl_pins( self, vsync: impl Peripheral

+ 'd, h_enable: impl Peripheral

+ 'd, - pclk: impl Peripheral

+ 'd, ) -> Self { crate::into_ref!(vsync); crate::into_ref!(h_enable); - crate::into_ref!(pclk); vsync.set_to_input(crate::private::Internal); vsync.connect_input_to_peripheral(InputSignal::CAM_V_SYNC, crate::private::Internal); h_enable.set_to_input(crate::private::Internal); h_enable.connect_input_to_peripheral(InputSignal::CAM_H_ENABLE, crate::private::Internal); - pclk.set_to_input(crate::private::Internal); - pclk.connect_input_to_peripheral(InputSignal::CAM_PCLK, crate::private::Internal); + + self.lcd_cam + .cam_ctrl1() + .modify(|_, w| w.cam_vh_de_mode_en().clear_bit()); + + self + } + + pub fn with_ctrl_pins_and_de( + self, + vsync: impl Peripheral

+ 'd, + hsync: impl Peripheral

+ 'd, + h_enable: impl Peripheral

+ 'd, + ) -> Self { + crate::into_ref!(vsync); + crate::into_ref!(hsync); + crate::into_ref!(h_enable); + + vsync.set_to_input(crate::private::Internal); + vsync.connect_input_to_peripheral(InputSignal::CAM_V_SYNC, crate::private::Internal); + hsync.set_to_input(crate::private::Internal); + hsync.connect_input_to_peripheral(InputSignal::CAM_H_SYNC, crate::private::Internal); + h_enable.set_to_input(crate::private::Internal); + h_enable.connect_input_to_peripheral(InputSignal::CAM_H_ENABLE, crate::private::Internal); + + self.lcd_cam + .cam_ctrl1() + .modify(|_, w| w.cam_vh_de_mode_en().set_bit()); self } diff --git a/examples/src/bin/lcd_cam_ov2640.rs b/examples/src/bin/lcd_cam_ov2640.rs index b1c9860936e..20a124bc734 100644 --- a/examples/src/bin/lcd_cam_ov2640.rs +++ b/examples/src/bin/lcd_cam_ov2640.rs @@ -83,7 +83,8 @@ fn main() -> ! { let lcd_cam = LcdCam::new(peripherals.LCD_CAM); let mut camera = Camera::new(lcd_cam.cam, channel.rx, cam_data_pins, 20u32.MHz(), &clocks) .with_master_clock(cam_xclk) - .with_ctrl_pins(cam_vsync, cam_href, cam_pclk); + .with_pixel_clock(cam_pclk) + .with_ctrl_pins(cam_vsync, cam_href); let delay = Delay::new(&clocks); From 0b6abc1a6d6e0311fdbcc1a94335ce5b1b260afc Mon Sep 17 00:00:00 2001 From: Dominic Fischer Date: Sun, 23 Jun 2024 00:08:08 +0100 Subject: [PATCH 2/2] Fix DMA wait check in LCD_CAM --- esp-hal/CHANGELOG.md | 2 ++ esp-hal/src/lcd_cam/cam.rs | 24 ++++++++++++++++-------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index 16608e529bd..50584609699 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -20,6 +20,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- ESP32-S3: Fix DMA waiting check in LCD_CAM (#1707) + ### Changed - Refactor `Dac1`/`Dac2` drivers into a single `Dac` driver (#1661) diff --git a/esp-hal/src/lcd_cam/cam.rs b/esp-hal/src/lcd_cam/cam.rs index 8abda6e4b2e..1162d86403f 100644 --- a/esp-hal/src/lcd_cam/cam.rs +++ b/esp-hal/src/lcd_cam/cam.rs @@ -203,14 +203,22 @@ where impl<'d, RX: Rx> DmaSupport for Camera<'d, RX> { fn peripheral_wait_dma(&mut self, _is_tx: bool, _is_rx: bool) { - while ! - // Wait for IN_SUC_EOF (i.e. VSYNC) - self.rx_channel.is_done() || - // Or for IN_DSCR_EMPTY (i.e. No more buffer space) - self.rx_channel.has_dscr_empty_error() || - // Or for IN_DSCR_ERR (i.e. bad descriptor) - self.rx_channel.has_error() - {} + loop { + // Wait for IN_SUC_EOF (i.e. VSYNC) + if self.rx_channel.is_done() { + break; + } + + // Or for IN_DSCR_EMPTY (i.e. No more buffer space) + if self.rx_channel.has_dscr_empty_error() { + break; + } + + // Or for IN_DSCR_ERR (i.e. bad descriptor) + if self.rx_channel.has_error() { + break; + } + } } fn peripheral_dma_stop(&mut self) {