lovyan03 / LovyanGFX

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

Sprite engine randomly stopped working. #287

Closed XanCraft21 closed 2 years ago

XanCraft21 commented 2 years ago

hello, i was going to do anyther sprite buffer experiment, when i just realized that the sprite engine just suddenly stopped working, i tried downgrading the library and the esp32 core drivers and it still won’t work. Direct display driving works fine, but the sprites do absolutely nothing. I initialized it normally and i remember it working fine before, and i am also keeping the resolution within the ram limits. I do believe my computer has viruses from hackers that are preventing this code from working as intended, so it’s most likely only on my end. Thank you for any help you can give me.

Latest version of arduino ide and the esp32 core on windows 10, standard esp-wroom-32 chipset, display type full color oled ssd1351 spi interface, latest library version.

tobozo commented 2 years ago

I do believe my computer has viruses from hackers

are you sure those are hackers and not the government ?

lovyan03 commented 2 years ago

If it was caused by a virus or hacker there is nothing I can do. I suggest you throw your computer out the window right now and buy a new one.

XanCraft21 commented 2 years ago

I do plan to backup my files and wipe everything because i can’t just buy a new pc. But can anyone test this issue themselves to see if anyone else has their’s not working? Steps to replicate, 1: setup the sprite as normal with hints from example code 2 in how to use, bit depth 16 bits, 2: fill entire sprite with random colors and print random text, 3: is the display completely blank? Compare without the sprite to make sure the display is working correctly. And tobozo how did you know that’s who hacked me?

EDIT: forgot to add send sprite to display with pushSprite();.

XanCraft21 commented 2 years ago

Is anyone going to try to help me? Just because there’s a hacker doesn’t mean we can’t just add a bypass script. All i ask is that other people test the sprite engine to see if i am or am not the only person with the problem.

tobozo commented 2 years ago

@XanCraft21 please see the bug report template and provide whatever info is necessary to reproduce the issue, otherwise you will not be taken seriously :wink:

XanCraft21 commented 2 years ago

I put that info in a previous comment. I will repost it i guess but more spaced out.

Steps to reproduce: 1: make sure the display is wired correctly and working 2: setup sprite normally 3: test the sprite, fill it with random colors and text 4: send the sprite to the display 5: is the screen blank? If so, the sprite engine is broken.

tobozo commented 2 years ago

thanks for making the steps more readable but this is still incomplete and too vague to reproduce

lovyan03 commented 2 years ago

Why are you ruling out the possibility of bugs in your source code? You should provide source code. A written description is of little value.

XanCraft21 commented 2 years ago

Give me some time to post my code that i made for my test.

XanCraft21 commented 2 years ago

This is just a basic test code, currently setup in arduino for ssd1351 oled by waveshare, which has a faster clock speed than any other display with ssd1351. i can't copy the entire file since github doesn't support arduino ino files, so I hope this here will work.

#define LGFX_USE_V1

#include <LovyanGFX.hpp>

int screenWidth = 128;
int screenHeight = 128;

int textSize = 2;

bool psram = false;

class LGFX : public lgfx::LGFX_Device {
  //lgfx::Panel_GC9A01      _panel_instance;
  //lgfx::Panel_HX8357B     _panel_instance;
  //lgfx::Panel_HX8357D     _panel_instance;
  //lgfx::Panel_ILI9163     _panel_instance;
  //lgfx::Panel_ILI9225     _panel_instance;
  //lgfx::Panel_ILI9341     _panel_instance;
  //lgfx::Panel_ILI9342     _panel_instance;
  //lgfx::Panel_ILI9481     _panel_instance;
  //lgfx::Panel_ILI9486     _panel_instance;
  //lgfx::Panel_ILI9488     _panel_instance;
  //lgfx::Panel_SSD1331     _panel_instance;
  lgfx::Panel_SSD1351     _panel_instance;
  //lgfx::Panel_SSD1963     _panel_instance;
  //lgfx::Panel_ST7735S     _panel_instance;
  //lgfx::Panel_ST7789      _panel_instance;
  //lgfx::Panel_ST7796      _panel_instance;

  lgfx::Bus_SPI       _bus_instance;

  lgfx::Light_PWM     _light_instance;

  public:

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

      cfg.spi_host = VSPI_HOST;
      cfg.spi_mode = 2;
      cfg.freq_write = 25000000;
      cfg.freq_read  = 16000000;
      cfg.spi_3wire  = false;
      cfg.use_lock   = false;
      cfg.dma_channel = SPI_DMA_CH_AUTO;
      cfg.pin_sclk = 18;
      cfg.pin_mosi = 23;
      cfg.pin_miso = 19;
      cfg.pin_dc   = 26;

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

    {
      auto cfg = _panel_instance.config();

      cfg.pin_cs           =    25;
      cfg.pin_rst          =    27;
      cfg.pin_busy         =    -1;

      cfg.panel_width      =   128;
      cfg.panel_height     =   128;
      cfg.memory_width     =   128;
      cfg.memory_height    =   128;
      cfg.offset_x         =     0;
      cfg.offset_y         =     0;
      cfg.offset_rotation  =     0;
      cfg.dummy_read_pixel =     8;
      cfg.dummy_read_bits  =     1;
      cfg.readable         = false;
      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 = 32;
      cfg.invert = false;
      cfg.freq   = 44100;
      cfg.pwm_channel = 7;

      _light_instance.config(cfg);
      _panel_instance.setLight(&_light_instance);
    }

    setPanel(&_panel_instance);
  }
};

LGFX display;
LGFX_Sprite sprite(&display);

void setup() {
  display.setColorDepth(16);
  display.init();
  display.setBrightness(110);

  sprite.setColorDepth(16);
  sprite.setTextSize(textSize);
  sprite.setTextColor(0xffff);
  sprite.setTextWrap(true);
  sprite.setPsram(psram);

  sprite.createSprite(screenWidth, screenHeight);
}

void loop() {
  sprite.fillSprite(0b1111100000000000);
  sprite.pushSprite(0, 0);
  delay(1000);
  sprite.fillSprite(0b0000011111100000);
  sprite.pushSprite(0, 0);
  delay(1000);
  sprite.fillSprite(0b0000000000011111);
  sprite.pushSprite(0, 0);
  delay(1000);
  sprite.fillSprite(0b1111111111100000);
  sprite.pushSprite(0, 0);
  delay(1000);
  sprite.fillSprite(0b0000011111111111);
  sprite.pushSprite(0, 0);
  delay(1000);
  sprite.fillSprite(0b1111100000011111);
  sprite.pushSprite(0, 0);
  delay(1000);
  sprite.fillSprite(0b1111111111111111);
  sprite.pushSprite(0, 0);
  delay(1000);
  sprite.fillSprite(0b0000000000000000);
  sprite.pushSprite(0, 0);
  delay(1000);
}
XanCraft21 commented 2 years ago

Sorry for it rendering all messed up, the code is over 100 lines so I can't help if github glitches badly for oversized comments. i hope it's still readable.

lovyan03 commented 2 years ago

you can use gist.

lovyan03 commented 2 years ago

You can post your code here and share the URL. https://gist.github.com/

XanCraft21 commented 2 years ago

Ok, thanks for the tip. I will try that soon. Is the one here still valid enough to copy and paste into arduino ide and run with esp32 dev module, latest version of arduino, this library, and the esp32 core?

lovyan03 commented 2 years ago

When presenting information, please do not write latest but the exact version number.

lovyan03 commented 2 years ago

Also, please note if you have enabled PSRAM in the board manager. For example, ArduinoESP32 v2.0.4 will kill VSPI if PSRAM is enabled.

XanCraft21 commented 2 years ago

I understand that, and i have psram disabled in both the board setup and the code, i still can’t get it to work. Can someone please test it and help me figure out what might be wrong? Thank you!

lovyan03 commented 2 years ago

私はこういう無駄なやり取りが嫌いなのでIssueテンプレートを使って欲しいと思っています。

XanCraft21 commented 2 years ago

But i already included all the information that is asked for in the template. I used parts from the template and incorporated it into my initial comment when i first made this issue, it’s all right there at the very top. And i posted my code for you to look at a few scrolls down. I don’t understand why this has to be such a big deal, i just need someone to test my code and help me figure out why it’s not working. And when i said latest version, look on the main page of the repo, it’s on the right, releases, 0.4.18 (latest). If you don’t want to help me, just say so. Don’t just ignore people when they have something they need help with, it’s bad sportsmanship. Anyway thank you for what little help you could provide.

lovyan03 commented 2 years ago

あなたが助けを必要としているなら、最低限の情報は正しく提示する必要があります。あなたが使用している Arduino ESP32 のバージョンは何ですか?スプライトを使用せずに動作させた場合に動作するかどうかはあなたが提示したコードで確認できますか?問題を正確に分析するために私がどれだけの時間をあなたに費やさなければならないかわかりませんか?それがわからないのならば、わたしはあなたを助ける事ができません。

XanCraft21 commented 2 years ago

Environment:

MCU or Board name: ESP-WROOM-32 Panel Driver IC: SSD1351 Bus type: SPI LovyanGFX version: v0.4.18 Framework version: Arduino ESP32 v2.0.5 Build Environment: ArduinoIDE Operating System: Windows 10

Problem Description:

Sprite engine stopped working. Tried swapping versions of the library and ESP32 Framework. Tried restarting Arduino. Tried changing board or app settings. Checked if display is wired and working correctly. normal display driving works fine.

Expected Behavior:

Sprite image appears correctly on the display panel.

Actual Behavior:

The display is blank.

Steps to reproduce:

step 1. Gather components, MCU, display panel, breadboard, jumper wires. step 2. Connect VCC to 3.3 volts. step 3. Connect GND to GND. step 4. Connect MOSI to GPIO 23. step 5. Connect CLK to GPIO 18. step 6. Connect CS to any GPIO (25). step 7. Connect D/C to any GPIO (26). step 8. Connect RESET to any GPIO (27). step 9. Open ArduinoIDE and create and compile the code sketch for testing the sprite engine. step 10. Connect MCU to USB and select port to begin upload. step 11. Stare at display for a few minutes to see if anything happens. If nothing happens, a software error has occurred.

Code to reproduce this issue:

Link to GIST: https://gist.github.com/XanCraft21/3c64c0bb37d35460a6035fd3ab29e6cd

Is this enough information now?

lovyan03 commented 2 years ago

ok. thanks. Using M5Stack which I can try right now. I tried changing the configuration part to AUTODETECT and it worked without any problems.

There are a few things I would like you to try. Does drawing work immediately after display.init?

    display.init();

// add this.
    display.fillRect(20,20,20,20,TFT_BLUE);
    delay(1000);

If it is not working, what happens if you make the following changes?

// change spi_mode from 2 to 0.
//      cfg.spi_mode = 2;
      cfg.spi_mode = 0;
lovyan03 commented 2 years ago

I tried your sketch as is with SSD1351, but it did not work with SPI MODE 2. SPI MODE 0 seems to work fine.

https://user-images.githubusercontent.com/42724151/192405740-563c7783-52cd-4e31-b6c8-1a66d4e82171.MOV

XanCraft21 commented 2 years ago

That’s very strange, i have never experienced that before. Usually it works fine on spi mode 2. Could there be a problem with the ESP32 framework?

After further testing the sprite engine works now.

Sorry if i gave you any hassle, thank you for help. Everything works fine now and the issue is solved.

lovyan03 commented 2 years ago

Usually it is SPI MODE 0. I have never seen a display panel that requires SPI MODE 2. I don't think there is anything wrong with the framework, it just happens to work.

XanCraft21 commented 2 years ago

I have at least 1 display that requires spi mode 2 or it doesn’t work. A 1.3 inch lcd with driver ST7789. That driver has a weird quirk, if the CS pin is not toggled before operation, nothing happens on spi mode 0.

the specific ST7789 display i have is a generic adapter board that has absolutely no CS pin. I originally thought the display was defective until i did some digging and tests. This display is found on AliExpress from china.

I have found there are different versions of the same display that have the CS pin, like one i found from a company called Waveshare. I could never understand why the ST7789 driver works like this.

lovyan03 commented 2 years ago

I know that poorly designed garbage that does not have a CS pin requires SPI MODE 3. ( not MODE 2 )

XanCraft21 commented 2 years ago

Hmm i did not take SPI mode 3 into consideration, thanks for the tip.

Also, at least there are better versions of the garbage display, the generic 1.54 inch and larger ST7789 displays have the CS pin, to me those are superior to the bad 1.3 inch versions.

lovyan03 commented 2 years ago

To Sitronix's credit, the ST7789 is not garbage. I say that assembly boards and those who manufacture and sell them that use the ST7789 in SPI mode but omit the CS pin are garbage.

Read the specifications. The timing chart clearly states that data is read on the rising edge. This implies that this is SPI MODE 0 or 3.

image

Briefly, the display driver monitors the CS and SCLK pins for changes. It then starts receiving commands triggered by the CS pin changing from HIGH to LOW, but poorly designed garbage leaves the CS pin connected to GND, so the driver never gets this trigger. In other words, it misses the first bit of the first command.

The way to avoid this is to send an extra 1-bit SCLK after energizing. The reason for using SPI MODE 3 is simply to have the SPI driver perform this 1-bit transmission on your behalf.

image

XanCraft21 commented 2 years ago

I can understand that better now. I missed that part last time i read the datasheet, thank you for pointing that out. I do wish the manufacturers of the adaptor boards would make the board just a little wider to have room expose the CS pin, since the boards are too small.

it could also be possible to sacrifice the backlight control pin for the CS pin, but then the brightness cannot be lowered.