lvgl / lvgl_esp32_drivers

Drivers for ESP32 to be used with LVGL
MIT License
305 stars 272 forks source link

ILI9341 Display mirrored #234

Closed dpwlt closed 5 months ago

dpwlt commented 6 months ago

HW: ESP32-2432S028R Touch: XPT2046 TFT: ILI9341

I've managed to build and flash the LVGL demo to the device but the display is mirrored, text is backwards. The touch works correctly and the touch is shown on the correct part of the interface even though the actual touch is on the opposite side of the display.

I've attempted to find the cause of the issue and it appears that there is a setting for ML (Vertical refresh bit) which can be set. The command is in the data sheet of ILI9341: 8.2.29. Memory Access Control (36h). I am unsure how to set this in the config. Could you help please?

image

image

littleboot commented 5 months ago

what IDF version are you using? it look like it has something to do with the MADCTL (rotation register) of the driver.

https://forum.lvgl.io/t/why-are-text-and-widgets-mirrored/13453 (Something todo with MADCTL settings) https://github.com/Bodmer/TFT_eSPI/issues/96

I'm using the exact same hardware, with the same issue have not manged to implement a fix yet. if you manged to get it to work could you share your project?

littleboot commented 5 months ago

Oke I found it, display looks oke now. changed the MADCTL to: 0x68

in managed_components\espressif__esp_lcd_ili9341\esp_lcd_ili9341.c

from:

/* Memory access contorl, MX=MY=0, MV=1, ML=0, BGR=1, MH=0 */
{LCD_CMD_MADCTL, {(LCD_CMD_MV_BIT | 0x08)}, 1},

to

/* Memory access contorl, MX=MY=0, MV=1, ML=0, BGR=1, MH=0 */
{LCD_CMD_MADCTL, {(0x68)}, 1},

How? I just brute forced the problem: I knew this was the register causing the issue so I just started changing the value: 0x18 0x28 0x38 0x48 ect until the display looked correct.

PS I used this project for testing: https://github.com/limpens/esp32-2432S028 using idf5.1 to compile it

dpwlt commented 5 months ago

@littleboot - Thank you so much for your reply. With a bit of messing I've got it working now!

I'm using IDF4.4, I had issues with 5 and will be doing a clean install at some point to understand them. Meantime I have managed to sort the issue by following your method.

I changed a value in the ili9341_set_orientation function in lvgl_esp32_drivers\lvgl_tft\ili9341.c

from: #elif defined (CONFIG_LVGL_PREDEFINED_DISPLAY_NONE) uint8_t data[] = {0x48, 0x88, 0x28, 0xE8};

To: #elif defined (CONFIG_LVGL_PREDEFINED_DISPLAY_NONE) uint8_t data[] = {0xC8, 0x88, 0x28, 0xE8};

The project used for testing was 'Sunton-esp32-2.8-LVGL_Full_Test' which was downloaded from a google drive folder https://drive.google.com/drive/folders/1WE6-deYVILK3k2NOrxQnq73NqyO18ksO provided with the board Once again thanks for your help!

littleboot commented 5 months ago

@dpwlt Hi today I looked into the display board code again. I manged to get it all working and compile it with IDF 5.1. I think you will be interested and others looking with the same hardware and problems too, so I'm sharing it here:

I discovered someone (hiruna) already updated the lv_port_esp32, he even made a pull request no idea why it is still not accepted and merged with the official repo. He also fixed all the lvgl_esp32_drivers and updated the LVGL library version. https://github.com/hiruna/lv_port_esp32

When you clone this repo you will be able to compile it with IDF V5.1

To fix the display inversion / orientation problem and also incorrect color problem (orange color instead of blue): Change the "Memory Access Control register" definition bytes for this screen in the ili9341.c driver file. image image

use this buffer configuration: uint8_t data[] = {0x00, 0x80, 0x60, 0x20};

The color problem can be fixed by changing the BGR_RGBBGROrder bit.

I determined these bytes by reading: Datasheet ili9341 driver page 129 "8.2.29. Memory Access Control (36h)" and I added some test code to the ili9341_set_orientation function to overwrite the data buffer for testing:

    //Memory Access Control register (36h)
    uint8_t MAC_reg = 0x00; 

    //Register Bit values
    //These 3 bits control MCU to memory write/read direction.
    uint8_t MY_RowAddressOrder = 0; //D7
    uint8_t MX_ColumnAddressOrder = 1; //D6
    uint8_t MV_RowColumnExchange = 1; //D5
    //LCD vertical refresh direction control.
    uint8_t ML_VerticalRefreshOrder = 0; //D4
    //Color selector switch control (0=RGB color filter panel, 1=BGR color filter panel)
    uint8_t BGR_RGBBGROrder = 0; //D3
    //LCD horizontal refreshing direction control.
    uint8_t MH_HorizontalRefreshOrder = 0; //D2
    //D1 = Don't care
    //D0 = Don't care

    MAC_reg |= (MY_RowAddressOrder << 7);
    MAC_reg |= (MX_ColumnAddressOrder << 6);
    MAC_reg |= (MV_RowColumnExchange << 5);
    MAC_reg |= (ML_VerticalRefreshOrder << 4);
    MAC_reg |= (BGR_RGBBGROrder << 3);
    MAC_reg |= (MH_HorizontalRefreshOrder << 2);

    ESP_LOGI(TAG, "MAC_reg value: 0x%02X", MAC_reg);

    data[orientation] = MAC_reg;

You can set the orientation using the sdkconfig menu, these are my sdkconfig defaults (to use it, save it in project root as "sdkconfig.defaults" and delete the original sdkconfig file)

# This file was generated using idf.py save-defconfig. It can be edited manually.
# Espressif IoT Development Framework (ESP-IDF)  Project Minimal Configuration
#
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
CONFIG_LV_COLOR_16_SWAP=y
CONFIG_LV_MEM_SIZE_KILOBYTES=38
CONFIG_LV_USE_PERF_MONITOR=y
CONFIG_LV_FONT_MONTSERRAT_8=y
CONFIG_LV_FONT_MONTSERRAT_10=y
CONFIG_LV_FONT_MONTSERRAT_12=y
CONFIG_LV_FONT_MONTSERRAT_16=y
CONFIG_LV_FONT_MONTSERRAT_18=y
CONFIG_LV_FONT_MONTSERRAT_20=y
CONFIG_LV_FONT_MONTSERRAT_22=y
CONFIG_LV_FONT_MONTSERRAT_24=y
CONFIG_LV_FONT_MONTSERRAT_26=y
CONFIG_LV_FONT_MONTSERRAT_28=y
CONFIG_LV_FONT_MONTSERRAT_30=y
CONFIG_LV_FONT_MONTSERRAT_32=y
CONFIG_LV_LABEL_LONG_TXT_HINT=n
CONFIG_LV_USE_DEMO_WIDGETS=y
CONFIG_LV_DEMO_WIDGETS_SLIDESHOW=y
CONFIG_LV_HOR_RES_MAX=240
CONFIG_LV_VER_RES_MAX=320
CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE=y
CONFIG_LV_TFT_DISPLAY_SPI_FULL_DUPLEX=y
CONFIG_LV_TFT_USE_CUSTOM_SPI_CLK_DIVIDER=y
CONFIG_LV_DISPLAY_USE_SPI_MISO=y
CONFIG_LV_DISP_SPI_MISO=12
CONFIG_LV_DISP_USE_RST=n
CONFIG_LV_BACKLIGHT_ACTIVE_LVL=y
CONFIG_LV_DISP_PIN_BCKL=21
CONFIG_USE_LV_TOUCH_CALIBRATION=n

I attached my ili9341.c file, just for reference, changing only the data buffer definition is sufficient, you already managed to do so :P. But I hope this will explain it if you are interested. ili9341.zip

Next on my list is to make a template project for this hardware in squareline studio, if you are interested let me know I will share it if and when I get it to work.

dpwlt commented 5 months ago

@littleboot - Thanks for sharing, I'm always interested in trying to understand the why of a fix :)

I've had a bit of a play around with Squareline studio but as I was having issues with the display orientation I moved onto something else, I'll be coming back to this project once I've got my Galagino arcade build completed. I ended up buying a few of these boards so yes I'm definitely interested in seeing how this works in Squareline for the next project, the LVGL UI is very pretty compared to what I made myself.

I really appreciate you coming back to share this insight. Have a great weekend!

littleboot commented 4 months ago

@dpwlt Got it all working, forked the repositories from hiruna and added the Sunton ESP32-2432S028 board to the predefined displays. I also updated the readme with some instructions. You can find it here: https://github.com/littleboot/lv_port_esp32_squareline_studio Good luck, if you can't get it to work let me know.