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.81k stars 1.1k forks source link

spiEndTransaction crashes #3436

Open Bobobel opened 3 months ago

Bobobel commented 3 months ago
  1. A description of the problem and the conditions that cause it to occur: First Spite drawing OK. Button touch OK, touch OK, touch:crash after second or third or.. Backtrace:

    0 0x40083749 in panic_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/panic.c:408

    1 0x40088695 in esp_system_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/esp_system.c:137

    2 0x4008d659 in __assert_func at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/newlib/assert.c:85

    3 0x40088eda in xQueueGenericSend at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/queue.c:821 (discriminator 2)

    4 0x400ef06d in spiEndTransaction at C:/Users/Juergen/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-spi.c:1153

    5 0x400ee78e in SPIClass::endTransaction() at C:/Users/Juergen/.platformio/packages/framework-arduinoespressif32/libraries/SPI/src/SPI.cpp:194

    6 0x400d67de in TFT_eSPI::end_tft_write() at .pio/libdeps/esp32dev/TFT_eSPI/TFT_eSPI.cpp:109

    (inlined by) TFT_eSPI::pushImage(int, int, int, int, unsigned char, bool, unsigned short) at .pio/libdeps/esp32dev/TFT_eSPI/TFT_eSPI.cpp:1881

    7 0x400d7afa in TFT_eSprite::pushSprite(int, int) at .pio/libdeps/esp32dev/TFT_eSPI/Extensions/Sprite.cpp:674

No problem, if I do not use pushSprite and gettouch outside of freertos tasks, but crashes with two individual tasks (same core ESP32)

  1. IDE VsCode, PlatformIO with Arduino
  2. latest "2.5.43" TFT_eSPI library version
  3. Board package version platform = espressif32@6.8.1 board = esp32dev
  4. Procesor, ESP32 devkit something(china)
  5. TFT driver (e.g. ILI9341)
  6. Interface type SPI

Plus further information as appropriate to the problem:

  1. TFT to processor connections used -D ILI9163_DRIVER=1 ; Select ILI9163 driver -D TFT_WIDTH=320 ; Set TFT size -D TFT_HEIGHT=240 -D TFT_MISO=19 ; Define SPI pins -D TFT_MOSI=23 -D TFT_SCLK=18 -D TFT_CS=5 -D TFT_DC=22 ; Data/Comand pin -D TFT_RST=4 -D LOAD_GLCD=1 ; Load Fonts -D LOAD_FONT2=1 -D LOAD_FONT4=1 -D LOAD_FONT6=1 -D LOAD_FONT7=1 -D OAD_GFXFF=1 -D USE_VSPI_PORT=1 -D SPI_FREQUENCY=20000000 ; Set SPI frequency -D SPI_READ_FREQUENCY=10000000 ; Optional reduced SPI frequency for reading TFT -D SPI_TOUCH_FREQUENCY=2000000
  2. A zip file containing your setup file: see above
  3. A zip file containing a simple and complete example sketch 👍 My dear, if this is necessary, I will do that, but its a lot of crazy stuff! I have two task at core0; one reads touch and buttons (50 ms wait in between at least) The other does a hole bunch of drawings within a sprite buffer besides of the buttons. It runs very vell thanks to your great lib if I use it on it self. But crashes together with the other task. I reduced SPI freq from 40/20/2.5M down to 20M/10M/2M with no better.

The idea is : hopefully sufficiently info (:->

I have used TFT_eSPI several times with Arduino IDE for little games, so thank you very much for your work! For PlatformIO I had the same problem as issue #1507. Please give a hint in your docs for PlatformIO users not to include "Extensions/Touch.h". Do you see a chance to open the lib for ESP-IDF? I would very much prefer yours rather than lvgl (I used it, but nothing similiar to sprites). I had a try, but too many severe errors.

Thanks you very much 👍

Bobobel commented 3 months ago

PS: Stacksize is 10000 for drawing, 6000 for touch/buttons. Seems to be sufficient. Priority of tasks: tskIDLE_PRIORITY+1 for drawing, tskIDLE_PRIORITY for touch. Nothing else with SPI as far as I do understand. Core1 uses ADC with DMA.

Bobobel commented 3 months ago

Added an error log for a stripped down version. Sprites do work, buttons do appear, but after 1 to 5 button clicks it crashes n TFT_eSPI::end_tft_write() at .pio/libdeps/esp32dev/TFT_eSPI/TFT_eSPI.cpp:109. Source, errorlog.txt and platformio.ini attached as ZIP. I increased Stack and used another board (az-delivery-devkit-v4) which should be similiar to mine without any change. Maybe my inquiry will help you to improve and fortif Sprite_Touch_Test.zip y TFT_eSPI reagarding freertos task problems (which kind of?).

Bobobel commented 3 months ago

Today I merged the button task part into the sprite task, now that simplified source in above ZIP run smoothly and fast (at least 10 cyles per second with the delays implemented). I think, it is only a little problem in redrawing the buttons in TFT_eSPI. I noticed, that the inner part (rectengular, none rounded!) of the last pressed btton before crashing stays yellow for some moments. Maybe that is of help?

hitecSmartHome commented 3 months ago

I have also experienced endtransaction crash when rendering a jpeg

hitecSmartHome commented 3 months ago

Here is my crash log

Decoding stack results
0x400837f6: panic_abort at C:\Users\Pc\.platformio\packages\framework-espidf@3.40407.0\components\esp_system\panic.c line 408
0x401d0375: esp_system_abort at C:\Users\Pc\.platformio\packages\framework-espidf@3.40407.0\components\esp_system\esp_system.c line 137
0x4008fc22: __assert_func at C:\Users\Pc\.platformio\packages\framework-espidf@3.40407.0\components\newlib\assert.c line 47
0x4008ae05: xQueueGenericSend at C:\Users\Pc\.platformio\packages\framework-espidf@3.40407.0\components\freertos\queue.c line 820
0x401bf679: spiEndTransaction at C:/Users/Pc/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-spi.c line 1153
0x401ad437: SPIClass::endTransaction() at C:/Users/Pc/.platformio/packages/framework-arduinoespressif32/libraries/SPI/src/SPI.cpp line 194
0x401b34f9: TFT_eSPI::pushImage(int, int, int, int, unsigned short*) at lib/TFT_eSPI/TFT_eSPI.cpp line 109
0x4016bf29: HsH_Display::jpegRender(int, int) at src/NewDisplay/Utils.cpp line 50
0x4016bfdd: HsH_Display::drawJpeg(char const*, int, int) at src/NewDisplay/Utils.cpp line 96
0x4016c013: HsH_Display::drawETHIcon() at src/NewDisplay/Utils.cpp line 106
0x40168082: HsH_Display::drawNetworkIcon() at src/NewDisplay/NewDisplay.cpp line 69
0x401680d8: HsH_Display::showInfo() at src/NewDisplay/NewDisplay.cpp line 39
0x4019fea5: std::_Function_handler   >::_M_invoke(const std::_Any_data &) at src/main.cpp line 60
0x400d4b06: std::function ::operator()() const at c:\users\pc\.platformio\packages\toolchain-xtensa-esp32@8.4.0+2021r2-patch5\xtensa-esp32-elf\include\c++\8.4.0\bits/std_function.h line 260
0x40165049: HsH_Network::invokeOnConnect() at src/Network/Network.cpp line 61
0x4016408f: std::_Function_handler   >::_M_invoke(const std::_Any_data &, arduino_event_id_t &&, arduino_event_info_t &&) at src/Network/Ethernet.cpp line 17
0x401a8249: WiFiGenericClass::_eventCallback(arduino_event_t*) at c:\users\pc\.platformio\packages\toolchain-xtensa-esp32@8.4.0+2021r2-patch5\xtensa-esp32-elf\include\c++\8.4.0\bits/std_function.h line 682
0x401a827d: _arduino_event_task(void*) at C:/Users/Pc/.platformio/packages/framework-arduinoespressif32/libraries/WiFi/src/WiFiGeneric.cpp line 306

And here is my latest function which calls pushImage() It worked fine before. It renders a jpeg file from LittleFS.

void HsH_Display::jpegRender(int xpos, int ypos) {
    uint16_t *pImg;
    uint16_t mcu_w = JpegDec.MCUWidth;
    uint16_t mcu_h = JpegDec.MCUHeight;
    uint32_t max_x = JpegDec.width;
    uint32_t max_y = JpegDec.height;

    if (mcu_w == 0 || mcu_h == 0 || max_x == 0 || max_y == 0) {
        return;
    }

    bool swapBytes = tft.getSwapBytes();
    tft.setSwapBytes(true);
    uint32_t min_w = jpg_min(mcu_w, max_x % mcu_w);
    uint32_t min_h = jpg_min(mcu_h, max_y % mcu_h);

    uint32_t win_w = mcu_w;
    uint32_t win_h = mcu_h;

    max_x += xpos;
    max_y += ypos;

    while (JpegDec.read()) {
        pImg = JpegDec.pImage;
        int mcu_x = JpegDec.MCUx * mcu_w + xpos;
        int mcu_y = JpegDec.MCUy * mcu_h + ypos;
        if (mcu_x + mcu_w <= max_x)
            win_w = mcu_w;
        else
            win_w = min_w;
        if (mcu_y + mcu_h <= max_y)
            win_h = mcu_h;
        else
            win_h = min_h;
        if (win_w != mcu_w) {
            uint16_t *cImg;
            int p = 0;
            cImg = pImg + win_w;
            for (int h = 1; h < win_h; h++) {
                p += mcu_w;
                for (int w = 0; w < win_w; w++) {
                    *cImg = *(pImg + w + p);
                    cImg++;
                }
            }
        }
        if ((mcu_x + win_w) <= tft.width() && (mcu_y + win_h) <= tft.height())
            tft.pushImage(mcu_x, mcu_y, win_w, win_h, pImg);
        else if ((mcu_y + win_h) >= tft.height())
            JpegDec.abort();
    }
    tft.setSwapBytes(swapBytes);
}

I'm using the JPEGDecoder library which can be found here: https://github.com/Bodmer/JPEGDecoder