Bodmer / TFT_eSPI

Arduino and PlatformIO IDE compatible TFT library optimised for the Raspberry Pi Pico (RP2040), STM32, ESP8266 and ESP32 that supports different driver chips
Other
3.79k stars 1.09k forks source link

Black screen when using DMA on ESP32, v2.3.41-current (2.3.51) #850

Closed stevesch closed 3 years ago

stevesch commented 3 years ago

DMA behavior for ESP32 seems to have changed on v2.3.41 and later. I had a few screens (ST7735_GREENTAB2, ST7735_DRIVER, ILI9341_DRIVER) running properly w/DMA on 2.3.4 and prior. 2.3.41+ now shows black screen-- code still runs, but nothing displays (DMA is being used for simple full-screen or near full-screen backbuffer transfer).

Side note on this: I previously had issues running the same code on a ESP32 TTGO T-Display (ST7789_DRIVER) with DMA-- it would crash. With 2.3.41+ it no longer crashes but also shows black/empty display, so possible improvement (not crashing-- still not displaying anything though).

Running under PlatformIO.

Bodmer commented 3 years ago

I'm guessing your sketch does not bracket the DMA transfer with startWrite() and endWrite() to hold TFT_CS low as in the examples. The ESP32 can automatically hold the TFT_CS line low and I removed this feature.

I have reinstated automatic TFT_CS control for the ESP32 in the latest 2.4.52 so that should fix it for your sketch. Note however your sketch will not work on an STM32 without adding the startWrite() and endWrite() but that is probably not an issue for you.

Only one line changed here, so you could edit this yourself and avoid downloading the new version.

stevesch commented 3 years ago

Great! I hadn't noticed the startWrite/endWrite in the example I referenced (SpriteRotating-- just calls startWrite before the infinite loop). The DMA code is now working on my various boards using v2.3.51. ST7735, 128x160 -- OK (81fps w/27MHz SPI) ILI9341, 240x320 (213x284 due to mem constraints) -- OK (42fps w/40MHz SPI)

Curiously, my TTGO T-Display boards still show all black-- tried various frequencies, etc. There might be some other interaction going on in my code though. It happily runs at 76fps w/40MHz SPI (38fps w/20MHz SPI), but nothing displays. Non-DMA works fine (I'm basically just calling dmaWait() and pushImageDMA() and alternating between two backbuffers in the case of DMA vs just calling pushSprite() when not using DMA).

Great lib btw.

Bodmer commented 3 years ago

Just realised the line change to remove DMA control of the TFT CS line was to make TFT reads work. It is not clear to me why this fixes the read problem...

To resolve in the short term I will add control flag to the initDMA function. This means that at the next update you will need to modify your sketch to use initDMA(true) to enable control ot the TFT_CS by the DMA engine.

Bodmer commented 3 years ago

Option added at 2.3.53, so you will need to modify your sketch to use initDMA(true) to enable control ot the TFT_CS by the DMA engine. By default TFT_CS is not controlled by the ESP32 DMA engine, sketches are then compatible with the STM32 processor implementation.