lovyan03 / LovyanGFX

SPI LCD graphics library for ESP32 (ESP-IDF/ArduinoESP32) / ESP8266 (ArduinoESP8266) / SAMD51(Seeed ArduinoSAMD51)
Other
1.03k stars 189 forks source link

Problem with ESP32s3 and 480x272 RGB display (module ESP32-4827S043) #374

Closed Emmanuele75 closed 1 year ago

Emmanuele75 commented 1 year ago

Carefully written Issues are more likely to be given priority. 丁寧に記述された報告は優先して対応される可能性が高くなります。

Environment ( 実行環境 )

Problem Description ( 問題の内容 )

I encountered a serious bug with the ESP32-4827S043 module, which houses an ESP32S3 and a 4.3" RGB display. In particular there seems to be problems with the LVGL library, under some conditions the display is not drawn completely. This happens when there are few animations, on the contrary it seems to work well with complex drawings and lots of active animations. From what I understand the problem lies with writePixels. I tried changing the flush_cb from:

void my_disp_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.writePixels((lgfx::rgb565_t *)&color_p->full, w * h);
   tft.endWrite();
   lv_disp_flush_ready(disp);
}

to:

void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p){\n
  uint16_t c;
  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);
  for (int y = area->y1; y <= area->y2; y++) {
    for (int x = area->x1; x <= area->x2; x++) {
      c = color_p->full;
      tft.writeColor(c, 1);
      color_p++;
    }
  }
  tft.endWrite();
  lv_disp_flush_ready(disp); 
}

Now the display works fine but it's terribly slow and the animations aren't smooth. How to solve this problem? Thanks! s3

tobozo commented 1 year ago

hi, thanks for your feedback :+1:

this is untested code, but this loop may be slightly faster:

  for (int y = area->y1; y <= area->y2; y++) {
    tft.setAddrWindow(area->x1, y, w, 1);
    tft.writePixels((lgfx::rgb565_t *)&color_p->full[y*w], w);
  }
Emmanuele75 commented 1 year ago

`I can't compile, I get this error:

C:\Users\emman\Desktop\KEY\COD\LvglWidgets\LvglWidgets.ino: In function 'void my_disp_flush(lv_disp_drv_t, const lv_area_t, lv_color_t)': LvglWidgets:78:57: error: invalid types 'uint16_t {aka short unsigned int}[int]' for array subscript tft.writePixels((lgfx::rgb565_t )&color_p->full[y*w], w); ^ exit status 1 invalid types 'uint16_t {aka short unsigned int}[int]' for array subscript

`

tobozo commented 1 year ago

yep, untested code means it probably has errors you have to fix

I can't check now but the idea is to improve the performance by using writePixels() to send a full line instead of one pixel per iteration.

maybe try one of these:

    tft.writePixels((lgfx::rgb565_t*)(&color_p->full)[y*w], w);
    uint16_t* framebufptr = (uint16_t*)&color_p->full;
    uint16_t* scanlineptr = framebufptr + (y*w);
    tft.writePixels((lgfx::rgb565_t*)scanlineptr, w);
Emmanuele75 commented 1 year ago

okay. I'll try)

Emmanuele75 commented 1 year ago

Following your suggestion I compiled this code:

void my_disp_flush( lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p ){
  int c = 0;
  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);
  for (int y = area->y1; y <= area->y2; y++) {
    uint16_t* framebufptr = (uint16_t*)&color_p->full;
    uint16_t* scanlineptr = framebufptr + (c*w);
    tft.writePixels((lgfx::rgb565_t*)scanlineptr, w);
    c++;
  }     
   tft.endWrite();
   lv_disp_flush_ready(disp);
}

Unfortunately the result does not change, the display is not drawn well. So at the moment the only solution is to draw point by point. Do you have any other suggestions for me to get rid of this bug? Thanks!

tobozo commented 1 year ago

Do you have any other suggestions for me to get rid of this bug?

not without seeing your LGFX configuration

Emmanuele75 commented 1 year ago

My lgfx_4827S043.h:

#define LGFX_USE_V1
#include <LovyanGFX.hpp>
#include <lgfx/v1/platforms/esp32s3/Panel_RGB.hpp>
#include <lgfx/v1/platforms/esp32s3/Bus_RGB.hpp>

class LGFX : public lgfx::LGFX_Device{
  lgfx::Bus_RGB     _bus_instance;
  lgfx::Panel_RGB   _panel_instance;
  lgfx::Light_PWM   _light_instance;
  lgfx::Touch_XPT2046 _touch_instance;

public:LGFX(void){
  auto cfg    = _bus_instance.config();
  cfg.panel   = &_panel_instance;
  cfg.pin_d0  = GPIO_NUM_8;  // B0
  cfg.pin_d1  = GPIO_NUM_3;  // B1
  cfg.pin_d2  = GPIO_NUM_46; // B2
  cfg.pin_d3  = GPIO_NUM_9;  // B3
  cfg.pin_d4  = GPIO_NUM_1;  // B4
  cfg.pin_d5  = GPIO_NUM_5;  // G0
  cfg.pin_d6  = GPIO_NUM_6;  // G1
  cfg.pin_d7  = GPIO_NUM_7;  // G2
  cfg.pin_d8  = GPIO_NUM_15; // G3
  cfg.pin_d9  = GPIO_NUM_16; // G4
  cfg.pin_d10 = GPIO_NUM_4;  // G5
  cfg.pin_d11 = GPIO_NUM_45; // R0
  cfg.pin_d12 = GPIO_NUM_48; // R1
  cfg.pin_d13 = GPIO_NUM_47; // R2
  cfg.pin_d14 = GPIO_NUM_21; // R3
  cfg.pin_d15 = GPIO_NUM_14; // R4
  cfg.pin_henable       = GPIO_NUM_40;
  cfg.pin_vsync         = GPIO_NUM_41;
  cfg.pin_hsync         = GPIO_NUM_39;
  cfg.pin_pclk          = GPIO_NUM_42;
  cfg.freq_write        = 9000000;   //16000000
  cfg.hsync_polarity    = 0; //0
  cfg.hsync_front_porch = 8; //8
  cfg.hsync_pulse_width = 1; //4
  cfg.hsync_back_porch  = 43; //43
  cfg.vsync_polarity    = 0;  //0
  cfg.vsync_front_porch = 8; //8
  cfg.vsync_pulse_width = 4; //4
  cfg.vsync_back_porch  = 12; //12
  cfg.pclk_idle_high    = 1; //1
  _bus_instance.config(cfg);
  _panel_instance.setBus(&_bus_instance);

  { auto cfg = _panel_instance.config();
  cfg.memory_width  = 480;
  cfg.memory_height = 272;
  cfg.panel_width   = 480;
  cfg.panel_height  = 272;
  cfg.offset_x      = 0;
  cfg.offset_y      = 0;
  _panel_instance.config(cfg);
  }

  { auto cfg = _panel_instance.config_detail();
  cfg.use_psram = 1;
  _panel_instance.config_detail(cfg);
  }

  { auto cfg = _light_instance.config();
  cfg.pin_bl = GPIO_NUM_2;
  _light_instance.config(cfg);
  }
  _panel_instance.light(&_light_instance);

{ 
      auto cfg = _touch_instance.config();
      cfg.x_min      = 100;    
      cfg.x_max      = 4000;   
      cfg.y_min      = 100;     
      cfg.y_max      = 4000;    
      cfg.pin_int    = -1;    
      cfg.bus_shared = true;  
      cfg.offset_rotation = 0;// 0-7
      cfg.spi_host = 1; // 
      cfg.freq = 1000000;    
      cfg.pin_sclk = 12;     
      cfg.pin_mosi = 11;     
      cfg.pin_miso = 13;     
      cfg.pin_cs   = 38;     
      _touch_instance.config(cfg);
      _panel_instance.setTouch(&_touch_instance);  
    }
  setPanel(&_panel_instance); 
  }
};
static LGFX tft; 
tobozo commented 1 year ago

cfg.freq_write = 9000000; seems strange, did you try other values ? 2MHz should be a reasonable start

also I'm not sure about cfg.bus_shared = true; as it doesn't seem like panel and touch are using the same bus

Emmanuele75 commented 1 year ago

As for cfg.freq_write it works from 8MHz to 12MHz other values cause the display to flicker and not solve the problem. For cfg.bus_shared = true or false nothing changes, touch works fine.

tobozo commented 1 year ago

another detail: the documentation specifies hsync_polarity and vsync_polarity as negative, so maybe those need to be set to 1 in the LGFX config ?

image

Emmanuele75 commented 1 year ago

I just did the test by changing the parametershsync_polarity and vsync_polarity with 1, the result doesn't change. 0 or 1 the display is also drawn badly

tobozo commented 1 year ago

hsync_pulse_width = 1 seems under the minimal value

image

Emmanuele75 commented 1 year ago

I will do the tests with the new parameters and I will send you the photos.

Emmanuele75 commented 1 year ago

a1 Image 1 with the new parameters, without CPU and memory usage. Image 2 is about point to point display draw.

Emmanuele75 commented 1 year ago

I tried the library Arduino_GFX_Library.h and the display seems to work fine, it draws everything and fast...the problem is that the display flickers :(

tobozo commented 1 year ago

comparing image1 with the image in the first post shows that it had some effect, so maybe it's worth poking with the values.

It would be interesting to know if that glitch always happens at the same line (e.g is that 240th or 256th?).

If so then it could be possible to just split the buffer in two separate writes, e.g. write the first chunk, use tft.endWrite() + tft.startWrite() and write the second chunk?

again, this is untested pseudo-code:


void my_disp_flush( lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p ){
  int c = 0;
  uint32_t w = ( area->x2 - area->x1 + 1 );
  uint32_t h = ( area->y2 - area->y1 + 1 );

  uint32_t max_height = 240; // adjust this

  tft.setAddrWindow(area->x1, area->y1, w, h);

  tft.startWrite();

  if( h > max_height ) {
      tft.writePixels((lgfx::rgb565_t*)&color_p->full, w*max_height); // write first chunk
      tft.endWrite();
      tft.startWrite();
      uint16_t* framebufptr = (uint16_t*)&color_p->full;
      uint16_t* scanlineptr = framebufptr + (max_height*w);
      tft.writePixels((lgfx::rgb565_t*)scanlineptr, w*(h%max_height)); // write second chunk
  } else {
     tft.writePixels((lgfx::rgb565_t*)&color_p->full, w*h);  // write full buffer
  }

  tft.endWrite();
  lv_disp_flush_ready(disp);
}
Emmanuele75 commented 1 year ago

I tried the new code, nothing changes, 240/256 same result. As for the images I sent you, the difference between the first and last is that the CPU USAGE is activated in the first.

Emmanuele75 commented 1 year ago

With active cpu usage the display works better!

Emmanuele75 commented 1 year ago

Video

https://user-images.githubusercontent.com/128136690/226758261-7cb16802-394d-480d-aed6-bd8362bc9cc0.mp4

Emmanuele75 commented 1 year ago

draw point to point:

https://user-images.githubusercontent.com/128136690/226759187-9bb0179a-4cc4-4ea8-833f-d511e36ada1b.mp4

lovyan03 commented 1 year ago

@Emmanuele75 @tobozo Sorry, I have an idea of the cause and will now work on a fix in the develop branch. The cause is that you are not calling the write back function properly when writing to PSRAM.

lovyan03 commented 1 year ago

Incidentally, the following settings on the user side would improve performance and solve the problem.

lv_conf.h

#define LV_COLOR_16_SWAP 1
Emmanuele75 commented 1 year ago

I did as you said, but unfortunately nothing changes!

lovyan03 commented 1 year ago

@Emmanuele75 umm, ok... Please try using the develop branch version...

Emmanuele75 commented 1 year ago

ok, i will let you know soon

Emmanuele75 commented 1 year ago

Now everything works fine!!! My final configuration:

Development branch version
 #define LV_COLOR_16_SWAP 1
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p){
  tft.pushImageDMA( area->x1
                  , area->y1
                  , area->x2 - area->x1 + 1
                  , area->y2 - area->y1 + 1
                  , ( lgfx::swap565_t* )&color_p->full );
  lv_disp_flush_ready(disp); 
}

Thank you very much!!!

Emmanuele75 commented 1 year ago

I forgot... This is my display configuration:

#define LGFX_USE_V1
#include <LovyanGFX.hpp>
#include <lgfx/v1/platforms/esp32s3/Panel_RGB.hpp>
#include <lgfx/v1/platforms/esp32s3/Bus_RGB.hpp>

class LGFX : public lgfx::LGFX_Device{
  lgfx::Bus_RGB     _bus_instance;
  lgfx::Panel_RGB   _panel_instance;
  lgfx::Light_PWM   _light_instance;
  lgfx::Touch_XPT2046 _touch_instance;

public:LGFX(void){
  auto cfg    = _bus_instance.config();
  cfg.panel   = &_panel_instance;
  cfg.pin_d0  = GPIO_NUM_8;  // B0
  cfg.pin_d1  = GPIO_NUM_3;  // B1
  cfg.pin_d2  = GPIO_NUM_46; // B2
  cfg.pin_d3  = GPIO_NUM_9;  // B3
  cfg.pin_d4  = GPIO_NUM_1;  // B4
  cfg.pin_d5  = GPIO_NUM_5;  // G0
  cfg.pin_d6  = GPIO_NUM_6;  // G1
  cfg.pin_d7  = GPIO_NUM_7;  // G2
  cfg.pin_d8  = GPIO_NUM_15; // G3
  cfg.pin_d9  = GPIO_NUM_16; // G4
  cfg.pin_d10 = GPIO_NUM_4;  // G5
  cfg.pin_d11 = GPIO_NUM_45; // R0
  cfg.pin_d12 = GPIO_NUM_48; // R1
  cfg.pin_d13 = GPIO_NUM_47; // R2
  cfg.pin_d14 = GPIO_NUM_21; // R3
  cfg.pin_d15 = GPIO_NUM_14; // R4
  cfg.pin_henable       = GPIO_NUM_40;
  cfg.pin_vsync         = GPIO_NUM_41;
  cfg.pin_hsync         = GPIO_NUM_39;
  cfg.pin_pclk          = GPIO_NUM_42;
  cfg.freq_write        = 9000000;   //16000000
  cfg.hsync_polarity    = 0; //0
  cfg.hsync_front_porch = 8; //8
  cfg.hsync_pulse_width = 4; //4
  cfg.hsync_back_porch  = 43; //43
  cfg.vsync_polarity    = 0;  //0
  cfg.vsync_front_porch = 8; //8
  cfg.vsync_pulse_width = 4; //4
  cfg.vsync_back_porch  = 12; //12
  cfg.pclk_idle_high    = 1; //1
  _bus_instance.config(cfg);
  _panel_instance.setBus(&_bus_instance);

  { auto cfg = _panel_instance.config();
  cfg.memory_width  = 480;
  cfg.memory_height = 272;
  cfg.panel_width   = 480;
  cfg.panel_height  = 272;
  cfg.offset_x      = 0;
  cfg.offset_y      = 0;
  _panel_instance.config(cfg);
  }

  { auto cfg = _panel_instance.config_detail();
  cfg.use_psram = 1;
  _panel_instance.config_detail(cfg);
  }

  { auto cfg = _light_instance.config();
  cfg.pin_bl = GPIO_NUM_2;
  _light_instance.config(cfg);
  }
  _panel_instance.light(&_light_instance);

{ 
      auto cfg = _touch_instance.config();
      cfg.x_min      = 100;    
      cfg.x_max      = 4000;   
      cfg.y_min      = 100;     
      cfg.y_max      = 4000;    
      cfg.pin_int    = -1;    
      cfg.bus_shared = true;  
      cfg.offset_rotation = 0;// 0-7
      cfg.spi_host = 1; // 
      cfg.freq = 1000000;    
      cfg.pin_sclk = 12;     
      cfg.pin_mosi = 11;     
      cfg.pin_miso = 13;     
      cfg.pin_cs   = 38;     
      _touch_instance.config(cfg);
      _panel_instance.setTouch(&_touch_instance);  
    }
  setPanel(&_panel_instance); 
  }
};
static LGFX tft; 
ruihe1117 commented 1 year ago

@Emmanuele75 Hi, I am trying to drive the RGB565 screen with ESP32-S3, but I am not familiar with the GFX library and do not know how to use the LVGL example, can you share a copy of your just fixed lvgl example code? I would like to learn an example of how gfx uses lvgl.

my email rui_he1117📧163.com

thank you very much!

Emmanuele75 commented 1 year ago

@ruihe1117

#pragma GCC optimize ("Ofast")
#include <arduino.h>
#include <lvgl.h>
#define LGFX_USE_V1
#include <LovyanGFX.h>
#include "ui.h"

#include "lgfx_4827S043C.h"
//#include "lgfx_4827S043R.h"

/*Change to your screen resolution*/
static const uint32_t screenWidth  = 480;
static const uint32_t screenHeight = 272;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t disp_draw_buf[screenWidth * 10];

void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p){
  tft.pushImageDMA( area->x1
                  , area->y1
                  , area->x2 - area->x1 + 1
                  , area->y2 - area->y1 + 1
                  , ( lgfx::swap565_t* )&color_p->full );
  lv_disp_flush_ready(disp); 
}

/*Read the touchpad*/
void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data){
  int32_t x, y; 
  if (tft.getTouch(&x, &y)) {
      data->state = LV_INDEV_STATE_PR;
      data->point.x = x;
      data->point.y = y;
  }else{
    data->state = LV_INDEV_STATE_REL;
  }
}

void setup(){
  Serial.begin(115200);  
  tft.begin();        
  tft.setRotation(0);
  tft.setBrightness(255);  
  lv_init(); 

  lv_disp_draw_buf_init(&draw_buf, disp_draw_buf, NULL, screenWidth * 10);
  static lv_disp_drv_t disp_drv;

/* Initialize the display */
  lv_disp_drv_init(&disp_drv);
  /* Change the following line to your display resolution */
  disp_drv.hor_res = screenWidth;
  disp_drv.ver_res = screenHeight;
  disp_drv.flush_cb = my_disp_flush;
  disp_drv.draw_buf = &draw_buf;
  lv_disp_drv_register(&disp_drv);

  /* Initialize the (dummy) 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 = my_touchpad_read;
  lv_indev_drv_register(&indev_drv);

  ui_init(); 
}

void loop(){     
  lv_timer_handler();  
  delay(5); 
}
tobozo commented 1 year ago

@ruihe1117 I've edited the email address (changed @ to 📧) in your post to avoid drawing attention from spambots

gamma2 commented 1 year ago

i just bought the esp32-4827S043 board and i am trying to test your code can you share the ui.h and ui.c files?

Thanks

Emmanuele75 commented 1 year ago

download squareline studio and export the sample file to your project folder and you're done.

ruihe1117 commented 1 year ago

@Emmanuele75 @lovyan03

First of all, I really feel your help;

The screen I am using is an 800x480RGB screen. With the help of the above, I can already display it normally and have enabled "dual buffering full pixel refresh" (when not enabled, the display is blocked). "But my screen is only half displayed, everything else is normal, and I tested it on two screens with completely different hardware designs, and the results were only half displayed.".

Have you ever encountered a situation where only half of the display is displayed? Or are there any possible problems? IMG_20230327_164147_edit_408947206059994.jpg

https://user-images.githubusercontent.com/116372394/227892671-fe117345-966c-4e71-8716-1a049b502c1b.mp4

Emmanuele75 commented 1 year ago

@ruihe1117 I'll do some tests with 800x480 displays and then get back to you

Zer0-bit commented 1 year ago

I tested and everything renders fine on the 800x480 LCD variant but effects are very sluggish, feels like it's an issue only with full page rendering though as localised transitions like scrolling and swiping elements seem fine. @lovyan03 maybe you have an idea of why is this happening ?

Emmanuele75 commented 1 year ago

@Zer0-bit I too have experienced a lot of slowness with the 800x480 display, it seems that ESP32 is not up to par.

Zer0-bit commented 1 year ago

@Emmanuele75 it's 100% not the mcu not being able to run smoother, the same LVGL code runs quite smooth and transitions look like transitions if using Arduino GFX.

Emmanuele75 commented 1 year ago

@Zer0-bit could you post the configuration for Arduino_GFX?

Zer0-bit commented 1 year ago

@Emmanuele75 - i mean i can, not sure if it's not against certain rules around here ?

tobozo commented 1 year ago

please share your working configurations, every GFX driver eventually benefits from the others, the more the merrier

Zer0-bit commented 1 year ago

@tobozo sure no problems, i can add my project's working config later but just to mention the arduino gfx guys provide a working config by default for these displays on this link https://github.com/moononournation/Arduino_GFX/wiki/Dev-Device-Declaration Look for the ESP32-4827S043 and ESP32-8048S070 displays in there.

Zer0-bit commented 1 year ago

Okay so here's the behaviour using the standard widgets demo and LovyanGFX:

https://user-images.githubusercontent.com/42692077/229564555-ce2e7dab-11e6-4497-93ba-a0507e783b9d.mp4

LGFX_ESP32S3_RGB_ESP32-8048S043.h

#define LGFX_USE_V1
#include <LovyanGFX.hpp>

#include <lgfx/v1/platforms/esp32s3/Panel_RGB.hpp>
#include <lgfx/v1/platforms/esp32s3/Bus_RGB.hpp>

class LGFX : public lgfx::LGFX_Device{
  lgfx::Bus_RGB     _bus_instance;
  lgfx::Panel_RGB   _panel_instance;
  lgfx::Light_PWM   _light_instance;
  lgfx::Touch_GT911 _touch_instance;

public:LGFX(void){
  auto cfg              = _bus_instance.config();
  cfg.panel             = &_panel_instance;
  cfg.pin_d0            = 8;  // B0
  cfg.pin_d1            = 3;  // B1
  cfg.pin_d2            = 46; // B2
  cfg.pin_d3            = 9;  // B3
  cfg.pin_d4            = 1;  // B4
  cfg.pin_d5            = 5;  // G0
  cfg.pin_d6            = 6;  // G1
  cfg.pin_d7            = 7;  // G2
  cfg.pin_d8            = 15; // G3
  cfg.pin_d9            = 16; // G4
  cfg.pin_d10           = 4;  // G5
  cfg.pin_d11           = 45; // R0
  cfg.pin_d12           = 48; // R1
  cfg.pin_d13           = 47; // R2
  cfg.pin_d14           = 21; // R3
  cfg.pin_d15           = 14; // R4
  cfg.pin_henable       = 40;
  cfg.pin_vsync         = 41;
  cfg.pin_hsync         = 39;
  cfg.pin_pclk          = 42;
  cfg.freq_write        = 14000000;
  cfg.hsync_polarity    = 0;
  cfg.hsync_front_porch = 8;
  cfg.hsync_pulse_width = 4;
  cfg.hsync_back_porch  = 43;
  cfg.vsync_polarity    = 0;
  cfg.vsync_front_porch = 8;
  cfg.vsync_pulse_width = 4;
  cfg.vsync_back_porch  = 12;
  cfg.pclk_idle_high    = 1;
  _bus_instance.config(cfg);
  _panel_instance.setBus(&_bus_instance);

  { auto cfg = _panel_instance.config();
  cfg.memory_width      = 800;
  cfg.memory_height     = 480;
  cfg.panel_width       = 800;
  cfg.panel_height      = 480;
  cfg.offset_x          = 0;
  cfg.offset_y          = 0;
  _panel_instance.config(cfg);
  }

  { auto cfg = _panel_instance.config_detail();
  cfg.use_psram         = 1;
  _panel_instance.config_detail(cfg);
  }

  { auto cfg = _light_instance.config();
  cfg.pin_bl            = 2;
  cfg.freq              = 44100;
  cfg.pwm_channel       = 7;
  _light_instance.config(cfg);
  }
  _panel_instance.light(&_light_instance);

{
  auto cfg = _touch_instance.config();
  cfg.x_min = 25;
  cfg.x_max = 473;
  cfg.y_min = 14;
  cfg.y_max = 264;
  cfg.pin_int = -1;
  cfg.bus_shared = true;
  cfg.offset_rotation = 0;
  // I2C接続
  cfg.i2c_port = 1;
  cfg.pin_sda = 19;
  cfg.pin_scl = 20;
  cfg.pin_rst = 38;
  cfg.freq = 400000;
  cfg.i2c_addr = 0x5D;  // 0x5D , 0x14
  _touch_instance.config(cfg);
  _panel_instance.setTouch(&_touch_instance);
}
  setPanel(&_panel_instance); // 使用するパネルをセットします。
  }
};

lvgl_widgets.ino

#include "lvgl.h"
#include "demos/lv_demos.h"

#include "LGFX_ESP32S3_RGB_ESP32-8048S043.h"

// #pragma GCC optimize ("Ofast")
///////////////////// LCD INIT ////////////////////
static LGFX lcd;                 // LGFXのインスタンスを作成。

static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[ 800 * 10 ];

void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p){
  lcd.pushImageDMA( area->x1
                  , area->y1
                  , area->x2 - area->x1 + 1
                  , area->y2 - area->y1 + 1
                  , ( lgfx::rgb565_t* )&color_p->full );
  lv_disp_flush_ready(disp);
}

void my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) {
    uint16_t touchX, touchY;
    bool touched;
    touched = lcd.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;
    }
}

/////////////// LCD INIT////////////////
void lcd_init(void) {
    lcd.begin();          /* TFT init */
    lcd.setRotation(0); /* Landscape orientation, flipped */
    lcd.setBrightness(128);

    lv_init();
    lv_disp_draw_buf_init( &draw_buf, buf, NULL, 800 * 10 );

    /*Initialize the display*/
    static lv_disp_drv_t disp_drv;
    lv_disp_drv_init( &disp_drv );
    /*Change the following line to your display resolution*/
    disp_drv.hor_res = 800;
    disp_drv.ver_res = 480;
    disp_drv.flush_cb = my_disp_flush;
    disp_drv.draw_buf = &draw_buf;
    lv_disp_drv_register( &disp_drv );

    /*Initialize the (dummy) 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 = my_touchpad_read;
    lv_indev_drv_register( &indev_drv );
}

void setup() {
  Serial.begin( 115200 );
  lcd_init();

  // Init LCD objects
  lv_demo_widgets();
}

void loop() {
    lv_timer_handler(); /* let the GUI do its work */
    delay(5);
}

And here's the same demo but running under Arduino GFX:

https://user-images.githubusercontent.com/42692077/229564718-0601d954-a89c-48c8-84a1-1718779a1376.mp4

#pragma GCC optimize ("Ofast")
#include <lvgl.h>
#include <demos/lv_demos.h>
/*******************************************************************************
 ******************************************************************************/
#include <Wire.h>
#include <Arduino_GFX_Library.h>
#define TFT_BL 2

Arduino_ESP32RGBPanel *rgbpanel = new Arduino_ESP32RGBPanel(
  40 /* DE */, 41 /* VSYNC */, 39 /* HSYNC */, 42 /* PCLK */,
  45 /* R0 */, 48 /* R1 */, 47 /* R2 */, 21 /* R3 */, 14 /* R4 */,
  5 /* G0 */, 6 /* G1 */, 7 /* G2 */, 15 /* G3 */, 16 /* G4 */, 4 /* G5 */,
  8 /* B0 */, 3 /* B1 */, 46 /* B2 */, 9 /* B3 */, 1 /* B4 */,
  0 /* hsync_polarity */, 8 /* hsync_front_porch */, 4 /* hsync_pulse_width */, 43 /* hsync_back_porch */,
  0 /* vsync_polarity */, 8 /* vsync_front_porch */, 4 /* vsync_pulse_width */, 12 /* vsync_back_porch */,
  1 /* pclk_active_neg */, 16000000 /* prefer_speed */,
  0 /* de_idle_high */, 0 /* pclk_idle_high */
);

Arduino_RGB_Display *gfx = new Arduino_RGB_Display(
  800 /* width */, 480 /* height */, rgbpanel
);

#include "touch.h"
/* Change to your screen resolution */
static uint32_t screenWidth;
static uint32_t screenHeight;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t *disp_draw_buf;
static lv_disp_drv_t disp_drv;

/* Display flushing */
void my_disp_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);

#if (LV_COLOR_16_SWAP != 0)
  gfx->draw16bitBeRGBBitmap(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
#else
  gfx->draw16bitRGBBitmap(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
#endif

  lv_disp_flush_ready(disp);
}

void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
  if (touch_has_signal())
  {
    if (touch_touched())
    {
      data->state = LV_INDEV_STATE_PR;

      /*Set the coordinates*/
      data->point.x = touch_last_x;
      data->point.y = touch_last_y;
    }
    else if (touch_released())
    {
      data->state = LV_INDEV_STATE_REL;
    }
  }
  else
  {
    data->state = LV_INDEV_STATE_REL;
  }
}

void setup()
{
  Serial.begin(115200);
  // while (!Serial);
  Serial.println("LVGL Widgets Demo");

  // Init touch device

  // Init Display
  gfx->begin();
#ifdef TFT_BL
  pinMode(TFT_BL, OUTPUT);
  digitalWrite(TFT_BL, HIGH);
#endif
  gfx->fillScreen(RED);
  delay(500);
  gfx->fillScreen(GREEN);
  delay(500);
  gfx->fillScreen(BLUE);
  delay(500);
  gfx->fillScreen(BLACK);
  delay(500);
  lv_init();
  delay(10);
  touch_init();
  screenWidth = gfx->width();
  screenHeight = gfx->height();
#ifdef ESP32
  disp_draw_buf = (lv_color_t *)heap_caps_malloc(sizeof(lv_color_t) * screenWidth * screenHeight/4 , MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
#else
  disp_draw_buf = (lv_color_t *)malloc(sizeof(lv_color_t) * screenWidth * screenHeight/4);
#endif
  if (!disp_draw_buf)
  {
    Serial.println("LVGL disp_draw_buf allocate failed!");
  }
  else
  {
    lv_disp_draw_buf_init(&draw_buf, disp_draw_buf, NULL, screenWidth * screenHeight/4);

    /* Initialize the display */
    lv_disp_drv_init(&disp_drv);
    /* Change the following line to your display resolution */
    disp_drv.hor_res = screenWidth;
    disp_drv.ver_res = screenHeight;
    disp_drv.flush_cb = my_disp_flush;
    disp_drv.draw_buf = &draw_buf;
    lv_disp_drv_register(&disp_drv);

    /* Initialize the (dummy) 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 = my_touchpad_read;
    lv_indev_drv_register(&indev_drv);

    Serial.println("Setup done");
  }
  lv_demo_widgets();
}

void loop()
{
  lv_timer_handler(); /* let the GUI do its work */
  delay(5);
}

@lovyan03 @tobozo above you can see the configs and the result in those videos.

Alternatively i created a platformio ready repo that can be pulled and built. https://github.com/Zer0-bit/lvgl-widgets/tree/master P.S. Might require to copy the demos folder under this path .pio/libdeps/s3-lcd-lgfx-high-dpi/lvgl/ to the .pio/libdeps/s3-lcd-lgfx-high-dpi/lvgl/src

gamma2 commented 1 year ago

God morning, i need help and i apologize if i'm not expert in this thing, but when i try to compile emmanuele75's example i get the following errors and the compilation aborts:


PLATFORM: Espressif 32 (6.1.0) > Espressif ESP32-S3-DevKitC-1-N16R8V (16 MB QD, 8MB PSRAM) HARDWARE: ESP32S3 240MHz, 320KB RAM, 16MB Flash DEBUG: Current (esp-builtin) On-board (esp-builtin) External (cmsis-dap, esp-bridge, esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa) PACKAGES:

My platformio.ini is :

[env:esp32-s3-devkitc-1-n16r8v] platform = espressif32
board = esp32-s3-devkitc-1-n16r8v framework = arduino build_type = debug build_flags = -D CONFIG_ESP32_SPIRAM_SUPPORT=y -D CORE_DEBUG_LEVEL=5 monitor_speed = 115200 monitor_filters = log2file, esp32_exception_decoder, default monitor_raw = yes

ENVIRONMENT

MCU or Board name: ESP32-4827S043) [ESP32s3 + 4.3" RGB display] Panel Driver IC: ILI6485 Bus type: RGB LovyanGFX version: 1.1.5 lvgl version: 8.0.3-dev FrameWork version: ArduinoESP32 v2.0.7 Build Environment : Platformio (framework = Arduino) Operating System: Windows 10

Tanks in advance for the help

github-actions[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

github-actions[bot] commented 1 year ago

This issue has been automatically closed because it has not had recent activity. Thank you for your contributions.