QSPI bus driver and Waveshare ESP32-S3 Touch AMOLED 2.41" board support#10844
QSPI bus driver and Waveshare ESP32-S3 Touch AMOLED 2.41" board support#10844ppsx wants to merge 11 commits intoadafruit:mainfrom
Conversation
There was a problem hiding this comment.
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
qspibusmodule providing QSPI bus protocol support analogous tofourwirefor 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.
tannewt
left a comment
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 : 0is redundant since CIRCUITPY_LCD_POWER_ON_LEVEL is already defined as either 0 or 1 (see lines 32-34). Simplify this to justCIRCUITPY_LCD_POWER_ON_LEVELto 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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
|
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 :) |
- 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>
|
Please make sure the automated tests also pass. |
There was a problem hiding this comment.
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.
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.
Creating new PR for RM690B0 display driver for Waveshare ESP32-S3 Touch AMOLED 2.41"
Contains: