Skip to content

feat(lcd_cam): add DPI bounce buffer support for PSRAM-backed RGB displays#5262

Draft
fmauNeko wants to merge 7 commits intoesp-rs:mainfrom
fmauNeko:feat/dpi-display-bounce-buffers
Draft

feat(lcd_cam): add DPI bounce buffer support for PSRAM-backed RGB displays#5262
fmauNeko wants to merge 7 commits intoesp-rs:mainfrom
fmauNeko:feat/dpi-display-bounce-buffers

Conversation

@fmauNeko
Copy link
Copy Markdown

Submission Checklist 📝

  • I have updated existing examples or added new ones (if applicable).
  • I have used cargo xtask fmt-packages command to ensure that all changed code is formatted correctly.
  • My changes were added to the CHANGELOG.md in the proper section.
  • I have added necessary changes to user code to the latest Migration Guide. (no migration needed — no breaking changes)
  • My changes are in accordance to the esp-rs developer guidelines

Extra:

Pull Request Details 📖

Description

Fix the DPI (RGB parallel) LCD driver and add bounce buffer support for driving large PSRAM-backed framebuffers, matching the architecture used by ESP-IDF's esp_lcd_panel_rgb.c (source).

Bug fix: lcd_always_out_en was not set in the DPI driver's apply_config(), causing the LCD_CAM peripheral to stop outputting pixel data after lcd_dout_cyclelen cycles instead of streaming continuously from DMA. The I8080 driver already set this register correctly — the DPI driver was simply missing it.

New feature: DmaBounceBuffer + Dpi::send_bounce_buffered() enable driving 800×480 (or larger) RGB displays with framebuffers in PSRAM. The architecture uses two SRAM bounce buffers in a circular DMA descriptor chain; DpiBounceTransfer::poll() checks for GDMA EOF events and copies the next framebuffer chunk into the completed bounce buffer. Double-buffered rendering is supported via set_back_buffer() / back_buffer() / swap_buffers() for tear-free frame transitions.

New example: qa-test/src/bin/lcd_dpi_bounce.rs demonstrates the full pipeline on the PandaTouch board (ESP32-S3, 800×480 RGB565 at 23 MHz, Octal PSRAM).

Future work (separate PR): Changing hsync_idle_level / vsync_idle_level defaults from Level::Low to Level::High to match ESP-IDF convention. This is a breaking change that would need the breaking-change-esp-hal label. The example sets Level::High explicitly for now.

Testing

  • Tested on PandaTouch hardware (ESP32-S3 + 800×480 RGB panel + 8MB Octal PSRAM)
  • Display shows solid colors cycling every 2 seconds with tear-free transitions (double buffering)
  • cargo xtask fmt-packages
  • cargo xtask lint-packages --chips esp32s3 esp-hal
  • cargo xtask check-changelog
  • cargo xtask update-metadata --check
  • cargo xtask build examples lcd_dpi_bounce --package qa-test --chip esp32s3
  • cargo xtask build examples lcd_dpi --package qa-test --chip esp32s3 ✅ (existing example unaffected)

Copilot AI review requested due to automatic review settings March 25, 2026 23:22
@fmauNeko fmauNeko force-pushed the feat/dpi-display-bounce-buffers branch from cc0395f to 5a22130 Compare March 25, 2026 23:24
@Dominaezzz Dominaezzz self-assigned this Mar 25, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds continuous DPI (RGB parallel) streaming support for PSRAM-backed framebuffers by introducing a GDMA “bounce buffer” pipeline, and fixes a DPI register configuration issue that could stop pixel output after a limited number of cycles.

Changes:

  • Fix DPI configuration by setting lcd_always_out_en for continuous output.
  • Add DmaBounceBuffer + Dpi::send_bounce_buffered() / DpiBounceTransfer for SRAM bounce-buffered streaming from PSRAM.
  • Add a new qa-test example for PandaTouch demonstrating bounce-buffered DPI + double buffering, and document changes in the changelog.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 5 comments.

File Description
qa-test/src/bin/lcd_dpi_bounce.rs New example demonstrating PSRAM framebuffer + bounce-buffered DPI transfer and buffer swapping on ESP32-S3.
esp-hal/src/lcd_cam/lcd/dpi.rs Implements bounce-buffer infrastructure and transfer type; fixes DPI lcd_always_out_en configuration.
esp-hal/CHANGELOG.md Adds changelog entries for the new bounce-buffer feature and the DPI fix.

