Skip to content

QSPI bus driver and Waveshare ESP32-S3 Touch AMOLED 2.41" board support#10844

Open
ppsx wants to merge 11 commits intoadafruit:mainfrom
ppsx:rm690b0
Open

QSPI bus driver and Waveshare ESP32-S3 Touch AMOLED 2.41" board support#10844
ppsx wants to merge 11 commits intoadafruit:mainfrom
ppsx:rm690b0

Conversation

@ppsx
Copy link

@ppsx ppsx commented Feb 23, 2026

Creating new PR for RM690B0 display driver for Waveshare ESP32-S3 Touch AMOLED 2.41"
Contains:

  • QSPI bus driver
  • Waveshare ESP32-S3 Touch AMOLED 2.41" support

Copilot AI review requested due to automatic review settings February 23, 2026 23:09
Copy link

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

This pull request introduces a new QSPI (Quad-SPI) bus driver for CircuitPython, specifically to support the Waveshare ESP32-S3 Touch AMOLED 2.41" display which uses the RM690B0 controller. The implementation follows CircuitPython's established display bus architecture patterns.

Changes:

  • Adds a new qspibus module providing QSPI bus protocol support analogous to fourwire for standard SPI
  • Implements ESP32-S3 specific QSPI bus driver using ESP-IDF's LCD panel IO API with DMA and ISR support
  • Adds board definition for Waveshare ESP32-S3 Touch AMOLED 2.41" with comprehensive pin mappings
  • Optimizes display buffer sizes for QSPI panels to reduce command/window overhead

Reviewed changes

Copilot reviewed 22 out of 22 changed files in this pull request and generated 14 comments.

Show a summary per file
File Description
shared-bindings/qspibus/__init__.c Python module definition for qspibus
shared-bindings/qspibus/__init__.h Module header with imports
shared-bindings/qspibus/QSPIBus.c Python bindings for QSPIBus class with send(), write_command(), write_data() methods
shared-bindings/qspibus/QSPIBus.h QSPIBus class interface declaration
ports/espressif/common-hal/qspibus/QSPIBus.c ESP32-S3 QSPI implementation using ESP-IDF LCD panel IO with DMA buffers and ISR callbacks
ports/espressif/common-hal/qspibus/QSPIBus.h ESP32-S3 QSPI bus structure definition
ports/espressif/common-hal/qspibus/__init__.c Empty implementation file (placeholder)
ports/espressif/common-hal/qspibus/__init__.h Empty header file (placeholder)
shared-module/displayio/bus_core.c Integrates QSPI bus into displayio bus abstraction
shared-module/displayio/__init__.h Adds QSPI bus to primary display bus union
shared-module/displayio/__init__.c Adds QSPI bus cleanup to display release path
shared-module/busdisplay/BusDisplay.c QSPI-specific buffer optimization for efficient refresh
py/circuitpy_mpconfig.mk Build flag for QSPI bus support
py/circuitpy_mpconfig.h QSPI display buffer size configuration
py/circuitpy_defns.mk Build pattern matching for qspibus module
ports/espressif/Makefile Links esp_lcd component when QSPIBUS enabled
ports/espressif/boards/waveshare_esp32_s3_amoled_241/mpconfigboard.h Board configuration with pin definitions and buffer size
ports/espressif/boards/waveshare_esp32_s3_amoled_241/mpconfigboard.mk Board build configuration enabling QSPIBUS
ports/espressif/boards/waveshare_esp32_s3_amoled_241/pins.c Comprehensive pin mapping with functional names
ports/espressif/boards/waveshare_esp32_s3_amoled_241/board.c Empty board initialization
ports/espressif/boards/waveshare_esp32_s3_amoled_241/sdkconfig ESP-IDF SDK configuration for PSRAM and peripherals
locale/circuitpython.pot Translation strings for QSPI error messages

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Member

@tannewt tannewt left a comment

Choose a reason for hiding this comment

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

This is definitely getting closer! Please prevent additional error messages from being added. You likely can reuse existing ones. Please also iterate with copilot on your own fork before making a PR.

Copy link

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 22 out of 22 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (2)

locale/circuitpython.pot:922

  • The error message "Data buffer is null" is added to the locale file but is never used in the codebase. Either remove this unused error message from the locale file or add the corresponding validation check in the code where it's needed.
