Merge pull request #69 from skie97/fix/c6-co5300-display
This commit is contained in:
@@ -170,7 +170,7 @@ build_flags =
|
|||||||
-DLV_USE_SNAPSHOT=0
|
-DLV_USE_SNAPSHOT=0
|
||||||
|
|
||||||
lib_deps =
|
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
|
moononournation/GFX Library for Arduino@^1.6.4
|
||||||
lewisxhe/SensorLib@^0.2.6
|
lewisxhe/SensorLib@^0.2.6
|
||||||
lewisxhe/XPowersLib@^0.2.7
|
lewisxhe/XPowersLib@^0.2.7
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
// Waveshare ESP32-C6-Touch-AMOLED-2.16.
|
// Waveshare ESP32-C6-Touch-AMOLED-2.16.
|
||||||
//
|
//
|
||||||
// Despite the matching "2.16" model number, this board is hardware-
|
// 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
|
// distinct from the S3 AMOLED-2.16: it shares the CO5300 panel controller
|
||||||
// family as the AMOLED-1.8), a CST9217 touch controller, and the C6 SoC's
|
// but uses a CST9217 touch controller and the C6 SoC's own GPIO map. There
|
||||||
// own GPIO map. There is no PSRAM. AXP2101 PMU and QMI8658 IMU carry over.
|
// is no PSRAM. AXP2101 PMU and QMI8658 IMU carry over.
|
||||||
//
|
//
|
||||||
// Pin assignments verified against the official Waveshare XiaoZhi BSP at
|
// Pin assignments verified against the official Waveshare XiaoZhi BSP at
|
||||||
// waveshareteam/ESP32-C6-Touch-AMOLED-2.16 (XiaoZhi config.h) and the
|
// waveshareteam/ESP32-C6-Touch-AMOLED-2.16 (XiaoZhi config.h) and the
|
||||||
@@ -16,14 +16,14 @@
|
|||||||
#define LCD_WIDTH 480
|
#define LCD_WIDTH 480
|
||||||
#define LCD_HEIGHT 480
|
#define LCD_HEIGHT 480
|
||||||
|
|
||||||
// ---- QSPI display pins (SH8601) ----
|
// ---- QSPI display pins (CO5300) ----
|
||||||
#define LCD_CS 15
|
#define LCD_CS 15
|
||||||
#define LCD_SCLK 0
|
#define LCD_SCLK 0
|
||||||
#define LCD_SDIO0 1
|
#define LCD_SDIO0 1
|
||||||
#define LCD_SDIO1 2
|
#define LCD_SDIO1 2
|
||||||
#define LCD_SDIO2 3
|
#define LCD_SDIO2 3
|
||||||
#define LCD_SDIO3 4
|
#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
|
// on its internal power-on reset. The Arduino_GFX driver gets
|
||||||
// GFX_NOT_DEFINED for reset.
|
// GFX_NOT_DEFINED for reset.
|
||||||
|
|
||||||
|
|||||||
@@ -3,49 +3,52 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <Arduino_GFX_Library.h>
|
#include <Arduino_GFX_Library.h>
|
||||||
|
|
||||||
// C6 AMOLED-2.16 uses an SH8601 panel — same driver family as the
|
// C6 AMOLED-2.16 uses a CO5300 AMOLED panel (per the Waveshare
|
||||||
// AMOLED-1.8 port. LCD reset is not wired to any MCU GPIO; the SH8601
|
// ESP32-C6-Touch-AMOLED-2.16 spec) — the same controller as the S3
|
||||||
// boots from its internal POR. Rotation is disabled (no PSRAM headroom
|
// AMOLED-2.16 sibling, so we drive it with Arduino_CO5300 and reuse that
|
||||||
// for the strip buffer).
|
// 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_DataBus* bus = nullptr;
|
||||||
static Arduino_SH8601* gfx = nullptr;
|
static Arduino_CO5300* gfx = nullptr;
|
||||||
|
|
||||||
void display_hal_init(void) {
|
void display_hal_init(void) {
|
||||||
bus = new Arduino_ESP32QSPI(
|
bus = new Arduino_ESP32QSPI(
|
||||||
LCD_CS, LCD_SCLK, LCD_SDIO0, LCD_SDIO1, LCD_SDIO2, LCD_SDIO3);
|
LCD_CS, LCD_SCLK, LCD_SDIO0, LCD_SDIO1, LCD_SDIO2, LCD_SDIO3);
|
||||||
gfx = new Arduino_SH8601(
|
// CO5300 constructor: (bus, rst, rotation, w, h, col_off1..2, row_off1..2).
|
||||||
bus, GFX_NOT_DEFINED, 0, LCD_WIDTH, LCD_HEIGHT);
|
// 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
|
// Arduino_CO5300::begin() already issues SLPOUT, SPI-mode control, pixel
|
||||||
// (02_Example/Arduino-v3.3.3/09_LVGL_V9_Test/bsp_lvgl_port.cpp in the
|
// format, brightness-control, DISPON and a default MADCTL. The ONLY thing it
|
||||||
// waveshareteam/ESP32-C6-Touch-AMOLED-2.16 repo). The stock Arduino_GFX
|
// does not set is this panel's manufacturer page-0x20 driving-voltage
|
||||||
// SH8601 init does SLPOUT + NORON + INVOFF + PIXFMT + DISPON + brightness,
|
// registers (0x19/0x1C) — without them the panel stays black even with the
|
||||||
// which is enough for the AMOLED-1.8 panel but leaves this 2.16 panel
|
// rails up. Set just those; everything else the SH8601-era hack also wrote
|
||||||
// dark. The page-switch sequence (0xFE 0x20 ... 0xFE 0x00) writes two
|
// (0xC4/0x36/0x53/0x51/0x63/0x29) is now covered by the class init.
|
||||||
// panel-specific manufacturer registers (0x19 and 0x1C) that gate the
|
//
|
||||||
// driving voltages — without them the panel stays black even with the
|
// Note: we deliberately do NOT restore the old MADCTL 0x30 (MV transpose).
|
||||||
// rails up and the reset pulse applied.
|
// The CO5300 class default (rotation-0, MADCTL 0x00) orients the panel with
|
||||||
static void send_vendor_init(Arduino_DataBus* b) {
|
// 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->beginWrite();
|
||||||
b->writeC8D8(0xFE, 0x20); // enter manufacturer command page 0x20
|
b->writeC8D8(0xFE, 0x20); // enter manufacturer command page 0x20
|
||||||
b->writeC8D8(0x19, 0x10); // panel driving
|
b->writeC8D8(0x19, 0x10); // panel driving voltage
|
||||||
b->writeC8D8(0x1C, 0xA0); // panel driving
|
b->writeC8D8(0x1C, 0xA0); // panel driving voltage
|
||||||
b->writeC8D8(0xFE, 0x00); // back to user command page
|
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();
|
b->endWrite();
|
||||||
delay(20);
|
delay(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_hal_begin(void) {
|
void display_hal_begin(void) {
|
||||||
gfx->begin();
|
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->fillScreen(0x0000);
|
||||||
gfx->setBrightness(200);
|
gfx->setBrightness(200);
|
||||||
}
|
}
|
||||||
@@ -67,8 +70,7 @@ void display_hal_tick(void) {
|
|||||||
// No rotation cycle on this board.
|
// No rotation cycle on this board.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mirrors the CO5300/SH8601 even-alignment pattern from the other ports.
|
// CO5300 requires even-aligned flush regions.
|
||||||
// Harmless on SH8601, kept for consistency.
|
|
||||||
void display_hal_round_area(int32_t* x1, int32_t* y1, int32_t* x2, int32_t* y2) {
|
void display_hal_round_area(int32_t* x1, int32_t* y1, int32_t* x2, int32_t* y2) {
|
||||||
*x1 = *x1 & ~1;
|
*x1 = *x1 & ~1;
|
||||||
*y1 = *y1 & ~1;
|
*y1 = *y1 & ~1;
|
||||||
|
|||||||
@@ -22,11 +22,16 @@ void touch_hal_init(void) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
touch.setMaxCoordinates(LCD_WIDTH, LCD_HEIGHT);
|
touch.setMaxCoordinates(LCD_WIDTH, LCD_HEIGHT);
|
||||||
// C6 2.16 panel mapping (verified empirically): the CST9217's raw
|
// C6 2.16 panel mapping. The original values (swap=true, mirrorX=true)
|
||||||
// axes are swapped relative to the SH8601 raster AND X is mirrored.
|
// were calibrated to the old display orientation that force-wrote MADCTL
|
||||||
// Matches the Waveshare BSP, which reads y = raw_byte1, x = W - raw_byte2.
|
// 0x30 (MV transpose + ML). The display now runs at the CO5300 class
|
||||||
touch.setSwapXY(true);
|
// default (MADCTL 0x00 — USB-port-on-the-side orientation), so the touch
|
||||||
touch.setMirrorXY(true, false);
|
// 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);
|
pinMode(TP_INT, INPUT_PULLUP);
|
||||||
attachInterrupt(TP_INT, touch_isr, FALLING);
|
attachInterrupt(TP_INT, touch_isr, FALLING);
|
||||||
Serial.println("Touch init OK");
|
Serial.println("Touch init OK");
|
||||||
|
|||||||
Reference in New Issue
Block a user