chore(examples): add submodule and remove LVGL examples
This commit is contained in:
@@ -1,256 +1,244 @@
|
||||
#include "DisplayDriverGFX.h"
|
||||
#include "LovyanPins.h"
|
||||
#include "board_config.h"
|
||||
#include <Arduino.h>
|
||||
#include <ESP_IOExpander_Library.h>
|
||||
|
||||
// Global display instance
|
||||
static LGFX* _gfx = nullptr;
|
||||
static ESP_IOExpander* _expander = nullptr;
|
||||
|
||||
// Forward declarations
|
||||
void initExpander();
|
||||
void initDisplay();
|
||||
|
||||
// ── Expander initialization (from Westcott) ──
|
||||
void initExpander()
|
||||
{
|
||||
Serial.println("IO expander init...");
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
#include <ESP_IOExpander_Library.h>
|
||||
#include "LovyanPins.h"
|
||||
#include "board_config.h"
|
||||
#include "DisplayDriverGFX.h"
|
||||
|
||||
#ifndef BLACK
|
||||
#define BLACK 0x0000
|
||||
#endif
|
||||
#ifndef WHITE
|
||||
#define WHITE 0xFFFF
|
||||
#endif
|
||||
#ifndef RED
|
||||
#define RED 0xF800
|
||||
#endif
|
||||
// ── Globals ──
|
||||
static LGFX* _gfx = nullptr;
|
||||
static ESP_IOExpander* _expander = nullptr;
|
||||
|
||||
// CH422G logical pin numbers
|
||||
#define EXIO_TP_RST IO_EXPANDER_PIN_NUM_1
|
||||
#define EXIO_LCD_BL IO_EXPANDER_PIN_NUM_2
|
||||
#define EXIO_LCD_RST IO_EXPANDER_PIN_NUM_3
|
||||
#define EXIO_SD_CS IO_EXPANDER_PIN_NUM_4
|
||||
#define EXIO_USB_SEL IO_EXPANDER_PIN_NUM_5
|
||||
// ── Forward declarations ──
|
||||
static void initExpander();
|
||||
static void initDisplay();
|
||||
|
||||
static ESP_IOExpander* expander = nullptr;
|
||||
// ── Dimensions ──
|
||||
static constexpr int DISP_W = 800;
|
||||
static constexpr int DISP_H = 480;
|
||||
|
||||
// ── IO Expander ──
|
||||
|
||||
void DisplayDriverGFX::expanderInit() {
|
||||
Serial.println("[IO] IO expander init...");
|
||||
expander = new ESP_IOExpander_CH422G(
|
||||
I2C_MASTER_NUM,
|
||||
// ── Expander initialization ──
|
||||
static void initExpander() {
|
||||
Serial.println("IO expander init...");
|
||||
|
||||
// Initialize I2C for expander
|
||||
Wire.begin(TOUCH_SDA, TOUCH_SCL);
|
||||
|
||||
_expander = new ESP_IOExpander_CH422G(
|
||||
(i2c_port_t)I2C_NUM_0,
|
||||
ESP_IO_EXPANDER_I2C_CH422G_ADDRESS
|
||||
);
|
||||
expander->init();
|
||||
expander->begin();
|
||||
expander->multiPinMode(
|
||||
EXIO_TP_RST | EXIO_LCD_BL | EXIO_LCD_RST | EXIO_SD_CS | EXIO_USB_SEL,
|
||||
OUTPUT
|
||||
);
|
||||
// Deassert resets, backlight OFF for now
|
||||
expander->multiDigitalWrite(
|
||||
EXIO_TP_RST | EXIO_LCD_RST | EXIO_SD_CS,
|
||||
0xFF
|
||||
);
|
||||
expander->digitalWrite(EXIO_LCD_BL, LOW);
|
||||
Serial.println("[IO] CH422G initialized");
|
||||
_expander->init();
|
||||
_expander->begin();
|
||||
|
||||
// Set all pins to output
|
||||
_expander->multiPinMode(TP_RST | LCD_BL | LCD_RST | SD_CS | USB_SEL, OUTPUT);
|
||||
|
||||
// Reset sequence
|
||||
_expander->digitalWrite(LCD_RST, LOW);
|
||||
delay(50);
|
||||
_expander->digitalWrite(LCD_RST, HIGH);
|
||||
delay(150);
|
||||
|
||||
// Turn on backlight
|
||||
_expander->digitalWrite(LCD_BL, HIGH);
|
||||
|
||||
Serial.println("IO expander ready");
|
||||
}
|
||||
|
||||
// ── Display initialization ──
|
||||
static void initDisplay() {
|
||||
Serial.println("LovyanGFX init...");
|
||||
|
||||
_gfx = new LGFX();
|
||||
_gfx->init();
|
||||
_gfx->setRotation(1); // Landscape
|
||||
_gfx->fillScreen(0x000000);
|
||||
|
||||
Serial.println("Display ready");
|
||||
}
|
||||
|
||||
// ── Singleton ──
|
||||
DisplayDriverGFX& DisplayDriverGFX::instance() {
|
||||
static DisplayDriverGFX inst;
|
||||
return inst;
|
||||
}
|
||||
|
||||
// ── IDisplayDriver implementation ──
|
||||
|
||||
void DisplayDriverGFX::begin() {
|
||||
initExpander();
|
||||
initDisplay();
|
||||
}
|
||||
|
||||
void DisplayDriverGFX::setBacklight(bool on) {
|
||||
if (expander) {
|
||||
expander->digitalWrite(EXIO_LCD_BL, on ? HIGH : LOW);
|
||||
Serial.printf("[GFX] Backlight %s\n", on ? "ON" : "OFF");
|
||||
if (_expander) {
|
||||
_expander->digitalWrite(LCD_BL, on ? HIGH : LOW);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Touch ──
|
||||
|
||||
void DisplayDriverGFX::touchInit() {
|
||||
Wire.begin(I2C_MASTER_SDA, I2C_MASTER_SCL);
|
||||
Wire.beginTransmission(GT911_ADDR);
|
||||
uint8_t err = Wire.endTransmission();
|
||||
if (err == 0) {
|
||||
Serial.println("[TOUCH] GT911 initialized");
|
||||
} else {
|
||||
Serial.printf("[TOUCH] GT911 not found (I2C err %d)\n", err);
|
||||
}
|
||||
int DisplayDriverGFX::width() {
|
||||
return DISP_W;
|
||||
}
|
||||
|
||||
int DisplayDriverGFX::height() {
|
||||
return DISP_H;
|
||||
}
|
||||
|
||||
// ── Touch handling ──
|
||||
|
||||
TouchEvent DisplayDriverGFX::readTouch() {
|
||||
TouchEvent ev = { false, 0, 0 };
|
||||
Wire.beginTransmission(GT911_ADDR);
|
||||
if (Wire.endTransmission() != 0) return ev;
|
||||
|
||||
// Read touch status register (0x814E)
|
||||
Wire.beginTransmission(GT911_ADDR);
|
||||
Wire.write(0x81);
|
||||
Wire.write(0x4E);
|
||||
Wire.endTransmission(false);
|
||||
Wire.requestFrom((uint8_t)GT911_ADDR, (uint8_t)1);
|
||||
if (!Wire.available()) return ev;
|
||||
|
||||
uint8_t status = Wire.read();
|
||||
uint8_t touches = status & 0x0F;
|
||||
|
||||
if ((status & 0x80) && touches > 0 && touches <= 5) {
|
||||
// Read first touch point (0x8150)
|
||||
Wire.beginTransmission(GT911_ADDR);
|
||||
Wire.write(0x81);
|
||||
Wire.write(0x50);
|
||||
Wire.endTransmission(false);
|
||||
Wire.requestFrom((uint8_t)GT911_ADDR, (uint8_t)4);
|
||||
if (Wire.available() >= 4) {
|
||||
uint8_t xl = Wire.read();
|
||||
uint8_t xh = Wire.read();
|
||||
uint8_t yl = Wire.read();
|
||||
uint8_t yh = Wire.read();
|
||||
ev.pressed = true;
|
||||
ev.x = (xh << 8) | xl;
|
||||
ev.y = (yh << 8) | yl;
|
||||
TouchEvent evt;
|
||||
|
||||
if (!_gfx) return evt;
|
||||
|
||||
int32_t x, y;
|
||||
if (_gfx->getTouch(&x, &y)) {
|
||||
evt.pressed = true;
|
||||
evt.x = static_cast<int>(x);
|
||||
evt.y = static_cast<int>(y);
|
||||
|
||||
// Track press start
|
||||
if (!_lastTouch.pressed) {
|
||||
_pressStartMs = millis();
|
||||
_isHolding = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Clear status
|
||||
Wire.beginTransmission(GT911_ADDR);
|
||||
Wire.write(0x81);
|
||||
Wire.write(0x4E);
|
||||
Wire.write(0x00);
|
||||
Wire.endTransmission();
|
||||
|
||||
return ev;
|
||||
|
||||
_lastTouch = evt;
|
||||
return evt;
|
||||
}
|
||||
|
||||
int DisplayDriverGFX::dashboardTouch(int x, int y) {
|
||||
// Unified 2x2 grid
|
||||
int col = (x * 2) / DISPLAY_WIDTH; // 0 or 1
|
||||
int row = (y * 2) / DISPLAY_HEIGHT; // 0 or 1
|
||||
return row * 2 + col; // 0, 1, 2, or 3
|
||||
// Dashboard tiles: 2 rows × 4 columns
|
||||
constexpr int cols = 4;
|
||||
constexpr int rows = 2;
|
||||
constexpr int tileW = DISP_W / cols;
|
||||
constexpr int tileH = DISP_H / rows;
|
||||
|
||||
if (x < 0 || x >= DISP_W || y < 0 || y >= DISP_H) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int col = x / tileW;
|
||||
int row = y / tileH;
|
||||
|
||||
return row * cols + col;
|
||||
}
|
||||
|
||||
HoldState DisplayDriverGFX::updateHold(unsigned long holdMs) {
|
||||
TouchEvent ev = readTouch();
|
||||
HoldState state;
|
||||
|
||||
if (ev.pressed) {
|
||||
if (!_lastTouched) {
|
||||
_holdStart = millis();
|
||||
_lastTouched = true;
|
||||
}
|
||||
unsigned long elapsed = millis() - _holdStart;
|
||||
float progress = constrain((float)elapsed / holdMs, 0.0f, 1.0f);
|
||||
|
||||
if (elapsed >= holdMs) {
|
||||
_lastTouched = false;
|
||||
_holdStart = 0;
|
||||
return {false, true, 1.0f};
|
||||
}
|
||||
return {true, false, progress};
|
||||
} else {
|
||||
_lastTouched = false;
|
||||
_holdStart = 0;
|
||||
return {false, false, 0.0f};
|
||||
if (!_lastTouch.pressed) {
|
||||
_isHolding = false;
|
||||
return state;
|
||||
}
|
||||
}
|
||||
void DisplayDriverGFX::updateHint() {
|
||||
// placeholder for idle hint animation
|
||||
}
|
||||
|
||||
// ── Display ──
|
||||
|
||||
void DisplayDriverGFX::begin() {
|
||||
// 1. Touch (I2C on GPIO 8/9)
|
||||
touchInit();
|
||||
delay(200);
|
||||
|
||||
// 2. IO expander
|
||||
expanderInit();
|
||||
|
||||
// 3. RGB display
|
||||
Serial.println("[GFX] GFX init...");
|
||||
Arduino_ESP32RGBPanel* rgbPanel = new Arduino_ESP32RGBPanel(
|
||||
LCD_DE, LCD_VSYNC, LCD_HSYNC, LCD_PCLK,
|
||||
LCD_R0, LCD_R1, LCD_R2, LCD_R3, LCD_R4,
|
||||
LCD_G0, LCD_G1, LCD_G2, LCD_G3, LCD_G4, LCD_G5,
|
||||
LCD_B0, LCD_B1, LCD_B2, LCD_B3, LCD_B4,
|
||||
0, // hsync_polarity
|
||||
40, // hsync_front_porch
|
||||
48, // hsync_pulse_width
|
||||
88, // hsync_back_porch
|
||||
0, // vsync_polarity
|
||||
13, // vsync_front_porch
|
||||
3, // vsync_pulse_width
|
||||
32, // vsync_back_porch
|
||||
1, // pclk_active_neg
|
||||
16000000 // prefer_speed
|
||||
);
|
||||
|
||||
_gfx = new Arduino_RGB_Display(
|
||||
DISPLAY_WIDTH, DISPLAY_HEIGHT, rgbPanel,
|
||||
DISPLAY_ROTATION, true
|
||||
);
|
||||
|
||||
if (!_gfx->begin()) {
|
||||
Serial.println("[GFX] *** Display init FAILED ***");
|
||||
return;
|
||||
|
||||
unsigned long elapsed = millis() - _pressStartMs;
|
||||
|
||||
if (!_isHolding) {
|
||||
// Start tracking hold
|
||||
_isHolding = true;
|
||||
}
|
||||
|
||||
Serial.printf("[GFX] Display OK: %dx%d\n", DISPLAY_WIDTH, DISPLAY_HEIGHT);
|
||||
Serial.printf("[MEM] Free heap: %d | Free PSRAM: %d\n",
|
||||
ESP.getFreeHeap(), ESP.getFreePsram());
|
||||
|
||||
// 4. Clear and backlight on
|
||||
_gfx->fillScreen(BLACK);
|
||||
setBacklight(true);
|
||||
drawBoot();
|
||||
|
||||
state.active = true;
|
||||
state.progress = static_cast<float>(elapsed) / static_cast<float>(holdMs);
|
||||
|
||||
if (state.progress >= 1.0f) {
|
||||
state.progress = 1.0f;
|
||||
state.completed = true;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
int DisplayDriverGFX::width() { return _gfx ? _gfx->width() : DISPLAY_WIDTH; }
|
||||
int DisplayDriverGFX::height() { return _gfx ? _gfx->height() : DISPLAY_HEIGHT; }
|
||||
|
||||
// ── Render (state machine driven) ──
|
||||
// ── Rendering ──
|
||||
|
||||
void DisplayDriverGFX::render(const ScreenState& state) {
|
||||
if (!_gfx) return;
|
||||
switch (state.screen) {
|
||||
case ScreenID::BOOT: drawBoot(); break;
|
||||
case ScreenID::DASHBOARD: drawDashboard(state); break;
|
||||
case ScreenID::ALERT: drawAlert(state); break;
|
||||
case ScreenID::OFF: drawOff(); break;
|
||||
default: drawBoot(); break;
|
||||
|
||||
// Clear with background color
|
||||
_gfx->fillScreen(0x001030); // Dark blue
|
||||
|
||||
if (!state.showDashboard) {
|
||||
// Show alert/message screen
|
||||
renderAlert(state);
|
||||
return;
|
||||
}
|
||||
|
||||
// Draw dashboard tiles
|
||||
constexpr int cols = 4;
|
||||
constexpr int rows = 2;
|
||||
constexpr int tileW = DISP_W / cols;
|
||||
constexpr int tileH = DISP_H / rows;
|
||||
constexpr int margin = 8;
|
||||
|
||||
for (int i = 0; i < state.dashTiles.size(); i++) {
|
||||
int col = i % cols;
|
||||
int row = i / cols;
|
||||
|
||||
int x = col * tileW + margin;
|
||||
int y = row * tileH + margin;
|
||||
int w = tileW - 2 * margin;
|
||||
int h = tileH - 2 * margin;
|
||||
|
||||
// Tile background
|
||||
uint16_t tileColor = state.dashTiles[i].active ? 0x04A0 : 0x0220;
|
||||
_gfx->fillRoundRect(x, y, w, h, 8, tileColor);
|
||||
|
||||
// Tile border
|
||||
_gfx->drawRoundRect(x, y, w, h, 8, 0xFFFF);
|
||||
|
||||
// Tile label
|
||||
_gfx->setTextColor(0xFFFF);
|
||||
_gfx->setTextSize(2);
|
||||
_gfx->setCursor(x + 10, y + 10);
|
||||
_gfx->print(state.dashTiles[i].label);
|
||||
}
|
||||
|
||||
// Draw WiFi status
|
||||
_gfx->setTextSize(1);
|
||||
_gfx->setCursor(DISP_W - 100, 10);
|
||||
_gfx->printf("WiFi: %s", state.wifiConnected ? "ON" : "OFF");
|
||||
}
|
||||
|
||||
void DisplayDriverGFX::drawBoot() {
|
||||
void DisplayDriverGFX::updateHint() {
|
||||
if (!_gfx) return;
|
||||
_gfx->fillScreen(BLACK);
|
||||
_gfx->setTextColor(WHITE);
|
||||
_gfx->setTextSize(4);
|
||||
_gfx->setCursor(250, 200);
|
||||
_gfx->println("Klubhaus Alert");
|
||||
_gfx->setTextSize(2);
|
||||
_gfx->setCursor(300, 260);
|
||||
_gfx->println("Booting...");
|
||||
|
||||
static uint32_t lastTime = 0;
|
||||
uint32_t now = millis();
|
||||
if (now - lastTime < 50) return;
|
||||
lastTime = now;
|
||||
|
||||
float t = (now % 2000) / 2000.0f;
|
||||
uint8_t v = static_cast<uint8_t>(30.0f + 30.0f * sinf(t * 2 * 3.14159f));
|
||||
uint16_t col = ((v >> 3) << 11) | ((v >> 2) << 5) | (v >> 3);
|
||||
|
||||
_gfx->drawCircle(DISP_W / 2, DISP_H / 2, 50, col);
|
||||
}
|
||||
|
||||
void DisplayDriverGFX::drawDashboard(const ScreenState& state) {
|
||||
if (!_gfx) return;
|
||||
_gfx->fillScreen(BLACK);
|
||||
_gfx->setTextColor(WHITE);
|
||||
// Helper for alert rendering (implement as needed)
|
||||
void DisplayDriverGFX::renderAlert(const ScreenState& state) {
|
||||
// Placeholder - implement based on your ScreenState fields
|
||||
_gfx->setTextColor(0xFFFF);
|
||||
_gfx->setTextSize(3);
|
||||
_gfx->setCursor(20, 20);
|
||||
_gfx->println("KLUBHAUS DASHBOARD");
|
||||
_gfx->setTextSize(2);
|
||||
_gfx->setCursor(20, 80);
|
||||
_gfx->printf("IP: %s", state.ipAddr.c_str());
|
||||
_gfx->setCursor(20, 110);
|
||||
_gfx->printf("RSSI: %d dBm", state.wifiRssi);
|
||||
_gfx->setCursor(20, 140);
|
||||
_gfx->setCursor(200, 200);
|
||||
_gfx->print("Alert Mode");
|
||||
}
|
||||
|
||||
void DisplayDriverGFX::drawAlert(const ScreenState& state) {
|
||||
if (!_gfx) return;
|
||||
_gfx->fillScreen(RED);
|
||||
_gfx->setTextColor(WHITE);
|
||||
_gfx->setTextSize(5);
|
||||
_gfx->setCursor(200, 180);
|
||||
_gfx->println("DOORBELL!");
|
||||
_gfx->setTextSize(3);
|
||||
_gfx->setCursor(100, 280);
|
||||
const char* body = state.alertBody.c_str();
|
||||
_gfx->println(state.alertBody.length() ? body : "Someone is at the door");
|
||||
}
|
||||
|
||||
void DisplayDriverGFX::drawOff() {
|
||||
if (!_gfx) return;
|
||||
_gfx->fillScreen(BLACK);
|
||||
setBacklight(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,29 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <IDisplayDriver.h>
|
||||
#include <Arduino_GFX_Library.h>
|
||||
#include <Arduino.h>
|
||||
#include "ScreenState.h"
|
||||
#include "IDisplayDriver.h"
|
||||
|
||||
struct TouchEvent {
|
||||
bool pressed = false;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
};
|
||||
|
||||
struct HoldState {
|
||||
bool active = false;
|
||||
bool completed = false;
|
||||
float progress = 0.0f; // 0.0 – 1.0
|
||||
};
|
||||
|
||||
class DisplayDriverGFX : public IDisplayDriver {
|
||||
public:
|
||||
// ── IDisplayDriver ──
|
||||
void begin() override;
|
||||
void setBacklight(bool on) override;
|
||||
void render(const ScreenState& state) override;
|
||||
|
||||
TouchEvent readTouch() override;
|
||||
int dashboardTouch(int x, int y) override;
|
||||
int dashboardTouch(int x, int y) override;
|
||||
HoldState updateHold(unsigned long holdMs) override;
|
||||
void updateHint() override;
|
||||
int width() override;
|
||||
int height() override;
|
||||
|
||||
int width() override;
|
||||
int height() override;
|
||||
|
||||
// ── Internal ──
|
||||
static DisplayDriverGFX& instance();
|
||||
|
||||
private:
|
||||
void expanderInit();
|
||||
void touchInit();
|
||||
void drawBoot();
|
||||
void drawDashboard(const ScreenState& state);
|
||||
void drawAlert(const ScreenState& state);
|
||||
void drawOff();
|
||||
Arduino_RGB_Display* _gfx = nullptr;
|
||||
bool _lastTouched = false;
|
||||
unsigned long _holdStart = 0;
|
||||
// Touch handling
|
||||
TouchEvent _lastTouch = {false, 0, 0};
|
||||
unsigned long _pressStartMs = 0;
|
||||
bool _isHolding = false;
|
||||
};
|
||||
|
||||
|
||||
118
boards/esp32-s3-lcd-43/LovyanPins.h
Normal file
118
boards/esp32-s3-lcd-43/LovyanPins.h
Normal file
@@ -0,0 +1,118 @@
|
||||
#pragma once
|
||||
|
||||
#define LGFX_USE_V1
|
||||
#include <LovyanGFX.hpp>
|
||||
#include <lgfx/v1/platforms/esp32s3/Panel_RGB.hpp>
|
||||
#include <lgfx/v1/platforms/esp32s3/Bus_RGB.hpp>
|
||||
|
||||
// ── Display dimensions ──
|
||||
#define TFT_HOR_RES 800
|
||||
#define TFT_VER_RES 480
|
||||
|
||||
// ── Touch I2C (from Westcott example) ──
|
||||
#define TOUCH_SDA 8
|
||||
#define TOUCH_SCL 9
|
||||
#define TOUCH_INT 4
|
||||
#define TOUCH_RST -1
|
||||
|
||||
// ── CH422G Expander pins ──
|
||||
#define TP_RST 1
|
||||
#define LCD_BL 2
|
||||
#define LCD_RST 3
|
||||
#define SD_CS 4
|
||||
#define USB_SEL 5
|
||||
|
||||
class LGFX : public lgfx::LGFX_Device {
|
||||
public:
|
||||
lgfx::Bus_RGB _bus_instance;
|
||||
lgfx::Panel_RGB _panel_instance;
|
||||
lgfx::Touch_GT911 _touch_instance;
|
||||
|
||||
LGFX(void) {
|
||||
// Panel config
|
||||
{
|
||||
auto cfg = _panel_instance.config();
|
||||
cfg.memory_width = TFT_HOR_RES;
|
||||
cfg.memory_height = TFT_VER_RES;
|
||||
cfg.panel_width = TFT_HOR_RES;
|
||||
cfg.panel_height = TFT_VER_RES;
|
||||
cfg.offset_x = 0;
|
||||
cfg.offset_y = 0;
|
||||
_panel_instance.config(cfg);
|
||||
}
|
||||
|
||||
// RGB parallel bus config (from Westcott)
|
||||
{
|
||||
auto cfg = _bus_instance.config();
|
||||
cfg.panel = &_panel_instance;
|
||||
|
||||
// Blue channel
|
||||
cfg.pin_d0 = 14;
|
||||
cfg.pin_d1 = 38;
|
||||
cfg.pin_d2 = 18;
|
||||
cfg.pin_d3 = 17;
|
||||
cfg.pin_d4 = 10;
|
||||
|
||||
// Green channel
|
||||
cfg.pin_d5 = 39;
|
||||
cfg.pin_d6 = 0;
|
||||
cfg.pin_d7 = 45;
|
||||
cfg.pin_d8 = 48;
|
||||
cfg.pin_d9 = 47;
|
||||
cfg.pin_d10 = 21;
|
||||
|
||||
// Red channel
|
||||
cfg.pin_d11 = 1;
|
||||
cfg.pin_d12 = 2;
|
||||
cfg.pin_d13 = 42;
|
||||
cfg.pin_d14 = 41;
|
||||
cfg.pin_d15 = 40;
|
||||
|
||||
// Timing
|
||||
cfg.pin_henable = 5;
|
||||
cfg.pin_vsync = 3;
|
||||
cfg.pin_hsync = 46;
|
||||
cfg.pin_pclk = 7;
|
||||
cfg.freq_write = 14000000;
|
||||
|
||||
cfg.hsync_polarity = 0;
|
||||
cfg.hsync_front_porch = 20;
|
||||
cfg.hsync_pulse_width = 10;
|
||||
cfg.hsync_back_porch = 10;
|
||||
|
||||
cfg.vsync_polarity = 0;
|
||||
cfg.vsync_front_porch = 10;
|
||||
cfg.vsync_pulse_width = 10;
|
||||
cfg.vsync_back_porch = 10;
|
||||
|
||||
cfg.pclk_active_neg = 0;
|
||||
cfg.de_idle_high = 0;
|
||||
cfg.pclk_idle_high = 0;
|
||||
|
||||
_bus_instance.config(cfg);
|
||||
}
|
||||
_panel_instance.setBus(&_bus_instance);
|
||||
|
||||
// Touch config (I2C port 1, address 0x14 - from Westcott!)
|
||||
{
|
||||
auto cfg = _touch_instance.config();
|
||||
cfg.x_min = 0;
|
||||
cfg.x_max = TFT_HOR_RES - 1;
|
||||
cfg.y_min = 0;
|
||||
cfg.y_max = TFT_VER_RES - 1;
|
||||
cfg.pin_int = TOUCH_INT;
|
||||
cfg.pin_rst = TOUCH_RST;
|
||||
cfg.bus_shared = false;
|
||||
cfg.offset_rotation = 0;
|
||||
cfg.i2c_port = I2C_NUM_1; // IMPORTANT: Port 1, not 0!
|
||||
cfg.pin_sda = TOUCH_SDA;
|
||||
cfg.pin_scl = TOUCH_SCL;
|
||||
cfg.freq = 400000;
|
||||
cfg.i2c_addr = 0x14; // IMPORTANT: Address 0x14, not 0x5D!
|
||||
_touch_instance.config(cfg);
|
||||
_panel_instance.setTouch(&_touch_instance);
|
||||
}
|
||||
|
||||
setPanel(&_panel_instance);
|
||||
}
|
||||
};
|
||||
@@ -1,41 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#define BOARD_NAME "WS_S3_43"
|
||||
#define DISPLAY_WIDTH 800
|
||||
#define DISPLAY_HEIGHT 480
|
||||
#define BOARD_NAME "WS_S3_43"
|
||||
#define DISPLAY_WIDTH 800
|
||||
#define DISPLAY_HEIGHT 480
|
||||
#define DISPLAY_ROTATION 0
|
||||
|
||||
// ── RGB parallel bus (from Westcott1 reference) ──
|
||||
#define LCD_DE 5
|
||||
#define LCD_VSYNC 3
|
||||
#define LCD_HSYNC 46
|
||||
#define LCD_PCLK 7
|
||||
#define LCD_DE 5
|
||||
#define LCD_VSYNC 3
|
||||
#define LCD_HSYNC 46
|
||||
#define LCD_PCLK 7
|
||||
|
||||
#define LCD_R0 1
|
||||
#define LCD_R1 2
|
||||
#define LCD_R2 42
|
||||
#define LCD_R3 41
|
||||
#define LCD_R4 40
|
||||
#define LCD_R0 1
|
||||
#define LCD_R1 2
|
||||
#define LCD_R2 42
|
||||
#define LCD_R3 41
|
||||
#define LCD_R4 40
|
||||
|
||||
#define LCD_G0 39
|
||||
#define LCD_G1 0
|
||||
#define LCD_G2 45
|
||||
#define LCD_G3 48
|
||||
#define LCD_G4 47
|
||||
#define LCD_G5 21
|
||||
#define LCD_G0 39
|
||||
#define LCD_G1 0
|
||||
#define LCD_G2 45
|
||||
#define LCD_G3 48
|
||||
#define LCD_G4 47
|
||||
#define LCD_G5 21
|
||||
|
||||
#define LCD_B0 14
|
||||
#define LCD_B1 38
|
||||
#define LCD_B2 18
|
||||
#define LCD_B3 17
|
||||
#define LCD_B4 10
|
||||
#define LCD_B0 14
|
||||
#define LCD_B1 38
|
||||
#define LCD_B2 18
|
||||
#define LCD_B3 17
|
||||
#define LCD_B4 10
|
||||
|
||||
// ── I2C bus (shared: CH422G + GT911) ──
|
||||
#define I2C_MASTER_NUM ((i2c_port_t)0)
|
||||
#define I2C_MASTER_SDA 8
|
||||
#define I2C_MASTER_SCL 9
|
||||
#define I2C_MASTER_NUM ((i2c_port_t)0)
|
||||
#define I2C_MASTER_SDA 8
|
||||
#define I2C_MASTER_SCL 9
|
||||
|
||||
// ── GT911 Touch ──
|
||||
#define GT911_ADDR 0x5D
|
||||
#define TOUCH_INT -1
|
||||
|
||||
#define GT911_ADDR 0x5D
|
||||
// #define TOUCH_INT -1
|
||||
|
||||
Reference in New Issue
Block a user