#: ports/espressif/common-hal/qspibus/QSPIBus.c
msgid "Data buffer is null"
msgstr ""

ports/espressif/common-hal/qspibus/QSPIBus.c:359

  • The ternary operator CIRCUITPY_LCD_POWER_ON_LEVEL ? 1 : 0 is redundant since CIRCUITPY_LCD_POWER_ON_LEVEL is already defined as either 0 or 1 (see lines 32-34). Simplify this to just CIRCUITPY_LCD_POWER_ON_LEVEL to make the code clearer and avoid potential confusion.
        gpio_set_level((gpio_num_t)self->power_pin, CIRCUITPY_LCD_POWER_ON_LEVEL ? 1 : 0);

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

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 22 out of 22 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@ppsx ppsx changed the title QSPI bus driver and …RM690B0 display driver for Waveshare ESP32-S3 Touch AMOLED 2.41" QSPI bus driver and Waveshare ESP32-S3 Touch AMOLED 2.41" board support Feb 24, 2026
@ppsx ppsx requested a review from Copilot February 24, 2026 23:56
Copy link

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 22 out of 22 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@ppsx
Copy link
Author

ppsx commented Feb 25, 2026

Thank you @tannewt for your feedback. I've implemented requested changes and did a couple of sessions with Copilot. Now the code needs some more professional view than me or Copilot :)

ppsx and others added 6 commits February 25, 2026 14:20
- Reuse existing CircuitPython error messages to reduce translation burden:
  "QSPI command/color timeout" -> "Operation timed out",
  "QSPI send[color] failed: %d" / "SPI bus init failed: %d" /
  "Panel IO init failed: %d" -> "%q failure: %d",
  "Failed to allocate DMA buffers" / "QSPI DMA buffers unavailable" ->
  "Could not allocate DMA capable buffer",
  "Data buffer is null" -> "Buffer too small".
  Net removal of 8 unique translatable strings with 0 new ones.

- Regenerate locale/circuitpython.pot to remove stale entries.

- Add _Static_assert in BusDisplay.c to guard the QSPI stack-allocated
  refresh buffer size (max 2048 uint32_t words = 8KB).

- Add comment clarifying that inflight_transfers bookkeeping is
  task-context only (ISR only signals semaphore), so no atomics needed.

- Fix SPDX file header format across all new qspibus files to match
  the CircuitPython project convention.
- Add reset() method binding (common_hal implementation already existed)
  with "No %q pin" error matching FourWire/ParallelBus pattern.
- Remove deinit(), __enter__(), __exit__() from Python API; display bus
  lifecycle is managed through displayio.release_displays().
- Remove two unreachable data == NULL guards: Python binding validates
  buffers via mp_get_buffer_raise(), and displayio always passes valid
  pointers.
- Align begin_transaction() with bus_free() by delegating to it, so
  transfer_in_progress and has_pending_command are checked before
  entering a transaction. This prevents silently discarding a staged
  write_command() or starting a transaction during active DMA.
- Regenerate locale/circuitpython.pot to remove stale "Data buffer is
  null" entry left over from the previous round of error message reuse.
#1)

* Initial plan

* Fix stale and missing locale entries for qspibus

Co-authored-by: ppsx <7107135+ppsx@users.noreply.github.com>

* qspibus: three low-cost cleanups consistent with CircuitPython conventions

Co-authored-by: ppsx <7107135+ppsx@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ppsx <7107135+ppsx@users.noreply.github.com>
Co-authored-by: ppsx <ppsx@users.noreply.github.com>
@tannewt
Copy link
Member

tannewt commented Feb 25, 2026

Please make sure the automated tests also pass.

Copy link

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 24 out of 24 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

ports/espressif/common-hal/qspibus/QSPIBus.c:467

  • Inconsistent indentation: this line uses 3 spaces instead of 4 spaces for indentation. All other if statements in this function use 4 spaces.
   if (!self->has_pending_command) {

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

ppsx added 3 commits February 25, 2026 21:12
Refactor display bus region-update command emission into a shared helper with
optional transaction management. Keep the existing public path unchanged, and
add a QSPIBus-only entrypoint that can send region commands without nesting
begin/end transaction calls.

Also remove the TileGrid 16bpp+Palette fast path so fill_area uses the generic
path, and fix indentation in QSPIBus write_data.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants