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