Git Product home page Git Product logo

lovyangfx's People

Contributors

36kyo avatar 610t avatar belm0 avatar benlye avatar ciniml avatar dimision avatar dominicdumont avatar estshorter avatar figueiredostable avatar fvanroie avatar hollyhockberry avatar imliubo avatar jp-bennett avatar lefty01 avatar lovyan03 avatar lsdlsd88 avatar mitchbradley avatar okuoku avatar paintyourdragon avatar tanakamasayuki avatar tobozo avatar toyoshim avatar wakwak-koba avatar wusiyu avatar yamamaya avatar yasuhirok-git avatar zingo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lovyangfx's Issues

Setting a specific sprite color to act as alpha channel (ie. not drawPixel if color =r,g,b)

Hi,

I've just started with ESP32 and using M5StickC to make some games.
I'm using your library, which seems great although I have a hard time finding out how to use it (eg. no idea how to generate bitmap/jpg/png hex arrays to be read by sprite.generateFromBitmap or similar, as that's not shown in the examples).
So I've made my custom pixel loader, with input generated in java and including a palette array and an array of indices, and I'd like to know how to set a color to act as a no draw pixel (to act as alpha, showing the pixel below the sprite).
Anyway, how can I achieve this simple alpha color feature... whether using existing bitmap loading (doc?) or compatible with my custom pixel loading?
I use sprite.drawPixel(x, y, lcd.color888(r,g,b)), where I set r, g, b from my custom image loader... maybe there's something like drawPixel(x, y, lcd.ALPHA)?
I understand maybe this is not possible, if data is sent in bulk to the display (really no idea how all this gfx stuff works internally, but saw some DMA reference that hints at that).
In that case, I guess my only option is to draw all relevant pixels directly to the lcd (ie. without sprites), skipping the alpha ones, which is going to be rather slow.

any other link to documentation, api reference would be great :)

Cheers

drawJpgFile doesn't work with datum

I found that drawJpgFile can't display image if I set datum except top_left.
lcd.drawJpgFile(SD, "/hoge.jpg", 0, 0,0, 0, 0, 0, 1.0, 1.0,top_left); //Work
lcd.drawJpgFile(SD, "/hoge.jpg", 0, 0,0, 0, 0, 0, 1.0, 1.0,top_center); //Can't display

Unitil the commit 48bee0d, both works well but from the next(a6bfce4), it doesn't.
It also doesn't work on M5GFX.

Thank you in advance for your help.

LovyanGFX_Clock on M5Stack Core2

I flashed the LovyanGFX_Clock firmware on an M5Stack Core2 with M2Burner. Now the Core2 is not switching on again. Tried the reset and power buttons.

Any idea what happened? Did I corrupt the boot flash? How can I recover the device?

Any idea welcome.

Thanks, Ondrej

Help documenting...

Hi there...

I'd like to help creating a truly english version of the documentation, and possibly create spiffy documentation on Read The Docs by creating a documentation source directory. Is there interest for that?

Dual display setup

Hello, I've been trying to setup a dual display setup, sadly it still doesn't work,
you can find the full code here: https://pastebin.com/vXLQESUd
my issue is that when I use this code, I can see both screen trigger during setup but the loop doesn't move forward, it just stay stuck and doesn't start the loop, could you tell me what I'm doing wrong.

Thanks

I've define both panels like this:

struct LGFX_Config
{
  static constexpr spi_host_device_t spi_host = VSPI_HOST;
  static constexpr int dma_channel = 1;
  static constexpr int spi_sclk = 18;
  static constexpr int spi_mosi = 23;
  static constexpr int spi_miso = -1;
  static constexpr int spi_dlen = 8;
};


//static LGFX lcd;
static lgfx::LGFX_SPI<LGFX_Config> lcd;
static lgfx::LGFX_SPI<LGFX_Config> lcdB;
static lgfx::Panel_ST7789 panel;
static lgfx::Panel_ST7789 panelB;
static TCPReceiver recv;
static TCPReceiver recvB;`

then in setup I did this:


`//SETTING LEFT PANEL
  panel.freq_write = 40000000;
  panel.freq_fill = 40000000;
  panel.freq_read = 6000000;
  panel.spi_mode = 3;
  panel.spi_mode_read = 0;
  panel.len_dummy_read_pixel = 8;
  panel.spi_read = true;
  panel.spi_3wire = false;
  panel.spi_cs = 5;
  panel.spi_dc = 2;
  panel.gpio_rst = 4;
  panel.gpio_bl = 32;
  panel.pwm_ch_bl = 7;
  panel.backlight_level = true;
  panel.invert = true;

  //SETTING RIGHT PANEL
  panelB.freq_write = 40000000;
  panelB.freq_fill = 40000000;
  panelB.freq_read = 6000000;
  panelB.spi_mode = 3;
  panelB.spi_mode_read = 0;
  panelB.len_dummy_read_pixel = 8;
  panelB.spi_read = true;
  panelB.spi_3wire = false;
  panelB.spi_cs = 17;
  panelB.spi_dc = 2;
  panelB.gpio_rst = 4;
  panelB.gpio_bl = 32;
  panelB.pwm_ch_bl = 7;
  panelB.backlight_level = true;
  panelB.invert = true;
  //  panel.rgb_order = false;

  lcd.setPanel(&panel);
  lcdB.setPanel(&panelB); //STARTING RIGHT PANEL

drawFastVLine, drawFastHLineの実行タイミングを変えると表示が潰れる

素晴らしいライブラリを使わせて頂き、ありがとうございます。

M5Paperで以下のコードの#define ERROR_DISPLAYを有効すると
2行表示していた文字と図が1行目の領域に潰れて表示されます。

この問題は、これらを最後にまとめて実行する事で回避できます。
改善できそうでしょうか?

  • ビルド環境
    • iMac
    • VScode + PlatformIO
    • LovyanGFX mainブランチ
#include <M5EPD.h>

#define LGFX_M5PAPER
#include <LovyanGFX.hpp>

static LGFX gfx;

// --------------------------------
//  これを有効にすると不具合が再現します
// --------------------------------
//#define ERROR_DISPLAY

void setup() {

    int x = 10;
    int y = 50;
    int y_offset = 120;

    M5.begin(true, true, true, true);
    gfx.init();
    gfx.setFont(&fonts::lgfxJapanGothic_32);

#ifdef ERROR_DISPLAY
    //ここだと表示が潰れる
    gfx.drawFastVLine(70, 0, gfx.height());
#endif

    gfx.setCursor(x, y);
    gfx.println("0.1");
    gfx.fillArc( 270, y + 8, 54, 32, 270 + 20, 270 - 20, TFT_BLACK);

#ifdef ERROR_DISPLAY
    //ここだと表示が潰れる
    gfx.drawFastHLine( 0, 124, gfx.width() );
#endif

    y = y + y_offset;
    gfx.setCursor(x, y);
    gfx.println("0.2");
    gfx.fillArc( 270, y + 22, 42, 28, 90 + 20, 90 - 20, TFT_BLACK);

#ifndef ERROR_DISPLAY
    //ここだと正常に表示できる
    gfx.drawFastVLine(70, 0, gfx.height());
    gfx.drawFastHLine( 0, 124, gfx.width() );
#endif

}

void loop() {}

Feature idea: Hierarchical sprites that pass-thru when not set up ...

I created Core2ez, a widget-based toolkit for the Core2. It's still very fresh, and it'll need more work. Given that M5Stack is going for your display driver, it might be good if I tell you something about what I have done. I think some of the things that I have implemented would be possibly be cleaner and useful for more people if they migrated to your driver. Also I'd just like to hear what you think...

The thing

I have a class called ezDisplayZone, which inherits from ezZone, which just defines a rectangle and you can ask it whether a given ezPoint is inside of it, etc etc. ezDisplayZone then lets you create a hierarchy of zones that are either directly on the screen, or inside a parent ezDisplayZone. ezDisplayZone then implements the methods of the display, so drawRoundRect is implemented. If you do not set it to buffer in a sprite, all it does is send it to its parent, after subtracting its own position within that parent from the coordinates.

When you set it to buffer, it will draw whatever comes 'from below' and will similarly 'pass up' when pushed, until it meets another sprite-buffered ezDisplayZone or the display itself. I implemented this as a shim, but it works remarkable well: an entire widget toolkit runs on it.

The idea

Could I maybe interest you to have this as part of the display driver instead. A sort of sprite that is pass-through when not active, that stores and corrects for its position in the parent sprite or screen?

I'd be happy to discuss further...

pushImage no longer compiles with a transparency color

Hi lovyan03,

First of all, I would like to thank you for your high quality work and the services offered by your LovyanGFX library.
Thank you so much for making it available to all of us.

However, since your last update v0.2.3, I can no longer compile my project when I specify a transparency color with the pushImage function :

// it doesn't compile anymore when :
// - TRANS_COLOR is defined as a single variable
// - TRANS_COLOR is defined as a global constant
// - TRANS_COLOR is defined as a static constant within a class
sprite.pushImage(x, y, w, h, data, TRANS_COLOR);

While it compiled perfectly with version 0.2.2.

Here's the error I get :

.pio/libdeps/m5/LovyanGFX/src/lgfx/LGFXBase.hpp: In instantiation of 'void lgfx::LGFXBase::pushImage(int32_t, int32_t, int32_t, int32_t, const T*, const U&) [with T = lgfx::rgb565_t; U = short unsigned int; int32_t = int]':
.pio/libdeps/m5/LovyanGFX/src/lgfx/LGFXBase.hpp:265:9:   required from 'void lgfx::LGFXBase::pushImage(int32_t, int32_t, int32_t, int32_t, const uint16_t*, const U&) [with U = short unsigned int; int32_t = int; uint16_t = short unsigned int]'
src/Player.cpp:14:91:   required from here
.pio/libdeps/m5/LovyanGFX/src/lgfx/LGFXBase.hpp:246:90: error: invalid use of non-static member function
       pixelcopy_t p(data, _write_conv.depth, get_depth<T>::value, hasPalette, nullptr, tr);

Am I misusing the new version of pushImage()?

Backlight flickers using init_without_reset()

Hi,
thanks for this wonderful library!

I am using an M5Stack module with a fairly low backlight setting of 8. I am using deep_sleep and some ULP code to keep the backlight on during sleep.. Whenever the device comes out of deepsleep, I use init_without_reset() which is great to avoid the screen from going blank. However, the screen is initialized with a backlight setting higher than mine which causes the screen to flicker for a split second.

I think I have traced down and avoided the problem. However, my C is not very good. Maybe you can use the code below to trace down the issue and develop a proper fix.

There seem to be two problems:

  1. the panel backlight value is initialized at 128, but lcd.setBacklight() can only be called after init
  2. PanelCommon.init() calls initPWM() without the optional duty parameter and therefore duty=128

I "fixed" 1) with repeating the init code in my own class and setting the panel backlight value after autodetect():

void WeatherDisplay::init_without_reset(std::uint8_t brightness) {
  int retry = 3;
  while (!mylcd.autodetect(false) && --retry);
  mylcd.getPanel()->brightness = brightness;
  //taken from private function mylcd.lgfx::LGFX_SPI<lgfx::LGFX_Config>::init_impl(false);
  mylcd.lgfx::LGFX_SPI<lgfx::LGFX_Config>::initBus(); 
  mylcd.lgfx::LGFX_SPI<lgfx::LGFX_Config>::initPanel(false); 
  mylcd.lgfx::LGFX_SPI<lgfx::LGFX_Config>::initTouch(); 

//  mylcd.init_without_reset();
}

I "fixed" 2) by adding the parameter in PanelCommon.hpp:

virtual void init(bool use_reset)
{
  ...
          initPWM(gpio_bl, pwm_ch_bl, pwm_freq, backlight_level ? brightness : (255 - brightness));
  ...
}

Build failure with the latest framework-arduinoespressif32 (idf-release/v4.2 branch)

Following compilation errors occur when using the latest framework-arduinoespressif32 (idf-release/v4.2 branch) and PlatformIO.
I'll create a PR to fix this issue.

Error 1

.pio\libdeps\m5paper-test\LovyanGFX\src\lgfx\platforms\esp32_common.cpp: In function 'void lgfx::spi::init(int, int, int, int, int)':
.pio\libdeps\m5paper-test\LovyanGFX\src\lgfx\platforms\esp32_common.cpp:199:33: error: 'DPORT_SPI_DMA_CHAN_SEL_REG' was not declared in this scope
         DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, dma_channel, (spi_host * 2));
                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~
.pio\libdeps\m5paper-test\LovyanGFX\src\lgfx\platforms\esp32_common.cpp:199:33: note: suggested alternative: 'SOC_SPI_DMA_CHAN_NUM'
         DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, dma_channel, (spi_host * 2));
                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~
                                 SOC_SPI_DMA_CHAN_NUM
.pio\libdeps\m5paper-test\LovyanGFX\src\lgfx\platforms\esp32_common.cpp:199:9: error: 'DPORT_SET_PERI_REG_BITS' was not declared in this scope
         DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, dma_channel, (spi_host * 2));
         ^~~~~~~~~~~~~~~~~~~~~~~
.pio\libdeps\m5paper-test\LovyanGFX\src\lgfx\platforms\esp32_common.cpp:199:9: note: suggested alternative: 'SET_PERI_REG_BITS'
         DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, dma_channel, (spi_host * 2));
         ^~~~~~~~~~~~~~~~~~~~~~~
         SET_PERI_REG_BITS

Error2

In file included from .pio/libdeps/m5paper-test/LovyanGFX/src/LovyanGFX.hpp:65,
                 from src\main.cpp:2:
.pio/libdeps/m5paper-test/LovyanGFX/src/lgfx/platforms/LGFX_SPI_ESP32.hpp: In function 'void lgfx::spi_dma_transfer_active(int)':
.pio/libdeps/m5paper-test/LovyanGFX/src/lgfx/platforms/LGFX_SPI_ESP32.hpp:65:5: error: 'spicommon_dmaworkaround_transfer_active' was not declared in this scope
     spicommon_dmaworkaround_transfer_active(dmachan);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.pio/libdeps/m5paper-test/LovyanGFX/src/lgfx/platforms/LGFX_SPI_ESP32.hpp:65:5: note: suggested alternative: 'spi_dma_transfer_active'
     spicommon_dmaworkaround_transfer_active(dmachan);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     spi_dma_transfer_active
*** [.pio\build\m5paper-test\src\main.cpp.o] Error 1

Code example

platformio.ini

[platformio]
packages_dir = .pio/packages

[env:m5paper-test]
platform = espressif32
board = m5stack-fire
framework = arduino
platform_packages =
    toolchain-xtensa32 @ https://bintray.com/platformio/tool-packages/download_file?file_path=53bcf98-toolchain-xtensa32-windows-2.80400.2020.tar.gz
    framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#idf-release/v4.2
build_flags =
    -DESP32=1
    -DARDUINO_ARCH_ESP32=1
lib_deps =
  lovyan03/LovyanGFX

src/main.cpp

#define LGFX_AUTODETECT
#include <LovyanGFX.hpp>

void setup(void)
{
}

void loop(void)
{
}

Build log for pio run

PS C:\Users\estshorter\src\esp> pio run
Processing m5paper-test (platform: espressif32; board: m5stack-fire; framework: arduino)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/espressif32/m5stack-fire.html
PLATFORM: Espressif 32 (2.1.0) > M5Stack FIRE
HARDWARE: ESP32 240MHz, 6.25MB RAM, 16MB Flash
DEBUG: Current (esp-prog) External (esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES:
 - framework-arduinoespressif32 0.0.0+sha.7d3f499
 - tool-esptoolpy 1.30000.201119 (3.0.0)
 - toolchain-xtensa32 2.80400.2020 (8.4.0)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 31 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <LovyanGFX> 0.3.5
|   |-- <SPI> 1.0
|   |-- <Wire> 1.0.1
Building in release mode
Compiling .pio\build\m5paper-test\lib64e\LovyanGFX\lgfx\platforms\esp32_common.cpp.o
Compiling .pio\build\m5paper-test\src\main.cpp.o
.pio\libdeps\m5paper-test\LovyanGFX\src\lgfx\platforms\esp32_common.cpp: In function 'void lgfx::spi::init(int, int, int, int, int)':
.pio\libdeps\m5paper-test\LovyanGFX\src\lgfx\platforms\esp32_common.cpp:199:33: error: 'DPORT_SPI_DMA_CHAN_SEL_REG' was not declared in this scope
         DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, dma_channel, (spi_host * 2));
                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~
.pio\libdeps\m5paper-test\LovyanGFX\src\lgfx\platforms\esp32_common.cpp:199:33: note: suggested alternative: 'SOC_SPI_DMA_CHAN_NUM'
         DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, dma_channel, (spi_host * 2));
                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~
                                 SOC_SPI_DMA_CHAN_NUM
.pio\libdeps\m5paper-test\LovyanGFX\src\lgfx\platforms\esp32_common.cpp:199:9: error: 'DPORT_SET_PERI_REG_BITS' was not declared in this scope
         DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, dma_channel, (spi_host * 2));
         ^~~~~~~~~~~~~~~~~~~~~~~
.pio\libdeps\m5paper-test\LovyanGFX\src\lgfx\platforms\esp32_common.cpp:199:9: note: suggested alternative: 'SET_PERI_REG_BITS'
         DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, dma_channel, (spi_host * 2));
         ^~~~~~~~~~~~~~~~~~~~~~~
         SET_PERI_REG_BITS
Compiling .pio\build\m5paper-test\FrameworkArduino\esp32-hal-matrix.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\esp32-hal-misc.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\esp32-hal-psram.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\esp32-hal-rmt.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\esp32-hal-sigmadelta.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\esp32-hal-spi.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\esp32-hal-time.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\esp32-hal-timer.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\esp32-hal-tinyusb.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\esp32-hal-touch.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\esp32-hal-uart.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\libb64\cdecode.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\libb64\cencode.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\main.cpp.o
*** [.pio\build\m5paper-test\lib64e\LovyanGFX\lgfx\platforms\esp32_common.cpp.o] Error 1
In file included from .pio/libdeps/m5paper-test/LovyanGFX/src/LovyanGFX.hpp:65,
                 from src\main.cpp:2:
.pio/libdeps/m5paper-test/LovyanGFX/src/lgfx/platforms/LGFX_SPI_ESP32.hpp: In function 'void lgfx::spi_dma_transfer_active(int)':
.pio/libdeps/m5paper-test/LovyanGFX/src/lgfx/platforms/LGFX_SPI_ESP32.hpp:65:5: error: 'spicommon_dmaworkaround_transfer_active' was not declared in this scope
     spicommon_dmaworkaround_transfer_active(dmachan);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.pio/libdeps/m5paper-test/LovyanGFX/src/lgfx/platforms/LGFX_SPI_ESP32.hpp:65:5: note: suggested alternative: 'spi_dma_transfer_active'
     spicommon_dmaworkaround_transfer_active(dmachan);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     spi_dma_transfer_active
*** [.pio\build\m5paper-test\src\main.cpp.o] Error 1
=============================================================================================================== [FAILED] Took 5.28 seconds ===============================================================================================================

Environment

  • PlatformIO IDE v2.2.1
  • VS Code 1.52.1
  • Win 10 20H2

On Wemos D32 Pro + TFT3.5inch touch , how to test 「 MovingIcons」 example ?

I am using Wemos D32 Pro + TFT3.5inch (ILI9488) . and connect line like the following image

image

When I test by 「 ClockSample」example, it 's fine for me by the following config.

struct LGFX_Config
{
  static constexpr spi_host_device_t spi_host = VSPI_HOST;
  static constexpr int dma_channel = 1;
  static constexpr int spi_sclk = 18;
  static constexpr int spi_mosi = 23;
  static constexpr int spi_miso = 19;
  static constexpr int spi_dlen = 8;
};

static lgfx::LGFX_SPI<LGFX_Config> lcd;


// Panelクラスのインスタンスを作成します。使用するパネルにあった記述をコメントアウトしてください。
//static lgfx::Panel_HX8357B panel;
//static lgfx::Panel_HX8357D panel;
//static lgfx::Panel_ILI9163 panel;
//static lgfx::Panel_ILI9341 panel;
//static lgfx::Panel_ILI9342 panel;
//static lgfx::Panel_ILI9486 panel;
static lgfx::Panel_ILI9488 panel;
//static lgfx::Panel_SSD1351 panel;
//static lgfx::Panel_ST7789 panel;
//static lgfx::Panel_ST7735S panel;

void panel_config(){
  panel.freq_write = 20000000;
  panel.freq_fill  = 27000000;
  panel.freq_read  = 16000000;
  panel.spi_mode = 0;
  panel.spi_mode_read = 0;
  panel.len_dummy_read_pixel = 8;
  panel.spi_read = true;
  panel.spi_3wire = false;
  panel.spi_cs = 14;
  panel.spi_dc = 27;
  panel.gpio_rst = 33;
  panel.gpio_bl  = 32;
  panel.pwm_ch_bl = 7;
  panel.backlight_level = true;
  panel.invert = false;
  panel.rgb_order = false;
  panel.memory_width  = 320;//320;
  panel.memory_height = 480;//240;
  panel.panel_width  = 320;//320;
  panel.panel_height = 480;//240;
  panel.offset_x = 0;
  panel.offset_y = 0;
  panel.rotation = 3;
  panel.offset_rotation = 0;  
}

// ....

void setup(){
  Serial.begin(115200);

#if defined(ARDUINO_M5Stick_C)
  axp.begin();
#endif

  panel_config();
  lcd.setPanel(&panel);
  lcd.init();

  //. ....
}

void loop(){
   //.....
}

However when I use this config for 「 MovingIcons」or 「 MovingCircles」 example ,
it occurs some strange display like the following clip.

https://streamable.com/4qw95u

How to solve this example ?
Thank you very much.

[branch:develop] ESP32-Chimera-Core + LGFX v1 observations and ideas

Compilation Tests

#define LGFX_USE_V1 was added to ESP32-Chimera-Core as instructed.

Tests scope:

  • M5Stack Classic
  • LoLin D32 Pro + ST7735
  • LoLin D32 Pro + ILI9341 + Touch
  • TTGO T-Watch 2020 v1
  • Odroid-Go

Test Sketches: esp32-doomfire, USB Soft Host, esp32-sidview

⚠️ some changes to fix compilation errors:

  1. Temporary fix for 'Font_Blah' was not declared in this scope
  // ESP32-Chimera-Core/src/M5Display.h
  static auto Font_Blah = fonts::Font_Blah;
  static auto Font_Blah1 = fonts::Font_Blah1;
  1. Commenting this out, but skipping tests using SD Card
  // ESP32-Chimera-Core/src/M5Display.cpp
  /*
  if ( lgfx::LGFX_Config::spi_host == HSPI_HOST ) {
    Lcd.setSPIShared(false);
  }
  */

Detection Fail

⚠️ Found one device compatibility problem with LoLin D32 Pro + ST7735 128x128 + no touch

Panel id 3ff0897c (ST7735) is ignored when LGFX_LOLIN_D32_PRO is used.

lgfx::V1 💔 (click to expand):

[W][LGFX_AutoDetect_ESP32.hpp:284] init_impl(): [Autodetect] load from NVS : board:0
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff7f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff7f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff3f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:09 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff3f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 3ff0897c <<<< detect ignored
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:70 = ffffff3f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff7f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff7f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff3f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:09 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff3f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 3ff0897c <<<< detect ignored
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:70 = ffffff3f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff7f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff7f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff3f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:09 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff3f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 3ff0897c <<<< detect ignored
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:70 = ffffff3f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff7f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff7f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff3f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:09 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff3f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 3ff0897c <<<< detect ignored
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:70 = ffffff3f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:361] init_impl(): [Autodetect] save to NVS : board:0

lgfx::V0 ✔️ (click to expand):

[W][LGFX_Config_AutoDetectESP32.hpp:288] autodetect(): [Autodetect] load from NVS : board:0
[W][LGFX_Config_AutoDetectESP32.hpp:306] autodetect(): [Autodetect] panel id:ffffff7f
[W][LGFX_Config_AutoDetectESP32.hpp:363] autodetect(): [Autodetect] panel id:ffffff7f
[W][LGFX_Config_AutoDetectESP32.hpp:424] autodetect(): [Autodetect] panel id:ffffffff
[W][LGFX_Config_AutoDetectESP32.hpp:466] autodetect(): [Autodetect] panel id:3ff0897c <<<< detect success
[W][LGFX_Config_AutoDetectESP32.hpp:476] autodetect(): [Autodetect] LoLinD32Pro ST7735
[W][LGFX_Config_AutoDetectESP32.hpp:1216] autodetect(): [Autodetect] save to NVS : board:12


Idea: Minimize impact of breaking changes

Extend gitTagVersion.h as follows:

  #define LGFX_VERSION_MAJOR 7
  #define LGFX_VERSION_MINOR 8
  #define LGFX_VERSION_PATCH 9
  #define LOVYANGFX_VERSION F( LGFX_VERSION_MAJOR "." LGFX_VERSION_MINOR "." LGFX_VERSION_PATCH )
  // #define LOVYANGFX_VERSION F("7.8.9") 

So any library/sketch can extend compatibility from v0 to v1 by doing this:

#if defined( LGFX_VERSION_MAJOR ) && LGFX_VERSION_MAJOR >= 1
  // newer driver version, assume `LGFX_USE_V1` is enabled
#else    
  // older driver version, use `lgfx::v0` syntax
#endif 

How to wire ESP32 I2S mode to TFT ?

I would like to try TFT parallel i2s mode.

Is there any ESP32 I2S + TFT wire-mapping
for trying LovyanGFX with parellel I2S mode ?

Thank you very much.

ILI9486L display support

Hello
I recently bought this screen from Aliexpress: https://www.aliexpress.com/item/3-5-inch-8P-SPI-TFT-LCD-Color-Screen-Module-ILI9486-Drive-IC-320-480-RGB/32828284227.html

After wired it to my ESP32 board and changed some settings in the example sketch "2_spi_setting", the display does not work at all.
By studying the datasheet, I realized that the ILI9486L controller only support RGB111 and RGB666 mode when using SPI mode(Chapter 7.5.3, Page 45). So I changed the configuration "write_depth" from "rgb565_2Byte" to "rgb666_3Byte" in the "PanelCommon.hpp"(Line 39), and then, I upload the code, the display seems worked flawlessly.
ili9486l_2

But when I moved to the project "ScreenShotReceiver" with same configurations, the WiFi information displayed normally, but the image seems got twisted.
ili9486l_1

Here is my configuration codes, and did I miss anything important?
`struct LGFX_Config
{
static constexpr spi_host_device_t spi_host = VSPI_HOST;
static constexpr int dma_channel = 1;
static constexpr int spi_sclk = 18;
static constexpr int spi_mosi = 23;
static constexpr int spi_miso = 19;
static constexpr int spi_dlen = 8;
};

static lgfx::LGFX_SPI<LGFX_Config> lcd;
static lgfx::Panel_ILI9486 panel;

void pannel_cfg()
{
panel.freq_write = 20000000;
panel.freq_fill = 27000000;
panel.freq_read = 16000000;
panel.spi_mode = 3;
panel.spi_mode_read = 0;
panel.len_dummy_read_pixel = 8;
panel.spi_read = false;
panel.spi_3wire = true;
panel.spi_cs = -1;
panel.spi_dc = 5;
panel.gpio_rst = 4;
panel.gpio_bl = 15;
panel.pwm_ch_bl = 7;
panel.backlight_level = true;
panel.invert = false;
panel.rgb_order = false;
panel.memory_width = 320;
panel.memory_height = 480;
panel.panel_width = 320;
panel.panel_height = 480;
panel.offset_x = 0;
panel.offset_y = 0;
panel.rotation = 0;
panel.offset_rotation = 0;
lcd.setPanel(&panel);
}`

0.3.2から #include<LovyanGFX.h>の解釈経路が異なる場合がある

LovyanGFX 0.3.0/0.3.2 Arduino M5Stack Grey.

#include<M5Stack.h> を #include<LovyanGFX.h> の前に入れるか入れないかでの経路が 0.3.2 から変わったようです。
0.3.0 までは同経路の解釈をしていると思われます。

LGFX_Sprite.hpp の 150行目付近の createFromBmp付近の分岐に #pragma messageを仕込んだ結果は以下の通りです。

0.3.2以降は必ず #include<M5Stack.h> すべきでしょうか?

scratch.ino

#include <M5Stack.h>
#include <LovyanGFX.h>

test.cpp

#include <LovyanGFX.h>

Ver 0.3.0 .ino/.cpp 同経路

In file included from /Users/gob/projects/M5Stack/libraries/LovyanGFX/src/LovyanGFX.hpp:43:0,
                 from /Users/gob/projects/M5Stack/libraries/LovyanGFX/src/LovyanGFX.h:5,
                 from /Users/gob/tmp/sketch/test.cpp:1:
/Users/gob/projects/M5Stack/libraries/LovyanGFX/src/lgfx/LGFX_Sprite.hpp:151:35: note: #pragma message: FS_H/SEEED_FS
    #pragma message("FS_H/SEEED_FS")
                                   ^
In file included from /Users/gob/projects/M5Stack/libraries/LovyanGFX/src/LovyanGFX.hpp:43:0,
                 from /Users/gob/projects/M5Stack/libraries/LovyanGFX/src/LovyanGFX.h:5,
                 from /Users/gob/projects/M5Stack/scratch/scratch.ino:7:
/Users/gob/projects/M5Stack/libraries/LovyanGFX/src/lgfx/LGFX_Sprite.hpp:151:32: note: #pragma message: FS_H/SEEED_FS
    #pragma message("FS_H/SEEED_FS")

Ver 0.3.2 .ino/.cpp 違経路

In file included from /Users/gob/projects/M5Stack/libraries/LovyanGFX/src/LovyanGFX.hpp:43:0,
                 from /Users/gob/projects/M5Stack/libraries/LovyanGFX/src/LovyanGFX.h:5,
                 from /Users/gob/projects/M5Stack/scratch/scratch.ino:7:
/Users/gob/projects/M5Stack/libraries/LovyanGFX/src/lgfx/LGFX_Sprite.hpp:151:32: note: #pragma message: FS_H/SEEED_FS
   #pragma message("FS_H/SEEED_FS")

warning: 'ty' and 'tx' may be used uninitialized in LGFX_Device::getTouch

I'm getting this warning when setting the compiler debug level to "All":

image

~/Arduino/libraries/LovyanGFX/src/lgfx/platforms/../LGFX_Device.hpp:156:14: warning: 'ty' may be used uninitialized in this function [-Wmaybe-uninitialized]
       if (y) *y = ty;
              ^
~/Arduino/libraries/LovyanGFX/src/lgfx/platforms/../LGFX_Device.hpp:153:24: note: 'ty' was declared here
       std::int32_t tx, ty;
                        ^
~/Arduino/libraries/LovyanGFX/src/lgfx/platforms/../LGFX_Device.hpp:155:14: warning: 'tx' may be used uninitialized in this function [-Wmaybe-uninitialized]
       if (x) *x = tx;
              ^
~/Arduino/libraries/LovyanGFX/src/lgfx/platforms/../LGFX_Device.hpp:153:20: note: 'tx' was declared here
       std::int32_t tx, ty;
                    ^

Initializing with std::int32_t tx=0, ty=0 makes the warning go away, but there may be side effects.

Maybe std::int32_t tx=-1, ty=-1 would be better ?

    template <typename T>
    std::uint_fast8_t getTouch(T *x, T *y, std::uint_fast8_t number = 0)
    {
      // std::int32_t tx, ty; // warning: 'ty' and 'tx' may be used uninitialized in this function [-Wmaybe-uninitialized]
      std::int32_t tx=0, ty=0; // no more warning
      auto res = getTouch(&tx, &ty, number);
      if (x) *x = tx;
      if (y) *y = ty;
      return res;
    }

sprite::createSprite() Guru meditation error with psram

Hardware: LoLin D32Pro (with psram) + TFT-2.4 @320x240

Problem description:

sprite::createSprite() crashes when used in combination with psram.

Expected behaviour:

createSprite should return NULL when allocation failed

How to reproduce:

// width = 240, height = 320 (portrait mode)
TFT_eSprite *sprite = new TFT_eSprite( &tft );

// this triggers a guru mediation error
sprite->setPsram(true);
void * sptr = sprite->createSprite( tft.width(), tft.height() );

// this triggers a guru mediation error
sprite->setPsram(false);
void * sptr = sprite->createSprite( tft.width(), tft.height() );

// this triggers a guru mediation error
sprite->setPsram(true);
sprite->setColorDepth(8);
void * sptr = sprite->createSprite( tft.width(), tft.height() );

// this succeeds
sprite->setPsram(false);
sprite->setColorDepth(8);
void * sptr = sprite->createSprite( tft.width(), tft.height() );

Error message in the console:


Guru Meditation Error: Core  1 panic'ed (StoreProhibited). Exception was unhandled.
Core 1 register dump:
PC      : 0x4008bf06  PS      : 0x00060533  A0      : 0x8008ddf6  A1      : 0x3ffb1e50  
A2      : 0xb3ff0706  A3      : 0x0000abab  A4      : 0xb33fffff  A5      : 0x00000001  
A6      : 0x00060520  A7      : 0x0000cdcd  A8      : 0x0000abab  A9      : 0x3ffb1e20  
A10     : 0x00004000  A11     : 0x00000000  A12     : 0x3ff65000  A13     : 0x3ff650c0  
A14     : 0xd941d941  A15     : 0xd941d941  SAR     : 0x00000012  EXCCAUSE: 0x0000001d  
EXCVADDR: 0xb3ff0706  LBEG    : 0x40088a24  LEND    : 0x40088a40  LCOUNT  : 0x00000000  

ELF file SHA256: 0000000000000000

Backtrace: 0x4008bf06:0x3ffb1e50 0x4008ddf3:0x3ffb1e80 0x4008e42d:0x3ffb1ea0 0x40081e11:0x3ffb1ec0 0x400dac8f:0x3ffb1ee0 0x400d376a:0x3ffb1f00 0x400d3a4d:0x3ffb1f30 0x400e59a2:0x3ffb1fb0 0x4008b162:0x3ffb1fd0

Decoded backtrace:

Decoding 12 results
0x4008bf06: uxPortCompareSet at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/tasks.c line 4560
:  (inlined by) vPortCPUAcquireMutexIntsDisabledInternal at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/portmux_impl.inc.h line 86
:  (inlined by) vPortCPUAcquireMutexIntsDisabled at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/portmux_impl.h line 98
:  (inlined by) vTaskEnterCritical at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/tasks.c line 4201
0x40088a24: memcpy at /home/mak/e/p/newlib_old/newlib_xtensa-bin/newlib_xtensa-2.2.0/xtensa-esp32-elf/newlib/libc/machine/xtensa/../../../../.././newlib/libc/machine/xtensa/memcpy.S line 175
0x40088a40: memcpy at /home/mak/e/p/newlib_old/newlib_xtensa-bin/newlib_xtensa-2.2.0/xtensa-esp32-elf/newlib/libc/machine/xtensa/../../../../.././newlib/libc/machine/xtensa/memcpy.S line 197
0x4008bf06: uxPortCompareSet at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/tasks.c line 4560
:  (inlined by) vPortCPUAcquireMutexIntsDisabledInternal at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/portmux_impl.inc.h line 86
:  (inlined by) vPortCPUAcquireMutexIntsDisabled at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/portmux_impl.h line 98
:  (inlined by) vTaskEnterCritical at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/tasks.c line 4201
0x4008ddf3: multi_heap_internal_lock at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/multi_heap.c line 380
0x4008e42d: multi_heap_malloc at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/multi_heap_poisoning.c line 321
0x40081e11: heap_caps_malloc at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/heap_caps.c line 232
0x400dac8f: lgfx::v1::Panel_Sprite::createSprite(int, int, lgfx::v1::color_conv_t*, bool) at /home/tobozo/Arduino/libraries/LovyanGFX/src/lgfx/v1/misc/colortype.hpp line 84
:  (inlined by) lgfx::v1::SpriteBuffer::reset(unsigned int, lgfx::v1::AllocationSource) at /home/tobozo/Arduino/libraries/LovyanGFX/src/lgfx/v1/misc/SpriteBuffer.hpp line 162
:  (inlined by) lgfx::v1::Panel_Sprite::createSprite(int, int, lgfx::v1::color_conv_t*, bool) at /home/tobozo/Arduino/libraries/LovyanGFX/src/lgfx/v1/LGFX_Sprite.cpp line 98
0x400d376a: lgfx::v1::LGFX_Sprite::createSprite(int, int) at /home/tobozo/Arduino/libraries/ESP32-USB-Soft-Host/src/ESP32-USBSoftHost.hpp line 192
:  (inlined by) setupUI() at /home/tobozo/Arduino/libraries/SID6581/examples/SidUSBSoftHost/C64_UI.h line 137
0x400d3a4d: setup() at /home/tobozo/Arduino/libraries/ESP32-USB-Soft-Host/src/ESP32-USBSoftHost.hpp line 192
0x400e59a2: loopTask(void*) at /home/tobozo/.arduino15/packages/esp32/hardware/esp32/1.0.6/cores/esp32/main.cpp line 18
0x4008b162: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 355 (discriminator 1)

Roadmap to legal compliance

  • Documentation
    • Use Doxygen ? automated example with ESP32-targz
    • How many languages ? ( current candidates : en / fr / jp )
    • ReadME: detailed scope of the library
      • software scope: AVR, ESP85266, ESP32-Arduino, esp-idf
      • hardware scope: simultaneously drive up to 8 (or more?) SPI displays
    • Gitter community ?
    • Wiki (can receive public contributions, needs to be enabled in github project settings) ?
  • License
    • Main license (MIT)
    • Inherited licenses template:
      • 1 Initial unmodified license
      • 2 Additional license
      • 3 Project specific notes
    • fonts need distinct license
  • Examples folder
    • Needs hierarchy (Basic/Advanced, ESP8266/ESP32/AVR)
    • Can act as unit tests (travis or github actions)
  • Unimplemented functions
    • Upper/lower layer interoperability (esp-idf, chimera-core)
    • Known API friendliness (M5Stack, TFT_eSPI)

Error compiling with M5Stack / M5StickCPlus since update 0.3.9

Hello @lovyan03,

Thanks for your last update... but since I switched to version 0.3.9, I have compilation problems with the <M5Stack.h> and <M5StickCPlus.h> libraries:

In file included from .pio/libdeps/stick/M5StickCPlus/src/M5Display.h:7:0,
                 from .pio/libdeps/stick/M5StickCPlus/src/M5StickCPlus.h:69,
                 from src/stick.cpp:2:
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:494:18: error: expected unqualified-id before numeric constant
 #define TL_DATUM 0 // Top left (default)
                  ^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:168:34: note: in expansion of macro 'TL_DATUM'
     static constexpr textdatum_t TL_DATUM   = textdatum_t::top_left;
                                  ^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:495:18: error: expected unqualified-id before numeric constant
 #define TC_DATUM 1 // Top centre
                  ^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:169:34: note: in expansion of macro 'TC_DATUM'
     static constexpr textdatum_t TC_DATUM   = textdatum_t::top_center;
                                  ^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:496:18: error: expected unqualified-id before numeric constant
 #define TR_DATUM 2 // Top right
                  ^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:170:34: note: in expansion of macro 'TR_DATUM'
     static constexpr textdatum_t TR_DATUM   = textdatum_t::top_right;
                                  ^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:497:18: error: expected unqualified-id before numeric constant
 #define ML_DATUM 3 // Middle left
                  ^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:171:34: note: in expansion of macro 'ML_DATUM'
     static constexpr textdatum_t ML_DATUM   = textdatum_t::middle_left;
                                  ^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:498:18: error: expected unqualified-id before numeric constant
 #define CL_DATUM 3 // Centre left, same as above
                  ^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:172:34: note: in expansion of macro 'CL_DATUM'
     static constexpr textdatum_t CL_DATUM   = textdatum_t::middle_left;
                                  ^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:499:18: error: expected unqualified-id before numeric constant
 #define MC_DATUM 4 // Middle centre
                  ^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:173:34: note: in expansion of macro 'MC_DATUM'
     static constexpr textdatum_t MC_DATUM   = textdatum_t::middle_center;
                                  ^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:500:18: error: expected unqualified-id before numeric constant
 #define CC_DATUM 4 // Centre centre, same as above
                  ^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:174:34: note: in expansion of macro 'CC_DATUM'
     static constexpr textdatum_t CC_DATUM   = textdatum_t::middle_center;
                                  ^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:501:18: error: expected unqualified-id before numeric constant
 #define MR_DATUM 5 // Middle right
                  ^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:175:34: note: in expansion of macro 'MR_DATUM'
     static constexpr textdatum_t MR_DATUM   = textdatum_t::middle_right;
                                  ^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:502:18: error: expected unqualified-id before numeric constant
 #define CR_DATUM 5 // Centre right, same as above
                  ^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:176:34: note: in expansion of macro 'CR_DATUM'
     static constexpr textdatum_t CR_DATUM   = textdatum_t::middle_right;
                                  ^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:503:18: error: expected unqualified-id before numeric constant
 #define BL_DATUM 6 // Bottom left
                  ^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:177:34: note: in expansion of macro 'BL_DATUM'
     static constexpr textdatum_t BL_DATUM   = textdatum_t::bottom_left;
                                  ^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:504:18: error: expected unqualified-id before numeric constant
 #define BC_DATUM 7 // Bottom centre
                  ^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:178:34: note: in expansion of macro 'BC_DATUM'
     static constexpr textdatum_t BC_DATUM   = textdatum_t::bottom_center;
                                  ^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:505:18: error: expected unqualified-id before numeric constant
 #define BR_DATUM 8 // Bottom right
                  ^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:179:34: note: in expansion of macro 'BR_DATUM'
     static constexpr textdatum_t BR_DATUM   = textdatum_t::bottom_right;
                                  ^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:506:21: error: expected unqualified-id before numeric constant
 #define L_BASELINE  9 // Left character baseline (Line the 'A' character would sit on)
                     ^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:180:34: note: in expansion of macro 'L_BASELINE'
     static constexpr textdatum_t L_BASELINE = textdatum_t::baseline_left;
                                  ^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:507:20: error: expected unqualified-id before numeric constant
 #define C_BASELINE 10 // Centre character baseline
                    ^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:181:34: note: in expansion of macro 'C_BASELINE'
     static constexpr textdatum_t C_BASELINE = textdatum_t::baseline_center;
                                  ^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:508:20: error: expected unqualified-id before numeric constant
 #define R_BASELINE 11 // Right character baseline
                    ^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:182:34: note: in expansion of macro 'R_BASELINE'
     static constexpr textdatum_t R_BASELINE = textdatum_t::baseline_right;
                                  ^
Archiving .pio/build/stick/libFrameworkArduinoVariant.a
Indexing .pio/build/stick/libFrameworkArduinoVariant.a
Compiling .pio/build/stick/FrameworkArduino/Esp.cpp.o
*** [.pio/build/stick/src/stick.cpp.o] Error 1

Do you know why?

I don't have these problems with the previous version.

Thank you in advance,
Steph

DOIT Devkit V1.0 + TFT 3.5 Touch (ILI9488) about touch interface can't calibrate. How to fix it?

I used Lolin D32 Pro + TFT3.5 Touch , it can calibrate well,

However when I changed the ESP32 board to DOIT Devkit V1.0 (30pins) + TFT3.5 Touch.
It can't calibrate. The result is the following clip.
https://streamable.com/iaebdt

[Code] ( Adapted from example 2_spi_setting )

#include <LovyanGFX.hpp>

struct LGFX_Config
{
  static constexpr spi_host_device_t spi_host = VSPI_HOST;
  static constexpr int dma_channel = 1;
  static constexpr int spi_sclk = 18;
  static constexpr int spi_mosi = 23;
  static constexpr int spi_miso = 19;
  static constexpr int spi_dlen = 8;
};

static lgfx::LGFX_SPI<LGFX_Config> lcd;
static lgfx::Panel_ILI9488 panel;
static lgfx::Touch_XPT2046 touch;

void panel_d32pro_config(){
  panel.freq_write = 20000000;
  panel.freq_fill  = 27000000;
  panel.freq_read  = 16000000;
  panel.spi_mode = 0;
  panel.spi_mode_read = 0;
  panel.len_dummy_read_pixel = 8;
  panel.spi_read = true;
  panel.spi_3wire = false;
  panel.spi_cs = 14;
  panel.spi_dc = 27;
  panel.gpio_rst = 33;
  panel.gpio_bl  = 32;
  panel.pwm_ch_bl = 7;
  panel.backlight_level = true;
  panel.invert = false;
  panel.rgb_order = false;
  panel.memory_width  = 320;//320;
  panel.memory_height = 480;//240;
  panel.panel_width  = 320;//320;
  panel.panel_height = 480;//240;
  panel.offset_x = 0;
  panel.offset_y = 0;
  panel.rotation = 3;
  panel.offset_rotation = 0;  
}

void panel_devkit_config(){
  panel.freq_write = 20000000;
  panel.freq_fill  = 27000000;
  panel.freq_read  = 16000000;
  panel.spi_mode = 0;
  panel.spi_mode_read = 0;
  panel.len_dummy_read_pixel = 8;
  panel.spi_read = true;
  panel.spi_3wire = false;
  panel.spi_cs = 15;
  panel.gpio_rst = 2;
  panel.spi_dc = 4;
  panel.gpio_bl  = 5;
  panel.pwm_ch_bl = 7;
  panel.backlight_level = true;
  panel.invert = false;
  panel.rgb_order = false;
  panel.memory_width  = 320;//320;
  panel.memory_height = 480;//240;
  panel.panel_width  = 320;//320;
  panel.panel_height = 480;//240;
  panel.offset_x = 0;
  panel.offset_y = 0;
  panel.rotation = 3;
  panel.offset_rotation = 0;  
}

void touch_config(){
  touch.spi_host = VSPI_HOST;  // VSPI_HOST or HSPI_HOST
  touch.spi_sclk = 18;
  touch.spi_mosi = 23;
  touch.spi_miso = 19;
  touch.spi_cs   = 27;
  touch.freq = 1000000;
  touch.bus_shared = true;  // If the LCD and touch share SPI, set to true.

  touch.x_min = 470; //0;
  touch.x_max = 3740; //319;
  touch.y_min = 3850;//0;
  touch.y_max = 447; //319;  
}

void setup(void)
{
  Serial.begin(115200);
  
//  panel_d32pro_config();   // D32Pro + TFT3.5 Touch
  panel_devkit_config();     // DOIT Devkit V1.0  + TFT3.5 Touch
  lcd.setPanel(&panel);
  touch_config();
  lcd.setTouch(&touch);

  lcd.init();

  if (lcd.width() > 240 || lcd.height() > 240) lcd.setTextSize(2);

  if (lcd.touch())
  {
    if (lcd.width() < lcd.height()) lcd.setRotation(3 & (lcd.getRotation() + 1));
    lcd.drawString("touch the arrow marker.", 0, lcd.height()>>1);
    lcd.calibrateTouch(nullptr, 0xFFFFFFU, 0x000000U, 30);
    lcd.clear();
  }
}

uint32_t count = ~0;
void loop(void)
{
  delay(10);
  lcd.startWrite();
  lcd.setRotation(++count & 7);
  lcd.setColorDepth((count & 8) ? 16 : 24);

  lcd.setTextColor(random(65536));
  lcd.drawNumber(lcd.getRotation(), 16, 0);

  lcd.setTextColor(0xFF0000U);
  lcd.drawString("R", 30, 16);
  lcd.setTextColor(0x00FF00U);
  lcd.drawString("G", 40, 16);
  lcd.setTextColor(0x0000FFU);
  lcd.drawString("B", 50, 16);

  lcd.drawRect(30,30,lcd.width()-60,lcd.height()-60,random(65536));

  lcd.endWrite();

  int32_t x, y;
  if (lcd.getTouch(&x, &y)) {
    Serial.printf("x,y = %d, %d\n", x,y);
    lcd.fillRect(x-2, y-2, 5, 5, random(65536));
  }
}

How to fix the issue?

Thank you very much.

Object oriented programming crashes my M5StickC Plus

Hi @lovyan03,

Sorry to bother you, but I can't figure out what's going on?

I'm trying to run simple code on an M5StickC Plus, but the ESP32 reacts strangely.

If it helps, I work with Visual Studio Code and PlatformIO on macOS 10.14.6:

  • VSCode v1.52.1
  • PIO Core v5.0.4
  • PIO Home v3.3.1
  • Espressif 32 v2.1.0

Here is the configuration file of my project :

; platformio.ini

[env:stick+]
platform   = espressif32
board      = m5stick-c
framework  = arduino
lib_deps   =
    m5stack/M5StickCPlus @ ^0.0.1
    lovyan03/LovyanGFX @ ^0.3.4

Here is the tree structure of my dummy project:

dummy
├── platformio.ini
└── src
    └── main.cpp

And here is my initial code:

// main.cpp

#include <M5StickCPlus.h>
#include <LovyanGFX.h>

LGFX lcd;
LGFX_Sprite fb(&lcd);

void setup() {
    M5.begin(false, true, false);
    lcd.init();
    lcd.setColorDepth(16);
    fb.createSprite(135, 240);
    
}

void loop() {
    M5.update();
    fb.clear(0xfe40);
    fb.pushSprite(0, 0);
}

Well... so far so good, I'm getting an orange screen on my stick.

Now I want to deport the content of my loop() in a GraphicsEngine class :

dummy
├── lib
│   └── GraphicsEngine
│       └── GraphicsEngine.h
├── platformio.ini
└── src
    └── main.cpp

So here is the new version of the code :

// main.cpp

#include <M5StickCPlus.h>
#include <LovyanGFX.h>
#include "GraphicsEngine.h"

LGFX lcd;
LGFX_Sprite fb(&lcd);

GraphicsEngine ge;

void setup() {
    M5.begin(false, true, false);
    lcd.init();
    lcd.setColorDepth(16);
    fb.createSprite(135, 240);
}

void loop() {
    M5.update();
    ge.draw(fb);
}
// lib/GraphicsEngine/GraphicsEngine.h

#pragma once

#include <LovyanGFX.h>

class GraphicsEngine {

    public:

        void draw(LGFX_Sprite &fb) {
            fb.clear(0xfe40);
            fb.pushSprite(0, 0);
        }
};

Everything functions normally, as before.

Now I want to separate the declarative part from the implementation of the class:

dummy
├── lib
│   └── GraphicsEngine
│       ├── GraphicsEngine.cpp
│       └── GraphicsEngine.h
├── platformio.ini
└── src
    └── main.cpp

And here's the new code (main.cpp does not change):

// lib/GraphicsEngine/GraphicsEngine.h

#pragma once

#include <LovyanGFX.h>

class GraphicsEngine {

    public:

        void draw(LGFX_Sprite &fb);

};
// lib/GraphicsEngine/GraphicsEngine.cpp

#include "GraphicsEngine.h"

void GraphicsEngine::draw(LGFX_Sprite &fb) {

    fb.clear(0xfe40);
    fb.pushSprite(0, 0);

}

And that's when it all goes to hell!
Black screen... and the stick restarts continuously.

Here are the crash logs if it can help you:

ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 188777542, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:8896
load:0x40080400,len:5828
entry 0x400806ac
Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC      : 0x400d7f6c  PS      : 0x00060330  A0      : 0x800d3db6  A1      : 0x3ffb1f00  
A2      : 0x400d268c  A3      : 0x3ffc01b8  A4      : 0x000d268c  A5      : 0x0000268c  
A6      : 0x00000000  A7      : 0x00000001  A8      : 0x00000000  A9      : 0x3ffb1ee0  
A10     : 0x3ffc01b8  A11     : 0x00010000  A12     : 0x00000000  A13     : 0x0000ffff  
A14     : 0x000000f0  A15     : 0x00000012  SAR     : 0x00000007  EXCCAUSE: 0x0000001c  
EXCVADDR: 0x00000078  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0x00000000  

Backtrace: 0x400d7f6c:0x3ffb1f00 0x400d3db3:0x3ffb1f90 0x400dab8d:0x3ffb1fb0 0x40088c99:0x3ffb1fd0

Rebooting...

There's probably something I'm missing, but I don't see what!

I seem to remember that I didn't encounter this kind of problem some time ago, when I was using version 0.2.4 of LovyanGFX...

Has something happened in the meantime that makes this way of structuring my code not work anymore?

Flipmode

Hello, is there a way to easily flip the display, something like a mirror mode?
Thank you

error: no matching function for call to 'max(int, long int)'

I got below error for Wio Terminal.

.pio\libdeps\seeed_wio_terminal\LovyanGFX\src\lgfx\panel\Panel_IT8951.cpp:411:82: error: no matching function for call to 'max(int, long int)'
                 pixel = std::min(15, std::max(0, pixel + btbl[(x + prev_pos) & 3]) >> 6);
                                                                                  ^

image

Idea: MultiSprite

Hello, I have created a "MultiSprite" concept, based on the examples of the library.

Basically, it manage the case where you don't have memory enough to store a sprite, and you have to split in "bands".

class MultiSprite
{
public:
	MultiSprite()
	{

	}

	void Init(LGFX* lcd, std::int_fast8_t div = 1)
	{
		_lcd = lcd;
		lcd_width = _lcd->width();
		lcd_height = _lcd->height();

		for (;;) {
			sprite_height = (lcd_height + div - 1) / div;
			bool fail = false;
			for (std::uint32_t i = 0; !fail && i < 2; ++i)
			{
				sprite[i].setColorDepth(lcd->getColorDepth());
				fail = !sprite[i].createSprite(lcd_width, sprite_height);
			}
			if (!fail) break;
			for (std::uint32_t i = 0; i < 2; ++i)
			{
				sprite[i].deleteSprite();
			}
			div *= 2;
		}
		_div = div;
	}

	LGFX* _lcd;

	uint32_t _div;
	uint16_t currentStrip = 0;

	std::int_fast16_t lcd_width;
	std::int_fast16_t lcd_height;

	MultiSpriteStrip sprite[2];
	int_fast16_t sprite_height;

	void startWrite() {_lcd->startWrite();};
	void endWrite() {_lcd->endWrite();};
	void display() {_lcd->display();};

	void Render(void (*render)(MultiSpriteStrip&, uint8_t))
	{
		currentStrip = 0;
		for (std::int32_t y = 0; y < lcd_height; y += sprite_height)
		{
			auto index = currentStrip % 2;
			sprite[index].lowerY = y;
			sprite[index].upperY = y + sprite_height;

			render(sprite[index], currentStrip);

			std::uint32_t len = sprite_height * lcd_width;
			if (y + sprite_height > lcd_height) {
				len = (lcd_height - y) * lcd_width;
			}
			_lcd->pushPixelsDMA(sprite[index].getBuffer(), len);
			currentStrip++;
		}
	}
};

No conversion between global (full screen) and local (sprite band) is required
This way, for example, the "moving circle" demo is as easy as

void draw(MultiSpriteStrip& sprite, uint8_t spriteNum)
{
	sprite.clear();

	for (std::uint32_t i = 0; i < obj_count; i++)
	{
		sprite.drawCircle(circles[i].x, circles[i].y, circles[i].r, circles[i].color);
	}

	if (spriteNum >= 3) drawFps(sprite);
}

void loop(void)
{
	fpsCounter.Update(millis());

	for (std::uint32_t i = 0; i != obj_count; i++)
	{
		circles[i].move();
	}

	multiSprite.Render(draw);
}

Please, let me know if you find it interesting, and if there is anything more that i can do for helping (share the code, fork, PR,...)

Thank you for you great work

How to config for TTGO T-Display (ST7789)

I wish to use TTGO T-Display 1.3inch (ST7789 240x135) on LovyaGFX library.

image

If TTGO T-Display config by TFT-eSPI, it's configed by the following.

https://github.com/Xinyuan-LilyGO/TTGO-T-Display/blob/master/TFT_eSPI/User_Setups/Setup25_TTGO_T_Display.h

#define ST7789_DRIVER

#define TFT_WIDTH  135
#define TFT_HEIGHT 240

#define CGRAM_OFFSET      // Library will add offsets required

//#define TFT_MISO -1

#define TFT_MOSI            19
#define TFT_SCLK            18
#define TFT_CS              5
#define TFT_DC              16
#define TFT_RST             23

#define TFT_BL          4  // Display backlight control pin

#define TFT_BACKLIGHT_ON HIGH  // HIGH or LOW are options

#define LOAD_GLCD
#define LOAD_FONT2
#define LOAD_FONT4
#define LOAD_FONT6
#define LOAD_FONT7
#define LOAD_FONT8
#define LOAD_GFXFF

#define SMOOTH_FONT

//#define SPI_FREQUENCY  27000000
  #define SPI_FREQUENCY  40000000   // Maximum for ILI9341


#define SPI_READ_FREQUENCY  6000000 // 6 MHz is the maximum SPI read speed for the ST7789V

When I config on LovyanGFX by the following code , it occurs some error , how to fix it ?
Thank you.

#include <LovyanGFX.hpp>


struct LGFX_Config
{
  static constexpr spi_host_device_t spi_host = VSPI_HOST;
  static constexpr int dma_channel = 1;
  static constexpr int spi_miso = 19;
  static constexpr int spi_sclk = 18;
  static constexpr int spi_mosi = -1;
  static constexpr int spi_dlen = 8;
};


static lgfx::LGFX_SPI<LGFX_Config> lcd;
static lgfx::Panel_ST7789 panel;


void setup(void)
{

//  panel.freq_write = 20000000;
  panel.freq_fill   = 40000000; //27000000;
  panel.freq_read   = 6000000;//16000000;
  panel.spi_mode    = 0;
  panel.spi_mode_read         = 0;
  panel.len_dummy_read_pixel  = 8;
  panel.spi_read    = true;
  panel.spi_3wire   = false;

  panel.spi_cs      = 5;
  panel.spi_dc      = 16;
  panel.gpio_rst    = 23;//-1;//33;

  panel.gpio_bl     = 4;//32;

  panel.pwm_ch_bl   = 7;
  panel.backlight_level = true;
  panel.reverse_invert = false;
  panel.rgb_order = false;
  
  panel.memory_width  = 240; //320;
  panel.memory_height = 135; //240;
  panel.panel_width   = 240; //320;
  panel.panel_height  = 135; //240;

  panel.offset_x = 0;
  panel.offset_y = 0;

  panel.rotation = 0;
  panel.offset_rotation = 0;

  lcd.setPanel(&panel);
  lcd.init();
}

uint32_t count = ~0;
void loop(void)
{
  delay(10);
  lcd.startWrite();
  lcd.setRotation(++count & 7);
  lcd.setColorDepth((count & 8) ? 16 : 24);

  lcd.setTextColor(random(65536));
  lcd.drawNumber(lcd.getRotation(), 16, 0);

  lcd.setTextColor(0xFF0000U);
  lcd.drawString("R", 30, 16);
  lcd.setTextColor(0x00FF00U);
  lcd.drawString("G", 40, 16);
  lcd.setTextColor(0x0000FFU);
  lcd.drawString("B", 50, 16);

  lcd.drawRect(30,30,lcd.width()-60,lcd.height()-60,random(65536));

  lcd.endWrite();

  int32_t x, y;
  if (lcd.getTouch(&x, &y)) {
    lcd.fillRect(x-2, y-2, 5, 5, random(65536));
  }
}

Some error on serial monitor...

rst:0x1 (POWERON_RESET),boot:0x1b (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:10944
load:0x40080400,len:6388
entry 0x400806b4

Confirming the pin setup

Hi So i just want to confirm how to do the pin config for the lib. I do have a ST7789 lcd and i see in you config : Lgfx-config-esp-Wrover-kit.hpp this :

static lgfx::Panel_ST7789 panel;
panel.spi_3wire = false;
panel.spi_cs = 22;
panel.spi_dc = 21;
panel.gpio_rst = 18;
panel.gpio_bl = 5;
panel.pwm_ch_bl = 7;

So is this the pin connected from the esp32 to the lcd ? As GPIO 22/21/18/5 .. but for 7 : is it Gpio 26 ? Fow the wrover esp32 normal 30pin version, not the 36pin.
And i think loading the tft-graphictest.ino will load the LovyanGFX.hpp and this call to the Lgfx-config...
And is there a way to force to lcd st7789 or it goes only with an autodetect ?
Thank again

Implementing an image processing filter

I would like to change the brightness of an image before pushing it to the LCD.

What would be the best way of accomplishing this? It would be nice if the library would support a lambda style processing.

here my pseudo code:

auto brightness_up = [](uint8_t r, uint8_t g, uint8_t b) ->  return {min(255, r + 10), min(255, g + 10), min(255, b + 10)}
sprite.pushSprite(lcd, brightness_up);

For now: What is the easiest way to implement such processing?

How to config for TFT 1.3inch ST7789

Hi,

I have tried to config for TFT1.3inch ST7789
by the following code

#include <LovyanGFX.hpp>

struct LGFX_Config
{
  static constexpr spi_host_device_t spi_host = VSPI_HOST;
  static constexpr int dma_channel  = 1;
  static constexpr int spi_miso     = -1; //19;
  static constexpr int spi_sclk     = 18;
  static constexpr int spi_mosi     = 23;
  static constexpr int spi_dlen     = 8;
};


static lgfx::LGFX_SPI<LGFX_Config> lcd;
static lgfx::Panel_ST7789 panel;


void setup(void)
{
  panel.freq_write            = 20000000;
  panel.freq_fill             = 27000000;
  panel.freq_read             = 16000000;
  panel.spi_mode              = 0;
  panel.spi_mode_read         = 0;
  panel.len_dummy_read_pixel  = 8;
  panel.spi_read              = true;
  panel.spi_3wire             = true; //false;

  panel.spi_cs                = -1;
  panel.spi_dc                = 4;
  panel.gpio_rst              = 2;
  panel.gpio_bl               = 5;

  panel.pwm_ch_bl             = 7;
  panel.backlight_level       = true;
  panel.reverse_invert        = false;
  panel.rgb_order             = false;
  
  panel.memory_width          = 240;
  panel.memory_height         = 240;
  panel.panel_width           = 240;
  panel.panel_height          = 240;

  panel.offset_x              = 0;
  panel.offset_y              = 0;

  panel.rotation              = 0;
  panel.offset_rotation       = 0;

  lcd.setPanel(&panel);
  lcd.init();
}

uint32_t count = ~0;
void loop(void)
{
  delay(10);
  lcd.startWrite();
  lcd.setRotation(++count & 7);
  lcd.setColorDepth((count & 8) ? 16 : 24);

  lcd.setTextColor(random(65536));
  lcd.drawNumber(lcd.getRotation(), 16, 0);

  lcd.setTextColor(0xFF0000U);
  lcd.drawString("R", 30, 16);
  lcd.setTextColor(0x00FF00U);
  lcd.drawString("G", 40, 16);
  lcd.setTextColor(0x0000FFU);
  lcd.drawString("B", 50, 16);

  lcd.drawRect(30,30,lcd.width()-60,lcd.height()-60,random(65536));

  lcd.endWrite();
}

But by the code , it can't display anything.

When I tried on TFT_eSPI as the same pins-config.

#define ST7789_DRIVER
#define TFT_WIDTH  240
#define TFT_HEIGHT 240

#define TFT_MISO -1   //19
#define TFT_MOSI 23
#define TFT_SCLK 18
#define TFT_CS     -1
#define TFT_DC      4 
#define TFT_RST    2 
#define TFT_BL       5

TFT can display.
How to solve the issue?
Thank you.

Incorrect character alignment at drawChar

Those characters are not aligned correctly.

canvas.setTextFont( &fonts::FreeMonoBold18pt7b );
canvas.setTextDatum( textdatum_t::top_left );
canvas.drawChar( '0', 50, 2 );
canvas.setTextFont( &fonts::Font4 );
canvas.drawChar( '0', 70, 2 );

Not working on TWatch 2020 V1

If I use the library on a TWatch 2020 I get no picture or other reaction from the screen.
It does work with the TTGO drivers, so the HW works.

I get this response on boot:

[W][LGFX_Config_AutoDetectESP32.hpp:288] autodetect(): [Autodetect] load from NVS : board:7
[E][esp32-hal-cpu.c:93] addApbChangeCallback(): duplicate func=400DA2A4 arg=3FFBDD74
[W][LGFX_Config_AutoDetectESP32.hpp:306] autodetect(): [Autodetect] panel id:00528585
[W][LGFX_Config_AutoDetectESP32.hpp:308] autodetect(): [Autodetect] TWatch
[E][esp32-hal-cpu.c:115] removeApbChangeCallback(): not found func=400DA2A4 arg=3FFBDD74
[E][esp32-hal-cpu.c:93] addApbChangeCallback(): duplicate func=400DA2A4 arg=3FFBDD74

Anybody else got this issue or am I the only one?

Using multiple displays on the same SPI bus - only one display works.

I am using two displays (part of the cheApR project) and i have chosen to save some GPIO pins for other use by wiring the displays in series, but with different CS pins. I tested the wiring by running a simple sketch using tft_eSPI and the displays work independently, with each display updating properly when its CS pin is pulled LOW.

When I use Lovyan, however, only the display with CS pin of 5 works, the display with CS pin of 25 does not. If I switch the CS pins (left uses 5 and right uses 25, then switch so left uses 25 and right uses 5) the display with CS pin of 5 always works.

This is the file that sets up the displays:

//  LovyanGFX by Lovyan03
//  https://github.com/lovyan03/LovyanGFX
//  https://github.com/lovyan03/ESP32_ScreenShotReceiver Better version than my cheApR_UI, give it a try

#include <LovyanGFX.hpp>
#include "src/TCPReceiverdual.h"

/////////////////////////////////////////////////////////////////
//DISPLAY SETUP

struct LGFX_DisplayA
{
  static constexpr spi_host_device_t spi_host = HSPI_HOST;
  static constexpr int dma_channel = 1;
  static constexpr int spi_sclk = 18;   //SCL_PIN
  static constexpr int spi_mosi = 23;    //SDA_PIN
  static constexpr int spi_miso = -1;   //NOT NEEDED
  static constexpr int spi_dlen = 8;
};

struct LGFX_DisplayB
{
  static constexpr spi_host_device_t spi_host = VSPI_HOST;
  static constexpr int dma_channel = 2;
  static constexpr int spi_sclk = 18;   //SCL_PIN
  static constexpr int spi_mosi = 23;   //SDA_PIN
  static constexpr int spi_miso = -1;   //NOT NEEDED
  static constexpr int spi_dlen = 8;
};

//
//
static LGFX_Sprite sprite[10];
static std::uint32_t count = 0;
static float zoom = 0;

static lgfx::LGFX_SPI<LGFX_DisplayA> lcd;  //display LEFT = LCD
static lgfx::LGFX_SPI<LGFX_DisplayB> lcdB; //display LEFT = LCD

static lgfx::Panel_ST7789 panel;
static lgfx::Panel_ST7789 panelB;

static TCPReceiver recv;
static TCPReceiver recvB;

/////////////////////////////////////////////////////////////////

void displaySetup() {
  //SETTING RIGHT PANEL
  panel.freq_write = 40000000;
  panel.freq_fill = 40000000;
  panel.freq_read = 6000000;
  panel.spi_mode = 3;
  panel.spi_mode_read = 0;
  panel.len_dummy_read_pixel = 8;
  panel.spi_read = false;
  panel.spi_3wire = false;
  panel.spi_cs = 5;   //CS PIN
  panel.spi_dc = 17;   //DC PIN
  panel.gpio_rst = 4;  //RST PIN
  panel.gpio_bl = 27; //BL PIN
  panel.pwm_ch_bl = 7;
  panel.backlight_level = false;
  panel.invert = true;
  panel.rgb_order = false;
  //  panel.memory_width  = 240;
  //  panel.memory_height = 240;
  //  panel.panel_width = 240;
  panel.panel_height = 240; //SET THIS WITH YOUR DISPLAY HEIGHT
  lcd.setPanel(&panel);//STARTING RIGHT PANEL

  //SETTING LEFT PANEL
  panelB.freq_write = 40000000;
  panelB.freq_fill = 40000000;
  panelB.freq_read = 6000000;
  panelB.spi_mode = 3;
  panelB.spi_mode_read = 0;
  panelB.len_dummy_read_pixel = 8;
  panelB.spi_read = false;
  panelB.spi_3wire = false;
  panelB.spi_cs = 25;   //CS PIN
  panelB.spi_dc = 17;   //DC_PIN
  panelB.gpio_rst = 4;   //RST_PIN
  panelB.gpio_bl = 27;    //BL_PIN
  panelB.pwm_ch_bl = 7;
  panelB.backlight_level = false;
  panelB.invert = true;
  panelB.rgb_order = false;
  //  panelB.memory_width  = 240;
  //  panelB.memory_height = 240;
  //  panelB.panel_width = 240;
  panelB.panel_height = 240; //SET THIS WITH YOUR DISPLAY HEIGHT
  lcdB.setPanel(&panelB); //STARTING RIGHT PANEL

  lcd.init();
  lcdB.init();

  //SET ROTATION OF DISPLAYS
  lcd.setRotation(1);
  lcdB.setRotation(3);

  //  MIRROR MODE
  //    lcd.setRotation(5);
  //    lcdB.setRotation(7);

  lcd.setTextColor(0x000000U, 0xFFFFFFU);
  lcdB.setTextColor(0x000000U, 0xFFFFFFU);


  // DISPLAY QUICK TEST LOOP
  //  while (1) {
  //    displayBatt();
  //    displayUptime();
  //    loopImg();
  //  }

  for ( int i = 0; i < 240; i++) {
    lcd.drawRect(0, i, lcd.width(), lcd.height(), 0xFF0000U);
    lcdB.drawRect(0, i, lcdB.width(), lcdB.height(), 0xFF0000U);
    delay(2);
  }

  for ( int i = 0; i < 240; i++) {
    lcd.drawRect(i, 0, lcd.width(), lcd.height(), 0xFFFFFFU);
    lcdB.drawRect(i, 0, lcdB.width(), lcdB.height(), 0xFFFFFFU);
    delay(2);
  }

  lcd.setFont(&fonts::Font2); lcdB.setFont(&fonts::Font2);
  lcd.setCursor(40, 110); lcd.print("CONNECTING TO WIFI");
  lcdB.setCursor(40, 110); lcdB.print("WAITING FOR IP");
}

Deprecated warning when compiling with ESP-IDF 4.x.

The following warning occurs when compiling with ESP-IDF 4.x.

In file included from .pio/libdeps/m5paper-test/LovyanGFX/src/utility/miniz.c:959:
.pio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp32/include/esp_spiram.h:1:2: warning: #warning esp_spiram.h has been replaced by esp32/spiram.h, please include esp32/spiram.h instead [-Wcpp]
 #warning esp_spiram.h has been replaced by esp32/spiram.h, please include esp32/spiram.h instead

This is because #include "esp_spiram.h" was deprecated in ESP-IDF 4.0.
I'll create a PR to fix this issue.

pushRotateZoom() / Is it a specification,my mistake or bug?

M5Stack gray, Arduino, LovyanGFX 0.2.7

pushRotateZoom()
想定範囲を超えて描画が行われているように見えますが、仕様でしょうか?
または私の使い方に誤りがありますか?
It appears to be out of the expected range.
Is it a specification,my mistake or bug?

大きさは問題なく描画位置が zoom/2 pixelずれている気がしますが...。

pushotateZoom

#include <M5Stack.h>
#include <LovyanGFX.hpp>

static LGFX lcd;
static LGFX_Sprite sprite(&lcd);

#define SW (18)
#define SH (18)

void setup()
{
    M5.begin(false /* LCD*/, true /* SD*/ , true /*Serial*/);

    lcd.init();
    lcd.setRotation(1);
    lcd.setBrightness(32);
    
    sprite.createSprite(SW,SH);

    float z = 1.0f;

    sprite.fillScreen(TFT_DARKGREEN);
    sprite.setPivot(0,0);
    for(int i=0; i<4; i++, z+=1.0f)
    {
	sprite.pushRotateZoom(i * sprite.width(), 32, 0, 1.0f, z);
	sprite.pushRotateZoom(180, 32 + i * sprite.height(), 0, z, 1.0f);
    }
    lcd.drawLine(0,32,SW*5,32,TFT_RED);
    lcd.drawLine(180,32, 180, 32+SH*5, TFT_BLUE);

    z = 1.0f;
    sprite.fillScreen(TFT_YELLOW);
    sprite.setPivot(SW/2,SH/2); // center
    for(int i=0; i<4; i++, z+=1.0f)
    {
	sprite.pushRotateZoom(i * sprite.width() + SW/2, 180, 0 ,1.0f, z);
	sprite.pushRotateZoom(216, 144 + i * sprite.height() + SH/2, 0, z, 1.0f);
    }

    for(int i = 0; i < 5; ++i)
    {
	lcd.drawLine(0,180 - i*SH/2, 100, 180 - i*SH/2, TFT_RED);
	lcd.drawLine(0,180 + i*SH/2, 100, 180 + i*SH/2, TFT_RED);
	lcd.drawLine(216 - i*SW/2 ,144,216 - i*SW/2, 240, TFT_BLUE);
	lcd.drawLine(216 + i*SW/2 ,144,216 + i*SW/2, 240, TFT_BLUE);
    }
    lcd.drawLine(0,180,100,180, TFT_RED);
    lcd.drawLine(216,144,216,240, TFT_BLUE);
}


void loop()
{
    delay(1);
}

Does not seem to work on Core2 when co-existing with M5Core2 library ?

On my Core2, with the master branches of LovyanGFX and m5core2, if I try this:

#include <M5Core2.h>
#define LGFX_M5STACK_CORE2
#include <LovyanGFX.hpp>

static LGFX scr;

void setup() {
  M5.begin(false);
  scr.fillCircle(160, 120, 100, TFT_RED); 
}

void loop() {
}

I get a boot loop with this:

PC: 0x400d3bf8: lgfx::LGFX_SPI ::begin_transaction() at /Users/rop/code/Arduino/libraries/LovyanGFX/src/lgfx/platforms/LGFX_SPI_ESP32.hpp line 233
EXCVADDR: 0x00000008

Decoding stack results
0x400d3bf8: lgfx::LGFX_SPI ::begin_transaction() at /Users/rop/code/Arduino/libraries/LovyanGFX/src/lgfx/platforms/LGFX_SPI_ESP32.hpp line 233
0x400d3cf5: lgfx::LGFX_SPI ::beginTransaction_impl() at /Users/rop/code/Arduino/libraries/LovyanGFX/src/lgfx/platforms/LGFX_SPI_ESP32.hpp line 225
0x400db473: lgfx::LGFXBase::fillCircle(int, int, int) at /Users/rop/code/Arduino/libraries/LovyanGFX/src/lgfx/LGFXBase.hpp line 167
0x400d2ff1: setup() at /Users/rop/code/Arduino/libraries/LovyanGFX/src/lgfx/LGFXBase.hpp line 95
0x400df00b: loopTask(void*) at /Users/rop/Library/Arduino15/packages/m5stack/hardware/esp32/1.0.5/cores/esp32/main.cpp line 14
0x4008b619: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143

 

#include <M5Core2.h>

void setup() {
  M5.begin();
  M5.Lcd.fillCircle(160, 120, 100, TFT_RED); 
}

void loop() {
}

works as expected

please add support for the ILI9481 display if possible

Hi Lovyan, first of all, thank you for your great work on making this library. Was using the TFT_eSPI from Bodmer, thanks to him as well of course, but yours seems a bit faster and I love your analog gauge. Today I received my ILI9481 IPS displays and wonder if you could add that driver to your library. The display is a 3.5" 480x320 pixel with the FT6236 capacitive touchscreen controller, which you library supports as well, and has the ILI9481 driver chip as opposed to the ILI9488 which my Makerfabs display uses. Btw, Bodmer's library does support the ILI9481 and I tried to add it to your library but the configuration files are quite different. I am of course happy to test and give feedback. The reason why I did go with the ILI9481 is that the display is IPS and fully sunlight readable which I need for my project. Thank you very much in advance and if there is anything I can do to help. please let me know.
Happy New Year.

[Feature request] Add FontStyle getter/setter

basically the ability to achieve things like this:

// setup font style in a sprite
sprite.setFont( &myFont );
sprite.setTextSize(1);
sprite.setTextColor( fgcolor, bgcolor );
sprite.setTextDatum( MC_DATUM );

// then later

display1.getFontStyle( sprite.getFontStyle() );

using some wrapper where font + textstyle are available

struct FontStyle 
{ 
  TextStyle _style;
  IFont _font;
};

How to display image with ESP32 3.5" TFT touch(capacitive) board

Hello @lovyan03,
I have ESP32 3.5" TFT touch(capacitive) board and I want to push the image from the camera with CAMERA_PIXEL_FORMAT -> PIXFORMAT_GRAYSCALE however, I got the result below.
image

    if (img == nullptr || img == 0) 
    {
        Serial.printf("snap fail\n");
        return;
    }

    tft.pushImage(0, 0, 96, 96, (lgfx::swap565_t*)img->buf); 
}

How do I display a grayscale image on the TFT screen?
For more details check the repo - Link

sprite.setPsram(true) + sprite.setColorDepth(16)

  • Observed on M5Core2 and Wrover-Kit (ILI9341)
  • Using this for creating a 320x240 sprite:
    static LGFX_Sprite sprite = LGFX_Sprite( &tft );

these work:

    sprite.setColorDepth( 8 );
    sprite.setPsram( true );
    sprite.setColorDepth( 24 );
    sprite.setPsram( true );

image

however these do not seem to produce a valid result

    sprite.setColorDepth( tft.getColorDepth() );
    sprite.setPsram( true );
    sprite.setColorDepth( 16 );
    sprite.setPsram( true );

image

Is that a limitation of the display ?

[E][lgfx_base.hpp:2495] draw_jpg(): jpeg prepare error:3

None of my jpeg would work, only this error was thrown jpeg prepare error:3 which means Insufficient memory pool for the image.

This is the function:

    void draw_jpg(DataWrapper* data, int16_t x, int16_t y, int16_t maxWidth, int16_t maxHeight, int16_t offX, int16_t offY, jpeg_div_t scale)
    {
      draw_jpg_info_t jpeg;
      pixelcopy_t pc(nullptr, this->getColorDepth(), bgr888_t::depth, this->hasPalette());
      jpeg.pc = &pc;
      jpeg.tft = this;
      jpeg.data = data;
      jpeg.x = x - offX;
      jpeg.y = y - offY;
      jpeg.scale = scale;

      TJpgD jpegdec;

      const uint16_t sz_pool = 2500;
      uint8_t pool[sz_pool];
     
      // ( ... )
    }

I found two problems with this part of the code:

      const uint16_t sz_pool = 2500;
      uint8_t pool[sz_pool];
  1. pool allocation fails when performed from inside the function
  2. sz_pool value isn't high enough

Moving the two declarations outside the function and raising the value fixed it for me.

    #define sz_pool 4096
    uint8_t pool[sz_pool];

    void draw_jpg(DataWrapper* data, int16_t x, int16_t y, int16_t maxWidth, int16_t maxHeight, int16_t offX, int16_t offY, jpeg_div_t scale)
    {
      // (...)
    }

This quick workaround may not be the best solution though, it wastes 4Kb of ram for nothing when this jpeg function isn't used.

I haven't tested images bigger than 32x32 yet, the value 4096 may need to be higher with bigger images.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.