lovyan03 / LovyanGFX

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

So much problem to convert a working code from TFT_eSPI #519

Closed Smanar closed 3 months ago

Smanar commented 3 months ago

Environment

Problem Description

I have a working code that use TFT_eSPI, I m trying to convert it using this lib

Expected Behavior

The same result with both lib

Actual Behavior

notworking

Code to reproduce this issue

The complete code is here https://github.com/Smanar/CYD-Domoticz-Remote/tree/testLovyanGFX

I have so much problem using the fast method with

//#define LGFX_AUTODETECT
//#include <LovyanGFX.hpp>
//#include <LGFX_TFT_eSPI.hpp>
//static TFT_eSPI tft;               // TFT_eSPI is an alias for LGFX.
//static TFT_eSprite sprite(&tft);   // TFT_eSprite is alias for LGFX_Sprite

Just a white display, So I m trying a custom configuration https://github.com/Smanar/CYD-Domoticz-Remote/blob/testLovyanGFX/src/core/screen_driver.cpp#L25

On the capture we can see the code use a rotation mode and just after another one, superposed to the first one, but I see nothing in the code that can do another rotation.

I have so much thing that work differently, for exemple here https://github.com/Smanar/CYD-Domoticz-Remote/blob/testLovyanGFX/src/core/screen_driver.cpp#L336

And for information, the setting I m using are the better one I have found, else I just have blurred screen.

3 days I m on it, I realy don't see what is the problem.

tobozo commented 3 months ago

hi,

hard to say where the problem comes from when it can have at least half a dozen sources.

please provide a more simple example of the issue without involving lvgl since it is outside the scope of this repository

Smanar commented 3 months ago

Have made a 1 file code, with the minimal code, but still using Lvgl https://github.com/Smanar/CYD-Domoticz-Remote/blob/testLovyanGFX/src/main.cpp

It's possible to switch lib in the platformio.ini file.

I can make a new capture wit the new code but it's the same thing. The correct display on 75% of the display and a frozen bad display on the 25%.

tobozo commented 3 months ago

yes there are symptoms, but unless you can prove they're caused by LovyanGFX, it's tempting to say the issue is elsewhere.

best way to prove it is to capture the output of a known example where the same cropping issue can be observed e.g. this one

if you can't reproduce the issue in a basic example sketch, then the problem is probably with the lvgl configuration

Smanar commented 3 months ago

Ok, so new code with your sample > https://github.com/Smanar/CYD-Domoticz-Remote/blob/testLovyanGFX/src/main.cpp BTW you know, it's not possible to compile your sample without including TFT_eSPI, you are missing declarations.

So the result, with TFT_eSPI 1

And with LovyanGFX 2

The color issue is not a problem.

tobozo commented 3 months ago

The color issue is not a problem.

If you say so, however the upper part of the LovyanGFX display seems to be empty/cropped, which means there is an orientation offset problem and you should probably tweak some values in _panel_instance:

My advice: Don't assume LovyanGFX works exactly like TFT_eSPI (especially the configuration), don't mix configurations in your setup e.g. resist to the temptation of factorizing every common configuration value into the platformio.ini file.

Although some of the values in red can be shared between both configurations, they will be much easier to debug if they are moved to separate config files. The values in green can be kept to select one or another config file.

image

example with lgfx.config.h and 'tft_espi.config.h`

#if defined LOVYANGFX 
  #include "lgfx.config.h"
#else if defined TFT_ESPI
  #include "tft_espi.config.h"
#else  
  #error "No display driver selected"
#endif 
Smanar commented 3 months ago

Yes, I need to rewrite the code for "multi support', but Its something new, lot of work to do still, for the moment I m making tests.

If you say so

lol, yep, because this setting I know how to change it, and it work (cfg.invert works fine, I don't change it to keep the code minimal)

If I m right cfg.memory_width and cfg.memory_height are useless on this device no ?

This device is a ESP32_2432S028, used a lot, there is no defauts setting somewhere ? I have tried too LGFX_ESP32_2432S028 without sucess. I m not the first one using this libs on this device ?

BTW, I have better result ATM, I will give you final values later, but a new question, whySerial.printf(">>> %d\n", int(tft.getRotation())); return always 0 ?

Edit: So final value is 4 for landscape mode rotation, and need to reverse cfg.panel_width and cfg.panel_height, and need to keep them not reversed in lvgl.

tobozo commented 3 months ago

If I m right cfg.memory_width and cfg.memory_height are useless on this device no ?

well, they affect stuff like hardware scrolling and DMA transfer, so if they're inverted and should not, it can create adverse effects.

according to this source, these are the values your LGFX panel config should hold for your display model:


class LGFX : public lgfx::LGFX_Device
{
  lgfx::Panel_ILI9341 _panel_instance;
  lgfx::Bus_SPI       _bus_instance;
  lgfx::Light_PWM     _light_instance;
  lgfx::Touch_XPT2046 _touch_instance;
//----------------------------------------------------------------------  
public:LGFX(void){
  {
    auto cfg = _bus_instance.config();
    cfg.spi_host   = SPI2_HOST;
    cfg.spi_mode   = 0;
    cfg.freq_write = 40000000;
    cfg.freq_read  = 16000000; 
    cfg.spi_3wire  = false; 
    cfg.use_lock   = true; 
    cfg.dma_channel=  1; 
    cfg.pin_sclk   = 14;
    cfg.pin_mosi   = 13; 
    cfg.pin_miso   = 12;
    cfg.pin_dc     =  2; 
    _bus_instance.config(cfg); 
    _panel_instance.setBus(&_bus_instance);
  }
  { 
    auto cfg = _panel_instance.config();
    cfg.pin_cs          =    15;
    cfg.pin_rst         =    -1;
    cfg.pin_busy        =    -1;
    cfg.memory_width    =   240;
    cfg.memory_height   =   320;
    cfg.panel_width     =   240;
    cfg.panel_height    =   320;
    cfg.offset_x        =     0;
    cfg.offset_y        =     0;
    cfg.offset_rotation =     0;
    cfg.dummy_read_pixel=     8;
    cfg.dummy_read_bits =     1;
    cfg.readable        =  true;
    cfg.invert          = false;
    cfg.rgb_order       = false;
    cfg.dlen_16bit      = false;
    cfg.bus_shared      = false;
    _panel_instance.config(cfg);
  }
  {
    auto cfg = _light_instance.config();
    cfg.pin_bl = 21; 
    cfg.invert = false;  
    cfg.freq   = 44100;
    cfg.pwm_channel = 7; 
    _light_instance.config(cfg);
    _panel_instance.setLight(&_light_instance);
  }
  { 
    auto cfg = _touch_instance.config();
    cfg.x_min      = 300; 
    cfg.x_max      = 3900; 
    cfg.y_min      = 200;
    cfg.y_max      = 3700; 
    cfg.pin_int    = 36; 
    cfg.bus_shared = false; 
    cfg.offset_rotation = 6; 
    cfg.spi_host = VSPI_HOST;
    cfg.freq = 1000000;
    cfg.pin_sclk = 25; 
    cfg.pin_mosi = 32; 
    cfg.pin_miso = 39;
    cfg.pin_cs   = 33; 
    _touch_instance.config(cfg);
    _panel_instance.setTouch(&_touch_instance);
  }
  setPanel(&_panel_instance);// 使用するパネルをセットします。
  }
};
LGFX tft; // 準備したクラスのインスタンスを作成します。

and from the provided example these are the lvgl functions you should use along with LovyanGFX only:


// !!! LVGL screen width/height may be different from tft config (orientation offset is applied)
static const uint32_t screenWidth  = 320;
static const uint32_t screenHeight = 240;
// keep the buffer declaration separated from TFT_eSPI as they allocate memory differently
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[2][screenWidth * 10]; 

// Display flushing
void my_disp_flush( lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) 
{
  if (tft.getStartCount()==0){  // Run if not already started
    tft.startWrite();
  } 
  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);
}

void init_display() 
{
  static lv_disp_drv_t disp_drv;     // Descriptor of a display driver
  lv_disp_drv_init(&disp_drv);       // Basic initialization
  disp_drv.flush_cb = my_disp_flush; // Set your driver function
  disp_drv.draw_buf = &draw_buf;     // Assign the buffer
  disp_drv.hor_res  = screenWidth;   // horizontal resolution
  disp_drv.ver_res  = screenHeight;  // vertical resolution
  lv_disp_drv_register(&disp_drv);   // Finally register the driver
  lv_disp_set_bg_color(NULL,lv_color_hex(0x0000));// background black
}

anyway, there are enough significant differences with TFT_eSPI's generic implementation to justify the separation of both logics into different files.

Smanar commented 3 months ago

anyway, there are enough significant differences with TFT_eSPI's generic implementation to justify the separation of both logics into different files.

Right, but now need to make the touch part working ^^.

For information the value I m using for a landscape side.

      {
        auto cfg = _panel_instance.config();

        cfg.pin_cs           =    15;
        cfg.pin_rst          =    -1;
        cfg.pin_busy         =    -1;
        cfg.memory_width     =    320;
        cfg.memory_height    =    240;
        cfg.panel_width      =    320;
        cfg.panel_height     =    240;
        cfg.offset_x         =     0;
        cfg.offset_y         =     0;
        cfg.offset_rotation  =     4;
        cfg.dummy_read_pixel =     8;
        cfg.dummy_read_bits  =     1;
        cfg.readable         = true;
        cfg.invert           = true;
        cfg.rgb_order        = true;
        cfg.dlen_16bit       = false;
        cfg.bus_shared       = false;

        _panel_instance.config(cfg);
      }

Thx for help, for the moment it's working. Just a last question about Serial.printf(">>> %d\n", int(tft.getRotation())); that return always 0 ?

tobozo commented 3 months ago

Just a last question about Serial.printf(">>> %d\n", int(tft.getRotation())); that return always 0 ?

kamoulox? :rofl: