[Help] Waveshare ESP32-S3-LCD-3.16, st7701 RGB565 using lovyangfx

Hello Experts,

I was trying to run small examples ESP32-S3-LCD-3.16 module, which has ST7701 (RGB565).
I am trying to use lovyangfx library, till now no success!

I referred to demo and schematics provided in wiki to identify LCD connections.

Attaching sample program, which results in blank screen.

Please help me with finding the problem and how to get the display working?

#define LGFX_USE_V1
#include <LovyanGFX.hpp>
#include <lgfx/v1/platforms/esp32s3/Panel_RGB.hpp>
#include <lgfx/v1/platforms/esp32s3/Bus_RGB.hpp>
#include <lgfx/v1/platforms/esp32/Light_PWM.hpp>
//pin configuration
//i2c
#define I2C_SDA_GPIO  15
#define I2C_SCL_GPIO  7
//i2c device QMI8658
#define QMI_DEV_ADDR  0x6B          //TODO or 0x6A
#define QMI_INT_GPIO  0             //TODO
#define QMI_SDA_GPIO  I2C_SDA_GPIO
#define QMI_SCL_GPIO  I2C_SCL_GPIO

/*
reference: 
    - https://community.home-assistant.io/t/waveshare-esp32-s3-lcd-3-16-sample-config/945239
    - https://files.waveshare.com/wiki/ESP32-S3-LCD-3.16/ESP32-S3-LCD-3.16-Schematic.pdf
    - https://www.haraldkreuzer.net/en/news/getting-started-sunton-esp32-s3-7-inch-display-lovyangfx-and-lvgl
*/

//uart
#define UART_TX_GPIO  43
#define UART_RX_GPIO  44

//lcd configuration
#define LCD_H_RES       320
#define LCD_V_RES       820

#define LCD_IO_SPI_CS      42   //  reference: ESP32-S3-LCD-3.16-Schematic.pdf
#define LCD_IO_SPI_SCK     2    //     CLK 2
#define LCD_IO_SPI_SDO     1    //     MOSI 1

#define LCD_IO_RGB_HSYNC   38
#define LCD_IO_RGB_VSYNC   39
#define LCD_IO_RGB_DE      40
#define LCD_IO_RGB_PCLK    41

//#define LCD_IO_RGB_DISP    37       //?
#define LCD_IO_RGB_RESET   16

#define LCD_IO_RGB_R0      17
#define LCD_IO_RGB_R1      46
#define LCD_IO_RGB_R2      3
#define LCD_IO_RGB_R3      8
#define LCD_IO_RGB_R4      18

#define LCD_IO_RGB_G0      14
#define LCD_IO_RGB_G1      13
#define LCD_IO_RGB_G2      12
#define LCD_IO_RGB_G3      11
#define LCD_IO_RGB_G4      10
#define LCD_IO_RGB_G5      9

#define LCD_IO_RGB_B0      21
#define LCD_IO_RGB_B1      5
#define LCD_IO_RGB_B2      45
#define LCD_IO_RGB_B3      48
#define LCD_IO_RGB_B4      47

#define LCD_BACKLIGHT_GPIO  6

class LGFX : public lgfx::LGFX_Device
{
public:
  lgfx::Bus_RGB _bus_instance;
  lgfx::Light_PWM _light_instance;
  lgfx::Panel_ST7701 _panel_instance;

  // TODO reset pin??
  LGFX(void)
  {
    { // ST7701
      auto cfg = _panel_instance.config();

      cfg.pin_cs = LCD_IO_SPI_CS;
      cfg.pin_rst = LCD_IO_RGB_RESET;

      cfg.memory_width = LCD_H_RES;
      cfg.memory_height = LCD_V_RES;
      cfg.panel_width = LCD_H_RES;
      cfg.panel_height = LCD_V_RES;

      cfg.offset_x = 0;
      cfg.offset_y = 0;

      cfg.rgb_order = true;   //https://github.com/lovyan03/LovyanGFX/blob/6f6e9a052fc719ecb2b42640b0207215050d2560/src/lgfx/v1/panel/Panel_Device.hpp#L100
      cfg.invert = false;

      _panel_instance.config(cfg);
    }

    { // Use PSRAM for frame buffer if available XXX
      auto cfg = _panel_instance.config_detail();

      cfg.pin_cs = LCD_IO_SPI_CS; // XXX contradiction schematic: pin 42, in demo firmware pin 0
      cfg.pin_sclk = LCD_IO_SPI_SCK;
      cfg.pin_mosi = LCD_IO_SPI_SDO;
      cfg.use_psram = 1; // 0=SRAM only / 1=both / 2=PSRAM only

      _panel_instance.config_detail(cfg);
    }

    {
      auto cfg = _bus_instance.config();
      cfg.panel = &_panel_instance;

      // blue
      cfg.pin_d0 = LCD_IO_RGB_B0; // B0
      cfg.pin_d1 = LCD_IO_RGB_B1; // B1
      cfg.pin_d2 = LCD_IO_RGB_B2; // B2
      cfg.pin_d3 = LCD_IO_RGB_B3; // B3
      cfg.pin_d4 = LCD_IO_RGB_B4; // B4

      // green
      cfg.pin_d5 = LCD_IO_RGB_G0;  // G0
      cfg.pin_d6 = LCD_IO_RGB_G1;  // G1
      cfg.pin_d7 = LCD_IO_RGB_G2;  // G2
      cfg.pin_d8 = LCD_IO_RGB_G3;  // G3
      cfg.pin_d9 = LCD_IO_RGB_G4;  // G4
      cfg.pin_d10 = LCD_IO_RGB_G5; // G5

      // red
      cfg.pin_d11 = LCD_IO_RGB_R0; // R0
      cfg.pin_d12 = LCD_IO_RGB_R1; // R1
      cfg.pin_d13 = LCD_IO_RGB_R2; // R2
      cfg.pin_d14 = LCD_IO_RGB_R3; // R3
      cfg.pin_d15 = LCD_IO_RGB_R4; // R4

      cfg.pin_henable = LCD_IO_RGB_DE; // data enable, when high actively read RGB data
      cfg.pin_vsync = LCD_IO_RGB_VSYNC;
      cfg.pin_hsync = LCD_IO_RGB_HSYNC;
      cfg.pin_pclk = LCD_IO_RGB_PCLK;
      cfg.freq_write = 12000000; // 18MHz? kept to 12MHz for stability during CPU load

      // cfg.pclk_active_neg = 1;  //default
      // cfg.de_idle_high = 0;     //default
      // cfg.pclk_idle_high = 0;   //default

      cfg.hsync_polarity = 0;       //from ws demo lvgl_port.c
      cfg.hsync_front_porch = 30;
      cfg.hsync_pulse_width = 6;
      cfg.hsync_back_porch = 30;

      cfg.vsync_polarity = 0;
      cfg.vsync_front_porch = 20;
      cfg.vsync_pulse_width = 40;
      cfg.vsync_back_porch = 20;
      cfg.pclk_idle_high = 1; // from https://community.home-assistant.io/t/waveshare-esp32-s3-lcd-3-16-sample-config/945239

      _bus_instance.config(cfg);
      _panel_instance.setBus(&_bus_instance);
    }

    {
      auto cfg = _light_instance.config();
      cfg.pin_bl = LCD_BACKLIGHT_GPIO;
      cfg.freq = 5 * 1000; // 5kHz
      cfg.pwm_channel = 1;

      _light_instance.config(cfg);
      _panel_instance.light(&_light_instance);
    }
    setPanel(&_panel_instance);
  }
};

static LGFX lcd;

void setup()
{
  Serial.begin(115200);
  Serial.println("Setup started....");
  delay(1000);
  lcd.init();

  lcd.setRotation(1);
  lcd.setBrightness(128);

  lcd.setColorDepth(16);

  lcd.drawPixel(0, 0, 0xFFFF);
  lcd.drawFastVLine(4, 0, 100, lcd.color565(0, 255, 0));

  lcd.setColor(0x0000FFU);
  lcd.drawCircle(40, 80, 20);
  lcd.drawEllipse(80, 40, 10, 20);
  lcd.drawArc(80, 80, 20, 10, 0, 90);
  lcd.drawTriangle(60, 80, 80, 80, 80, 60);
  delay(2000);

  lcd.fillScreen(0xFFFFFFu);
  lcd.setColor(0x00FF00u);
  lcd.fillScreen();

  //lcd.clear(0xFFFFFFu);
  //lcd.setBaseColor(0x000000u);
  //lcd.clear();

  Serial.println("Setup done....");
  delay(2000);
}

void loop()
{
  Serial.println("loop......");
  delay(2000);
}

Blank screen... assuming this is an example from the st7701 library, and the display and ESP32 have factory connectors (no soldering needed, pre-made wiring)..

Verify the steps taken to load and run a sketch. Is the ESP still in "boot mode" and needs the reset button pressed to be in "run" mode?

Does the display show any signs of power/data (black screen changes to very dark gray) after compile/upload is finished?

Do you see "loop..." in the Serial monitor?

Thank you for response.

I think I have something, it looks like CS pin is not 42. When I changed it to 0 same as in waveshare demo code.

I could see some backlight change, but fillColor() does not have any effect.... so all in all not much progress.

And I tried other functionalities like BLE/ wifi/ i2c does work.

#define LGFX_USE_V1
#include <LovyanGFX.hpp>
#include <lgfx/v1/platforms/esp32s3/Panel_RGB.hpp>
#include <lgfx/v1/platforms/esp32s3/Bus_RGB.hpp>
#include <lgfx/v1/platforms/esp32/Light_PWM.hpp>
//pin configuration
//i2c
#define I2C_SDA_GPIO  15
#define I2C_SCL_GPIO  7
//i2c device QMI8658
#define QMI_DEV_ADDR  0x6B          //TODO or 0x6A
#define QMI_INT_GPIO  0             //TODO
#define QMI_SDA_GPIO  I2C_SDA_GPIO
#define QMI_SCL_GPIO  I2C_SCL_GPIO

/*
reference: 
    - https://community.home-assistant.io/t/waveshare-esp32-s3-lcd-3-16-sample-config/945239
    - https://files.waveshare.com/wiki/ESP32-S3-LCD-3.16/ESP32-S3-LCD-3.16-Schematic.pdf
    - https://www.haraldkreuzer.net/en/news/getting-started-sunton-esp32-s3-7-inch-display-lovyangfx-and-lvgl
*/

//uart
#define UART_TX_GPIO  43
#define UART_RX_GPIO  44

//lcd configuration
#define LCD_H_RES       320
#define LCD_V_RES       820

#define LCD_IO_SPI_CS      0   //  reference: ESP32-S3-LCD-3.16-Schematic.pdf
#define LCD_IO_SPI_SCK     2    //     CLK 2
#define LCD_IO_SPI_SDO     1    //     MOSI 1

#define LCD_IO_RGB_HSYNC   38
#define LCD_IO_RGB_VSYNC   39
#define LCD_IO_RGB_DE      40
#define LCD_IO_RGB_PCLK    41

//#define LCD_IO_RGB_DISP    37       //?
#define LCD_IO_RGB_RESET   16

#define LCD_IO_RGB_R0      17
#define LCD_IO_RGB_R1      46
#define LCD_IO_RGB_R2      3
#define LCD_IO_RGB_R3      8
#define LCD_IO_RGB_R4      18

#define LCD_IO_RGB_G0      14
#define LCD_IO_RGB_G1      13
#define LCD_IO_RGB_G2      12
#define LCD_IO_RGB_G3      11
#define LCD_IO_RGB_G4      10
#define LCD_IO_RGB_G5      9

#define LCD_IO_RGB_B0      21
#define LCD_IO_RGB_B1      5
#define LCD_IO_RGB_B2      45
#define LCD_IO_RGB_B3      48
#define LCD_IO_RGB_B4      47

#define LCD_BACKLIGHT_GPIO  6

class LGFX : public lgfx::LGFX_Device
{
public:
  lgfx::Bus_RGB _bus_instance;
  lgfx::Light_PWM _light_instance;
  lgfx::Panel_ST7701 _panel_instance;

  // TODO reset pin??
  LGFX(void)
  {
    { // ST7701
      auto cfg = _panel_instance.config();

      cfg.pin_cs = LCD_IO_SPI_CS;
      cfg.pin_rst = LCD_IO_RGB_RESET;

      cfg.memory_width = LCD_H_RES;
      cfg.memory_height = LCD_V_RES;
      cfg.panel_width = LCD_H_RES;
      cfg.panel_height = LCD_V_RES;

      cfg.offset_x = 0;
      cfg.offset_y = 0;

      cfg.rgb_order = true;   //https://github.com/lovyan03/LovyanGFX/blob/6f6e9a052fc719ecb2b42640b0207215050d2560/src/lgfx/v1/panel/Panel_Device.hpp#L100
      cfg.invert = false;

      _panel_instance.config(cfg);
    }

    { // Use PSRAM for frame buffer if available XXX
      auto cfg = _panel_instance.config_detail();

      cfg.pin_cs = LCD_IO_SPI_CS; // XXX contradiction schematic: pin 42, in demo firmware pin 0
      cfg.pin_sclk = LCD_IO_SPI_SCK;
      cfg.pin_mosi = LCD_IO_SPI_SDO;
      cfg.use_psram = 1; // 0=SRAM only / 1=both / 2=PSRAM only

      _panel_instance.config_detail(cfg);
    }

    {
      auto cfg = _bus_instance.config();
      cfg.panel = &_panel_instance;

      // blue
      cfg.pin_d0 = LCD_IO_RGB_B0; // B0
      cfg.pin_d1 = LCD_IO_RGB_B1; // B1
      cfg.pin_d2 = LCD_IO_RGB_B2; // B2
      cfg.pin_d3 = LCD_IO_RGB_B3; // B3
      cfg.pin_d4 = LCD_IO_RGB_B4; // B4

      // green
      cfg.pin_d5 = LCD_IO_RGB_G0;  // G0
      cfg.pin_d6 = LCD_IO_RGB_G1;  // G1
      cfg.pin_d7 = LCD_IO_RGB_G2;  // G2
      cfg.pin_d8 = LCD_IO_RGB_G3;  // G3
      cfg.pin_d9 = LCD_IO_RGB_G4;  // G4
      cfg.pin_d10 = LCD_IO_RGB_G5; // G5

      // red
      cfg.pin_d11 = LCD_IO_RGB_R0; // R0
      cfg.pin_d12 = LCD_IO_RGB_R1; // R1
      cfg.pin_d13 = LCD_IO_RGB_R2; // R2
      cfg.pin_d14 = LCD_IO_RGB_R3; // R3
      cfg.pin_d15 = LCD_IO_RGB_R4; // R4

      cfg.pin_henable = LCD_IO_RGB_DE; // data enable, when high actively read RGB data
      cfg.pin_vsync = LCD_IO_RGB_VSYNC;
      cfg.pin_hsync = LCD_IO_RGB_HSYNC;
      cfg.pin_pclk = LCD_IO_RGB_PCLK;
      cfg.freq_write = 12000000; // 18MHz? kept to 12MHz for stability during CPU load

      // cfg.pclk_active_neg = 1;  //default
      // cfg.de_idle_high = 0;     //default
      // cfg.pclk_idle_high = 0;   //default

      cfg.hsync_polarity = 0;       //from ws demo lvgl_port.c
      cfg.hsync_front_porch = 30;
      cfg.hsync_pulse_width = 6;
      cfg.hsync_back_porch = 30;

      cfg.vsync_polarity = 0;
      cfg.vsync_front_porch = 20;
      cfg.vsync_pulse_width = 40;
      cfg.vsync_back_porch = 20;
      cfg.pclk_idle_high = 1; // from https://community.home-assistant.io/t/waveshare-esp32-s3-lcd-3-16-sample-config/945239

      _bus_instance.config(cfg);
      _panel_instance.setBus(&_bus_instance);
    }

    {
      auto cfg = _light_instance.config();
      cfg.pin_bl = LCD_BACKLIGHT_GPIO;
      cfg.freq = 5 * 1000; // 5kHz
      cfg.pwm_channel = 1;

      _light_instance.config(cfg);
      _panel_instance.light(&_light_instance);
    }
    setPanel(&_panel_instance);
  }
};

static LGFX lcd;

void setup()
{
  Serial.begin(115200);
  Serial.println("Setup started....");
  
  delay(2000);

  lcd.init();

  lcd.setRotation(0);
  lcd.setBrightness(64);

  lcd.setColorDepth(16);
  lcd.clear(TFT_BLACK);
  delay(2000);

  lcd.setTextColor(TFT_WHITE);
  lcd.setTextSize(4);
  lcd.setCursor(20,20);
  lcd.println("ST7701 + ESP32-S3");

  Serial.println("Setup done....");
  delay(2000);
}

void loop()
{
  Serial.println("loop......");
  delay(2000);
}