From 2ea173fa7517ceca5c1c05b230c68df950e5dae6 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Tue, 8 Nov 2022 20:35:59 +0100 Subject: [PATCH] Add Arduino_GFX driver --- platformio.ini | 4 + src/drv/tft/tft_driver.h | 3 + src/drv/tft/tft_driver_arduinogfx.cpp | 272 ++++++++++++++++++++++++++ src/drv/tft/tft_driver_arduinogfx.h | 168 ++++++++++++++++ test/test_checkbox.tavern.yaml | 1 + test/test_value_str.tavern.yaml | 9 +- user_setups/esp32s3/gs-t3e.ini | 70 +++++++ 7 files changed, 523 insertions(+), 4 deletions(-) create mode 100644 src/drv/tft/tft_driver_arduinogfx.cpp create mode 100644 src/drv/tft/tft_driver_arduinogfx.h create mode 100644 user_setups/esp32s3/gs-t3e.ini diff --git a/platformio.ini b/platformio.ini index 6b4d34fd..beb4457b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -105,6 +105,10 @@ build_src_filter = +<*> -<.git/> - - - - - + +namespace dev { + +void tftPinInfo(const __FlashStringHelper* pinfunction, int8_t pin) +{ + if(pin != -1) { + char buffer[64]; + snprintf_P(buffer, sizeof(buffer), PSTR("%-12s: %s (GPIO %02d)"), String(pinfunction).c_str(), + haspDevice.gpio_name(pin).c_str(), pin); + LOG_VERBOSE(TAG_TFT, buffer); + } +} + +void ArduinoGfx::init(int w, int h) +{ + LOG_TRACE(TAG_TFT, F(D_SERVICE_STARTING)); + + /* More data bus class: https://github.com/moononournation/Arduino_GFX/wiki/Data-Bus-Class */ + Arduino_ESP32RGBPanel* bus = new Arduino_ESP32RGBPanel( + 39 /* CS */, 15 /* SCK */, 14 /* SDA */, 18 /* DE */, 17 /* VSYNC */, 16 /* HSYNC */, 21 /* PCLK */, 4 /* R0 */, + 3 /* R1 */, 2 /* R2 */, 1 /* R3 */, 0 /* R4 */, 10 /* G0 */, 9 /* G1 */, 8 /* G2 */, 7 /* G3 */, 6 /* G4 */, + 5 /* G5 */, 15 /* B0 */, 14 /* B1 */, 13 /* B2 */, 12 /* B3 */, 11 /* B4 */); + + /* More display class: https://github.com/moononournation/Arduino_GFX/wiki/Display-Class */ + tft = new Arduino_ST7701_RGBPanel(bus, GFX_NOT_DEFINED /* RST */, 0 /* rotation */, true /* IPS */, 480 /* width */, + 480 /* height */, st7701_type1_init_operations, + sizeof(st7701_type1_init_operations), true /* BGR */); + + /* TFT init */ + LOG_DEBUG(TAG_TFT, F("%s - %d"), __FILE__, __LINE__); + tft->begin(GFX_NOT_DEFINED); + LOG_DEBUG(TAG_TFT, F("%s - %d"), __FILE__, __LINE__); + // tft.setSwapBytes(true); /* set endianess */ + LOG_INFO(TAG_TFT, F(D_SERVICE_STARTED)); +} + +void ArduinoGfx::show_info() +{ + splashscreen(); + + // LOG_VERBOSE(TAG_TFT, F("ArduinoGfx : v%d.%d.%d"), LGFX_VERSION_MAJOR, LGFX_VERSION_MINOR, + // LGFX_VERSION_PATCH); auto panel = tft.getPanel(); if(!panel) return; + + // if(!panel->getBus()) return; + // lgfx::v1::bus_type_t bus_type = panel->getBus()->busType(); + + // if(bus_type == lgfx::v1::bus_parallel8) { + // LOG_VERBOSE(TAG_TFT, F("Interface : Parallel 8bit")); + // auto bus = (lgfx::Bus_Parallel8*)panel->getBus(); + // auto cfg = bus->config(); // Get the structure for bus configuration. + // tftPinInfo(F("TFT_WR"), cfg.pin_wr); + // tftPinInfo(F("TFT_RD"), cfg.pin_rd); + // tftPinInfo(F("TFT_RS"), cfg.pin_rs); + + // tftPinInfo(F("TFT_D0"), cfg.pin_d0); + // tftPinInfo(F("TFT_D1"), cfg.pin_d1); + // tftPinInfo(F("TFT_D2"), cfg.pin_d2); + // tftPinInfo(F("TFT_D3"), cfg.pin_d3); + // tftPinInfo(F("TFT_D4"), cfg.pin_d4); + // tftPinInfo(F("TFT_D5"), cfg.pin_d5); + // tftPinInfo(F("TFT_D6"), cfg.pin_d6); + // tftPinInfo(F("TFT_D7"), cfg.pin_d7); + // } + + // #if defined(ESP32S2) || defined(ESP32S3) + // if(bus_type == lgfx::v1::bus_parallel16) { + // LOG_VERBOSE(TAG_TFT, F("Interface : Parallel 16bit")); + // auto bus = (lgfx::v1::Bus_Parallel16*)panel->getBus(); + // auto cfg = bus->config(); // Get the structure for bus configuration. + // tftPinInfo(F("TFT_WR"), cfg.pin_wr); + // tftPinInfo(F("TFT_RD"), cfg.pin_rd); + // tftPinInfo(F("TFT_RS"), cfg.pin_rs); + + // tftPinInfo(F("TFT_D0"), cfg.pin_d0); + // tftPinInfo(F("TFT_D1"), cfg.pin_d1); + // tftPinInfo(F("TFT_D2"), cfg.pin_d2); + // tftPinInfo(F("TFT_D3"), cfg.pin_d3); + // tftPinInfo(F("TFT_D4"), cfg.pin_d4); + // tftPinInfo(F("TFT_D5"), cfg.pin_d5); + // tftPinInfo(F("TFT_D6"), cfg.pin_d6); + // tftPinInfo(F("TFT_D7"), cfg.pin_d7); + // tftPinInfo(F("TFT_D8"), cfg.pin_d8); + // tftPinInfo(F("TFT_D9"), cfg.pin_d9); + // tftPinInfo(F("TFT_D01"), cfg.pin_d10); + // tftPinInfo(F("TFT_D11"), cfg.pin_d11); + // tftPinInfo(F("TFT_D12"), cfg.pin_d12); + // tftPinInfo(F("TFT_D13"), cfg.pin_d13); + // tftPinInfo(F("TFT_D14"), cfg.pin_d14); + // tftPinInfo(F("TFT_D15"), cfg.pin_d15); + // } + // #endif + + // if(bus_type == lgfx::v1::bus_spi) { + // LOG_VERBOSE(TAG_TFT, F("Interface : Serial")); + // auto bus = (lgfx::Bus_SPI*)panel->getBus(); + // auto cfg = bus->config(); // Get the structure for bus configuration. + // tftPinInfo(F("TFT_MOSI"), cfg.pin_mosi); + // tftPinInfo(F("TFT_MISO"), cfg.pin_miso); + // tftPinInfo(F("TFT_SCLK"), cfg.pin_sclk); + // tftPinInfo(F("TFT_DC"), cfg.pin_dc); + // } + + // { + // auto cfg = panel->config(); // Get the structure for panel configuration. + // tftPinInfo(F("TFT_CS"), cfg.pin_cs); + // tftPinInfo(F("TFT_RST"), cfg.pin_rst); + // tftPinInfo(F("TFT_BUSY"), cfg.pin_busy); + // } + + // if(bus_type == lgfx::v1::bus_spi) { + // auto bus = (lgfx::Bus_SPI*)panel->getBus(); + // auto cfg = bus->config(); // Get the structure for bus configuration. + // uint32_t freq = cfg.freq_write / 100000; + // LOG_VERBOSE(TAG_TFT, F("TFT SPI freq: %d.%d MHz"), freq / 10, freq % 10); + // } + + // lgfx::v1::ITouch* touch = panel->getTouch(); + // if(touch) { + // auto cfg = touch->config(); // Get the structure for bus configuration. + // uint32_t freq = cfg.freq / 100000; + // tftPinInfo(F("TOUCH_INT"), cfg.pin_int); + // tftPinInfo(F("TOUCH_RST"), cfg.pin_rst); + // if(touch->isSPI()) { + // tftPinInfo(F("TOUCH_MISO"), cfg.pin_miso); + // tftPinInfo(F("TOUCH_MOSI"), cfg.pin_mosi); + // tftPinInfo(F("TOUCH_SCLK"), cfg.pin_sclk); + // tftPinInfo(F("TOUCH_CS"), cfg.pin_cs); + // LOG_VERBOSE(TAG_TFT, F("Touch SPI freq. : %d.%d MHz"), freq / 10, freq % 10); + // } else { + // tftPinInfo(F("TOUCH_SDA"), cfg.pin_sda); + // tftPinInfo(F("TOUCH_SCL"), cfg.pin_scl); + // tftPinInfo(F("TOUCH_ADDR"), cfg.i2c_addr); + // LOG_VERBOSE(TAG_TFT, F("Touch I2C freq. : %d.%d MHz"), freq / 10, freq % 10); + // } + // } +} + +void ArduinoGfx::splashscreen() +{ + uint8_t fg[] = logoFgColor; + uint8_t bg[] = logoBgColor; + lv_color_t fgColor = lv_color_make(fg[0], fg[1], fg[2]); + lv_color_t bgColor = lv_color_make(bg[0], bg[1], bg[2]); + + tft->fillScreen(bgColor.full); + int x = (tft->width() - logoWidth) / 2; + int y = (tft->height() - logoHeight) / 2; + tft->drawXBitmap(x, y, logoImage, logoWidth, logoHeight, fgColor.full); + // tft.fillSmoothRoundRect(x, y, logoWidth, logoWidth, 15, fgColor.full); +} + +void ArduinoGfx::set_rotation(uint8_t rotation) +{ + LOG_VERBOSE(TAG_TFT, F("Rotation : %d"), rotation); + tft->setRotation(rotation); +} + +void ArduinoGfx::set_invert(bool invert) +{ + char buffer[4]; + memcpy_P(buffer, invert ? PSTR(D_YES) : PSTR(D_NO), sizeof(buffer)); + + LOG_VERBOSE(TAG_TFT, F("Invert Color: %s"), buffer); + tft->invertDisplay(invert); +} + +/* Update TFT */ +void IRAM_ATTR ArduinoGfx::flush_pixels(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p) +{ + uint32_t w = (area->x2 - area->x1 + 1); + uint32_t h = (area->y2 - area->y1 + 1); + +#if(LV_COLOR_16_SWAP != 0) + tft->draw16bitBeRGBBitmap(area->x1, area->y1, (uint16_t*)&color_p->full, w, h); +#else + tft->draw16bitRGBBitmap(area->x1, area->y1, (uint16_t*)&color_p->full, w, h); +#endif + + lv_disp_flush_ready(disp); +} + +bool ArduinoGfx::is_driver_pin(uint8_t pin) +{ + return false; +} + +const char* ArduinoGfx::get_tft_model() +{ +#if defined(ILI9341_DRIVER) + return "ILI9341"; +#elif defined(ILI9342_DRIVER) + return "ILI9342"; +#elif defined(ST7735_DRIVER) + return "ST7735"; +#elif defined(ILI9163_DRIVER) + return "ILI9163"; +#elif defined(S6D02A1_DRIVER) + return "S6D02A1"; +#elif defined(ST7796_DRIVER) + return "ST7796"; +#elif defined(ILI9486_DRIVER) + return "ILI9486"; +#elif defined(ILI9481_DRIVER) + return "ILI9481"; +#elif defined(ILI9488_DRIVER) + return "ILI9488"; +#elif defined(HX8357D_DRIVER) + return "HX8357D"; +#elif defined(EPD_DRIVER) + return "EPD"; +#elif defined(ST7789_DRIVER) + return "ST7789"; +#elif defined(R61581_DRIVER) + return "R61581"; +#elif defined(ST7789_2_DRIVER) + return "ST7789_2"; +#elif defined(R61529_DRIVER) + return "R61529"; +#elif defined(RM68140_DRIVER) + return "RM68140"; +#else + return "Other"; +#endif +} + +uint32_t ArduinoGfx::get_tft_driver() +{ +#if defined(ILI9341_DRIVER) + return 0x9341; +#elif defined(ST7735_DRIVER) + return 0x7735; +#elif defined(ILI9163_DRIVER) + return 0x9163; +#elif defined(S6D02A1_DRIVER) + return 0x6D02A1; +#elif defined(ST7796_DRIVER) + return 0x7796; +#elif defined(ILI9486_DRIVER) + return 0x9486; +#elif defined(ILI9481_DRIVER) + return 0x9481; +#elif defined(ILI9488_DRIVER) + return 0x9488; +#elif defined(HX8357D_DRIVER) + return 0x8357D; +#elif defined(EPD_DRIVER) + return 0xED; +#elif defined(ST7789_DRIVER) + return 0x7789; +#elif defined(ST7789_2_DRIVER) + return 0x77892; +#elif defined(R61581_DRIVER) + return 0x61581; +#elif defined(R61529_DRIVER) + return 0x61529; +#elif defined(RM68140_DRIVER) + return 0x68140; +#else + return 0x0; +#endif +} + +} // namespace dev + +dev::ArduinoGfx haspTft; +#endif \ No newline at end of file diff --git a/src/drv/tft/tft_driver_arduinogfx.h b/src/drv/tft/tft_driver_arduinogfx.h new file mode 100644 index 00000000..863deb85 --- /dev/null +++ b/src/drv/tft/tft_driver_arduinogfx.h @@ -0,0 +1,168 @@ +/* MIT License - Copyright (c) 2019-2022 Francis Van Roie + For full license information read the LICENSE file in the project folder */ + +#ifndef HASP_ARDUINOGFX_DRIVER_H +#define HASP_ARDUINOGFX_DRIVER_H + +#if defined(ARDUINO) && defined(HASP_USE_ARDUINOGFX) +#include + +#include "lvgl.h" +#include + +#include "tft_driver.h" +#include "hal/hasp_hal.h" +#include "dev/device.h" +#include "hasp_debug.h" + +#ifdef HASP_CUSTOMIZE_BOOTLOGO +#include "custom/bootlogo.h" // Sketch tab header for xbm images +#else +#include "custom/bootlogo_template.h" // Sketch tab header for xbm images +#endif + +#ifndef TOUCH_CS +#define TOUCH_CS -1 +#endif + +#ifndef TOUCH_IRQ +#define TOUCH_IRQ -1 +#endif + +#ifndef TFT_MOSI +#define TFT_MOSI -1 +#endif +#ifndef TFT_MISO +#define TFT_MISO -1 +#endif +#ifndef TFT_SCLK +#define TFT_SCLK -1 +#endif +#ifndef TFT_BUSY +#define TFT_BUSY -1 +#endif + +#ifndef TFT_D0 +#define TFT_D0 -1 +#endif +#ifndef TFT_D1 +#define TFT_D1 -1 +#endif +#ifndef TFT_D2 +#define TFT_D2 -1 +#endif +#ifndef TFT_D3 +#define TFT_D3 -1 +#endif +#ifndef TFT_D4 +#define TFT_D4 -1 +#endif +#ifndef TFT_D5 +#define TFT_D5 -1 +#endif +#ifndef TFT_D6 +#define TFT_D6 -1 +#endif +#ifndef TFT_D7 +#define TFT_D7 -1 +#endif +#ifndef TFT_D8 +#define TFT_D8 -1 +#endif +#ifndef TFT_D9 +#define TFT_D9 -1 +#endif +#ifndef TFT_D10 +#define TFT_D10 -1 +#endif +#ifndef TFT_D11 +#define TFT_D11 -1 +#endif +#ifndef TFT_D12 +#define TFT_D12 -1 +#endif +#ifndef TFT_D13 +#define TFT_D13 -1 +#endif +#ifndef TFT_D14 +#define TFT_D14 -1 +#endif +#ifndef TFT_D15 +#define TFT_D15 -1 +#endif +#ifndef TFT_RD +#define TFT_RD -1 +#endif +#ifndef TFT_WR +#define TFT_WR -1 +#endif +#ifndef TFT_DC +#define TFT_DC -1 +#endif +#ifndef SPI_READ_FREQUENCY +#define SPI_READ_FREQUENCY 0 +#endif +#ifndef TFT_OFFSET_ROTATION +#define TFT_OFFSET_ROTATION 0 +#endif +#ifndef TOUCH_OFFSET_ROTATION +#define TOUCH_OFFSET_ROTATION 0 +#endif +#ifndef I2C_TOUCH_PORT +#define I2C_TOUCH_PORT 0 +#endif + +namespace dev { + +class ArduinoGfx : BaseTft { + + public: + /* Display class: https://github.com/moononournation/Arduino_GFX/wiki/Display-Class */ + Arduino_GFX* tft = NULL; + + void init(int w, int h); + void show_info(); + void splashscreen(); + + void set_rotation(uint8_t rotation); + void set_invert(bool invert); + + void flush_pixels(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p); + bool is_driver_pin(uint8_t pin); + + const char* get_tft_model(); + + int32_t width() + { + return tft->width(); + } + int32_t height() + { + return tft->height(); + } + + private: + uint32_t tft_driver; + + uint32_t get_tft_driver(); + uint32_t get_touch_driver(); + + void tftOffsetInfo(uint8_t pin, uint8_t x_offset, uint8_t y_offset) + { + if(x_offset != 0) { + LOG_VERBOSE(TAG_TFT, F("R%u x offset = %i"), pin, x_offset); + } + if(y_offset != 0) { + LOG_VERBOSE(TAG_TFT, F("R%u y offset = %i"), pin, y_offset); + } + } +}; + +} // namespace dev + +using dev::ArduinoGfx; +extern dev::ArduinoGfx haspTft; + +#endif // ARDUINO + +#endif // HASP_ARDUINOGFX_DRIVER_H \ No newline at end of file diff --git a/test/test_checkbox.tavern.yaml b/test/test_checkbox.tavern.yaml index dc721221..f499c90c 100644 --- a/test/test_checkbox.tavern.yaml +++ b/test/test_checkbox.tavern.yaml @@ -84,6 +84,7 @@ stages: topic: hasp/{plate}/command/jsonl json: obj: "{obj}" + page: 1 id: 1 x: 128 y: 128 diff --git a/test/test_value_str.tavern.yaml b/test/test_value_str.tavern.yaml index 90c68f1d..93655a61 100644 --- a/test/test_value_str.tavern.yaml +++ b/test/test_value_str.tavern.yaml @@ -50,10 +50,11 @@ marks: - parametrize: key: obj vals: - - cpicker - - table +# - cpicker +# - table - tabview - - chart +# - chart + - spinner - gauge - btn - label @@ -66,7 +67,6 @@ marks: - obj - linemeter - dropdown - - spinner - roller - btnmatrix @@ -113,6 +113,7 @@ stages: topic: hasp/{plate}/command/jsonl json: obj: "{obj}" + page: 1 id: 1 x: 0 y: 0 diff --git a/user_setups/esp32s3/gs-t3e.ini b/user_setups/esp32s3/gs-t3e.ini new file mode 100644 index 00000000..da9976e3 --- /dev/null +++ b/user_setups/esp32s3/gs-t3e.ini @@ -0,0 +1,70 @@ +;***************************************************; +; GS-T3E with TFT 3.95" ; +; - Custom esp32-s3 board ; +; - st7701s TFT ; +; - gt911 touch controller ; +;***************************************************; + +[gs-t3e] +;board = esp32-s3-devkitc-1 +board = esp32s3_qio_opi + +build_flags = + ${env.build_flags} + ${esp32s3.build_flags} + ${esp32s3.ps_ram} + -D HASP_MODEL="GS-T3E" + ;-DARDUINO_USB_CDC_ON_BOOT + ;-DUSE_USB_CDC_CONSOLE + +;region -- LovyanGFX build options ------------------------ + -D HASP_USE_ARDUINOGFX=1 + -D ST7701_DRIVER=1 + ;-D TOUCH_DRIVER=0x911 + -D TFT_WIDTH=480 + -D TFT_HEIGHT=480 + -D SPI_FREQUENCY=20000000 + -D TFT_RD=-1 + -D TFT_WR=47 + -D TFT_RS=0 + -DESP32_PARALLEL + -D TFT_D0=9 + -D TFT_D1=46 + -D TFT_D2=3 + -D TFT_D3=8 + -D TFT_D4=18 + -D TFT_D5=17 + -D TFT_D6=16 + -D TFT_D7=15 + -D TFT_CS=-1 + -D TFT_RST=4 + -D TFT_BUSY=-1 + -D TFT_BCKL=38 + -D I2C_TOUCH_FREQUENCY=400000 + -D I2C_TOUCH_ADDRESS=0x5D ; or 0x14 + -D I2C_TOUCH_PORT=1 + -D TOUCH_SDA=40 + -D TOUCH_SCL=41 + -D TOUCH_RST=-1 +;endregion + +;region -- Library options ------------------------------- +lib_deps = + ${env.lib_deps} + ${esp32s3.lib_deps} + ${arduino_esp32s3_v2.lib_deps} + ${arduinogfx.lib_deps} + ${goodix.lib_deps} + +lib_ignore = + ${env.lib_ignore} + ${esp32s3.lib_ignore} + ${arduino_esp32s3_v2.lib_ignore} +;endregion + + +;[env:gs-t3e_8MB] +;extends = gs-t3e, esp32s3_8mb_v2 + +[env:gs-t3e_16MB] +extends = gs-t3e, esp32s3_16mb_v2 \ No newline at end of file