fix(c6): drive AMOLED-2.16 C6 panel as CO5300, side-USB orientation
platformio.ini and the board files labelled the Waveshare ESP32-C6-Touch-AMOLED-2.16 as an SH8601 panel, when it actually uses a CO5300 (per the official spec) -- the same controller as the S3 AMOLED-2.16. It still rendered because display.cpp grafted CO5300-style manufacturer registers (a 0xFE page-switch writing the 0x19/0x1C driving-voltage registers) onto the Arduino_SH8601 class, and both controllers speak standard MIPI DCS for pixel writes. Rebase onto Arduino_CO5300 (matching the S3 AMOLED-2.16 sibling) and keep only the page-0x20 panel-driving registers (0x19/0x1C) the class init omits; everything else (0xC4/0x36/0x53/0x51/0x63/0x29) is now covered by Arduino_CO5300::begin(). Adopt the CO5300 rotation-0 default (MADCTL 0x00) instead of the old forced 0x30 transpose, orienting the board with the USB port on the side (the preferred desk orientation). Touch axis mapping is re-derived and tap-tested on hardware to match: swap=false, mirror=(false,false). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
9392d23092
commit
9375bd6d66
@@ -170,7 +170,7 @@ build_flags =
|
||||
-DLV_USE_SNAPSHOT=0
|
||||
|
||||
lib_deps =
|
||||
; 1.6.4+ required for Arduino_SH8601 (this board uses SH8601, not CO5300)
|
||||
; this board uses the CO5300 (same controller as the S3 2.16); Arduino_CO5300
|
||||
moononournation/GFX Library for Arduino@^1.6.4
|
||||
lewisxhe/SensorLib@^0.2.6
|
||||
lewisxhe/XPowersLib@^0.2.7
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
// Waveshare ESP32-C6-Touch-AMOLED-2.16.
|
||||
//
|
||||
// Despite the matching "2.16" model number, this board is hardware-
|
||||
// distinct from the S3 AMOLED-2.16: it uses an SH8601 panel (same driver
|
||||
// family as the AMOLED-1.8), a CST9217 touch controller, and the C6 SoC's
|
||||
// own GPIO map. There is no PSRAM. AXP2101 PMU and QMI8658 IMU carry over.
|
||||
// distinct from the S3 AMOLED-2.16: it shares the CO5300 panel controller
|
||||
// but uses a CST9217 touch controller and the C6 SoC's own GPIO map. There
|
||||
// is no PSRAM. AXP2101 PMU and QMI8658 IMU carry over.
|
||||
//
|
||||
// Pin assignments verified against the official Waveshare XiaoZhi BSP at
|
||||
// waveshareteam/ESP32-C6-Touch-AMOLED-2.16 (XiaoZhi config.h) and the
|
||||
@@ -16,14 +16,14 @@
|
||||
#define LCD_WIDTH 480
|
||||
#define LCD_HEIGHT 480
|
||||
|
||||
// ---- QSPI display pins (SH8601) ----
|
||||
// ---- QSPI display pins (CO5300) ----
|
||||
#define LCD_CS 15
|
||||
#define LCD_SCLK 0
|
||||
#define LCD_SDIO0 1
|
||||
#define LCD_SDIO1 2
|
||||
#define LCD_SDIO2 3
|
||||
#define LCD_SDIO3 4
|
||||
// LCD reset is not wired to a MCU GPIO on this board — the SH8601 relies
|
||||
// LCD reset is not wired to a MCU GPIO on this board — the CO5300 relies
|
||||
// on its internal power-on reset. The Arduino_GFX driver gets
|
||||
// GFX_NOT_DEFINED for reset.
|
||||
|
||||
|
||||
@@ -3,49 +3,52 @@
|
||||
#include <Arduino.h>
|
||||
#include <Arduino_GFX_Library.h>
|
||||
|
||||
// C6 AMOLED-2.16 uses an SH8601 panel — same driver family as the
|
||||
// AMOLED-1.8 port. LCD reset is not wired to any MCU GPIO; the SH8601
|
||||
// boots from its internal POR. Rotation is disabled (no PSRAM headroom
|
||||
// for the strip buffer).
|
||||
// C6 AMOLED-2.16 uses a CO5300 AMOLED panel (per the Waveshare
|
||||
// ESP32-C6-Touch-AMOLED-2.16 spec) — the same controller as the S3
|
||||
// AMOLED-2.16 sibling, so we drive it with Arduino_CO5300 and reuse that
|
||||
// class's vendor-correct init rather than the SH8601 class + a hand-patched
|
||||
// sequence. LCD reset is not wired to any MCU GPIO; the panel boots from its
|
||||
// internal power-on reset (rst = GFX_NOT_DEFINED). Rotation is disabled (no
|
||||
// PSRAM headroom for a rotation strip).
|
||||
|
||||
static Arduino_DataBus* bus = nullptr;
|
||||
static Arduino_SH8601* gfx = nullptr;
|
||||
static Arduino_CO5300* gfx = nullptr;
|
||||
|
||||
void display_hal_init(void) {
|
||||
bus = new Arduino_ESP32QSPI(
|
||||
LCD_CS, LCD_SCLK, LCD_SDIO0, LCD_SDIO1, LCD_SDIO2, LCD_SDIO3);
|
||||
gfx = new Arduino_SH8601(
|
||||
bus, GFX_NOT_DEFINED, 0, LCD_WIDTH, LCD_HEIGHT);
|
||||
// CO5300 constructor: (bus, rst, rotation, w, h, col_off1..2, row_off1..2).
|
||||
// No reset GPIO on this board; the 480-wide panel is full-width so all
|
||||
// offsets are 0 — matches the S3 AMOLED-2.16 instantiation.
|
||||
gfx = new Arduino_CO5300(
|
||||
bus, GFX_NOT_DEFINED, 0 /* rotation disabled */,
|
||||
LCD_WIDTH, LCD_HEIGHT, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
// Vendor-specific init commands from the Waveshare C6-2.16 BSP
|
||||
// (02_Example/Arduino-v3.3.3/09_LVGL_V9_Test/bsp_lvgl_port.cpp in the
|
||||
// waveshareteam/ESP32-C6-Touch-AMOLED-2.16 repo). The stock Arduino_GFX
|
||||
// SH8601 init does SLPOUT + NORON + INVOFF + PIXFMT + DISPON + brightness,
|
||||
// which is enough for the AMOLED-1.8 panel but leaves this 2.16 panel
|
||||
// dark. The page-switch sequence (0xFE 0x20 ... 0xFE 0x00) writes two
|
||||
// panel-specific manufacturer registers (0x19 and 0x1C) that gate the
|
||||
// driving voltages — without them the panel stays black even with the
|
||||
// rails up and the reset pulse applied.
|
||||
static void send_vendor_init(Arduino_DataBus* b) {
|
||||
// Arduino_CO5300::begin() already issues SLPOUT, SPI-mode control, pixel
|
||||
// format, brightness-control, DISPON and a default MADCTL. The ONLY thing it
|
||||
// does not set is this panel's manufacturer page-0x20 driving-voltage
|
||||
// registers (0x19/0x1C) — without them the panel stays black even with the
|
||||
// rails up. Set just those; everything else the SH8601-era hack also wrote
|
||||
// (0xC4/0x36/0x53/0x51/0x63/0x29) is now covered by the class init.
|
||||
//
|
||||
// Note: we deliberately do NOT restore the old MADCTL 0x30 (MV transpose).
|
||||
// The CO5300 class default (rotation-0, MADCTL 0x00) orients the panel with
|
||||
// the USB port on the side, which is the preferred desk orientation for this
|
||||
// board.
|
||||
static void send_panel_driving_init(Arduino_DataBus* b) {
|
||||
b->beginWrite();
|
||||
b->writeC8D8(0xFE, 0x20); // enter manufacturer command page 0x20
|
||||
b->writeC8D8(0x19, 0x10); // panel driving
|
||||
b->writeC8D8(0x1C, 0xA0); // panel driving
|
||||
b->writeC8D8(0x19, 0x10); // panel driving voltage
|
||||
b->writeC8D8(0x1C, 0xA0); // panel driving voltage
|
||||
b->writeC8D8(0xFE, 0x00); // back to user command page
|
||||
b->writeC8D8(0xC4, 0x80); // SPI mode control
|
||||
b->writeC8D8(0x36, 0x30); // MADCTL (BSP value)
|
||||
b->writeC8D8(0x53, 0x20); // CTRL display 1 (brightness control on)
|
||||
b->writeC8D8(0x51, 0xFF); // brightness = max
|
||||
b->writeC8D8(0x63, 0xFF); // HBM brightness = max
|
||||
b->writeCommand(0x29); // DISPON (idempotent — stock init already did this)
|
||||
b->endWrite();
|
||||
delay(20);
|
||||
}
|
||||
|
||||
void display_hal_begin(void) {
|
||||
gfx->begin();
|
||||
send_vendor_init(bus); // patch up panel-specific regs the stock init misses
|
||||
send_panel_driving_init(bus); // panel-specific regs the class init omits
|
||||
gfx->fillScreen(0x0000);
|
||||
gfx->setBrightness(200);
|
||||
}
|
||||
@@ -67,8 +70,7 @@ void display_hal_tick(void) {
|
||||
// No rotation cycle on this board.
|
||||
}
|
||||
|
||||
// Mirrors the CO5300/SH8601 even-alignment pattern from the other ports.
|
||||
// Harmless on SH8601, kept for consistency.
|
||||
// CO5300 requires even-aligned flush regions.
|
||||
void display_hal_round_area(int32_t* x1, int32_t* y1, int32_t* x2, int32_t* y2) {
|
||||
*x1 = *x1 & ~1;
|
||||
*y1 = *y1 & ~1;
|
||||
|
||||
@@ -22,11 +22,16 @@ void touch_hal_init(void) {
|
||||
return;
|
||||
}
|
||||
touch.setMaxCoordinates(LCD_WIDTH, LCD_HEIGHT);
|
||||
// C6 2.16 panel mapping (verified empirically): the CST9217's raw
|
||||
// axes are swapped relative to the SH8601 raster AND X is mirrored.
|
||||
// Matches the Waveshare BSP, which reads y = raw_byte1, x = W - raw_byte2.
|
||||
touch.setSwapXY(true);
|
||||
touch.setMirrorXY(true, false);
|
||||
// C6 2.16 panel mapping. The original values (swap=true, mirrorX=true)
|
||||
// were calibrated to the old display orientation that force-wrote MADCTL
|
||||
// 0x30 (MV transpose + ML). The display now runs at the CO5300 class
|
||||
// default (MADCTL 0x00 — USB-port-on-the-side orientation), so the touch
|
||||
// mapping is re-derived to match. SensorLib applies swap then mirror
|
||||
// (TouchDrvInterface::updateXY); tap-tested on C6 hardware, the raw
|
||||
// CST9217 coordinates map straight through in this orientation — no swap,
|
||||
// no mirror.
|
||||
touch.setSwapXY(false);
|
||||
touch.setMirrorXY(false, false);
|
||||
pinMode(TP_INT, INPUT_PULLUP);
|
||||
attachInterrupt(TP_INT, touch_isr, FALLING);
|
||||
Serial.println("Touch init OK");
|
||||
|
||||
Reference in New Issue
Block a user