Comment thread esp-hal/CHANGELOG.md
Comment thread esp-hal/src/lcd_cam/lcd/dpi.rs Outdated
Comment thread esp-hal/src/lcd_cam/lcd/dpi.rs Outdated
Comment thread esp-hal/src/lcd_cam/lcd/dpi.rs Outdated
Comment thread esp-hal/CHANGELOG.md Outdated
Copy link
Copy Markdown
Collaborator

@Dominaezzz Dominaezzz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR!

Comment thread esp-hal/src/lcd_cam/lcd/dpi.rs Outdated
Comment thread esp-hal/src/lcd_cam/lcd/dpi.rs Outdated
@fmauNeko fmauNeko force-pushed the feat/dpi-display-bounce-buffers branch 2 times, most recently from 525da3e to 8c4e9e3 Compare March 25, 2026 23:57
Copilot AI review requested due to automatic review settings March 25, 2026 23:59
@fmauNeko fmauNeko force-pushed the feat/dpi-display-bounce-buffers branch from 8c4e9e3 to ae73526 Compare March 25, 2026 23:59
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 3 changed files in this pull request and generated 4 comments.

Comment thread esp-hal/src/lcd_cam/lcd/dpi.rs Outdated
Comment thread esp-hal/src/lcd_cam/lcd/dpi.rs Outdated
Comment thread esp-hal/src/lcd_cam/lcd/dpi.rs Outdated
Comment thread esp-hal/src/lcd_cam/lcd/dpi.rs Outdated
Comment thread esp-hal/src/lcd_cam/lcd/dpi.rs Outdated
Comment thread esp-hal/src/lcd_cam/lcd/dpi.rs Outdated
Comment thread qa-test/src/bin/lcd_dpi_bounce.rs Outdated
@bugadani
Copy link
Copy Markdown
Contributor

Future work (separate PR): Changing hsync_idle_level / vsync_idle_level defaults from Level::Low to Level::High to match ESP-IDF convention. This is a breaking change that would need the breaking-change-esp-hal label. The example sets Level::High explicitly for now.

I should have read this first. If this PR is AI-generated, invest the time to review your work before you submit it.

@fmauNeko fmauNeko marked this pull request as draft March 26, 2026 12:17
…plays

Fix lcd_always_out_en not being set in the DPI driver's apply_config(),
which caused the LCD_CAM peripheral to stop outputting pixel data after
lcd_dout_cyclelen cycles instead of streaming continuously from DMA.

Add DmaBounceBuffer and Dpi::send_bounce_buffered() to enable driving
large (800x480+) RGB displays with framebuffers in PSRAM, matching the
bounce buffer architecture used by ESP-IDF's esp_lcd_panel_rgb.c.

Architecture:
- Two SRAM bounce buffers with a circular 2-descriptor DMA chain
- DpiBounceTransfer::poll() checks for GDMA EOF events and copies
  the next framebuffer chunk into the completed bounce buffer
- Double-buffered rendering via set_back_buffer() / back_buffer() /
  swap_buffers() for tear-free frame transitions

Add lcd_dpi_bounce qa-test example demonstrating the full pipeline on
the PandaTouch board (ESP32-S3, 800x480 RGB565, 23MHz, Octal PSRAM).
Review fixes:
- Update send_bounce_buffered() docs to reflect polling-only API
  (ISR binding was removed earlier; docs still mentioned it)
- Validate back buffer size in set_back_buffer() to prevent OOB
  reads when framebuffer pointer is swapped
- Break swap_buffers() spin loop on is_done() to avoid deadlock
  if DMA enters error state

CI fixes:
- Gate all bounce buffer types behind #[cfg(feature = "unstable")]
  so critical_section (an optional dep) isn't required in non-unstable
  builds — fixes esp-hal (xtensa), msrv (xtensa), docs (xtensa)
- Fix clippy: map_or(false, ...) -> is_some_and(...)
@fmauNeko fmauNeko force-pushed the feat/dpi-display-bounce-buffers branch from a6515f5 to 28f28ea Compare March 26, 2026 13:04
@github-actions
Copy link
Copy Markdown

New commits in main has made this PR unmergable. Please resolve the conflicts.

@github-actions github-actions Bot added the merge-conflict Merge conflict detected. Automatically added/removed by CI. label Mar 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-conflict Merge conflict detected. Automatically added/removed by CI.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants