lovyan03 / LovyanGFX

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

Request for RA8875 800x480 support #52

Closed BlynkGO closed 1 year ago

BlynkGO commented 3 years ago

Request for TFT SPI 5.0inch (RA8875) SPI4pin too.

https://www.buydisplay.com/5-inch-tft-lcd-display-capacitive-touchscreen-ra8875-controller-800x480

Thank you very much.

lovyan03 commented 3 years ago

@BlynkGO Thanks for the request. I've looked into it and it looks like it's a very different specs from the traditional panels and seems to be a high performance panel. I'm not sure if I can achieve sufficient support, but I've ordered it anyway.

BlynkGO commented 3 years ago

Thank you.

楽しみにしています!

lovyan03 commented 3 years ago

The shop contacted me and it seems that somehow the package was returned to the shop. I was informed that it will be shipped again. It will still take a while for it to arrive. (´;ω;`)

yashmulgaonkar commented 2 years ago

+1 for this! Any updates for the RA8875? Great Library on nonRA8875 setups!

lovyan03 commented 2 years ago

https://twitter.com/lovyan03/status/1438122734806974464

I started to test the operation of the RA8875 with SPI. The performance is still quite low, but I succeeded in drawing basic shapes for now.

lovyan03 commented 2 years ago

@BlynkGO @yashm Thank you for your patience. I have updated the develop branch and added RA8875 support.

Tests of operation with SPI connections have been completed, but parallel connections have not yet been tested.

DanielFranco227 commented 1 year ago

Hello. I am stucked trying to test operation of RA8875. Do you have any existing src code already tested and setup if possible to share with me? I am developing it with ESP32 . I would appreciate it.

lovyan03 commented 1 year ago

@DanielFranco227 Perhaps this configuration will work. If it does not work, please tell us a little more about your situation.

btw, Parallel connection operation of the RA8875 has not yet been implemented.

#define LGFX_USE_V1

#include <LovyanGFX.hpp>

class LGFX : public lgfx::LGFX_Device
{
  lgfx::Panel_RA8875 _panel_instance;
  lgfx::Bus_SPI _bus_instance;

public:

  LGFX(void)
  {
    {
      auto cfg = _bus_instance.config();

      cfg.spi_host = SPI2_HOST;
      cfg.freq_write = 40000000;
      cfg.freq_read  =  5000000;
      cfg.pin_sclk = 18;
      cfg.pin_mosi = 23;
      cfg.pin_miso = 19;
      cfg.spi_3wire = false;

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

    {
      auto cfg = _panel_instance.config();

      cfg.pin_cs = 14;
      cfg.pin_rst = 33;
      cfg.pin_busy = 27;

      cfg.dummy_read_pixel = 16;
      cfg.dummy_read_bits  = 0;
      cfg.readable = true;

      _panel_instance.config(cfg);
    }

    setPanel(&_panel_instance);
  }
};
DanielFranco227 commented 1 year ago

Update: I tried with the pinout config you provided above and it is working now. Thank you so much for your help

DanielFranco227 commented 1 year ago

Update: Testing GPIO 34 as cfg.pin_busy crashes the program.

Update: I tried with the pinout config you provided above and it is working now. Thank you so much for your help

lovyan03 commented 1 year ago

@DanielFranco227 Thanks for the information. We have updated the develop branch as we found that the pin mode setting for the busy pins was not implemented during initialization.

DanielFranco227 commented 1 year ago

Hello. I've been using lgvl v8 but during transition of page, animations are really slow. Do you know any tips to improve performance? or do you have any example that is working with no issues? Thanks in advance

lovyan03 commented 1 year ago

@DanielFranco227 Page transitions mean that you are rewriting the entire screen. If SPI 40MHz is set up, the limit is about 6.5FPS. The amount of communication goes like this.

amount of pixel data : 800 x 480 x 16bpp = 6,144,000 bit 
SPI speed : 40,000,000 Hz

Time required for transmission : 6,144,000 / 40,000,000 = 0.1536 = 153.6 msec
Frame rate : 40,000,000 / 6,144,000 = 6.51 FPS

Please quantify how slow is "really slow."

DanielFranco227 commented 1 year ago

Video of the screen running with a test program: https://youtube.com/shorts/4HiK7YT8tL4

Video of the test program in squareline simulator: https://youtu.be/tGtuNzJfM3I

You can see the spinner running when it is idle but when you change page or select an object, it takes more than 1 sec to show next screen values

lovyan03 commented 1 year ago

Frankly, this topic is not about LovyanGFX. I don't want to go into details here because you are asking me to show you how to use LVGL.

I think that's about the speed you get when you run LVGL on a microcontroller without setting it up properly.

At the very least, it will never run at the same speed as a PC simulator. Such speeds are not possible, so do not expect too much.

Check out this series of tweets and give it a try.

https://twitter.com/lovyan03/status/1504298966577725441 https://twitter.com/lovyan03/status/1504298970574893058 https://twitter.com/lovyan03/status/1504298974874042368 https://twitter.com/lovyan03/status/1504298978950938626 https://twitter.com/lovyan03/status/1504324849174720513

BlynkGO commented 1 year ago

Hi, great news for RA8875 supported.

By the way, what is the pin_busy?

image

The pin_busy is the WAIT pin (pin 9) of the TFT?

image

Thank you.

lovyan03 commented 1 year ago

@BlynkGO yes. It's busy state pin.

BlynkGO commented 1 year ago

@BlynkGO yes. It's busy state pin.

Thank you very much.

DanielFranco227 commented 1 year ago

Frankly, this topic is not about LovyanGFX. I don't want to go into details here because you are asking me to show you how to use LVGL.

I think that's about the speed you get when you run LVGL on a microcontroller without setting it up properly.

At the very least, it will never run at the same speed as a PC simulator. Such speeds are not possible, so do not expect too much.

Check out this series of tweets and give it a try.

https://twitter.com/lovyan03/status/1504298966577725441 https://twitter.com/lovyan03/status/1504298970574893058 https://twitter.com/lovyan03/status/1504298974874042368 https://twitter.com/lovyan03/status/1504298978950938626 https://twitter.com/lovyan03/status/1504324849174720513

Thank you very much for your time and recommendations.

I tried to compare 2 different tft drivers with the same program without using lvgl. I used one of your test programs and I noticed a huge difference in the fps. Panel_RA8875: 6 FPS Panel_ILI9488: 30 FPS

Is the same behavior on your side too? I would appreciate any help you can provide me.

The code is the following:


LGFX display;

unsigned long IRAM_ATTR millis_custom()
{
  return (unsigned long)(esp_timer_get_time() / 1000ULL);
}
#include <vector>
#define LINE_COUNT 6

// LGFX lcd;
#define lcd display
static std::vector<int> points[LINE_COUNT];
static int colors[] = { TFT_RED, TFT_GREEN, TFT_BLUE, TFT_CYAN, TFT_MAGENTA, TFT_YELLOW };
static int xoffset, yoffset, point_count;
int getBaseColor(int x, int y)
{
  return ((x^y)&3 || ((x-xoffset)&31 && y&31) ? TFT_BLACK : ((!y || x == xoffset) ? TFT_WHITE : TFT_DARKGREEN));
}

void app_main()
{
  display.init();

  if (lcd.width() < lcd.height()) lcd.setRotation(lcd.getRotation() ^ 1);

  yoffset = lcd.height() >> 1;
  xoffset = lcd.width()  >> 1;
  point_count = lcd.width() + 1;

  for (int i = 0; i < LINE_COUNT; i++)
  {
    points[i].resize(point_count);
  }

  lcd.startWrite();
  lcd.setAddrWindow(0, 0, lcd.width(), lcd.height());
  for (int y = 0; y < lcd.height(); y++)
  {
    for (int x = 0; x < lcd.width(); x++)
    {
      lcd.writeColor(getBaseColor(x, y - yoffset), 1);
    }
  }
  lcd.endWrite();
  xTaskCreatePinnedToCore(guiTask, "gui", 4096 * 2, NULL, 0, NULL, 1);
  vTaskDelete(NULL);
}

static void guiTask(void *pvParameter)
{
  for (;;)
  {
  static int prev_sec;
  static int fps;
  ++fps;
  int sec = millis_custom() / 1000;
  if (prev_sec != sec)
  {
    prev_sec = sec;
    lcd.setCursor(0,0);
    lcd.printf("fps:%03d", fps);
    fps = 0;
  }

  static int count;

  for (int i = 0; i < LINE_COUNT; i++)
  {
    points[i][count % point_count] = (sinf((float)count / (10 + 30 * i))+sinf((float)count / (13 + 37 * i))) * (lcd.height() >> 2);
  }

  ++count;

  lcd.startWrite();
  int index1 = count % point_count;
  for (int x = 0; x < point_count-1; x++)
  {
    int index0 = index1;
    index1 = (index0 +1) % point_count;
    for (int i = 0; i < LINE_COUNT; i++)
    {
      int y = points[i][index0];
      if (y != points[i][index1])
      {
        lcd.writePixel(x, y + yoffset, getBaseColor(x, y));
      }
    }

    for (int i = 0; i < LINE_COUNT; i++)
    {
      int y = points[i][index1];
      lcd.writePixel(x, y + yoffset, colors[i]);
    }
  }
  lcd.endWrite();
  }
}
DanielFranco227 commented 1 year ago

Frankly, this topic is not about LovyanGFX. I don't want to go into details here because you are asking me to show you how to use LVGL. I think that's about the speed you get when you run LVGL on a microcontroller without setting it up properly. At the very least, it will never run at the same speed as a PC simulator. Such speeds are not possible, so do not expect too much. Check out this series of tweets and give it a try. https://twitter.com/lovyan03/status/1504298966577725441 https://twitter.com/lovyan03/status/1504298970574893058 https://twitter.com/lovyan03/status/1504298974874042368 https://twitter.com/lovyan03/status/1504298978950938626 https://twitter.com/lovyan03/status/1504324849174720513

Thank you very much for your time and recommendations.

I tried to compare 2 different tft drivers with the same program without using lvgl. I used one of your test programs and I noticed a huge difference in the fps. Panel_RA8875: 6 FPS Panel_ILI9488: 30 FPS

Is the same behavior on your side too? I would appreciate any help you can provide me.

The code is the following:


LGFX display;

unsigned long IRAM_ATTR millis_custom()
{
  return (unsigned long)(esp_timer_get_time() / 1000ULL);
}
#include <vector>
#define LINE_COUNT 6

// LGFX lcd;
#define lcd display
static std::vector<int> points[LINE_COUNT];
static int colors[] = { TFT_RED, TFT_GREEN, TFT_BLUE, TFT_CYAN, TFT_MAGENTA, TFT_YELLOW };
static int xoffset, yoffset, point_count;
int getBaseColor(int x, int y)
{
  return ((x^y)&3 || ((x-xoffset)&31 && y&31) ? TFT_BLACK : ((!y || x == xoffset) ? TFT_WHITE : TFT_DARKGREEN));
}

void app_main()
{
  display.init();

  if (lcd.width() < lcd.height()) lcd.setRotation(lcd.getRotation() ^ 1);

  yoffset = lcd.height() >> 1;
  xoffset = lcd.width()  >> 1;
  point_count = lcd.width() + 1;

  for (int i = 0; i < LINE_COUNT; i++)
  {
    points[i].resize(point_count);
  }

  lcd.startWrite();
  lcd.setAddrWindow(0, 0, lcd.width(), lcd.height());
  for (int y = 0; y < lcd.height(); y++)
  {
    for (int x = 0; x < lcd.width(); x++)
    {
      lcd.writeColor(getBaseColor(x, y - yoffset), 1);
    }
  }
  lcd.endWrite();
  xTaskCreatePinnedToCore(guiTask, "gui", 4096 * 2, NULL, 0, NULL, 1);
  vTaskDelete(NULL);
}

static void guiTask(void *pvParameter)
{
  for (;;)
  {
  static int prev_sec;
  static int fps;
  ++fps;
  int sec = millis_custom() / 1000;
  if (prev_sec != sec)
  {
    prev_sec = sec;
    lcd.setCursor(0,0);
    lcd.printf("fps:%03d", fps);
    fps = 0;
  }

  static int count;

  for (int i = 0; i < LINE_COUNT; i++)
  {
    points[i][count % point_count] = (sinf((float)count / (10 + 30 * i))+sinf((float)count / (13 + 37 * i))) * (lcd.height() >> 2);
  }

  ++count;

  lcd.startWrite();
  int index1 = count % point_count;
  for (int x = 0; x < point_count-1; x++)
  {
    int index0 = index1;
    index1 = (index0 +1) % point_count;
    for (int i = 0; i < LINE_COUNT; i++)
    {
      int y = points[i][index0];
      if (y != points[i][index1])
      {
        lcd.writePixel(x, y + yoffset, getBaseColor(x, y));
      }
    }

    for (int i = 0; i < LINE_COUNT; i++)
    {
      int y = points[i][index1];
      lcd.writePixel(x, y + yoffset, colors[i]);
    }
  }
  lcd.endWrite();
  }
}

Sorry, I respond to myself: It is normal due to the size of the screen and number of pixels. It is exactly the fps expected. Besides any other advice you can give me, if you have the same fps number, it is ok for me.

Thank you in advance

lovyan03 commented 1 year ago

@DanielFranco227 Yes, as I previously answered to you.

If SPI 40MHz is set up, the limit is about 6.5FPS.

Any higher speed is theoretically impossible. Alternatively, if you call setColorDepth(8) and operated in RGB332 mode, you should be able to cut the communication time in half and reducing the number of colors.

Since stable operation at SPI 80MHz will be difficult, the only remaining method is a parallel connection. However, the LovyanGFX RA8875 parallel connection has not yet been tested. I would like to eventually support parallel connection operation, but it will be a while before we can do that because the tasks are piling up.

BlynkGO commented 1 year ago

@lovyan03 Hi, my tft now can display and can touch already. The next issue when I wire TFT's backlight pin to ESP32's GPIO32 with the following backlight config.

class LGFX: public lgfx::LGFX_Device {
  private:
    lgfx::Panel_RA8875  _panel_instance;
     .....
    lgfx::Light_PWM     _light_instance;
  public:
    LGFX(void){
      { 
         ....
      }
      { // バックライト制御の設定を行います。(必要なければ削除)
        auto cfg = _light_instance.config();    // バックライト設定用の構造体を取得します。

        cfg.pin_bl      = 32;                // バックライトが接続されているピン番号
        cfg.invert      = false;             // バックライトの輝度を反転させる場合 true
        cfg.freq        = 44100;           // バックライトのPWM周波数
        cfg.pwm_channel = 15;        // 使用するPWMのチャンネル番号

        _light_instance.config(cfg);
        _panel_instance.setLight(&_light_instance);  // バックライトをパネルにセットします。
      }
      setPanel(&_panel_instance);
   }
}

The result occurs the following. image

How to solve the issue for backlight-PWM. Thank you.

lovyan03 commented 1 year ago

@BlynkGO Is your ESP32 the first generation ESP32 and not the ESP32S2 or S3? I tried the following code with the first generation ESP32 and the backlight flickers without any problem.

#define LGFX_USE_V1
#include <LovyanGFX.hpp>
lgfx::Light_PWM _pwm;
void setup()
{
  auto cfg = _pwm.config();
  cfg.pin_bl = 32;
  cfg.invert = false;
  cfg.pwm_channel = 15;
  cfg.freq = 44100;
  _pwm.config(cfg);
  _pwm.init(128);

  for (int i = 0; i < 65535; ++i)
  {
    _pwm.setBrightness(i & 255);
    delay(1);
  }
}
BlynkGO commented 1 year ago

@lovyan03 Thank you , backlight PWM has already done.

By the way, TFT 5 inch RA8875 800x480 with capacitive GSL1680F touch interface.

I tried by the following code, but it's not worked.

[Wiring ] TFT's pin 34 ( CTP I2C SDA ) <----> ESP32 GPIO 21 (I2C SDA) TFT's pin 35 ( CTP I2C SCL ) <----> ESP32 GPIO 22 (I2C SCL)

[Code]

class LGFX : public lgfx::LGFX_Device {
  private:
    ....
    lgfx::Touch_GSL1680F_800x480 _touch_instance;
    ....

  public:
    LGFX(void)
    {
      lgfx::Panel_RA8875  _panel_instance;
      .....
      .....

      { // タッチスクリーン制御の設定を行います。(必要なければ削除)
        auto cfg = _touch_instance.config();

        cfg.x_min      = 0;
        cfg.x_max      = 799;
        cfg.y_min      = 0;
        cfg.y_max      = 479;
        cfg.pin_int    = -1;        // INTが接続されているピン番号
        cfg.bus_shared = true; // 画面と共通のバスを使用している場合 trueを設定
        cfg.offset_rotation = 0;// 表示とタッチの向きのが一致しない場合の調整 0~7の値で設定

        cfg.i2c_port = 0;           // 使用するI2Cを選択 (0 or 1)
        cfg.i2c_addr = 0x40;        // I2Cデバイスアドレス番号
        cfg.pin_sda  = 21;          // SDAが接続されているピン番号
        cfg.pin_scl  = 22;          // SCLが接続されているピン番号
        cfg.freq     = 400000;      // I2Cクロックを設定

        _touch_instance.config(cfg);
        _panel_instance.setTouch(&_touch_instance);  // タッチスクリーンをパネルにセットします。
      }

      setPanel(&_panel_instance);
    }
};

How to config GSL1680F touch interface for https://www.buydisplay.com/5-inch-tft-lcd-display-capacitive-touchscreen-ra8875-controller-800x480 ?

lovyan03 commented 1 year ago

@BlynkGO image

If # 32 remains LOW, TP is not activated. Try connecting it to the same pin as the RST on the LCD.

BlynkGO commented 1 year ago

@lovyan03

Thank you very much.

dmartauz commented 1 year ago

@DanielFranco227 Yes, as I previously answered to you.

If SPI 40MHz is set up, the limit is about 6.5FPS.

Any higher speed is theoretically impossible. Alternatively, if you call setColorDepth(8) and operated in RGB332 mode, you should be able to cut the communication time in half and reducing the number of colors.

Since stable operation at SPI 80MHz will be difficult, the only remaining method is a parallel connection. However, the LovyanGFX RA8875 parallel connection has not yet been tested. I would like to eventually support parallel connection operation, but it will be a while before we can do that because the tasks are piling up.

@lovyan03 any news on RA8875 parallel connection support?

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.