vitotai / BrewPiLessGx

BrewPiLess with touched TFT.
6 stars 4 forks source link

Support for WT32-SC01 plus #4

Open troky opened 4 months ago

troky commented 4 months ago

Is it possible to add support for WT32-SC01 Plus ? It is ESP32-WROVER-2-N8R2 based board with ST7796UI 3.5" 480*320 LCD and I2C FT6336U touch. It has 6 GPIO available.

I can help with implementation if you could just create some basic skeleton/env (e.g. add defines and config params...) for it.

vitotai commented 4 months ago

It seems a better module that I wish I had found it. Or, maybe I've seen it, but I couldn't find the schematics and have no idea how to use it. Any way, You can try this branch for generic display drivers that are supported by ArduinoGFX library. https://github.com/vitotai/BrewPiLessGx/tree/GenericDriver

You will need to add a ST7796 driver in src/esp32/lv_disp.cpp like line 14~16 for ST7789.

Then you will have to add some code to defines the parameters of the driver and TFT in src/esp32/lv_drv_conf.h You need to know the pins of SPI and bus speed. Rotation might be something you need to try, as well as TFT_IPS, which seems to affect color, like reversed color.

For touch driver, it seems to be more complicated. I haven't found a library of touch drivers. So you will have to figure out it by yourself by referencing src/esp32/lv_touch.cpp

troky commented 4 months ago

I made it work (touchpad, too)... I added https://github.com/smartpanle/PanelLan_esp32_arduino to lib_deps and made driver for it:

sc01-plus.cpp:

#ifdef SC01_PLUS

#include <lvgl.h>

#include "PanelLan.h" 

#define BUFFER_SIZE (320 *10)

PanelLan tft(BOARD_SC01_PLUS);

/*** Setup screen resolution for LVGL ***/
static const uint16_t screenWidth = 480;
static const uint16_t screenHeight = 320;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[screenWidth * 10];

//static int32_t x, y;

 /*** Display callback to flush the buffer to screen ***/
  void display_flush(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);

    tft.startWrite();
    tft.setAddrWindow(area->x1, area->y1, w, h);
    tft.pushColors((uint16_t *)&color_p->full, w * h, true);
    tft.endWrite();

    lv_disp_flush_ready(disp);
  }

  /*** Touchpad callback to read the touchpad ***/
  void touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
  {
    uint16_t touchX, touchY;
    bool touched = tft.getTouch(&touchX, &touchY);

    if (!touched)
    {
      data->state = LV_INDEV_STATE_REL;
    }
    else
    {
      data->state = LV_INDEV_STATE_PR;

      /*Set the coordinates*/
      data->point.x = touchX;
      data->point.y = touchY;

      // Serial.printf("Touch (x,y): (%03d,%03d)\n",touchX,touchY );
    }
  }

void display_setup()
{
   // Init Display
   tft.init();
   tft.initDMA();
   tft.fillScreen(TFT_BLACK);

   lv_init();

   // Setting display to landscape
   if (tft.width() < tft.height()) {
      tft.setRotation(tft.getRotation() ^ 1);
   }

   /* LVGL : Setting up buffer to use for display */
   lv_disp_draw_buf_init(&draw_buf, buf, NULL, screenWidth * 10);

   /*** LVGL : Setup & Initialize the display device driver ***/
   static lv_disp_drv_t disp_drv;
   lv_disp_drv_init(&disp_drv);
   disp_drv.hor_res = screenWidth;
   disp_drv.ver_res = screenHeight;
   disp_drv.flush_cb = display_flush;
   disp_drv.draw_buf = &draw_buf;
   lv_disp_drv_register(&disp_drv);

   /*** LVGL : Setup & Initialize the input device driver ***/
   static lv_indev_drv_t indev_drv;
   lv_indev_drv_init(&indev_drv);
   indev_drv.type = LV_INDEV_TYPE_POINTER;
   indev_drv.read_cb = touchpad_read;
   lv_indev_drv_register(&indev_drv);
}
#endif

.. pretty simple :)

I suggest you move each driver in separate .cpp file (maybe in drivers/folder?) and enclose its code in #ifdef..#endif Each driver should have display_init() for initialization and display_flush() and touchpad_read() callbacks

Of course some changes are needed in Config.h... but one step at the time. Config is a bit messy - BP(L) logic and features and hardware config should be separated for easier additio of new platforms without interrupting core BP logic.

troky commented 4 months ago

forgot to add platfomio.ini env:

[env:SC01_PLUS]
platform = ${common_env_data.esp32_framework}
framework = arduino

;board = wt32-sc01-plus
board = unphone8 
board_build.mcu = esp32s3
board_build.arduino.memory_type = qio_qspi 

lib_extra_dirs = 
    ${common_env_data.esp32_lib}

lib_deps = ${common_env_data.lib_deps_external_esp32} 
    lovyan03/LovyanGFX
    https://github.com/smartpanle/PanelLan_esp32_arduino

lib_ignore = esp32_smartdisplay

board_build.partitions = ./partition.csv
board_build.embed_txtfiles = 
    src/skins/skin_brewpi.json
    src/skins/skin_info.json

board_build.filesystem = littlefs

build_unflags = -DARDUINO_USB_MODE=1
build_flags =
    ${common_env_data.graphics_build_flags}
    -DSC01_PLUS
    -DBOARD_HAS_PSRAM
    -mfix-esp32-psram-cache-issue
    ;-DCONFIG_IDF_TARGET_ESP32S3
    ;-D ARDUINO_USB_MODE=0
    ;-DARDUINO_USB_CDC_ON_BOOT
    ;-DUSE_USB_CDC_CONSOLE
    -DSerialDebug=true

monitor_speed = 115200
upload_speed = 921600

upload_port = COM13
monitor_port = COM13

monitor_filters = esp32_exception_decoder
vitotai commented 4 months ago

I suggest you move each driver in separate .cpp file (maybe in drivers/folder?) and enclose its code in #ifdef..#endif Each driver should have display_init() for initialization and display_flush() and touchpad_read() callbacks

Of course some changes are needed in Config.h... but one step at the time. Config is a bit messy - BP(L) logic and features and hardware config should be separated for easier additio of new platforms without interrupting core BP logic.

Yeah, I am currently reorganize the source to make it easier to configure.