feat: M5Stack PaperS3 support (panel-IC 3004, FastEPD parallel path) - #159
Merged
Merged
Conversation
Applied via opendisplay-protocol tools/sync_protocol_header.py --push --artifact protocol --only Firmware. Comment-only (0x0043 response layout changelog note); zero wire change. sync --check now green for both vendored headers.
- vendored structs header synced from canonical (enum 3004, structs 2.1, config minor 1.5) via sync_protocol_header.py --push - fastepd_parallel_panel(): map 3004 -> BB_PANEL_M5PAPERS3 (FastEPD 2.2.0 native parallel driver owns bus/power/waveforms) - fastepd_driver_used(): include 3004 in the native-parallel set - esp32-s3-N16R8: pin FastEPD exactly to 2.2.0 during bring-up (positional BB_PANEL_* enum upstream)
…stream PaperS3 defect - fastepd_apply_mode(): the effective 1bpp/4bpp mode follows the runtime config (color_scheme) but FastEPD's mode was sticky per hardware init; a MONO<->GRAY16 config change between transfers left incoming data interpreted at the previous depth (recognizable-but-distorted output). Re-asserted on every warm prepare (direct, partial, warm begin). - FastEPD pinned to 2ead295d (2.2.0 + row-timing fix) with the upstream defect documented: alternating-column pinstripes on the tested PaperS3 unit, reproduced library-only on 2.2.0 and main; M5GFX renders cleanly (panel exonerated). main also hangs the refresh in this firmware.
…D pins Root cause (proven by an 8-step standalone-vs-firmware bisection with serial traces, framebuffer checksums and library state dumps): with no DataBus config, initOrRestoreWireForOpenDisplay() falls back to Wire.begin() on the ESP32-S3 default I2C pins GPIO 8/9 — two of the PaperS3's eight EPD parallel data lines. The I2C driver fought the LCD bus on those bits: alternating-column corruption and fine dark stripes in both 1bpp and 4bpp, firmware-only (library-only sketches were clean once actually executing). Fixed configuration-side: the PaperS3 presets now carry the board's real I2C bus (DataBus 0x24, SCL=42 SDA=41). Reverted to the validated FastEPD 2.2.0 exact pin and stock glue (single-arg initPanel, unconditional deInit): the 16 MHz clock, bus-keep-alive and main-branch experiments were compensating for the Wire collision, not a library defect. The config-driven pixel-mode re-assert (fastepd_apply_mode) remains — a real, separate bug. Also observed for upstream consideration: FastEPD main (4ab71558) changes deInit() to tear down the parallel bus devices, which breaks warm einkPower(1) reuse patterns; and a failed initPanel currently leaves transfers silently unanswered (no NACK) in this firmware.
Member
|
Thank you for your contribution. No need to split it, I will do a more in depth review once OpenDisplay/opendisplay-protocol#14 is merged |
Contributor
Author
|
Hello @jonasniesner , |
Member
|
Thank you, merged. I will review the preset once you open the PR for it ;) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds M5Stack PaperS3 (ESP32-S3, 960x540 ED047TC1-class parallel e-paper, 16-gray) as a config-only device.
Closes #16.
Depends on OpenDisplay/opendisplay-protocol#14 (canonical enum + parity restore; the vendored headers on this branch are byte-identical to that branch —
sync_protocol_header.py --check: 2 in sync).Firmware changes (deliberately minimal)
display_fastepd.cpp: map panel-IC 3004 ->BB_PANEL_M5PAPERS3(incl. the FastEPD-dispatch guard), useCLEAR_SLOWfor the full refresh on this panel, and re-assert the config-driven pixel mode on warm transfer paths (a warm MONO<->GRAY16 config switch previously interpreted transfers at the wrong depth).platformio.ini: pin FastEPD to exactly 2.2.0 with a defect-history note — FastEPD main'sdeInittears down the parallel bus, which hangs this firmware's init/deinit-per-refresh pattern (filed upstream as deInit() on main tears down the parallel bus (behavior change vs 2.2.0) bitbank2/FastEPD#38).esp32-s3-N16R8matches the hardware (16 MB QIO flash, OPI PSRAM, native USB CDC); no new environment.Everything else — GT911 touch, buzzer, battery telemetry, deep-sleep/timer-wake lifecycle — is stock firmware driven by configuration. A simple-config preset for opendisplay.org will follow separately once a hosted build exists.
Validation
Validated on a physical PaperS3 with an automated acceptance suite, 24 scenarios green on this exact branch (rebased on current main):
CMD_DEEP_SLEEP0x0053, and the documentedCMD_POWER_OFF0x0052 NACK contract on this latch-less boardNotes for reviewers
Wire.begin()on GPIO 8/9, which are EPD data lines on the PaperS3 — every render corrupts into stripes/column artifacts. That was the hardest defect of this bring-up; I filed Wire fallback claims default I2C pins (GPIO 8/9) that can collide with panel data lines #161 proposing a guard. The preset carries I2C SCL=42 / SDA=41.flags=6(SWAP_XY | INVERT_Y), corner-verified on hardware.Happy to split this into smaller commits or adjust anything on request.