Update with epdiy last version support

This commit is contained in:
martinberlin 2023-08-24 12:45:30 +02:00
parent d738aaa84f
commit 87bf29d676
56 changed files with 1844 additions and 859 deletions

View file

@ -1,16 +1,22 @@
if(ESP_PLATFORM) if(ESP_PLATFORM)
file(GLOB SOURCES *.c) file(GLOB SOURCES *.c)
set(LVGL_INCLUDE_DIRS . lvgl_tft lvgl_touch/L58/include) set(LVGL_INCLUDE_DIRS . lvgl_tft)
list(APPEND SOURCES "lvgl_tft/disp_driver.c") list(APPEND SOURCES "lvgl_tft/disp_driver.c")
list(APPEND SOURCES "lvgl_tft/esp_lcd_backlight.c")
#@todo add SimleInclude macro here
# Include only the source file of the selected # Include only the source file of the selected
# display controller. # display controller.
if(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341) if(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341)
list(APPEND SOURCES "lvgl_tft/ili9341.c") list(APPEND SOURCES "lvgl_tft/ili9341.c")
elseif(CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER) elseif(CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER)
list(APPEND SOURCES "lvgl_tft/epdiy_epaper.c") list(APPEND SOURCES "lvgl_tft/epdiy_epaper.cpp")
elseif(CONFIG_LV_EPAPER_CALEPD_DISPLAY_CONTROLLER)
list(APPEND SOURCES "lvgl_tft/calepd_epaper.cpp")
elseif(CONFIG_LV_SHARP_DISPLAY_CONTROLLER)
list(APPEND SOURCES "lvgl_tft/sharp_mip.cpp")
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481) elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481)
list(APPEND SOURCES "lvgl_tft/ili9481.c") list(APPEND SOURCES "lvgl_tft/ili9481.c")
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9486) elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9486)
@ -42,10 +48,6 @@ elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_RA8875)
list(APPEND SOURCES "lvgl_tft/ra8875.c") list(APPEND SOURCES "lvgl_tft/ra8875.c")
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_GC9A01) elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_GC9A01)
list(APPEND SOURCES "lvgl_tft/GC9A01.c") list(APPEND SOURCES "lvgl_tft/GC9A01.c")
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9163C)
list(APPEND SOURCES "lvgl_tft/ili9163c.c")
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_PCD8544)
list(APPEND SOURCES "lvgl_tft/pcd8544.c")
else() else()
message(WARNING "LVGL ESP32 drivers: Display controller not defined.") message(WARNING "LVGL ESP32 drivers: Display controller not defined.")
endif() endif()
@ -66,7 +68,6 @@ if(CONFIG_LV_TOUCH_CONTROLLER)
elseif(CONFIG_LV_TOUCH_CONTROLLER_FT6X06) elseif(CONFIG_LV_TOUCH_CONTROLLER_FT6X06)
list(APPEND SOURCES "lvgl_touch/ft6x36.c") list(APPEND SOURCES "lvgl_touch/ft6x36.c")
elseif(CONFIG_LV_TOUCH_CONTROLLER_L58) elseif(CONFIG_LV_TOUCH_CONTROLLER_L58)
list(APPEND SOURCES "lvgl_touch/L58/L58Touch.cpp")
list(APPEND SOURCES "lvgl_touch/l58.cpp") list(APPEND SOURCES "lvgl_touch/l58.cpp")
elseif(CONFIG_LV_TOUCH_CONTROLLER_STMPE610) elseif(CONFIG_LV_TOUCH_CONTROLLER_STMPE610)
list(APPEND SOURCES "lvgl_touch/stmpe610.c") list(APPEND SOURCES "lvgl_touch/stmpe610.c")
@ -76,23 +77,21 @@ if(CONFIG_LV_TOUCH_CONTROLLER)
list(APPEND SOURCES "lvgl_touch/FT81x.c") list(APPEND SOURCES "lvgl_touch/FT81x.c")
elseif(CONFIG_LV_TOUCH_CONTROLLER_RA8875) elseif(CONFIG_LV_TOUCH_CONTROLLER_RA8875)
list(APPEND SOURCES "lvgl_touch/ra8875_touch.c") list(APPEND SOURCES "lvgl_touch/ra8875_touch.c")
elseif(CONFIG_LV_TOUCH_CONTROLLER_GT911)
list(APPEND SOURCES "lvgl_touch/gt911.c")
endif() endif()
if(CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI) if(CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI)
list(APPEND SOURCES "lvgl_touch/tp_spi.c") list(APPEND SOURCES "lvgl_touch/tp_spi.c")
elseif(CONFIG_LV_TOUCH_DRIVER_PROTOCOL_I2C)
list(APPEND SOURCES "lvgl_touch/tp_i2c.c")
endif() endif()
endif() endif()
if(CONFIG_LV_I2C)
list(APPEND SOURCES "lvgl_i2c/i2c_manager.c")
endif()
idf_component_register(SRCS ${SOURCES} idf_component_register(SRCS ${SOURCES}
INCLUDE_DIRS ${LVGL_INCLUDE_DIRS} INCLUDE_DIRS ${LVGL_INCLUDE_DIRS}
REQUIRES lvgl) REQUIRES epdiy
lvgl CalEPD sharp-lcd
)
target_compile_definitions(${COMPONENT_LIB} PUBLIC "-DLV_LVGL_H_INCLUDE_SIMPLE") target_compile_definitions(${COMPONENT_LIB} PUBLIC "-DLV_LVGL_H_INCLUDE_SIMPLE")
else() else()

16
Kconfig
View file

@ -1,14 +1,2 @@
menu "LVGL ESP Drivers" rsource "lvgl_tft/Kconfig"
rsource "lvgl_touch/Kconfig"
rsource "lvgl_tft/Kconfig"
rsource "lvgl_touch/Kconfig"
endmenu
menu "I2C Port Settings"
depends on LV_I2C && !HAVE_I2C_MANAGER
rsource "lvgl_i2c/Kconfig"
endmenu

View file

@ -6,8 +6,6 @@ For a ready to use ESP32 project take look at the [lv_port_esp32](https://github
- [Supported display controllers](#supported-display-controllers) - [Supported display controllers](#supported-display-controllers)
- [Supported indev controllers](#supported-indev-controllers) - [Supported indev controllers](#supported-indev-controllers)
- [Support for predefined development kits](#support-for-predefined-development-kits) - [Support for predefined development kits](#support-for-predefined-development-kits)
- [Thread-safe I2C with I2C Manager](#thread-safe-i2c-with-i2c-manager)
- [Backlight control](#backlight-control)
**NOTE:** You need to set the display horizontal and vertical size, color depth and **NOTE:** You need to set the display horizontal and vertical size, color depth and
swap of RGB565 color on the LVGL configuration menuconfig (it's not handled automatically). swap of RGB565 color on the LVGL configuration menuconfig (it's not handled automatically).
@ -19,7 +17,6 @@ swap of RGB565 color on the LVGL configuration menuconfig (it's not handled auto
| Display Controller | Type | Interface | Color depth (LV_COLOR_DEPTH) | Swap RGB565 color (LV_COLOR_16_SWAP) | | Display Controller | Type | Interface | Color depth (LV_COLOR_DEPTH) | Swap RGB565 color (LV_COLOR_16_SWAP) |
|---------------------------------------------|------------|------------------------|------------------------------|----------------------------------------| |---------------------------------------------|------------|------------------------|------------------------------|----------------------------------------|
| ILI9341 | TFT | SPI | 16: RGB565 | Yes | | ILI9341 | TFT | SPI | 16: RGB565 | Yes |
| ILI9163C | TFT | SPI | 16: RGB565 | Yes |
| ILI9486 | TFT | SPI | 16: RGB565 | Yes | | ILI9486 | TFT | SPI | 16: RGB565 | Yes |
| ILI9488 | TFT | SPI | 16: RGB565 | No | | ILI9488 | TFT | SPI | 16: RGB565 | No |
| HX8357B/HX8357D | TFT | SPI | 16: RGB565 | Yes | | HX8357B/HX8357D | TFT | SPI | 16: RGB565 | Yes |
@ -30,25 +27,17 @@ swap of RGB565 color on the LVGL configuration menuconfig (it's not handled auto
| RA8875 | TFT | SPI | 16: RGB565 | Yes | | RA8875 | TFT | SPI | 16: RGB565 | Yes |
| SH1107 | Monochrome | SPI | 1: 1byte per pixel | No | | SH1107 | Monochrome | SPI | 1: 1byte per pixel | No |
| SSD1306 | Monochrome | I2C | 1: 1byte per pixel | No | | SSD1306 | Monochrome | I2C | 1: 1byte per pixel | No |
| PCD8544 | Monochrome | SPI | 1: 1byte per pixel | No |
| IL3820 | e-Paper | SPI | 1: 1byte per pixel | No | | IL3820 | e-Paper | SPI | 1: 1byte per pixel | No |
| UC8151D/ GoodDisplay GDEW0154M10 DES | e-Paper | SPI | 1: 1byte per pixel | No | | UC8151D/ GoodDisplay GDEW0154M10 DES | e-Paper | SPI | 1: 1byte per pixel | No |
| FitiPower JD79653A/ GoodDisplay GDEW0154M09 | e-Paper | SPI | 1: 1byte per pixel | No | | FitiPower JD79653A/ GoodDisplay GDEW0154M09 | e-Paper | SPI | 1: 1byte per pixel | No |
| EPDiy supported epaper (needs PCB) | e-Paper | Parallel | 4: RGB232 16 grayscales | No
Please note that EPDiy supported epapers include also the Lilygo EPD47 that comes with it's own PCB and ESP32 WROVER. Is possible also to build your own EPDiy PCB, please find the [project KiCad source files, schematics, and documentation here](https://github.com/vroland/epdiy/tree/master/hardware/epaper-breakout).
To use an EPDiy supported epaper you need to add it [as a component using git submodules](https://github.com/martinberlin/lv_port_esp32-epaper/tree/master/components) and also update the CMakeLists of lvgl component to [REQUIRE that library](https://github.com/martinberlin/lv_port_esp32-epaper/wiki).
git submodule add https://github.com/martinberlin/epdiy-rotation.git components/epd_driver
## Supported indev controllers ## Supported indev controllers
- XPT2046 - XPT2046
- FT3236, FT6X36 - FT3236
- FT6206 controllers should work as well (not tested) - other FT6X36 or the FT6206 controllers should work as well (not tested)
- STMPE610 - STMPE610
- FT81x (Single, Dual, and Quad SPI) - FT81x (Single, Dual, and Quad SPI)
- L58 touch component hook (Used in Lilygo EPD47 parallel with EPDiy driver)
If your display or input device (touch) controller is not supported consider contributing to this repo by If your display or input device (touch) controller is not supported consider contributing to this repo by
adding support to it! [Contribute controller support](CONTRIBUTE_CONTROLLER_SUPPORT.md) adding support to it! [Contribute controller support](CONTRIBUTE_CONTROLLER_SUPPORT.md)
@ -62,7 +51,6 @@ and sets the gpio numbers for the interface.
|---------------------------|-----------------------|-----------|-----------|-----------| |---------------------------|-----------------------|-----------|-----------|-----------|
| ESP Wrover Kit v4.1 | ILI9341 | SPI | 240 | 320 | | ESP Wrover Kit v4.1 | ILI9341 | SPI | 240 | 320 |
| M5Stack | ILI9341 | SPI | 240 | 320 | | M5Stack | ILI9341 | SPI | 240 | 320 |
| M5Stack Core2 | ILI9341 | SPI | 240 | 320 |
| M5Stick | SH1107 | SPI | - | - | | M5Stick | SH1107 | SPI | - | - |
| M5StickC | ST7735S | SPI | 80 | 160 | | M5StickC | ST7735S | SPI | 80 | 160 |
| Adafruit 3.5 Featherwing | HX8357 | SPI | 480 | 320 | | Adafruit 3.5 Featherwing | HX8357 | SPI | 480 | 320 |
@ -75,27 +63,3 @@ and sets the gpio numbers for the interface.
**NOTE:** See [Supported display controllers](#supported-display-controllers) for more information on display configuration. **NOTE:** See [Supported display controllers](#supported-display-controllers) for more information on display configuration.
**NOTE:** See [Supported indev controllers](#supported-indev-controllers) for more information about indev configuration. **NOTE:** See [Supported indev controllers](#supported-indev-controllers) for more information about indev configuration.
## Thread-safe I2C with I2C Manager
LVGL can use I2C to read from a touch sensor or write to a display, possibly
many times a second. Meanwhile, other tasks may also want to read from i2c
devices on the same bus. I2C using the ESP-IDF is not thread-safe.
I2C Manager (`i2c_manager`) is a component that will let code in multiple threads
talk to devices on the I2C ports without getting in each other's way. These drivers
use a built-in copy of I2C Manager to talk to the I2C port, but you can also use
the I2C Manager component itself and have others play nice with LVGL and vice-versa.
[Click here](i2c_manager/README.md) for details.
## Backlight control
Control of LCD's backlight is provided by separate module that is independent from the display driver.
Configuration of the backlight controller can be found in menuconfig `LVGL ESP Drivers -> LVGL TFT Display controller`.
There are three modes of operation:
1. Off - No backlight control
2. Switch - Allows ON/OFF control
3. PWM - Allows brightness control (by Pulse-Width-Modulated signal)

View file

@ -1,7 +1,7 @@
# LVGL ESP32 drivers # LVGL ESP32 drivers
# Define sources and include dirs # Define sources and include dirs
COMPONENT_SRCDIRS := . lvgl_tft lvgl_touch lvgl_i2c COMPONENT_SRCDIRS := . lvgl_tft lvgl_touch
COMPONENT_ADD_INCLUDEDIRS := . COMPONENT_ADD_INCLUDEDIRS := .
# LVGL is supposed to be used as a ESP-IDF component # LVGL is supposed to be used as a ESP-IDF component
@ -44,6 +44,4 @@ $(call compile_only_if,$(and $(CONFIG_LV_TOUCH_CONTROLLER),$(CONFIG_LV_TOUCH_CON
$(call compile_only_if,$(and $(CONFIG_LV_TOUCH_CONTROLLER),$(CONFIG_LV_TOUCH_CONTROLLER_RA8875)), lvgl_touch/ra8875_touch.o) $(call compile_only_if,$(and $(CONFIG_LV_TOUCH_CONTROLLER),$(CONFIG_LV_TOUCH_CONTROLLER_RA8875)), lvgl_touch/ra8875_touch.o)
$(call compile_only_if,$(and $(CONFIG_LV_TOUCH_CONTROLLER),$(CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI)), lvgl_touch/tp_spi.o) $(call compile_only_if,$(and $(CONFIG_LV_TOUCH_CONTROLLER),$(CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI)), lvgl_touch/tp_spi.o)
$(call compile_only_if,$(and $(CONFIG_LV_TOUCH_CONTROLLER),$(CONFIG_LV_TOUCH_DRIVER_PROTOCOL_I2C)), lvgl_touch/tp_i2c.o)
# I2C Manager
$(call compile_only_if,$(CONFIG_LV_I2C), lvgl_i2c/i2c_manager.o)

View file

@ -14,13 +14,14 @@
#include "lvgl_touch/tp_spi.h" #include "lvgl_touch/tp_spi.h"
#include "lvgl_spi_conf.h" #include "lvgl_spi_conf.h"
#include "lvgl_i2c_conf.h"
#include "lvgl_i2c/i2c_manager.h" #include "driver/i2c.h"
#ifdef LV_LVGL_H_INCLUDE_SIMPLE #ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h" #include "src/lv_core/lv_refr.h"
#else #else
#include "lvgl/lvgl.h" #include "lvgl/src/lv_core/lv_refr.h"
#endif #endif
/********************* /*********************
@ -52,12 +53,7 @@
/* Interface and driver initialization */ /* Interface and driver initialization */
void lvgl_driver_init(void) void lvgl_driver_init(void)
{ {
/* Since LVGL v8 LV_HOR_RES_MAX and LV_VER_RES_MAX are not defined, so
* print it only if they are defined. */
#if (LVGL_VERSION_MAJOR < 8)
ESP_LOGI(TAG, "Display hor size: %d, ver size: %d", LV_HOR_RES_MAX, LV_VER_RES_MAX); ESP_LOGI(TAG, "Display hor size: %d, ver size: %d", LV_HOR_RES_MAX, LV_VER_RES_MAX);
#endif
ESP_LOGI(TAG, "Display buffer size: %d", DISP_BUF_SIZE); ESP_LOGI(TAG, "Display buffer size: %d", DISP_BUF_SIZE);
#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X) #if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X)
@ -67,7 +63,7 @@ void lvgl_driver_init(void)
DISP_SPI_MISO, DISP_SPI_MOSI, DISP_SPI_CLK, DISP_SPI_MISO, DISP_SPI_MOSI, DISP_SPI_CLK,
SPI_BUS_MAX_TRANSFER_SZ, 1, SPI_BUS_MAX_TRANSFER_SZ, 1,
DISP_SPI_IO2, DISP_SPI_IO3); DISP_SPI_IO2, DISP_SPI_IO3);
disp_spi_add_device(TFT_SPI_HOST); disp_spi_add_device(TFT_SPI_HOST);
disp_driver_init(); disp_driver_init();
@ -85,92 +81,152 @@ void lvgl_driver_init(void)
TP_SPI_MISO, DISP_SPI_MOSI, DISP_SPI_CLK, TP_SPI_MISO, DISP_SPI_MOSI, DISP_SPI_CLK,
SPI_BUS_MAX_TRANSFER_SZ, 1, SPI_BUS_MAX_TRANSFER_SZ, 1,
-1, -1); -1, -1);
disp_spi_add_device(TFT_SPI_HOST); disp_spi_add_device(TFT_SPI_HOST);
tp_spi_add_device(TOUCH_SPI_HOST); tp_spi_add_device(TOUCH_SPI_HOST);
disp_driver_init(); disp_driver_init();
touch_driver_init(); touch_driver_init();
return; return;
#endif #endif
#if defined (SHARED_I2C_BUS)
ESP_LOGI(TAG, "Initializing shared I2C master");
lvgl_i2c_driver_init(DISP_I2C_PORT,
DISP_I2C_SDA, DISP_I2C_SCL,
DISP_I2C_SPEED_HZ);
disp_driver_init();
touch_driver_init();
return;
#endif
/* Display controller initialization */ /* Display controller initialization */
#if defined CONFIG_LV_TFT_DISPLAY_PROTOCOL_SPI #if defined CONFIG_LV_TFT_DISPLAY_PROTOCOL_SPI
ESP_LOGI(TAG, "Initializing SPI master for display"); ESP_LOGI(TAG, "Initializing SPI master for display");
lvgl_spi_driver_init(TFT_SPI_HOST, lvgl_spi_driver_init(TFT_SPI_HOST,
DISP_SPI_MISO, DISP_SPI_MOSI, DISP_SPI_CLK, DISP_SPI_MISO, DISP_SPI_MOSI, DISP_SPI_CLK,
SPI_BUS_MAX_TRANSFER_SZ, 1, SPI_BUS_MAX_TRANSFER_SZ, 1,
DISP_SPI_IO2, DISP_SPI_IO3); DISP_SPI_IO2, DISP_SPI_IO3);
disp_spi_add_device(TFT_SPI_HOST); disp_spi_add_device(TFT_SPI_HOST);
disp_driver_init(); disp_driver_init();
#elif defined (CONFIG_LV_I2C_DISPLAY) #elif defined (CONFIG_LV_TFT_DISPLAY_PROTOCOL_I2C)
ESP_LOGI(TAG, "Initializing I2C master for display");
/* Init the i2c master on the display driver code */
lvgl_i2c_driver_init(DISP_I2C_PORT,
DISP_I2C_SDA, DISP_I2C_SCL,
DISP_I2C_SPEED_HZ);
disp_driver_init(); disp_driver_init();
#elif defined (CONFIG_LV_EPAPER_DISPLAY_PROTOCOL_PARALLEL) #elif defined (CONFIG_LV_EPAPER_DISPLAY_PROTOCOL_PARALLEL)
// Do not initialize SPI. Uses EPDiy // Do not initialize SPI. Uses EPDiy
ESP_LOGI(TAG, "Initializing Parallel driver for display"); ESP_LOGI(TAG, "Initializing driver for display");
// Check how not to initialize SPI. disp_driver_init() call is needed: // Check how not to initialize SPI. disp_driver_init() call is needed:
disp_driver_init(); disp_driver_init();
#elif defined (CONFIG_LV_I2C_DISPLAY)
disp_driver_init();
#else #else
#error "No protocol defined for display controller" #error "No protocol defined for display controller"
#endif #endif
/* Touch controller initialization */ /* Touch controller initialization */
#if CONFIG_LV_TOUCH_CONTROLLER != TOUCH_CONTROLLER_NONE #if CONFIG_LV_TOUCH_CONTROLLER != TOUCH_CONTROLLER_NONE
#if defined (CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI) #if defined (CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI)
ESP_LOGI(TAG, "Initializing SPI master for touch"); ESP_LOGI(TAG, "Initializing SPI master for touch");
lvgl_spi_driver_init(TOUCH_SPI_HOST, lvgl_spi_driver_init(TOUCH_SPI_HOST,
TP_SPI_MISO, TP_SPI_MOSI, TP_SPI_CLK, TP_SPI_MISO, TP_SPI_MOSI, TP_SPI_CLK,
0 /* Defaults to 4094 */, 2, 0 /* Defaults to 4094 */, 2,
-1, -1); -1, -1);
tp_spi_add_device(TOUCH_SPI_HOST); tp_spi_add_device(TOUCH_SPI_HOST);
touch_driver_init(); touch_driver_init();
#elif defined (CONFIG_LV_I2C_TOUCH) #elif defined (CONFIG_LV_TOUCH_DRIVER_PROTOCOL_I2C)
ESP_LOGI(TAG, "Initializing I2C master for touch");
lvgl_i2c_driver_init(TOUCH_I2C_PORT,
TOUCH_I2C_SDA, TOUCH_I2C_SCL,
TOUCH_I2C_SPEED_HZ);
touch_driver_init(); touch_driver_init();
#elif defined (CONFIG_LV_TOUCH_DRIVER_ADC) #elif defined (CONFIG_LV_TOUCH_DRIVER_ADC)
touch_driver_init(); touch_driver_init();
#elif defined (CONFIG_LV_TOUCH_DRIVER_DISPLAY) || defined (CONFIG_LV_TOUCH_CONTROLLER_L58) #elif defined (CONFIG_LV_TOUCH_DRIVER_DISPLAY) || defined (CONFIG_LV_TOUCH_CONTROLLER_L58)
touch_driver_init(); touch_driver_init();
#else #else
#error "No protocol defined for touch controller" #error "No protocol defined for touch controller"
#endif #endif
#else #else
#endif #endif
} }
/* Config the i2c master
/* Initialize spi bus master
* *
* NOTE: dma_chan type and value changed to int instead of spi_dma_chan_t * This should init the i2c master to be used on display and touch controllers.
* for backwards compatibility with ESP-IDF versions prior v4.3. * So we should be able to know if the display and touch controllers shares the
* * same i2c master.
* We could use the ESP_IDF_VERSION_VAL macro available in the "esp_idf_version.h"
* header available since ESP-IDF v4.
*/ */
bool lvgl_i2c_driver_init(int port, int sda_pin, int scl_pin, int speed_hz)
{
esp_err_t err;
ESP_LOGI(TAG, "Initializing I2C master port %d...", port);
ESP_LOGI(TAG, "SDA pin: %d, SCL pin: %d, Speed: %d (Hz)",
sda_pin, scl_pin, speed_hz);
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = sda_pin,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_io_num = scl_pin,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = speed_hz,
};
ESP_LOGI(TAG, "Setting I2C master configuration...");
err = i2c_param_config(port, &conf);
assert(ESP_OK == err);
ESP_LOGI(TAG, "Installing I2C master driver...");
err = i2c_driver_install(port,
I2C_MODE_MASTER,
0, 0 /*I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE */,
0 /* intr_alloc_flags */);
assert(ESP_OK == err);
return ESP_OK != err;
}
/* Initialize spi bus master */
bool lvgl_spi_driver_init(int host, bool lvgl_spi_driver_init(int host,
int miso_pin, int mosi_pin, int sclk_pin, int miso_pin, int mosi_pin, int sclk_pin,
int max_transfer_sz, int max_transfer_sz,
int dma_channel, int dma_channel,
int quadwp_pin, int quadhd_pin) int quadwp_pin, int quadhd_pin)
{ {
/** #if defined (CONFIG_IDF_TARGET_ESP32)
* @brief in idf 4.3 is giving me an error: assert((SPI_HOST <= host) && (VSPI_HOST >= host));
* error: 'SPI_HOST_MAX' undeclared
*/
assert((0 <= host) && (SPI_HOST_MAX > host));
const char *spi_names[] = { const char *spi_names[] = {
"SPI1_HOST", "SPI2_HOST", "SPI3_HOST" "SPI_HOST", "HSPI_HOST", "VSPI_HOST"
}; };
#elif defined (CONFIG_IDF_TARGET_ESP32C3)
//assert((SPI2_HOST <= host) && (SPI2_HOST >= host));
const char *spi_names[] = {
"SPI2_HOST", "", ""
};
#elif defined (CONFIG_IDF_TARGET_ESP32S2) || defined (CONFIG_IDF_TARGET_ESP32S3)
//assert((SPI_HOST <= host) && (HSPI_HOST >= host));
const char *spi_names[] = {
"SPI_HOST", "", ""
};
#endif
ESP_LOGI(TAG, "Configuring SPI host %s", spi_names[host]); ESP_LOGI(TAG, "Configuring SPI host %s (%d)", spi_names[host], host);
ESP_LOGI(TAG, "MISO pin: %d, MOSI pin: %d, SCLK pin: %d, IO2/WP pin: %d, IO3/HD pin: %d", ESP_LOGI(TAG, "MISO pin: %d, MOSI pin: %d, SCLK pin: %d, IO2/WP pin: %d, IO3/HD pin: %d",
miso_pin, mosi_pin, sclk_pin, quadwp_pin, quadhd_pin); miso_pin, mosi_pin, sclk_pin, quadwp_pin, quadhd_pin);
@ -178,19 +234,17 @@ bool lvgl_spi_driver_init(int host,
spi_bus_config_t buscfg = { spi_bus_config_t buscfg = {
.miso_io_num = miso_pin, .miso_io_num = miso_pin,
.mosi_io_num = mosi_pin, .mosi_io_num = mosi_pin,
.sclk_io_num = sclk_pin, .sclk_io_num = sclk_pin,
.quadwp_io_num = quadwp_pin, .quadwp_io_num = quadwp_pin,
.quadhd_io_num = quadhd_pin, .quadhd_io_num = quadhd_pin,
.max_transfer_sz = max_transfer_sz .max_transfer_sz = max_transfer_sz
}; };
ESP_LOGI(TAG, "Initializing SPI bus..."); ESP_LOGI(TAG, "Initializing SPI bus...");
#if defined (CONFIG_IDF_TARGET_ESP32C3) esp_err_t ret = spi_bus_initialize(host, &buscfg, dma_channel);
dma_channel = SPI_DMA_CH_AUTO;
#endif
esp_err_t ret = spi_bus_initialize(host, &buscfg, (spi_dma_chan_t)dma_channel);
assert(ret == ESP_OK); assert(ret == ESP_OK);
return ESP_OK != ret; return ESP_OK != ret;
} }

View file

@ -16,7 +16,6 @@ extern "C" {
#include "lvgl_spi_conf.h" #include "lvgl_spi_conf.h"
#include "lvgl_tft/disp_driver.h" #include "lvgl_tft/disp_driver.h"
#include "lvgl_tft/esp_lcd_backlight.h"
#include "lvgl_touch/touch_driver.h" #include "lvgl_touch/touch_driver.h"
/********************* /*********************
@ -43,11 +42,14 @@ extern "C" {
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40) #define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7796S #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7796S
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * LV_VER_RES_MAX/3) #define DISP_BUF_SIZE (LV_HOR_RES_MAX * LV_VER_RES_MAX/3)
// IMPORTANT: This will render the screen in 10 times: // IMPORTANT: This will render the screen in 8 times (Max more and it skips lines)
#elif defined (CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER) #elif defined (CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER)
#define DISP_BUF_SIZE LV_HOR_RES_MAX*(LV_VER_RES_MAX/10) #define DISP_BUF_SIZE LV_HOR_RES_MAX*(LV_VER_RES_MAX/ 8)
#elif defined ()
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 90) #elif defined (CONFIG_LV_EPAPER_CALEPD_DISPLAY_CONTROLLER)
#define DISP_BUF_SIZE LV_HOR_RES_MAX*(LV_VER_RES_MAX/10)
#elif defined (CONFIG_LV_SHARP_DISPLAY_CONTROLLER)
#define DISP_BUF_SIZE LV_HOR_RES_MAX*(LV_VER_RES_MAX)
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_HX8357 #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_HX8357
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40) #define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
@ -80,10 +82,6 @@ extern "C" {
#define DISP_BUF_SIZE ((LV_VER_RES_MAX * LV_VER_RES_MAX) / 8) // 5KB #define DISP_BUF_SIZE ((LV_VER_RES_MAX * LV_VER_RES_MAX) / 8) // 5KB
#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D) #elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D)
#define DISP_BUF_SIZE ((LV_VER_RES_MAX * LV_VER_RES_MAX) / 8) // 2888 bytes #define DISP_BUF_SIZE ((LV_VER_RES_MAX * LV_VER_RES_MAX) / 8) // 2888 bytes
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9163C
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_PCD8544)
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * (LV_VER_RES_MAX / 8))
#else #else
#error "No display controller selected" #error "No display controller selected"
#endif #endif
@ -97,14 +95,14 @@ extern "C" {
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
**********************/ **********************/
void lvgl_i2c_locking(void* leader);
/* Initialize detected SPI and I2C bus and devices */ /* Initialize detected SPI and I2C bus and devices */
void lvgl_driver_init(void); void lvgl_driver_init(void);
/* Initialize SPI master */ /* Initialize SPI master */
bool lvgl_spi_driver_init(int host, int miso_pin, int mosi_pin, int sclk_pin, bool lvgl_spi_driver_init(int host, int miso_pin, int mosi_pin, int sclk_pin,
int max_transfer_sz, int dma_channel, int quadwp_pin, int quadhd_pin); int max_transfer_sz, int dma_channel, int quadwp_pin, int quadhd_pin);
/* Initialize I2C master */
bool lvgl_i2c_driver_init(int port, int sda_pin, int scl_pin, int speed);
/********************** /**********************
* MACROS * MACROS

116
lvgl_i2c_conf.h Normal file
View file

@ -0,0 +1,116 @@
/**
* @file lvgl_i2c_config.h
*/
#ifndef LVGL_I2C_CONF_H
#define LVGL_I2C_CONF_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
/*********************
* DEFINES
*********************/
/* TODO: Define the I2C bus clock based on the selected display or touch
* controllers. */
/* Do both display and touch controllers uses I2C? */
#if defined (CONFIG_LV_TOUCH_DRIVER_PROTOCOL_I2C) && \
defined (CONFIG_LV_TFT_DISPLAY_PROTOCOL_I2C)
#if defined (CONFIG_LV_DISPLAY_I2C_PORT_0) && \
defined (CONFIG_LV_TOUCH_I2C_PORT_0)
#define SHARED_I2C_PORT
#define DISP_I2C_PORT I2C_NUM_0
#endif
#if defined (CONFIG_LV_DISPLAY_I2C_PORT_1) && \
defined (CONFIG_LV_TOUCH_I2C_PORT_1)
#define SHARED_I2C_PORT
#define DISP_I2C_PORT I2C_NUM_1
#endif
#if !defined (SHARED_I2C_PORT)
#endif
#endif
#if defined (SHARED_I2C_PORT)
/* If the port is shared the display and touch controllers must use the same
* SCL and SDA pins, otherwise let the user know with an error. */
#if (CONFIG_LV_DISP_PIN_SDA != CONFIG_LV_TOUCH_I2C_SDA) || \
(CONFIG_LV_DISP_PIN_SCL != CONFIG_LV_TOUCH_I2C_SCL)
#error "To share I2C port you need to choose the same SDA and SCL pins on both display and touch configurations"
#endif
#define DISP_I2C_SDA CONFIG_LV_DISP_PIN_SDA
#define DISP_I2C_SCL CONFIG_LV_DISP_PIN_SCL
#define DISP_I2C_ORIENTATION TFT_ORIENTATION_LANDSCAPE
/* Setting the I2C speed to the slowest one */
#if DISP_I2C_SPEED_HZ < TOUCH_I2C_SPEED_HZ
#define DISP_I2C_SPEED_HZ 400000 /* DISP_I2C_SPEED_HZ */
#else
#define DISP_I2C_SPEED_HZ 400000 /* DISP_I2C_SPEED_HZ */
#endif
#else
/* lets check if the touch controller uses I2C... */
#if defined (CONFIG_LV_TOUCH_DRIVER_PROTOCOL_I2C)
#if defined (CONFIG_LV_TOUCH_I2C_PORT_0)
#define TOUCH_I2C_PORT I2C_NUM_0
#else
#define TOUCH_I2C_PORT I2C_NUM_1
#endif
#define TOUCH_I2C_SDA CONFIG_LV_TOUCH_I2C_SDA
#define TOUCH_I2C_SCL CONFIG_LV_TOUCH_I2C_SCL
#define TOUCH_I2C_SPEED_HZ 400000
#endif
/* lets check if the display controller uses I2C... */
#if defined (CONFIG_LV_TFT_DISPLAY_PROTOCOL_I2C)
#if defined (CONFIG_LV_DISPLAY_I2C_PORT_0)
#define DISP_I2C_PORT I2C_NUM_0
#else
#define DISP_I2C_PORT I2C_NUM_1
#endif
#define DISP_I2C_SDA CONFIG_LV_DISP_PIN_SDA
#define DISP_I2C_SCL CONFIG_LV_DISP_PIN_SCL
#define DISP_I2C_ORIENTATION TFT_ORIENTATION_LANDSCAPE
#define DISP_I2C_SPEED_HZ 400000
#endif
#endif
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LVGL_I2C_CONF_H*/

View file

@ -64,10 +64,12 @@ extern "C" {
#define ENABLE_TOUCH_INPUT CONFIG_LV_ENABLE_TOUCH #define ENABLE_TOUCH_INPUT CONFIG_LV_ENABLE_TOUCH
#if defined (CONFIG_LV_TFT_DISPLAY_SPI2_HOST) #if defined (CONFIG_LV_TFT_DISPLAY_SPI_HSPI)
#define TFT_SPI_HOST SPI2_HOST #define TFT_SPI_HOST HSPI_HOST
#elif defined (CONFIG_LV_TFT_DISPLAY_SPI3_HOST) #elif defined (CONFIG_LV_TFT_DISPLAY_SPI_VSPI)
#define TFT_SPI_HOST SPI3_HOST #define TFT_SPI_HOST VSPI_HOST
#elif defined (CONFIG_LV_TFT_DISPLAY_SPI_FSPI)
#define TFT_SPI_HOST FSPI_HOST
#endif #endif
#if defined (CONFIG_LV_TFT_DISPLAY_SPI_HALF_DUPLEX) #if defined (CONFIG_LV_TFT_DISPLAY_SPI_HALF_DUPLEX)
@ -84,10 +86,12 @@ extern "C" {
#define DISP_SPI_TRANS_MODE_SIO #define DISP_SPI_TRANS_MODE_SIO
#endif #endif
#if defined (CONFIG_LV_TOUCH_CONTROLLER_SPI2_HOST) #if defined (CONFIG_LV_TOUCH_CONTROLLER_SPI_HSPI)
#define TOUCH_SPI_HOST SPI2_HOST #define TOUCH_SPI_HOST HSPI_HOST
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_SPI3_HOST) #elif defined (CONFIG_LV_TOUCH_CONTROLLER_SPI_VSPI)
#define TOUCH_SPI_HOST SPI3_HOST #define TOUCH_SPI_HOST VSPI_HOST
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_SPI_FSPI)
#define TOUCH_SPI_HOST FSPI_HOST
#endif #endif
/* Handle the FT81X Special case */ /* Handle the FT81X Special case */
@ -103,7 +107,7 @@ extern "C" {
// Detect the use of a shared SPI Bus and verify the user specified the same SPI bus for both touch and tft // Detect the use of a shared SPI Bus and verify the user specified the same SPI bus for both touch and tft
#if defined (CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI) && TP_SPI_MOSI == DISP_SPI_MOSI && TP_SPI_CLK == DISP_SPI_CLK #if defined (CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI) && TP_SPI_MOSI == DISP_SPI_MOSI && TP_SPI_CLK == DISP_SPI_CLK
#if TFT_SPI_HOST != TOUCH_SPI_HOST #if TFT_SPI_HOST != TOUCH_SPI_HOST
#error You must specify the same SPI host (SPIx_HOST) for both display and touch driver #error You must specify the same SPI host (HSPI, VSPI or FSPI) for both display and touch driver
#endif #endif
#define SHARED_SPI_BUS #define SHARED_SPI_BUS
@ -126,8 +130,7 @@ extern "C" {
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_SH1107) || \ defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_SH1107) || \
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X) || \ defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X) || \
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_IL3820) || \ defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_IL3820) || \
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_JD79653A) || \ defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_JD79653A)
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9163C)
#define SPI_BUS_MAX_TRANSFER_SZ (DISP_BUF_SIZE * 2) #define SPI_BUS_MAX_TRANSFER_SZ (DISP_BUF_SIZE * 2)
@ -154,12 +157,8 @@ extern "C" {
#define SPI_TFT_CLOCK_SPEED_HZ (40*1000*1000) #define SPI_TFT_CLOCK_SPEED_HZ (40*1000*1000)
#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341) #elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341)
#define SPI_TFT_CLOCK_SPEED_HZ (40*1000*1000) #define SPI_TFT_CLOCK_SPEED_HZ (40*1000*1000)
#elif defined(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9163C) #elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X)
#define SPI_TFT_CLOCK_SPEED_HZ (40 * 1000 * 1000)
#elif defined(CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X)
#define SPI_TFT_CLOCK_SPEED_HZ (32*1000*1000) #define SPI_TFT_CLOCK_SPEED_HZ (32*1000*1000)
#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_PCD8544)
#define SPI_TFT_CLOCK_SPEED_HZ (4*1000*1000)
#else #else
#define SPI_TFT_CLOCK_SPEED_HZ (40*1000*1000) #define SPI_TFT_CLOCK_SPEED_HZ (40*1000*1000)
#endif #endif

View file

@ -144,7 +144,7 @@ void DELAY_MS(uint16_t ms)
vTaskDelay(ms / portTICK_PERIOD_MS); vTaskDelay(ms / portTICK_PERIOD_MS);
} }
#if EVE_USE_PDN
void EVE_pdn_set(void) void EVE_pdn_set(void)
{ {
gpio_set_level(EVE_PDN, 0); /* Power-Down low */ gpio_set_level(EVE_PDN, 0); /* Power-Down low */
@ -155,7 +155,7 @@ void EVE_pdn_clear(void)
{ {
gpio_set_level(EVE_PDN, 1); /* Power-Down high */ gpio_set_level(EVE_PDN, 1); /* Power-Down high */
} }
#endif
void spi_acquire() void spi_acquire()
{ {
@ -841,13 +841,11 @@ uint8_t EVE_init(void)
uint8_t chipid = 0; uint8_t chipid = 0;
uint16_t timeout = 0; uint16_t timeout = 0;
#if EVE_USE_PDN
EVE_pdn_set(); EVE_pdn_set();
DELAY_MS(6); /* minimum time for power-down is 5ms */ DELAY_MS(6); /* minimum time for power-down is 5ms */
EVE_pdn_clear(); EVE_pdn_clear();
DELAY_MS(21); /* minimum time to allow from rising PD_N to first access is 20ms */ DELAY_MS(21); /* minimum time to allow from rising PD_N to first access is 20ms */
#endif
/* EVE_cmdWrite(EVE_CORERST,0); */ /* reset, only required for warm-start if PowerDown line is not used */ /* EVE_cmdWrite(EVE_CORERST,0); */ /* reset, only required for warm-start if PowerDown line is not used */

View file

@ -39,12 +39,8 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH
#define BLOCK_TRANSFER_SIZE 3840 // block transfer size when write data to CMD buffer #define BLOCK_TRANSFER_SIZE 3840 // block transfer size when write data to CMD buffer
void DELAY_MS(uint16_t ms); void DELAY_MS(uint16_t ms);
#if EVE_USE_PDN
void EVE_pdn_set(void); void EVE_pdn_set(void);
void EVE_pdn_clear(void); void EVE_pdn_clear(void);
#endif
void spi_acquire(); void spi_acquire();
void spi_release(); void spi_release();
@ -68,7 +64,7 @@ void EVE_get_cmdoffset(void);
/* commands to operate on memory: */ /* commands to operate on memory: */
void EVE_cmd_memzero(uint32_t ptr, uint32_t num); void EVE_cmd_memzero(uint32_t ptr, uint32_t num);
void EVE_cmd_memset(uint32_t ptr, uint8_t value, uint32_t num); void EVE_cmd_memset(uint32_t ptr, uint8_t value, uint32_t num);
void EVE_cmd_memwrite(uint32_t dest, uint32_t num, const uint8_t *data); void EVE_cmd_memwrite(uint32_t dest, uint32_t num, const uint8_t *data);
void EVE_cmd_memcpy(uint32_t dest, uint32_t src, uint32_t num); void EVE_cmd_memcpy(uint32_t dest, uint32_t src, uint32_t num);
#if FT81X_FULL #if FT81X_FULL

View file

@ -44,12 +44,11 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH
#include "FT81x.h" #include "FT81x.h"
#define EVE_CLK DISP_SPI_CLK // orange #define EVE_CLK DISP_SPI_CLK // orange
#define EVE_MISO DISP_SPI_MISO // yellow #define EVE_MISO DISP_SPI_MISO // yellow
#define EVE_MOSI DISP_SPI_MOSI // green #define EVE_MOSI DISP_SPI_MOSI // green
#define EVE_CS DISP_SPI_CS // blue #define EVE_CS DISP_SPI_CS // blue
#define EVE_PDN CONFIG_LV_DISP_PIN_RST // grey #define EVE_PDN CONFIG_LV_DISP_PIN_RST // grey
#define EVE_USE_PDN CONFIG_LV_DISP_USE_RST
#define SPI_TRANSER_SIZE (DISP_BUF_SIZE * (LV_COLOR_DEPTH / 8)) #define SPI_TRANSER_SIZE (DISP_BUF_SIZE * (LV_COLOR_DEPTH / 8))

View file

@ -250,7 +250,7 @@ void TFT_bitmap_display(void)
EVE_cmd_dl(TAG(0)); EVE_cmd_dl(TAG(0));
EVE_cmd_dl(DL_DISPLAY); /* instruct the graphics processor to show the list */ EVE_cmd_dl(DL_DISPLAY); /* instruct the graphics processor to show the list */
EVE_cmd_dl(CMD_SWAP); /* make this list active */ EVE_cmd_dl(CMD_SWAP); /* make this list active */
EVE_end_cmd_burst(); /* stop writing to the cmd-fifo */ EVE_end_cmd_burst(); /* stop writing to the cmd-fifo */
@ -262,18 +262,12 @@ void TFT_bitmap_display(void)
void FT81x_init(void) void FT81x_init(void)
{ {
#if EVE_USE_PDN
gpio_pad_select_gpio(EVE_PDN); gpio_pad_select_gpio(EVE_PDN);
#endif
gpio_set_level(EVE_CS, 1); gpio_set_level(EVE_CS, 1);
#if EVE_USE_PDN
gpio_set_direction(EVE_PDN, GPIO_MODE_OUTPUT); gpio_set_direction(EVE_PDN, GPIO_MODE_OUTPUT);
#endif
spi_acquire(); spi_acquire();
if(EVE_init()) if(EVE_init())
{ {
tft_active = 1; tft_active = 1;
@ -284,7 +278,7 @@ void FT81x_init(void)
EVE_cmd_memset(SCREEN_BITMAP_ADDR, BLACK, SCREEN_BUFFER_SIZE); // clear screen buffer EVE_cmd_memset(SCREEN_BITMAP_ADDR, BLACK, SCREEN_BUFFER_SIZE); // clear screen buffer
EVE_cmd_execute(); EVE_cmd_execute();
TFT_bitmap_display(); // set DL for fullscreen bitmap display TFT_bitmap_display(); // set DL for fullscreen bitmap display
} }
@ -326,4 +320,4 @@ void TFT_WriteBitmap(uint8_t* Bitmap, uint16_t X, uint16_t Y, uint16_t Width, ui
void FT81x_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map) void FT81x_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map)
{ {
TFT_WriteBitmap((uint8_t*)color_map, area->x1, area->y1, lv_area_get_width(area), lv_area_get_height(area)); TFT_WriteBitmap((uint8_t*)color_map, area->x1, area->y1, lv_area_get_width(area), lv_area_get_height(area));
} }

View file

@ -111,20 +111,31 @@ void GC9A01_init(void)
}; };
//Initialize non-SPI GPIOs #if GC9A01_BCKL == 15
gpio_pad_select_gpio(GC9A01_DC); gpio_config_t io_conf;
gpio_set_direction(GC9A01_DC, GPIO_MODE_OUTPUT); io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pin_bit_mask = GPIO_SEL_15;
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
gpio_config(&io_conf);
#endif
#if GC9A01_USE_RST //Initialize non-SPI GPIOs
gpio_pad_select_gpio(GC9A01_RST); gpio_pad_select_gpio(GC9A01_DC);
gpio_set_direction(GC9A01_DC, GPIO_MODE_OUTPUT);
gpio_pad_select_gpio(GC9A01_RST);
gpio_set_direction(GC9A01_RST, GPIO_MODE_OUTPUT); gpio_set_direction(GC9A01_RST, GPIO_MODE_OUTPUT);
#if GC9A01_ENABLE_BACKLIGHT_CONTROL
gpio_pad_select_gpio(GC9A01_BCKL);
gpio_set_direction(GC9A01_BCKL, GPIO_MODE_OUTPUT);
#endif
//Reset the display //Reset the display
gpio_set_level(GC9A01_RST, 0); gpio_set_level(GC9A01_RST, 0);
vTaskDelay(100 / portTICK_RATE_MS); vTaskDelay(100 / portTICK_RATE_MS);
gpio_set_level(GC9A01_RST, 1); gpio_set_level(GC9A01_RST, 1);
vTaskDelay(100 / portTICK_RATE_MS); vTaskDelay(100 / portTICK_RATE_MS);
#endif
ESP_LOGI(TAG, "Initialization."); ESP_LOGI(TAG, "Initialization.");
@ -139,6 +150,8 @@ void GC9A01_init(void)
cmd++; cmd++;
} }
GC9A01_enable_backlight(true);
GC9A01_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION); GC9A01_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION);
#if GC9A01_INVERT_COLORS == 1 #if GC9A01_INVERT_COLORS == 1
@ -154,7 +167,7 @@ void GC9A01_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * colo
uint8_t data[4]; uint8_t data[4];
/*Column addresses*/ /*Column addresses*/
GC9A01_send_cmd(0x2A); //0x2A GC9A01_send_cmd(0x2A); //0x2A
data[0] = (area->x1 >> 8) & 0xFF; data[0] = (area->x1 >> 8) & 0xFF;
data[1] = area->x1 & 0xFF; data[1] = area->x1 & 0xFF;
data[2] = (area->x2 >> 8) & 0xFF; data[2] = (area->x2 >> 8) & 0xFF;
@ -162,7 +175,7 @@ void GC9A01_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * colo
GC9A01_send_data(data, 4); GC9A01_send_data(data, 4);
/*Page addresses*/ /*Page addresses*/
GC9A01_send_cmd(0x2B); //0x2B GC9A01_send_cmd(0x2B); //0x2B
data[0] = (area->y1 >> 8) & 0xFF; data[0] = (area->y1 >> 8) & 0xFF;
data[1] = area->y1 & 0xFF; data[1] = area->y1 & 0xFF;
data[2] = (area->y2 >> 8) & 0xFF; data[2] = (area->y2 >> 8) & 0xFF;
@ -170,7 +183,7 @@ void GC9A01_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * colo
GC9A01_send_data(data, 4); GC9A01_send_data(data, 4);
/*Memory write*/ /*Memory write*/
GC9A01_send_cmd(0x2C); //0x2C GC9A01_send_cmd(0x2C); //0x2C
uint32_t size = lv_area_get_width(area) * lv_area_get_height(area); uint32_t size = lv_area_get_width(area) * lv_area_get_height(area);
@ -178,11 +191,27 @@ void GC9A01_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * colo
GC9A01_send_color((void*)color_map, size * 2); GC9A01_send_color((void*)color_map, size * 2);
} }
void GC9A01_enable_backlight(bool backlight)
{
#if GC9A01_ENABLE_BACKLIGHT_CONTROL
ESP_LOGI(TAG, "%s backlight.", backlight ? "Enabling" : "Disabling");
uint32_t tmp = 0;
#if (GC9A01_BCKL_ACTIVE_LVL==1)
tmp = backlight ? 1 : 0;
#else
tmp = backlight ? 0 : 1;
#endif
gpio_set_level(GC9A01_BCKL, tmp);
#endif
}
void GC9A01_sleep_in() void GC9A01_sleep_in()
{ {
uint8_t data[] = {0x08}; uint8_t data[] = {0x08};
GC9A01_send_cmd(0x10); //0x10 Enter Sleep Mode GC9A01_send_cmd(0x10); //0x10 Enter Sleep Mode
GC9A01_send_data(&data, 1); GC9A01_send_data(&data, 1);
} }
void GC9A01_sleep_out() void GC9A01_sleep_out()

View file

@ -25,9 +25,18 @@ extern "C" {
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
#define GC9A01_DC CONFIG_LV_DISP_PIN_DC #define GC9A01_DC CONFIG_LV_DISP_PIN_DC
#define GC9A01_RST CONFIG_LV_DISP_PIN_RST #define GC9A01_RST CONFIG_LV_DISP_PIN_RST
#define GC9A01_USE_RST CONFIG_LV_DISP_USE_RST #define GC9A01_BCKL CONFIG_LV_DISP_PIN_BCKL
#define GC9A01_ENABLE_BACKLIGHT_CONTROL CONFIG_LV_ENABLE_BACKLIGHT_CONTROL
#if CONFIG_LV_BACKLIGHT_ACTIVE_LVL
#define GC9A01_BCKL_ACTIVE_LVL 1
#else
#define GC9A01_BCKL_ACTIVE_LVL 0
#endif
#define GC9A01_INVERT_COLORS CONFIG_LV_INVERT_COLORS #define GC9A01_INVERT_COLORS CONFIG_LV_INVERT_COLORS
/********************** /**********************
@ -40,6 +49,7 @@ extern "C" {
void GC9A01_init(void); void GC9A01_init(void);
void GC9A01_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map); void GC9A01_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);
void GC9A01_enable_backlight(bool backlight);
void GC9A01_sleep_in(void); void GC9A01_sleep_in(void);
void GC9A01_sleep_out(void); void GC9A01_sleep_out(void);

View file

@ -21,10 +21,6 @@ menu "LVGL TFT/Epaper Display controller"
bool "M5Stack" bool "M5Stack"
select LV_TFT_DISPLAY_CONTROLLER_ILI9341 select LV_TFT_DISPLAY_CONTROLLER_ILI9341
select LV_TFT_DISPLAY_PROTOCOL_SPI select LV_TFT_DISPLAY_PROTOCOL_SPI
config LV_PREDEFINED_DISPLAY_M5CORE2
bool "M5Core2"
select LV_TFT_DISPLAY_CONTROLLER_ILI9341
select LV_TFT_DISPLAY_PROTOCOL_SPI
config LV_PREDEFINED_DISPLAY_M5STICK config LV_PREDEFINED_DISPLAY_M5STICK
bool "M5Stick" bool "M5Stick"
select LV_TFT_DISPLAY_CONTROLLER_SH1107 select LV_TFT_DISPLAY_CONTROLLER_SH1107
@ -50,7 +46,7 @@ menu "LVGL TFT/Epaper Display controller"
config LV_PREDEFINED_DISPLAY_WEMOS_LOLIN config LV_PREDEFINED_DISPLAY_WEMOS_LOLIN
bool "Wemos Lolin OLED" bool "Wemos Lolin OLED"
select LV_TFT_DISPLAY_CONTROLLER_SSD1306 select LV_TFT_DISPLAY_CONTROLLER_SSD1306
select LV_I2C_DISPLAY select LV_TFT_DISPLAY_PROTOCOL_I2C
select LV_TFT_DISPLAY_MONOCHROME select LV_TFT_DISPLAY_MONOCHROME
select LV_THEME_MONO select LV_THEME_MONO
config LV_PREDEFINED_DISPLAY_ATAG config LV_PREDEFINED_DISPLAY_ATAG
@ -93,7 +89,14 @@ menu "LVGL TFT/Epaper Display controller"
bool bool
help help
EPDIY parallel epaper controller. EPDIY parallel epaper controller.
config LV_EPAPER_CALEPD_DISPLAY_CONTROLLER
bool
help
CalEPD SPI epaper controller.
config LV_SHARP_DISPLAY_CONTROLLER
bool
help
SHARP memory LCD controller.
config LV_TFT_DISPLAY_CONTROLLER_ILI9341 config LV_TFT_DISPLAY_CONTROLLER_ILI9341
bool bool
help help
@ -174,15 +177,6 @@ menu "LVGL TFT/Epaper Display controller"
help help
ST7796S display controller. ST7796S display controller.
config LV_TFT_DISPLAY_CONTROLLER_ILI9163C
bool
help
ILI9163C display controller.
config LV_TFT_DISPLAY_CONTROLLER_PCD8544
bool
help
PCD8544 display controller (Nokia 3110/5110)
# Display controller communication protocol # Display controller communication protocol
# #
# This symbols define the communication protocol used by the # This symbols define the communication protocol used by the
@ -201,7 +195,7 @@ menu "LVGL TFT/Epaper Display controller"
help help
Display controller protocol SPI Display controller protocol SPI
config LV_I2C_DISPLAY config LV_TFT_DISPLAY_PROTOCOL_I2C
bool bool
help help
Display controller protocol I2C Display controller protocol I2C
@ -209,24 +203,24 @@ menu "LVGL TFT/Epaper Display controller"
# Used in display init function to send display orientation commands # Used in display init function to send display orientation commands
choice DISPLAY_ORIENTATION choice DISPLAY_ORIENTATION
prompt "Display orientation" prompt "Display orientation"
default LV_DISPLAY_ORIENTATION_PORTRAIT if !LV_TFT_DISPLAY_CONTROLLER_SSD1306 default DISPLAY_ORIENTATION_PORTRAIT if !LV_TFT_DISPLAY_CONTROLLER_SSD1306
default LV_DISPLAY_ORIENTATION_LANDSCAPE if LV_TFT_DISPLAY_CONTROLLER_SSD1306 default DISPLAY_ORIENTATION_LANDSCAPE if LV_TFT_DISPLAY_CONTROLLER_SSD1306
config LV_DISPLAY_ORIENTATION_PORTRAIT config DISPLAY_ORIENTATION_PORTRAIT
bool "Portrait" if !LV_TFT_DISPLAY_CONTROLLER_SSD1306 bool "Portrait" if !LV_TFT_DISPLAY_CONTROLLER_SSD1306
config LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED config DISPLAY_ORIENTATION_PORTRAIT_INVERTED
bool "Portrait inverted" if !LV_TFT_DISPLAY_CONTROLLER_SSD1306 bool "Portrait inverted" if !LV_TFT_DISPLAY_CONTROLLER_SSD1306
config LV_DISPLAY_ORIENTATION_LANDSCAPE config DISPLAY_ORIENTATION_LANDSCAPE
bool "Landscape" bool "Landscape"
config LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED config DISPLAY_ORIENTATION_LANDSCAPE_INVERTED
bool "Landscape inverted" bool "Landscape inverted"
endchoice endchoice
config LV_DISPLAY_ORIENTATION config LV_DISPLAY_ORIENTATION
int int
default 0 if LV_DISPLAY_ORIENTATION_PORTRAIT default 0 if DISPLAY_ORIENTATION_PORTRAIT
default 1 if LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED default 1 if DISPLAY_ORIENTATION_PORTRAIT_INVERTED
default 2 if LV_DISPLAY_ORIENTATION_LANDSCAPE default 2 if DISPLAY_ORIENTATION_LANDSCAPE
default 3 if LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED default 3 if DISPLAY_ORIENTATION_LANDSCAPE_INVERTED
config LV_TFT_DISPLAY_OFFSETS config LV_TFT_DISPLAY_OFFSETS
bool bool
@ -235,14 +229,14 @@ menu "LVGL TFT/Epaper Display controller"
config LV_TFT_DISPLAY_X_OFFSET config LV_TFT_DISPLAY_X_OFFSET
depends on LV_TFT_DISPLAY_OFFSETS depends on LV_TFT_DISPLAY_OFFSETS
int "X offset" int
default 40 if LV_PREDEFINED_DISPLAY_TTGO && (LV_DISPLAY_ORIENTATION_LANDSCAPE || LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED) default 40 if LV_PREDEFINED_DISPLAY_TTGO && (LV_DISPLAY_ORIENTATION_LANDSCAPE || LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED)
default 53 if LV_PREDEFINED_DISPLAY_TTGO && (LV_DISPLAY_ORIENTATION_PORTRAIT || LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED) default 53 if LV_PREDEFINED_DISPLAY_TTGO && (LV_DISPLAY_ORIENTATION_PORTRAIT || LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
default 0 default 0
config LV_TFT_DISPLAY_Y_OFFSET config LV_TFT_DISPLAY_Y_OFFSET
depends on LV_TFT_DISPLAY_OFFSETS depends on LV_TFT_DISPLAY_OFFSETS
int "Y offset" int
default 53 if LV_PREDEFINED_DISPLAY_TTGO && (LV_DISPLAY_ORIENTATION_LANDSCAPE || LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED) default 53 if LV_PREDEFINED_DISPLAY_TTGO && (LV_DISPLAY_ORIENTATION_LANDSCAPE || LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED)
default 40 if LV_PREDEFINED_DISPLAY_TTGO && (LV_DISPLAY_ORIENTATION_PORTRAIT || LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED) default 40 if LV_PREDEFINED_DISPLAY_TTGO && (LV_DISPLAY_ORIENTATION_PORTRAIT || LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
default 0 default 0
@ -284,6 +278,18 @@ menu "LVGL TFT/Epaper Display controller"
bool "EPDIY_GENERIC" bool "EPDIY_GENERIC"
select LV_EPAPER_EPDIY_DISPLAY_CONTROLLER select LV_EPAPER_EPDIY_DISPLAY_CONTROLLER
select LV_EPAPER_DISPLAY_PROTOCOL_PARALLEL select LV_EPAPER_DISPLAY_PROTOCOL_PARALLEL
config LV_EPAPER_DISPLAY_USER_CONTROLLER_CALEPD
bool "CALEPD_GENERIC"
# Use also Parallel to avoid LGVL SPI instantiation
select LV_EPAPER_CALEPD_DISPLAY_CONTROLLER
select LV_EPAPER_DISPLAY_PROTOCOL_PARALLEL
config LV_SHARP_USER_CONTROLLER
bool "SHARP_LCD"
# Use also Parallel to avoid LGVL SPI instantiation
select LV_SHARP_DISPLAY_CONTROLLER
select LV_EPAPER_DISPLAY_PROTOCOL_PARALLEL
config LV_TFT_DISPLAY_USER_CONTROLLER_ILI9341 config LV_TFT_DISPLAY_USER_CONTROLLER_ILI9341
bool "ILI9341" bool "ILI9341"
select LV_TFT_DISPLAY_CONTROLLER_ILI9341 select LV_TFT_DISPLAY_CONTROLLER_ILI9341
@ -328,7 +334,7 @@ menu "LVGL TFT/Epaper Display controller"
config LV_TFT_DISPLAY_USER_CONTROLLER_SSD1306 config LV_TFT_DISPLAY_USER_CONTROLLER_SSD1306
bool "SSD1306" bool "SSD1306"
select LV_TFT_DISPLAY_CONTROLLER_SSD1306 select LV_TFT_DISPLAY_CONTROLLER_SSD1306
select LV_I2C_DISPLAY select LV_TFT_DISPLAY_PROTOCOL_I2C
select LV_TFT_DISPLAY_MONOCHROME select LV_TFT_DISPLAY_MONOCHROME
config LV_TFT_DISPLAY_USER_CONTROLLER_FT81X config LV_TFT_DISPLAY_USER_CONTROLLER_FT81X
bool "FT81X" bool "FT81X"
@ -353,15 +359,6 @@ menu "LVGL TFT/Epaper Display controller"
bool "RA8875" bool "RA8875"
select LV_TFT_DISPLAY_CONTROLLER_RA8875 select LV_TFT_DISPLAY_CONTROLLER_RA8875
select LV_TFT_DISPLAY_PROTOCOL_SPI select LV_TFT_DISPLAY_PROTOCOL_SPI
config LV_TFT_DISPLAY_USER_CONTROLLER_ILI9163C
bool "ILI9163C"
select LV_TFT_DISPLAY_CONTROLLER_ILI9163C
select LV_TFT_DISPLAY_PROTOCOL_SPI
config LV_TFT_DISPLAY_USER_CONTROLLER_PCD8544
bool "PCD8544"
select LV_TFT_DISPLAY_CONTROLLER_PCD8544
select LV_TFT_DISPLAY_PROTOCOL_SPI
select LV_TFT_DISPLAY_MONOCHROME
endchoice endchoice
config CUSTOM_DISPLAY_BUFFER_SIZE config CUSTOM_DISPLAY_BUFFER_SIZE
@ -481,15 +478,20 @@ menu "LVGL TFT/Epaper Display controller"
endchoice endchoice
choice choice
prompt "TFT SPI Bus." if LV_TFT_DISPLAY_PROTOCOL_SPI prompt "TFT SPI Bus." if LV_TFT_DISPLAY_PROTOCOL_SPI && \
default LV_TFT_DISPLAY_SPI2_HOST !LV_PREDEFINED_DISPLAY_TTGO
default LV_TFT_DISPLAY_SPI_VSPI if LV_PREDEFINED_DISPLAY_TTGO && \
!IDF_TARGET_ESP32S2
default LV_TFT_DISPLAY_SPI_FSPI if IDF_TARGET_ESP32S2
help help
Select the SPI Bus the TFT Display is attached to. Select the SPI Bus the TFT Display is attached to.
config LV_TFT_DISPLAY_SPI2_HOST config LV_TFT_DISPLAY_SPI_HSPI
bool "SPI2_HOST" bool "HSPI"
config LV_TFT_DISPLAY_SPI3_HOST config LV_TFT_DISPLAY_SPI_VSPI
bool "SPI3_HOST" bool "VSPI" if !IDF_TARGET_ESP32S2
config LV_TFT_DISPLAY_SPI_FSPI
bool "FSPI" if IDF_TARGET_ESP32S2
endchoice endchoice
choice choice
@ -520,6 +522,18 @@ menu "LVGL TFT/Epaper Display controller"
depends on LV_TFT_DISPLAY_SPI_TRANS_MODE_SIO depends on LV_TFT_DISPLAY_SPI_TRANS_MODE_SIO
endchoice endchoice
choice
prompt "Display I2C port" if LV_TFT_DISPLAY_PROTOCOL_I2C
default LV_DISPLAY_I2C_PORT_0
help
Select the I2C port used by the display controller.
config LV_DISPLAY_I2C_PORT_0
bool "I2C PORT 0"
config LV_DISPLAY_I2C_PORT_1
bool "I2C PORT 1"
endchoice
config LV_TFT_USE_CUSTOM_SPI_CLK_DIVIDER config LV_TFT_USE_CUSTOM_SPI_CLK_DIVIDER
bool "Use custom SPI clock frequency." if LV_TFT_DISPLAY_PROTOCOL_SPI bool "Use custom SPI clock frequency." if LV_TFT_DISPLAY_PROTOCOL_SPI
default n default n
@ -597,16 +611,6 @@ menu "LVGL TFT/Epaper Display controller"
default 80 if LV_TFT_SPI_CLK_DIVIDER_80 default 80 if LV_TFT_SPI_CLK_DIVIDER_80
default 2 default 2
config LV_M5STICKC_HANDLE_AXP192
bool "Handle Backlight and TFT power for M5StickC using AXP192." if LV_PREDEFINED_DISPLAY_M5STICKC || LV_TFT_DISPLAY_CONTROLLER_ST7735S
default y if LV_PREDEFINED_DISPLAY_M5STICKC
select LV_I2C_DISPLAY
help
Display and TFT power supply on M5StickC is controlled using an
AXP192 Power Mangerment IC. Select yes if you want to enable TFT IC
(LDO3) and backlight power using AXP192 by LVGL, or select no if you
want to take care of power management in your own code.
config LV_INVERT_DISPLAY config LV_INVERT_DISPLAY
bool "IN DEPRECATION - Invert display." if LV_TFT_DISPLAY_CONTROLLER_RA8875 bool "IN DEPRECATION - Invert display." if LV_TFT_DISPLAY_CONTROLLER_RA8875
default n default n
@ -614,12 +618,37 @@ menu "LVGL TFT/Epaper Display controller"
If text is backwards on your display, try enabling this. If text is backwards on your display, try enabling this.
config LV_INVERT_COLORS config LV_INVERT_COLORS
bool "Invert colors in display" if LV_TFT_DISPLAY_CONTROLLER_ILI9341 || LV_TFT_DISPLAY_CONTROLLER_ST7735S || LV_TFT_DISPLAY_CONTROLLER_ILI9481 || LV_TFT_DISPLAY_CONTROLLER_ST7789 || LV_TFT_DISPLAY_CONTROLLER_SSD1306 || LV_TFT_DISPLAY_CONTROLLER_SH1107 || LV_TFT_DISPLAY_CONTROLLER_HX8357 || LV_TFT_DISPLAY_CONTROLLER_GC9A01 || LV_TFT_DISPLAY_CONTROLLER_ILI9163C bool "Invert colors in display" if LV_TFT_DISPLAY_CONTROLLER_ILI9341 || LV_TFT_DISPLAY_CONTROLLER_ST7735S || LV_TFT_DISPLAY_CONTROLLER_ILI9481 || LV_TFT_DISPLAY_CONTROLLER_ST7789 || LV_TFT_DISPLAY_CONTROLLER_SSD1306 || LV_TFT_DISPLAY_CONTROLLER_SH1107 || LV_TFT_DISPLAY_CONTROLLER_HX8357
default y if LV_PREDEFINED_DISPLAY_M5STACK || LV_PREDEFINED_DISPLAY_M5STICKC default y if LV_PREDEFINED_DISPLAY_M5STACK || LV_PREDEFINED_DISPLAY_M5STICKC
help help
If the colors look inverted on your display, try enabling this. If the colors look inverted on your display, try enabling this.
If it didn't help try LVGL configuration -> Swap the 2 bytes of RGB565 color. If it didn't help try LVGL configuration -> Swap the 2 bytes of RGB565 color.
config LV_M5STICKC_HANDLE_AXP192
bool "Handle Backlight and TFT power for M5StickC using AXP192." if LV_PREDEFINED_DISPLAY_M5STICKC || LV_TFT_DISPLAY_CONTROLLER_ST7735S
default y if LV_PREDEFINED_DISPLAY_M5STICKC
help
Display and TFT power supply on M5StickC is controlled using an AXP192 Power Mangerment IC.
Select yes if you want to enable TFT IC (LDO3) and backlight power using AXP192 by LVGL, or select no if you want to take care of
power management in your own code.
config LV_AXP192_PIN_SDA
int "GPIO for AXP192 I2C SDA"
depends on LV_M5STICKC_HANDLE_AXP192
range 0 39
default 21 if LV_PREDEFINED_DISPLAY_M5STICKC
default 21
help
Configure the AXP192 I2C SDA pin here.
config LV_AXP192_PIN_SCL
int "GPIO for AXP192 I2C SCL"
depends on LV_M5STICKC_HANDLE_AXP192
range 0 39
default 22 if LV_PREDEFINED_DISPLAY_M5STICKC
default 22
help
Configure the AXP192 I2C SDA pin here.
# menu will be visible only when LV_PREDEFINED_DISPLAY_NONE is y # menu will be visible only when LV_PREDEFINED_DISPLAY_NONE is y
menu "Display RA8875 Configuration" menu "Display RA8875 Configuration"
@ -747,11 +776,11 @@ menu "LVGL TFT/Epaper Display controller"
config LV_DISP_ST7789_SOFT_RESET config LV_DISP_ST7789_SOFT_RESET
bool "Soft reset - use software reset instead of reset pin" bool "Soft reset - use software reset instead of reset pin"
depends on LV_TFT_DISPLAY_CONTROLLER_ST7789 depends on LV_TFT_DISPLAY_CONTROLLER_ST7789
default n default n
help help
Use software reset and ignores configured reset pin (some hardware does not use a reset pin). Use software reset and ignores configured reset pin (some hardware does not use a reset pin).
endmenu endmenu
# menu will be visible only when LV_PREDEFINED_DISPLAY_NONE is y # menu will be visible only when LV_PREDEFINED_DISPLAY_NONE is y
@ -760,10 +789,12 @@ menu "LVGL TFT/Epaper Display controller"
config LV_DISP_SPI_MOSI config LV_DISP_SPI_MOSI
int "GPIO for MOSI (Master Out Slave In)" if LV_TFT_DISPLAY_PROTOCOL_SPI int "GPIO for MOSI (Master Out Slave In)" if LV_TFT_DISPLAY_PROTOCOL_SPI
range 0 39 if IDF_TARGET_ESP32
range 0 43 if IDF_TARGET_ESP32S2
default 23 if LV_PREDEFINED_DISPLAY_WROVER4 default 23 if LV_PREDEFINED_DISPLAY_WROVER4
default 23 if LV_PREDEFINED_DISPLAY_ATAG default 23 if LV_PREDEFINED_DISPLAY_ATAG
default 23 if LV_PREDEFINED_DISPLAY_M5STACK || LV_PREDEFINED_DISPLAY_M5STICK default 23 if LV_PREDEFINED_DISPLAY_M5STACK || LV_PREDEFINED_DISPLAY_M5STICK
default 23 if LV_PREDEFINED_DISPLAY_M5CORE2
default 15 if LV_PREDEFINED_DISPLAY_M5STICKC default 15 if LV_PREDEFINED_DISPLAY_M5STICKC
default 18 if LV_PREDEFINED_DISPLAY_ADA_FEATHERWING default 18 if LV_PREDEFINED_DISPLAY_ADA_FEATHERWING
default 23 if LV_PREDEFINED_PINS_TKOALA default 23 if LV_PREDEFINED_PINS_TKOALA
@ -771,13 +802,13 @@ menu "LVGL TFT/Epaper Display controller"
default 19 if LV_PREDEFINED_DISPLAY_TTGO_CAMERA_PLUS default 19 if LV_PREDEFINED_DISPLAY_TTGO_CAMERA_PLUS
default 13 if LV_PREDEFINED_DISPLAY_WT32_SC01 default 13 if LV_PREDEFINED_DISPLAY_WT32_SC01
default 13 default 13
help help
Configure the display MOSI pin here. Configure the display MOSI pin here.
config LV_DISPLAY_USE_SPI_MISO config LV_DISPLAY_USE_SPI_MISO
bool "GPIO for MISO (Master In Slave Out)" if LV_TFT_DISPLAY_PROTOCOL_SPI bool "GPIO for MISO (Master In Slave Out)" if LV_TFT_DISPLAY_PROTOCOL_SPI
default y if LV_PREDEFINED_PINS_TKOALA default y if LV_PREDEFINED_PINS_TKOALA
default y if LV_PREDEFINED_DISPLAY_M5CORE2
help help
Enable the MISO signal to control the display. You can disable Enable the MISO signal to control the display. You can disable
it when the display does not need MISO signal to be controlled. it when the display does not need MISO signal to be controlled.
@ -785,8 +816,10 @@ menu "LVGL TFT/Epaper Display controller"
config LV_DISP_SPI_MISO config LV_DISP_SPI_MISO
int "GPIO for MISO (Master In Slave Out)" if LV_TFT_DISPLAY_PROTOCOL_SPI int "GPIO for MISO (Master In Slave Out)" if LV_TFT_DISPLAY_PROTOCOL_SPI
depends on LV_DISPLAY_USE_SPI_MISO depends on LV_DISPLAY_USE_SPI_MISO
range 0 39 if IDF_TARGET_ESP32
range 0 43 if IDF_TARGET_ESP32S2
default 19 if LV_PREDEFINED_PINS_TKOALA default 19 if LV_PREDEFINED_PINS_TKOALA
default 38 if LV_PREDEFINED_DISPLAY_M5CORE2
default 0 default 0
help help
@ -804,6 +837,9 @@ menu "LVGL TFT/Epaper Display controller"
config LV_DISP_SPI_IO2 config LV_DISP_SPI_IO2
int "GPIO for Quad SPI IO2/WP" if LV_TFT_DISPLAY_PROTOCOL_SPI int "GPIO for Quad SPI IO2/WP" if LV_TFT_DISPLAY_PROTOCOL_SPI
depends on LV_TFT_DISPLAY_SPI_TRANS_MODE_QIO depends on LV_TFT_DISPLAY_SPI_TRANS_MODE_QIO
range -1 39 if IDF_TARGET_ESP32
range -1 43 if IDF_TARGET_ESP32S2
default 22 if LV_PREDEFINED_PINS_TKOALA && LV_TFT_DISPLAY_SPI_TRANS_MODE_QIO default 22 if LV_PREDEFINED_PINS_TKOALA && LV_TFT_DISPLAY_SPI_TRANS_MODE_QIO
default -1 default -1
help help
@ -812,6 +848,9 @@ menu "LVGL TFT/Epaper Display controller"
config LV_DISP_SPI_IO3 config LV_DISP_SPI_IO3
int "GPIO for Quad SPI IO3/HD" if LV_TFT_DISPLAY_PROTOCOL_SPI int "GPIO for Quad SPI IO3/HD" if LV_TFT_DISPLAY_PROTOCOL_SPI
depends on LV_TFT_DISPLAY_SPI_TRANS_MODE_QIO depends on LV_TFT_DISPLAY_SPI_TRANS_MODE_QIO
range -1 39 if IDF_TARGET_ESP32
range -1 43 if IDF_TARGET_ESP32S2
default 21 if LV_PREDEFINED_PINS_TKOALA && LV_TFT_DISPLAY_SPI_TRANS_MODE_QIO default 21 if LV_PREDEFINED_PINS_TKOALA && LV_TFT_DISPLAY_SPI_TRANS_MODE_QIO
default -1 default -1
help help
@ -819,8 +858,10 @@ menu "LVGL TFT/Epaper Display controller"
config LV_DISP_SPI_CLK config LV_DISP_SPI_CLK
int "GPIO for CLK (SCK / Serial Clock)" if LV_TFT_DISPLAY_PROTOCOL_SPI int "GPIO for CLK (SCK / Serial Clock)" if LV_TFT_DISPLAY_PROTOCOL_SPI
range 0 39 if IDF_TARGET_ESP32
range 0 43 if IDF_TARGET_ESP32S2
default 18 if LV_PREDEFINED_DISPLAY_M5STACK || LV_PREDEFINED_DISPLAY_M5STICK default 18 if LV_PREDEFINED_DISPLAY_M5STACK || LV_PREDEFINED_DISPLAY_M5STICK
default 18 if LV_PREDEFINED_DISPLAY_M5CORE2
default 13 if LV_PREDEFINED_DISPLAY_M5STICKC default 13 if LV_PREDEFINED_DISPLAY_M5STICKC
default 18 if LV_PREDEFINED_DISPLAY_ATAG default 18 if LV_PREDEFINED_DISPLAY_ATAG
default 19 if LV_PREDEFINED_DISPLAY_WROVER4 default 19 if LV_PREDEFINED_DISPLAY_WROVER4
@ -844,9 +885,11 @@ menu "LVGL TFT/Epaper Display controller"
config LV_DISP_SPI_CS config LV_DISP_SPI_CS
int "GPIO for CS (Slave Select)" if LV_TFT_DISPLAY_PROTOCOL_SPI int "GPIO for CS (Slave Select)" if LV_TFT_DISPLAY_PROTOCOL_SPI
depends on LV_DISPLAY_USE_SPI_CS depends on LV_DISPLAY_USE_SPI_CS
range 0 39 if IDF_TARGET_ESP32
range 0 43 if IDF_TARGET_ESP32S2
default 5 if LV_PREDEFINED_PINS_38V1 default 5 if LV_PREDEFINED_PINS_38V1
default 14 if LV_PREDEFINED_DISPLAY_M5STACK || LV_PREDEFINED_DISPLAY_M5STICK default 14 if LV_PREDEFINED_DISPLAY_M5STACK || LV_PREDEFINED_DISPLAY_M5STICK
default 5 if LV_PREDEFINED_DISPLAY_M5CORE2
default 5 if LV_PREDEFINED_DISPLAY_M5STICKC default 5 if LV_PREDEFINED_DISPLAY_M5STICKC
default 22 if LV_PREDEFINED_DISPLAY_WROVER4 default 22 if LV_PREDEFINED_DISPLAY_WROVER4
default 15 if LV_PREDEFINED_DISPLAY_ADA_FEATHERWING default 15 if LV_PREDEFINED_DISPLAY_ADA_FEATHERWING
@ -869,11 +912,13 @@ menu "LVGL TFT/Epaper Display controller"
config LV_DISP_PIN_DC config LV_DISP_PIN_DC
int "GPIO for DC (Data / Command)" if LV_TFT_DISPLAY_PROTOCOL_SPI int "GPIO for DC (Data / Command)" if LV_TFT_DISPLAY_PROTOCOL_SPI
range 0 39 if IDF_TARGET_ESP32
range 0 43 if IDF_TARGET_ESP32S2
depends on LV_DISPLAY_USE_DC depends on LV_DISPLAY_USE_DC
default 19 if LV_PREDEFINED_PINS_38V1 default 19 if LV_PREDEFINED_PINS_38V1
default 17 if LV_PREDEFINED_PINS_38V4 default 17 if LV_PREDEFINED_PINS_38V4
default 27 if LV_PREDEFINED_DISPLAY_M5STACK || LV_PREDEFINED_DISPLAY_M5STICK default 27 if LV_PREDEFINED_DISPLAY_M5STACK || LV_PREDEFINED_DISPLAY_M5STICK
default 15 if LV_PREDEFINED_DISPLAY_M5CORE2
default 23 if LV_PREDEFINED_DISPLAY_M5STICKC default 23 if LV_PREDEFINED_DISPLAY_M5STICKC
default 21 if LV_PREDEFINED_DISPLAY_WROVER4 default 21 if LV_PREDEFINED_DISPLAY_WROVER4
default 21 if LV_PREDEFINED_DISPLAY_WT32_SC01 default 21 if LV_PREDEFINED_DISPLAY_WT32_SC01
@ -887,22 +932,11 @@ menu "LVGL TFT/Epaper Display controller"
help help
Configure the display DC pin here. Configure the display DC pin here.
config LV_DISP_USE_RST
bool "Use a GPIO for resetting the display" if LV_TFT_DISPLAY_PROTOCOL_SPI
default n if LV_PREDEFINED_DISPLAY_M5CORE2
default y
help
Enable display reset control. Set this if the reset pin of the
display is connected to the host. If this is not set, then it is
the user's responsibility to ensure that the display is reset
before initialisation.
You may want to disable this option because the reset pin is not
connected, or is connected to an external component such as the
power management IC.
config LV_DISP_PIN_RST config LV_DISP_PIN_RST
int "GPIO for Reset" if LV_TFT_DISPLAY_PROTOCOL_SPI && !LV_DISP_ST7789_SOFT_RESET int "GPIO for Reset" if LV_TFT_DISPLAY_PROTOCOL_SPI && !LV_DISP_ST7789_SOFT_RESET
depends on LV_DISP_USE_RST range 0 39 if IDF_TARGET_ESP32
range 0 43 if IDF_TARGET_ESP32S2
default 18 if LV_PREDEFINED_PINS_38V1 default 18 if LV_PREDEFINED_PINS_38V1
default 25 if LV_PREDEFINED_PINS_38V4 default 25 if LV_PREDEFINED_PINS_38V4
default 33 if LV_PREDEFINED_DISPLAY_M5STACK || LV_PREDEFINED_DISPLAY_M5STICK default 33 if LV_PREDEFINED_DISPLAY_M5STACK || LV_PREDEFINED_DISPLAY_M5STICK
@ -921,103 +955,84 @@ menu "LVGL TFT/Epaper Display controller"
config LV_DISP_PIN_BUSY config LV_DISP_PIN_BUSY
int "GPIO for Busy" if LV_TFT_DISPLAY_CONTROLLER_IL3820 || LV_TFT_DISPLAY_CONTROLLER_JD79653A || LV_TFT_DISPLAY_CONTROLLER_UC8151D int "GPIO for Busy" if LV_TFT_DISPLAY_CONTROLLER_IL3820 || LV_TFT_DISPLAY_CONTROLLER_JD79653A || LV_TFT_DISPLAY_CONTROLLER_UC8151D
range 0 39 if IDF_TARGET_ESP32
range 0 43 if IDF_TARGET_ESP32S2
default 35 if LV_TFT_DISPLAY_CONTROLLER_IL3820 || LV_TFT_DISPLAY_CONTROLLER_JD79653A || LV_TFT_DISPLAY_CONTROLLER_UC8151D default 35 if LV_TFT_DISPLAY_CONTROLLER_IL3820 || LV_TFT_DISPLAY_CONTROLLER_JD79653A || LV_TFT_DISPLAY_CONTROLLER_UC8151D
default 35 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 default 35
default 21 if IDF_TARGET_ESP32C3
help help
Configure the display Busy pin here. Configure the display Busy pin here.
config LV_ENABLE_BACKLIGHT_CONTROL
bool "Enable control of the display backlight by using an GPIO." if \
( LV_PREDEFINED_DISPLAY_NONE && ! ( LV_TFT_DISPLAY_CONTROLLER_SH1107 || LV_TFT_DISPLAY_CONTROLLER_SSD1306 ) ) \
|| LV_PREDEFINED_DISPLAY_RPI_MPI3501
default y if LV_PREDEFINED_DISPLAY_M5STACK
default y if LV_PREDEFINED_DISPLAY_WROVER4
default y if LV_PREDEFINED_DISPLAY_ERTFT0356
default y if LV_PREDEFINED_DISPLAY_TTGO
default y if LV_PREDEFINED_DISPLAY_TTGO_CAMERA_PLUS
default y if LV_PREDEFINED_DISPLAY_WT32_SC01
help
Enable controlling the display backlight using an GPIO
config LV_BACKLIGHT_ACTIVE_LVL
bool "Is backlight turn on with a HIGH (1) logic level?"
depends on LV_ENABLE_BACKLIGHT_CONTROL
default y if LV_PREDEFINED_DISPLAY_M5STACK
default y if LV_PREDEFINED_DISPLAY_ERTFT0356
default y if LV_PREDEFINED_DISPLAY_TTGO
default y if LV_PREDEFINED_DISPLAY_TTGO_CAMERA_PLUS
default y if LV_PREDEFINED_DISPLAY_WT32_SC01
help
Some backlights are turned on with a high signal, others held low.
If enabled, a value of 1 will be sent to the display to enable the backlight,
otherwise a 0 will be expected to enable it.
config LV_DISP_PIN_BCKL
int "GPIO for Backlight Control"
depends on LV_ENABLE_BACKLIGHT_CONTROL
range 0 39 if IDF_TARGET_ESP32
range 0 43 if IDF_TARGET_ESP32S2
default 23 if LV_PREDEFINED_PINS_38V1
default 26 if LV_PREDEFINED_PINS_38V4
default 32 if LV_PREDEFINED_DISPLAY_M5STACK
default 5 if LV_PREDEFINED_DISPLAY_WROVER4
default 2 if LV_PREDEFINED_DISPLAY_ADA_FEATHERWING
default 27 if LV_PREDEFINED_DISPLAY_ERTFT0356
default 0 if LV_PREDEFINED_PINS_TKOALA
default 4 if LV_PREDEFINED_DISPLAY_TTGO
default 2 if LV_PREDEFINED_DISPLAY_TTGO_CAMERA_PLUS
default 23 if LV_PREDEFINED_DISPLAY_WT32_SC01
default 27
help
Configure the display BCLK (LED) pin here.
config LV_DISP_PIN_SDA
int "GPIO for I2C SDA" if LV_TFT_DISPLAY_PROTOCOL_I2C
range 0 39 if IDF_TARGET_ESP32
range 0 43 if IDF_TARGET_ESP32S2
default 5 if LV_PREDEFINED_DISPLAY_WEMOS_LOLIN
default 5
help
Configure the I2C SDA pin here.
config LV_DISP_PIN_SCL
int "GPIO for I2C SCL" if LV_TFT_DISPLAY_PROTOCOL_I2C
range 0 39 if IDF_TARGET_ESP32
range 0 43 if IDF_TARGET_ESP32S2
default 4 if LV_PREDEFINED_DISPLAY_WEMOS_LOLIN
default 4
help
Configure the I2C SCL pin here.
endmenu endmenu
choice
prompt "Select an I2C port for the display"
default LV_I2C_DISPLAY_PORT_0
depends on LV_I2C_DISPLAY
config LV_I2C_DISPLAY_PORT_0
bool
prompt "I2C port 0"
help
I2C is shared peripheral managed by I2C Manager. In order to configure I2C Manager (pinout, etc.) see menu
Component config->I2C Port Settings.
config LV_I2C_DISPLAY_PORT_1
bool
prompt "I2C port 1"
help
I2C is shared peripheral managed by I2C Manager. In order to configure I2C Manager (pinout, etc.) see menu
Component config->I2C Port Settings.
endchoice
choice
default LV_DISP_BACKLIGHT_SWITCH
prompt "Backlight Control" if \
(! ( LV_TFT_DISPLAY_CONTROLLER_SH1107 || LV_TFT_DISPLAY_CONTROLLER_SSD1306 ) )
config LV_DISP_BACKLIGHT_OFF
bool
prompt "Not Used"
help
Display backlight is not controlled by this driver, must be hardwired in hardware.
config LV_DISP_BACKLIGHT_SWITCH
bool
prompt "Switch control"
help
Display backlight can be switched on or off.
config LV_DISP_BACKLIGHT_PWM
bool
prompt "PWM control"
help
Display backlight is controlled by pulse-width modulation, allowing brightness settings.
endchoice
config LV_BACKLIGHT_ACTIVE_LVL
bool "Is backlight turn on with a HIGH (1) logic level?" if \
( LV_PREDEFINED_DISPLAY_NONE && ! ( LV_TFT_DISPLAY_CONTROLLER_SH1107 || LV_TFT_DISPLAY_CONTROLLER_SSD1306 ) ) \
|| LV_PREDEFINED_DISPLAY_RPI_MPI3501
depends on !LV_DISP_BACKLIGHT_OFF
default y if LV_PREDEFINED_DISPLAY_M5STACK
default y if LV_PREDEFINED_DISPLAY_ERTFT0356
default y if LV_PREDEFINED_DISPLAY_TTGO
default y if LV_PREDEFINED_DISPLAY_TTGO_CAMERA_PLUS
default y if LV_PREDEFINED_DISPLAY_WT32_SC01
help
Some backlights are turned on with a high signal, others held low.
If enabled, a value of 1 will be sent to the display to enable the backlight,
otherwise a 0 will be expected to enable it.
config LV_DISP_PIN_BCKL
int "GPIO for Backlight Control" if \
( LV_PREDEFINED_DISPLAY_NONE && ! ( LV_TFT_DISPLAY_CONTROLLER_SH1107 || LV_TFT_DISPLAY_CONTROLLER_SSD1306 ) ) \
|| LV_PREDEFINED_DISPLAY_RPI_MPI3501
depends on !LV_DISP_BACKLIGHT_OFF
default 23 if LV_PREDEFINED_PINS_38V1
default 26 if LV_PREDEFINED_PINS_38V4
default 32 if LV_PREDEFINED_DISPLAY_M5STACK
default 5 if LV_PREDEFINED_DISPLAY_WROVER4
default 2 if LV_PREDEFINED_DISPLAY_ADA_FEATHERWING
default 27 if LV_PREDEFINED_DISPLAY_ERTFT0356
default 0 if LV_PREDEFINED_PINS_TKOALA
default 4 if LV_PREDEFINED_DISPLAY_TTGO
default 2 if LV_PREDEFINED_DISPLAY_TTGO_CAMERA_PLUS
default 23 if LV_PREDEFINED_DISPLAY_WT32_SC01
default -1
help
Configure the display BCLK (LED) pin here.
config LV_I2C
bool
default y if LV_I2C_DISPLAY
config LV_I2C_DISPLAY_PORT
int
default 1 if LV_I2C_DISPLAY_PORT_1
default 0
endmenu endmenu

View file

@ -0,0 +1,95 @@
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "calepd_epaper.h"
// NOTE: This needs Epdiy component https://github.com/vroland/epdiy
// Run idf.py menuconfig-> Component Config -> E-Paper driver and select:
// Display type: LILIGO 4.7 ED047TC1
// Board: LILIGO T5-4.7 Epaper
// In the same section Component Config -> ESP32 Specifics -> Enable PSRAM
//#include "parallel/ED047TC1.h"
//Ed047TC1 display;
// SPI Generic epapers (Goodisplay/ Waveshare)
// Select the right class for your SPI epaper: https://github.com/martinberlin/cale-idf/wiki
//#include <gdew0583t7.h>
#include <goodisplay/gdey027T91.h>
EpdSpi io;
Gdey027T91 display(io);
/** test Display dimensions
* Do not forget to set: menuconfig -> Components -> LVGL configuration
* Max. Horizontal resolution 264 -> WIDTH of your epaper
* Max. Vertical resolution 176 -> HEIGHT
*/
/*********************
* DEFINES
*********************/
#define TAG "CalEPD"
uint16_t flushcalls = 0;
void delay(uint32_t period_ms) {
vTaskDelay(pdMS_TO_TICKS(period_ms));
}
/* Display initialization routine */
void calepd_init(void)
{
printf("calepd_init\n");
display.init();
display.setMonoMode(true);
display.setRotation(3);
// Partial update test
/* display.fillRect(1,10, display.width(), 20, EPD_BLACK);
display.updateWindow(1,10, display.width(), 20); */
printf("calEPD done with SPI init\n");
// Clear screen
//display.update();
}
/* Required by LVGL */
void calepd_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map)
{
++flushcalls;
printf("flush %d x:%d y:%d w:%d h:%d\n", flushcalls,area->x1,area->y1,lv_area_get_width(area),lv_area_get_height(area));
// Full update
if (lv_area_get_width(area)==display.width() && lv_area_get_height(area)==display.height()) {
display.update();
} else {
// Partial update:
//display.update(); // Uncomment to disable partial update
display.updateWindow(area->x1,area->y1,lv_area_get_width(area),lv_area_get_height(area));
//delay(10);
}
/* IMPORTANT!!!
* Inform the graphics library that you are ready with the flushing */
lv_disp_flush_ready(drv);
}
/* Called for each pixel */
void calepd_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t* buf,
lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
lv_color_t color, lv_opa_t opa)
{
// Test using RGB232
int16_t epd_color = EPD_WHITE;
// Color setting use: RGB232
// Only monochrome:All what is not white, turn black
if (color.full<254) {
//if (color.ch.red < 7 && color.ch.green < 7 && color.ch.blue < 7) {
epd_color = EPD_BLACK;
}
display.drawPixel((int16_t)x, (int16_t)y, epd_color);
//If not drawing anything: Debug to see if this function is called:
//printf("set_px %d %d R:%d G:%d B:%d\n",(int16_t)x,(int16_t)y, color.ch.red, color.ch.green, color.ch.blue);
}

38
lvgl_tft/calepd_epaper.h Normal file
View file

@ -0,0 +1,38 @@
/**
* Display class for generic e-Paper driven by EPDiy class
*/
#ifndef CALEPD_H
#define CALEPD_H
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#define EPDIY_COLUMNS (LV_HOR_RES_MAX / 8)
#ifdef __cplusplus
extern "C" {
#endif
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
#include "sdkconfig.h"
/* Configure your display */
void calepd_init(void);
/* LVGL callbacks */
void calepd_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map);
/* Only for monochrome displays. But we use epdiy_set_px also for epapers */
//void epdiy_rounder(lv_disp_drv_t *disp_drv, lv_area_t *area);
void calepd_set_px_cb(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* EPDIY_H */

View file

@ -4,15 +4,18 @@
#include "disp_driver.h" #include "disp_driver.h"
#include "disp_spi.h" #include "disp_spi.h"
#include "esp_lcd_backlight.h"
#include "sdkconfig.h"
void *disp_driver_init(void)
void disp_driver_init(void)
{ {
#if defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341 #if defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341
ili9341_init(); ili9341_init();
#elif defined CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER #elif defined CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER
epdiy_init(); epdiy_init();
#elif defined CONFIG_LV_EPAPER_CALEPD_DISPLAY_CONTROLLER
calepd_init();
#elif defined CONFIG_LV_SHARP_DISPLAY_CONTROLLER
sharp_init();
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481 #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481
ili9481_init(); ili9481_init();
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488 #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488
@ -25,7 +28,7 @@ void *disp_driver_init(void)
st7735s_init(); st7735s_init();
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_HX8357 #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_HX8357
hx8357_init(); hx8357_init();
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9486 #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9486
ili9486_init(); ili9486_init();
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SH1107 #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SH1107
sh1107_init(); sh1107_init();
@ -43,35 +46,6 @@ void *disp_driver_init(void)
jd79653a_init(); jd79653a_init();
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D
uc8151d_init(); uc8151d_init();
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9163C
ili9163c_init();
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_PCD8544
pcd8544_init();
#endif
// We still use menuconfig for these settings
// It will be set up during runtime in the future
#if (defined(CONFIG_LV_DISP_BACKLIGHT_SWITCH) || defined(CONFIG_LV_DISP_BACKLIGHT_PWM))
const disp_backlight_config_t bckl_config = {
.gpio_num = CONFIG_LV_DISP_PIN_BCKL,
#if defined CONFIG_LV_DISP_BACKLIGHT_PWM
.pwm_control = true,
#else
.pwm_control = false,
#endif
#if defined CONFIG_LV_BACKLIGHT_ACTIVE_LVL
.output_invert = false, // Backlight on high
#else
.output_invert = true, // Backlight on low
#endif
.timer_idx = 0,
.channel_idx = 0 // @todo this prevents us from having two PWM controlled displays
};
disp_backlight_h bckl_handle = disp_backlight_new(&bckl_config);
disp_backlight_set(bckl_handle, 100);
return bckl_handle;
#else
return NULL;
#endif #endif
} }
@ -80,7 +54,11 @@ void disp_driver_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t *
#if defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341 #if defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341
ili9341_flush(drv, area, color_map); ili9341_flush(drv, area, color_map);
#elif defined CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER #elif defined CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER
epdiy_flush(drv, area, color_map); epdiy_flush(drv, area, color_map);
#elif defined CONFIG_LV_EPAPER_CALEPD_DISPLAY_CONTROLLER
calepd_flush(drv, area, color_map);
#elif defined CONFIG_LV_SHARP_DISPLAY_CONTROLLER
sharp_flush(drv, area, color_map);
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481 #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481
ili9481_flush(drv, area, color_map); ili9481_flush(drv, area, color_map);
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488 #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488
@ -111,10 +89,6 @@ void disp_driver_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t *
jd79653a_lv_fb_flush(drv, area, color_map); jd79653a_lv_fb_flush(drv, area, color_map);
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D
uc8151d_lv_fb_flush(drv, area, color_map); uc8151d_lv_fb_flush(drv, area, color_map);
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9163C
ili9163c_flush(drv, area, color_map);
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_PCD8544
pcd8544_flush(drv, area, color_map);
#endif #endif
} }
@ -131,18 +105,22 @@ void disp_driver_rounder(lv_disp_drv_t * disp_drv, lv_area_t * area)
jd79653a_lv_rounder_cb(disp_drv, area); jd79653a_lv_rounder_cb(disp_drv, area);
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D
uc8151d_lv_rounder_cb(disp_drv, area); uc8151d_lv_rounder_cb(disp_drv, area);
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_PCD8544 #elif defined CONFIG_LV_SHARP_DISPLAY_CONTROLLER
pcd8544_rounder(disp_drv, area); sharp_rounder(disp_drv, area);
#endif #endif
} }
void disp_driver_set_px(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, void disp_driver_set_px(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
lv_color_t color, lv_opa_t opa) lv_color_t color, lv_opa_t opa)
{ {
#if defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SSD1306 #if defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SSD1306
ssd1306_set_px_cb(disp_drv, buf, buf_w, x, y, color, opa); ssd1306_set_px_cb(disp_drv, buf, buf_w, x, y, color, opa);
#elif defined CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER #elif defined CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER
epdiy_set_px_cb(disp_drv, buf, buf_w, x, y, color, opa); epdiy_set_px_cb(disp_drv, buf, buf_w, x, y, color, opa);
#elif defined CONFIG_LV_EPAPER_CALEPD_DISPLAY_CONTROLLER
calepd_set_px_cb(disp_drv, buf, buf_w, x, y, color, opa);
#elif defined CONFIG_LV_SHARP_DISPLAY_CONTROLLER
sharp_set_px_cb(disp_drv, buf, buf_w, x, y, color, opa);
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SH1107 #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SH1107
sh1107_set_px_cb(disp_drv, buf, buf_w, x, y, color, opa); sh1107_set_px_cb(disp_drv, buf, buf_w, x, y, color, opa);
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_IL3820 #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_IL3820
@ -151,7 +129,5 @@ void disp_driver_set_px(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_
jd79653a_lv_set_fb_cb(disp_drv, buf, buf_w, x, y, color, opa); jd79653a_lv_set_fb_cb(disp_drv, buf, buf_w, x, y, color, opa);
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D
uc8151d_lv_set_fb_cb(disp_drv, buf, buf_w, x, y, color, opa); uc8151d_lv_set_fb_cb(disp_drv, buf, buf_w, x, y, color, opa);
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_PCD8544
pcd8544_set_px_cb(disp_drv, buf, buf_w, x, y, color, opa);
#endif #endif
} }

View file

@ -22,6 +22,11 @@ extern "C" {
#include "ili9341.h" #include "ili9341.h"
#elif defined CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER #elif defined CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER
#include "lvgl_tft/epdiy_epaper.h" #include "lvgl_tft/epdiy_epaper.h"
#elif defined CONFIG_LV_EPAPER_CALEPD_DISPLAY_CONTROLLER
#include "lvgl_tft/calepd_epaper.h"
#elif defined CONFIG_LV_SHARP_DISPLAY_CONTROLLER
#include "lvgl_tft/sharp_mip.h"
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481 #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481
#include "ili9481.h" #include "ili9481.h"
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488 #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488
@ -52,10 +57,6 @@ extern "C" {
#include "jd79653a.h" #include "jd79653a.h"
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D
#include "uc8151d.h" #include "uc8151d.h"
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9163C
#include "ili9163c.h"
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_PCD8544
#include "pcd8544.h"
#endif #endif
/********************* /*********************
@ -71,7 +72,7 @@ extern "C" {
**********************/ **********************/
/* Initialize display */ /* Initialize display */
void *disp_driver_init(void); void disp_driver_init(void);
/* Display flush callback */ /* Display flush callback */
void disp_driver_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map); void disp_driver_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);

View file

@ -310,12 +310,7 @@ static void IRAM_ATTR spi_ready(spi_transaction_t *trans)
disp = lv_refr_get_disp_refreshing(); disp = lv_refr_get_disp_refreshing();
#endif #endif
#if LVGL_VERSION_MAJOR < 8
lv_disp_flush_ready(&disp->driver); lv_disp_flush_ready(&disp->driver);
#else
lv_disp_flush_ready(disp->driver);
#endif
} }
if (chained_post_cb) { if (chained_post_cb) {

125
lvgl_tft/epdiy_epaper.cpp Normal file
View file

@ -0,0 +1,125 @@
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "epdiy_epaper.h"
#include "epdiy.h"
//#include "epd_highlevel.h"
EpdiyHighlevelState hl;
uint16_t flushcalls = 0;
uint8_t * framebuffer;
uint8_t temperature = 25;
bool init = true;
// MODE_DU: Fast monochrome | MODE_GC16 slow with 16 grayscales
enum EpdDrawMode updateMode = MODE_DU;
/* Display initialization routine */
void epdiy_init(void)
{
epd_init(&epd_board_v7, &ED097TC2, EPD_LUT_64K);
// Set VCOM for boards that allow to set this in software (in mV).
// This will print an error if unsupported. In this case,
// set VCOM using the hardware potentiometer and delete this line.
epd_set_vcom(1760);
// Only for older versions epdiy
//epd_init(EPD_OPTIONS_DEFAULT);
hl = epd_hl_init(EPD_BUILTIN_WAVEFORM);
framebuffer = epd_hl_get_framebuffer(&hl);
epd_poweron();
//Clear all always in init:
epd_fullclear(&hl, temperature);
}
/* Suggested by @kisvegabor https://forum.lvgl.io/t/lvgl-port-to-be-used-with-epaper-displays/5630/26 */
void buf_area_to_framebuffer(const lv_area_t *area, const uint8_t *image_data) {
assert(framebuffer != NULL);
uint8_t *fb_ptr = &framebuffer[area->y1 * epd_width() / 2 + area->x1 / 2];
lv_coord_t img_w = lv_area_get_width(area);
for(uint32_t y = area->y1; y < area->y2; y++) {
memcpy(fb_ptr, image_data, img_w / 2);
fb_ptr += epd_width() / 2;
image_data += img_w / 2;
}
}
/* A copy from epd_copy_to_framebuffer with temporary lenght prediction */
void buf_copy_to_framebuffer(EpdRect image_area, const uint8_t *image_data) {
assert(framebuffer != NULL);
for (uint32_t i = 0; i < image_area.width * image_area.height; i++) {
uint8_t val = (i % 2) ? (image_data[i / 2] & 0xF0) >> 4
: image_data[i / 2] & 0x0F;
int xx = image_area.x + i % image_area.width;
if (xx < 0 || xx >= epd_width()) {
continue;
}
int yy = image_area.y + i / image_area.width;
if (yy < 0 || yy >= epd_height()) {
continue;
}
uint8_t *buf_ptr = &framebuffer[yy * epd_width() / 2 + xx / 2];
if (xx % 2) {
*buf_ptr = (*buf_ptr & 0x0F) | (val << 4);
} else {
*buf_ptr = (*buf_ptr & 0xF0) | val;
}
}
}
/* Required by LVGL. Sends the color_map to the screen with a partial update */
void epdiy_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map)
{
++flushcalls;
uint16_t w = lv_area_get_width(area);
uint16_t h = lv_area_get_height(area);
EpdRect update_area = {
.x = (uint16_t)area->x1,
.y = (uint16_t)area->y1,
.width = w,
.height = h
};
uint8_t* buf = (uint8_t *) color_map;
// Buffer debug
/*
for (int index=0; index<400; index++) {
printf("%x ", buf[index]);
} */
// UNCOMMENT only one of this options
// SAFE Option with EPDiy copy of epd_copy_to_framebuffer
buf_copy_to_framebuffer(update_area, buf);
//Faster mode suggested in LVGL forum (Leaves ghosting&prints bad sections / experimental) NOTE: Do NOT use in production
//buf_area_to_framebuffer(area, buf);
epd_hl_update_area(&hl, updateMode, temperature, update_area); //update_area
//printf("epdiy_flush %d x:%d y:%d w:%d h:%d\n", flushcalls,(uint16_t)area->x1,(uint16_t)area->y1,w,h);
/* Inform the graphics library that you are ready with the flushing */
lv_disp_flush_ready(drv);
}
/*
* Called for each pixel. Designed with the idea to fill the buffer directly, not to set each pixel, see LVGL Forum (buf_area_to_framebuffer)
*/
void epdiy_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t* buf,
lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
lv_color_t color, lv_opa_t opa)
{
// Test using RGB232
int16_t epd_color = 255;
if ((int16_t)color.full < 254) {
epd_color = (updateMode==MODE_DU) ? 0 : (int16_t)color.full / 3;
}
//Instead of using epd_draw_pixel: Set pixel directly in *buf that comes afterwards in flush as *color_map
uint16_t idx = (int16_t)y * buf_w / 2 + (int16_t)x / 2;
if (x % 2) {
buf[idx] = (buf[idx] & 0x0F) | (epd_color & 0xF0);
} else {
buf[idx] = (buf[idx] & 0xF0) | (epd_color >> 4);
}
}

View file

@ -0,0 +1,92 @@
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "epdiy_epaper.h"
#include "epd_driver.h"
#include "epd_highlevel.h"
/**************************************************************************************************
* NOTE: This file iis the first version that writes directly on the set_px callback
* each pixel into the epaper display buffer. The second version is not epdiy_epaper.cpp
* It writes *buf and then it comes as *color_map on the flush callback.
* Feel free to experiment with this 2. epdiy_epaper.cpp works better to make a small UX
**************************************************************************************************/
#define TAG "EPDIY"
EpdiyHighlevelState hl;
uint16_t flushcalls = 0;
uint8_t * framebuffer;
uint8_t temperature = 25;
/* Display initialization routine */
void epdiy_init(void)
{
epd_init(EPD_OPTIONS_DEFAULT);
hl = epd_hl_init(EPD_BUILTIN_WAVEFORM);
framebuffer = epd_hl_get_framebuffer(&hl);
epd_poweron();
//Clear all always in init?
//epd_fullclear(&hl, temperature);
}
uint16_t xo = 0;
uint16_t yo = 0;
/* Required by LVGL */
void epdiy_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map)
{
++flushcalls;
xo = area->x1;
yo = area->y1;
uint16_t w = lv_area_get_width(area);
uint16_t h = lv_area_get_height(area);
EpdRect update_area = {
.x = xo,
.y = yo,
.width = w,
.height = h,
};
epd_hl_update_area(&hl, MODE_GC16, temperature, update_area); //update_area
printf("epdiy_flush %d x:%d y:%d w:%d h:%d\n", flushcalls,xo,yo,w,h);
/* Inform the graphics library that you are ready with the flushing */
lv_disp_flush_ready(drv);
}
/*
* Called for each pixel. Designed with the idea to fill the buffer directly, not to set each pixel, see:
* https://forum.lvgl.io/t/lvgl-port-to-be-used-with-epaper-displays/5630/3
*/
void epdiy_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t* buf,
lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
lv_color_t color, lv_opa_t opa)
{
// Debug where x y is printed, not all otherwise is too much Serial
/* if ((int16_t)y%10==0 && flushcalls>0){
if ((int16_t)x%2==0){
printf("x%d y%d\n", (int16_t)x, (int16_t)y);
}
}
*/
// Test using RGB232
int16_t epd_color = 255;
if ((int16_t)color.full<250) {
epd_color = (int16_t)color.full/3;
}
int16_t x1 = (int16_t)x;
int16_t y1 = (int16_t)y;
//Instead of using epd_draw_pixel: Set pixel directly in buffer
//epd_draw_pixel(x1, y1, epd_color, framebuffer);
uint8_t *buf_ptr = &framebuffer[y1 * buf_w / 2 + x1 / 2];
if (x % 2) {
*buf_ptr = (*buf_ptr & 0x0F) | (epd_color & 0xF0);
} else {
*buf_ptr = (*buf_ptr & 0xF0) | (epd_color >> 4);
}
}

View file

@ -160,19 +160,21 @@ static uint8_t displayType = HX8357D;
void hx8357_init(void) void hx8357_init(void)
{ {
//Initialize non-SPI GPIOs //Initialize non-SPI GPIOs
gpio_pad_select_gpio(HX8357_DC); gpio_pad_select_gpio(HX8357_DC);
gpio_set_direction(HX8357_DC, GPIO_MODE_OUTPUT); gpio_set_direction(HX8357_DC, GPIO_MODE_OUTPUT);
gpio_pad_select_gpio(HX8357_RST);
#if HX8357_USE_RST
gpio_pad_select_gpio(HX8357_RST);
gpio_set_direction(HX8357_RST, GPIO_MODE_OUTPUT); gpio_set_direction(HX8357_RST, GPIO_MODE_OUTPUT);
#if HX8357_ENABLE_BACKLIGHT_CONTROL
gpio_pad_select_gpio(HX8357_BCKL);
gpio_set_direction(HX8357_BCKL, GPIO_MODE_OUTPUT);
#endif
//Reset the display //Reset the display
gpio_set_level(HX8357_RST, 0); gpio_set_level(HX8357_RST, 0);
vTaskDelay(10 / portTICK_RATE_MS); vTaskDelay(10 / portTICK_RATE_MS);
gpio_set_level(HX8357_RST, 1); gpio_set_level(HX8357_RST, 1);
vTaskDelay(120 / portTICK_RATE_MS); vTaskDelay(120 / portTICK_RATE_MS);
#endif
ESP_LOGI(TAG, "Initialization."); ESP_LOGI(TAG, "Initialization.");
@ -203,6 +205,8 @@ void hx8357_init(void)
#else #else
hx8357_send_cmd(HX8357_INVOFF); hx8357_send_cmd(HX8357_INVOFF);
#endif #endif
hx8357_enable_backlight(true);
} }
@ -239,6 +243,23 @@ void hx8357_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * colo
hx8357_send_color((void*)color_map, size * 2); hx8357_send_color((void*)color_map, size * 2);
} }
void hx8357_enable_backlight(bool backlight)
{
#if HX8357_ENABLE_BACKLIGHT_CONTROL
ESP_LOGD(TAG, "%s backlight.\n", backlight ? "Enabling" : "Disabling");
uint32_t tmp = 0;
#if (HX8357_BCKL_ACTIVE_LVL==1)
tmp = backlight ? 1 : 0;
#else
tmp = backlight ? 0 : 1;
#endif
gpio_set_level(HX8357_BCKL, tmp);
#endif
}
void hx8357_set_rotation(uint8_t r) void hx8357_set_rotation(uint8_t r)
{ {
r = r & 3; // can't be higher than 3 r = r & 3; // can't be higher than 3

View file

@ -35,10 +35,18 @@ extern "C" {
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
#define HX8357_DC CONFIG_LV_DISP_PIN_DC #define HX8357_DC CONFIG_LV_DISP_PIN_DC
#define HX8357_RST CONFIG_LV_DISP_PIN_RST #define HX8357_RST CONFIG_LV_DISP_PIN_RST
#define HX8357_USE_RST CONFIG_LV_DISP_USE_RST #define HX8357_BCKL CONFIG_LV_DISP_PIN_BCKL
#define HX8357_INVERT_COLORS CONFIG_LV_INVERT_COLORS
#define HX8357_ENABLE_BACKLIGHT_CONTROL CONFIG_LV_ENABLE_BACKLIGHT_CONTROL
#define HX8357_INVERT_COLORS CONFIG_LV_INVERT_COLORS
#if CONFIG_LV_BACKLIGHT_ACTIVE_LVL
#define HX8357_BCKL_ACTIVE_LVL 1
#else
#define HX8357_BCKL_ACTIVE_LVL 0
#endif
/******************* /*******************
@ -127,6 +135,7 @@ extern "C" {
void hx8357_init(void); void hx8357_init(void);
void hx8357_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map); void hx8357_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);
void hx8357_enable_backlight(bool backlight);
void hx8357_set_rotation(uint8_t r); void hx8357_set_rotation(uint8_t r);
/********************** /**********************

View file

@ -73,9 +73,9 @@ static uint8_t il3820_lut_initial[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; };
static uint8_t il3820_lut_default[] = { static uint8_t il3820_lut_default[] = {
0x10, 0x18, 0x18, 0x08, 0x18, 0x18, 0x10, 0x18, 0x18, 0x08, 0x18, 0x18,
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x13, 0x14, 0x44, 0x12, 0x00, 0x00, 0x13, 0x14, 0x44, 0x12,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; };
@ -113,7 +113,7 @@ void il3820_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_m
uint8_t *buffer = (uint8_t*) color_map; uint8_t *buffer = (uint8_t*) color_map;
uint16_t x_addr_counter = 0; uint16_t x_addr_counter = 0;
uint16_t y_addr_counter = 0; uint16_t y_addr_counter = 0;
/* Configure entry mode */ /* Configure entry mode */
il3820_write_cmd(IL3820_CMD_ENTRY_MODE, &il3820_scan_mode, 1); il3820_write_cmd(IL3820_CMD_ENTRY_MODE, &il3820_scan_mode, 1);
@ -131,7 +131,7 @@ void il3820_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_m
il3820_set_cursor(x_addr_counter, y_addr_counter); il3820_set_cursor(x_addr_counter, y_addr_counter);
il3820_send_cmd(IL3820_CMD_WRITE_RAM); il3820_send_cmd(IL3820_CMD_WRITE_RAM);
/* Write the pixel data to graphic RAM, linelen bytes at the time. */ /* Write the pixel data to graphic RAM, linelen bytes at the time. */
for(size_t row = 0; row <= (EPD_PANEL_HEIGHT - 1); row++){ for(size_t row = 0; row <= (EPD_PANEL_HEIGHT - 1); row++){
il3820_send_data(buffer, linelen); il3820_send_data(buffer, linelen);
@ -139,7 +139,7 @@ void il3820_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_m
} }
il3820_set_window(0, EPD_PANEL_WIDTH - 1, 0, EPD_PANEL_HEIGHT - 1); il3820_set_window(0, EPD_PANEL_WIDTH - 1, 0, EPD_PANEL_HEIGHT - 1);
il3820_update_display(); il3820_update_display();
/* IMPORTANT!!! /* IMPORTANT!!!
@ -152,7 +152,7 @@ void il3820_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_m
* BIT_SET(byte_index, bit_index) clears the bit_index pixel at byte_index of * BIT_SET(byte_index, bit_index) clears the bit_index pixel at byte_index of
* the display buffer. * the display buffer.
* BIT_CLEAR(byte_index, bit_index) sets the bit_index pixel at the byte_index * BIT_CLEAR(byte_index, bit_index) sets the bit_index pixel at the byte_index
* of the display buffer. */ * of the display buffer. */
void il3820_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t* buf, void il3820_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t* buf,
lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
lv_color_t color, lv_opa_t opa) lv_color_t color, lv_opa_t opa)
@ -198,24 +198,20 @@ void il3820_init(void)
/* Initialize non-SPI GPIOs */ /* Initialize non-SPI GPIOs */
gpio_pad_select_gpio(IL3820_DC_PIN); gpio_pad_select_gpio(IL3820_DC_PIN);
gpio_set_direction(IL3820_DC_PIN, GPIO_MODE_OUTPUT); gpio_set_direction(IL3820_DC_PIN, GPIO_MODE_OUTPUT);
gpio_pad_select_gpio(IL3820_BUSY_PIN);
gpio_set_direction(IL3820_BUSY_PIN, GPIO_MODE_INPUT);
#if IL3820_USE_RST
gpio_pad_select_gpio(IL3820_RST_PIN); gpio_pad_select_gpio(IL3820_RST_PIN);
gpio_set_direction(IL3820_RST_PIN, GPIO_MODE_OUTPUT); gpio_set_direction(IL3820_RST_PIN, GPIO_MODE_OUTPUT);
gpio_pad_select_gpio(IL3820_BUSY_PIN);
gpio_set_direction(IL3820_BUSY_PIN, GPIO_MODE_INPUT);
/* Harware reset */ /* Harware reset */
gpio_set_level( IL3820_RST_PIN, 0); gpio_set_level( IL3820_RST_PIN, 0);
vTaskDelay(IL3820_RESET_DELAY / portTICK_RATE_MS); vTaskDelay(IL3820_RESET_DELAY / portTICK_RATE_MS);
gpio_set_level( IL3820_RST_PIN, 1); gpio_set_level( IL3820_RST_PIN, 1);
vTaskDelay(IL3820_RESET_DELAY / portTICK_RATE_MS); vTaskDelay(IL3820_RESET_DELAY / portTICK_RATE_MS);
#endif
/* Software reset */ /* Software reset */
il3820_write_cmd(IL3820_CMD_SW_RESET, NULL, 0); il3820_write_cmd(IL3820_CMD_SW_RESET, NULL, 0);
/* Busy wait for the BUSY signal to go low */ /* Busy wait for the BUSY signal to go low */
il3820_waitbusy(IL3820_WAIT); il3820_waitbusy(IL3820_WAIT);
@ -243,10 +239,10 @@ void il3820_init(void)
// allow partial updates now // allow partial updates now
il3820_partial = true; il3820_partial = true;
/* Update LUT */ /* Update LUT */
il3820_write_cmd(IL3820_CMD_UPDATE_LUT, il3820_lut_default, sizeof(il3820_lut_default)); il3820_write_cmd(IL3820_CMD_UPDATE_LUT, il3820_lut_default, sizeof(il3820_lut_default));
/* Clear control memory and update */ /* Clear control memory and update */
il3820_clear_cntlr_mem(IL3820_CMD_WRITE_RAM, true); il3820_clear_cntlr_mem(IL3820_CMD_WRITE_RAM, true);
} }
@ -255,10 +251,10 @@ void il3820_init(void)
void il3820_sleep_in(void) void il3820_sleep_in(void)
{ {
uint8_t data[] = {0x01}; uint8_t data[] = {0x01};
/* Wait for the BUSY signal to go low */ /* Wait for the BUSY signal to go low */
il3820_waitbusy(IL3820_WAIT); il3820_waitbusy(IL3820_WAIT);
il3820_write_cmd(IL3820_CMD_SLEEP_MODE, data, 1); il3820_write_cmd(IL3820_CMD_SLEEP_MODE, data, 1);
} }
@ -268,15 +264,15 @@ static void il3820_waitbusy(int wait_ms)
int i = 0; int i = 0;
vTaskDelay(10 / portTICK_RATE_MS); // 10ms delay vTaskDelay(10 / portTICK_RATE_MS); // 10ms delay
for(i = 0; i < (wait_ms * 10); i++) { for(i = 0; i < (wait_ms * 10); i++) {
if(gpio_get_level(IL3820_BUSY_PIN) != IL3820_BUSY_LEVEL) { if(gpio_get_level(IL3820_BUSY_PIN) != IL3820_BUSY_LEVEL) {
return; return;
} }
vTaskDelay(10 / portTICK_RATE_MS); vTaskDelay(10 / portTICK_RATE_MS);
} }
ESP_LOGE( TAG, "busy exceeded %dms", i*10 ); ESP_LOGE( TAG, "busy exceeded %dms", i*10 );
} }
@ -292,10 +288,10 @@ static inline void il3820_data_mode(void)
gpio_set_level(IL3820_DC_PIN, 1); gpio_set_level(IL3820_DC_PIN, 1);
} }
static inline void il3820_write_cmd(uint8_t cmd, uint8_t *data, size_t len) static inline void il3820_write_cmd(uint8_t cmd, uint8_t *data, size_t len)
{ {
disp_wait_for_pending_transactions(); disp_wait_for_pending_transactions();
il3820_command_mode(); il3820_command_mode();
disp_spi_send_data(&cmd, 1); disp_spi_send_data(&cmd, 1);
@ -306,10 +302,10 @@ static inline void il3820_write_cmd(uint8_t cmd, uint8_t *data, size_t len)
} }
/* Send cmd to the display */ /* Send cmd to the display */
static inline void il3820_send_cmd(uint8_t cmd) static inline void il3820_send_cmd(uint8_t cmd)
{ {
disp_wait_for_pending_transactions(); disp_wait_for_pending_transactions();
il3820_command_mode(); il3820_command_mode();
disp_spi_send_data(&cmd, 1); disp_spi_send_data(&cmd, 1);
} }
@ -318,14 +314,14 @@ static inline void il3820_send_cmd(uint8_t cmd)
static void il3820_send_data(uint8_t *data, uint16_t length) static void il3820_send_data(uint8_t *data, uint16_t length)
{ {
disp_wait_for_pending_transactions(); disp_wait_for_pending_transactions();
il3820_data_mode(); il3820_data_mode();
disp_spi_send_colors(data, length); disp_spi_send_colors(data, length);
} }
/* Specify the start/end positions of the window address in the X and Y /* Specify the start/end positions of the window address in the X and Y
* directions by an address unit. * directions by an address unit.
* *
* @param sx: X Start position. * @param sx: X Start position.
* @param ex: X End position. * @param ex: X End position.
* @param ys: Y Start position. * @param ys: Y Start position.
@ -334,7 +330,7 @@ static void il3820_send_data(uint8_t *data, uint16_t length)
static inline void il3820_set_window( uint16_t sx, uint16_t ex, uint16_t ys, uint16_t ye) static inline void il3820_set_window( uint16_t sx, uint16_t ex, uint16_t ys, uint16_t ye)
{ {
uint8_t tmp[4] = {0}; uint8_t tmp[4] = {0};
tmp[0] = sx / 8; tmp[0] = sx / 8;
tmp[1] = ex / 8; tmp[1] = ex / 8;
@ -382,7 +378,7 @@ static void il3820_update_display(void)
} else { } else {
tmp = (IL3820_CTRL2_ENABLE_CLK | IL3820_CTRL2_ENABLE_ANALOG | IL3820_CTRL2_TO_PATTERN); tmp = (IL3820_CTRL2_ENABLE_CLK | IL3820_CTRL2_ENABLE_ANALOG | IL3820_CTRL2_TO_PATTERN);
} }
il3820_write_cmd(IL3820_CMD_UPDATE_CTRL2, &tmp, 1); il3820_write_cmd(IL3820_CMD_UPDATE_CTRL2, &tmp, 1);
il3820_write_cmd(IL3820_CMD_MASTER_ACTIVATION, NULL, 0); il3820_write_cmd(IL3820_CMD_MASTER_ACTIVATION, NULL, 0);
@ -398,10 +394,10 @@ static void il3820_clear_cntlr_mem(uint8_t ram_cmd, bool update)
/* Arrays used by SPI must be word alligned */ /* Arrays used by SPI must be word alligned */
WORD_ALIGNED_ATTR uint8_t clear_page[IL3820_COLUMNS]; WORD_ALIGNED_ATTR uint8_t clear_page[IL3820_COLUMNS];
memset(clear_page, 0xff, sizeof clear_page); memset(clear_page, 0xff, sizeof clear_page);
/* Configure entry mode */ /* Configure entry mode */
il3820_write_cmd(IL3820_CMD_ENTRY_MODE, &il3820_scan_mode, 1); il3820_write_cmd(IL3820_CMD_ENTRY_MODE, &il3820_scan_mode, 1);
/* Configure the window */ /* Configure the window */
il3820_set_window(0, EPD_PANEL_WIDTH - 1, 0, EPD_PANEL_HEIGHT - 1); il3820_set_window(0, EPD_PANEL_WIDTH - 1, 0, EPD_PANEL_HEIGHT - 1);

View file

@ -28,7 +28,6 @@ extern "C"
#define IL3820_DC_PIN CONFIG_LV_DISP_PIN_DC #define IL3820_DC_PIN CONFIG_LV_DISP_PIN_DC
#define IL3820_RST_PIN CONFIG_LV_DISP_PIN_RST #define IL3820_RST_PIN CONFIG_LV_DISP_PIN_RST
#define IL3820_USE_RST CONFIG_LV_DISP_USE_RST
#define IL3820_BUSY_PIN CONFIG_LV_DISP_PIN_BUSY #define IL3820_BUSY_PIN CONFIG_LV_DISP_PIN_BUSY
#define IL3820_BUSY_LEVEL 1 #define IL3820_BUSY_LEVEL 1

View file

@ -80,20 +80,31 @@ void ili9341_init(void)
{0, {0}, 0xff}, {0, {0}, 0xff},
}; };
//Initialize non-SPI GPIOs #if ILI9341_BCKL == 15
gpio_pad_select_gpio(ILI9341_DC); gpio_config_t io_conf;
gpio_set_direction(ILI9341_DC, GPIO_MODE_OUTPUT); io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pin_bit_mask = GPIO_SEL_15;
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
gpio_config(&io_conf);
#endif
#if ILI9341_USE_RST //Initialize non-SPI GPIOs
gpio_pad_select_gpio(ILI9341_RST); gpio_pad_select_gpio(ILI9341_DC);
gpio_set_direction(ILI9341_DC, GPIO_MODE_OUTPUT);
gpio_pad_select_gpio(ILI9341_RST);
gpio_set_direction(ILI9341_RST, GPIO_MODE_OUTPUT); gpio_set_direction(ILI9341_RST, GPIO_MODE_OUTPUT);
#if ILI9341_ENABLE_BACKLIGHT_CONTROL
gpio_pad_select_gpio(ILI9341_BCKL);
gpio_set_direction(ILI9341_BCKL, GPIO_MODE_OUTPUT);
#endif
//Reset the display //Reset the display
gpio_set_level(ILI9341_RST, 0); gpio_set_level(ILI9341_RST, 0);
vTaskDelay(100 / portTICK_RATE_MS); vTaskDelay(100 / portTICK_RATE_MS);
gpio_set_level(ILI9341_RST, 1); gpio_set_level(ILI9341_RST, 1);
vTaskDelay(100 / portTICK_RATE_MS); vTaskDelay(100 / portTICK_RATE_MS);
#endif
ESP_LOGI(TAG, "Initialization."); ESP_LOGI(TAG, "Initialization.");
@ -108,7 +119,9 @@ void ili9341_init(void)
cmd++; cmd++;
} }
ili9341_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION); ili9341_enable_backlight(true);
ili9341_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION);
#if ILI9341_INVERT_COLORS == 1 #if ILI9341_INVERT_COLORS == 1
ili9341_send_cmd(0x21); ili9341_send_cmd(0x21);
@ -140,10 +153,29 @@ void ili9341_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * col
/*Memory write*/ /*Memory write*/
ili9341_send_cmd(0x2C); ili9341_send_cmd(0x2C);
uint32_t size = lv_area_get_width(area) * lv_area_get_height(area); uint32_t size = lv_area_get_width(area) * lv_area_get_height(area);
ili9341_send_color((void*)color_map, size * 2); ili9341_send_color((void*)color_map, size * 2);
} }
void ili9341_enable_backlight(bool backlight)
{
#if ILI9341_ENABLE_BACKLIGHT_CONTROL
ESP_LOGI(TAG, "%s backlight.", backlight ? "Enabling" : "Disabling");
uint32_t tmp = 0;
#if (ILI9341_BCKL_ACTIVE_LVL==1)
tmp = backlight ? 1 : 0;
#else
tmp = backlight ? 0 : 1;
#endif
gpio_set_level(ILI9341_BCKL, tmp);
#endif
}
void ili9341_sleep_in() void ili9341_sleep_in()
{ {
uint8_t data[] = {0x08}; uint8_t data[] = {0x08};
@ -196,8 +228,6 @@ static void ili9341_set_orientation(uint8_t orientation)
#if defined CONFIG_LV_PREDEFINED_DISPLAY_M5STACK #if defined CONFIG_LV_PREDEFINED_DISPLAY_M5STACK
uint8_t data[] = {0x68, 0x68, 0x08, 0x08}; uint8_t data[] = {0x68, 0x68, 0x08, 0x08};
#elif defined (CONFIG_LV_PREDEFINED_DISPLAY_M5CORE2)
uint8_t data[] = {0x08, 0x88, 0x28, 0xE8};
#elif defined (CONFIG_LV_PREDEFINED_DISPLAY_WROVER4) #elif defined (CONFIG_LV_PREDEFINED_DISPLAY_WROVER4)
uint8_t data[] = {0x6C, 0xEC, 0xCC, 0x4C}; uint8_t data[] = {0x6C, 0xEC, 0xCC, 0x4C};
#elif defined (CONFIG_LV_PREDEFINED_DISPLAY_NONE) #elif defined (CONFIG_LV_PREDEFINED_DISPLAY_NONE)

View file

@ -20,15 +20,23 @@ extern "C" {
#else #else
#include "lvgl/lvgl.h" #include "lvgl/lvgl.h"
#endif #endif
#include "../lvgl_helpers.h"
#include "sdkconfig.h"
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
#define ILI9341_DC CONFIG_LV_DISP_PIN_DC #define ILI9341_DC CONFIG_LV_DISP_PIN_DC
#define ILI9341_USE_RST CONFIG_LV_DISP_USE_RST #define ILI9341_RST CONFIG_LV_DISP_PIN_RST
#define ILI9341_RST CONFIG_LV_DISP_PIN_RST #define ILI9341_BCKL CONFIG_LV_DISP_PIN_BCKL
#define ILI9341_ENABLE_BACKLIGHT_CONTROL CONFIG_LV_ENABLE_BACKLIGHT_CONTROL
#if CONFIG_LV_BACKLIGHT_ACTIVE_LVL
#define ILI9341_BCKL_ACTIVE_LVL 1
#else
#define ILI9341_BCKL_ACTIVE_LVL 0
#endif
#define ILI9341_INVERT_COLORS CONFIG_LV_INVERT_COLORS #define ILI9341_INVERT_COLORS CONFIG_LV_INVERT_COLORS
/********************** /**********************
@ -41,6 +49,7 @@ extern "C" {
void ili9341_init(void); void ili9341_init(void);
void ili9341_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map); void ili9341_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);
void ili9341_enable_backlight(bool backlight);
void ili9341_sleep_in(void); void ili9341_sleep_in(void);
void ili9341_sleep_out(void); void ili9341_sleep_out(void);

View file

@ -76,17 +76,19 @@ void ili9481_init(void)
//Initialize non-SPI GPIOs //Initialize non-SPI GPIOs
gpio_pad_select_gpio(ILI9481_DC); gpio_pad_select_gpio(ILI9481_DC);
gpio_set_direction(ILI9481_DC, GPIO_MODE_OUTPUT); gpio_set_direction(ILI9481_DC, GPIO_MODE_OUTPUT);
#if ILI9481_USE_RST
gpio_pad_select_gpio(ILI9481_RST); gpio_pad_select_gpio(ILI9481_RST);
gpio_set_direction(ILI9481_RST, GPIO_MODE_OUTPUT); gpio_set_direction(ILI9481_RST, GPIO_MODE_OUTPUT);
#if ILI9481_ENABLE_BACKLIGHT_CONTROL
gpio_pad_select_gpio(ILI9481_BCKL);
gpio_set_direction(ILI9481_BCKL, GPIO_MODE_OUTPUT);
#endif
//Reset the display //Reset the display
gpio_set_level(ILI9481_RST, 0); gpio_set_level(ILI9481_RST, 0);
vTaskDelay(100 / portTICK_RATE_MS); vTaskDelay(100 / portTICK_RATE_MS);
gpio_set_level(ILI9481_RST, 1); gpio_set_level(ILI9481_RST, 1);
vTaskDelay(100 / portTICK_RATE_MS); vTaskDelay(100 / portTICK_RATE_MS);
#endif
ESP_LOGI(TAG, "ILI9481 initialization."); ESP_LOGI(TAG, "ILI9481 initialization.");
@ -105,6 +107,8 @@ void ili9481_init(void)
cmd++; cmd++;
} }
ili9481_enable_backlight(true);
ili9481_set_orientation(ILI9481_DISPLAY_ORIENTATION); ili9481_set_orientation(ILI9481_DISPLAY_ORIENTATION);
} }
@ -164,6 +168,22 @@ void ili9481_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * col
heap_caps_free(mybuf); heap_caps_free(mybuf);
} }
void ili9481_enable_backlight(bool backlight)
{
#if ILI9481_ENABLE_BACKLIGHT_CONTROL
ESP_LOGI(TAG, "%s backlight.", backlight ? "Enabling" : "Disabling");
uint32_t tmp = 0;
#if (ILI9481_BCKL_ACTIVE_LVL==1)
tmp = backlight ? 1 : 0;
#else
tmp = backlight ? 0 : 1;
#endif
gpio_set_level(ILI9481_BCKL, tmp);
#endif
}
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/

View file

@ -25,12 +25,19 @@ extern "C" {
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
#define ILI9481_DC CONFIG_LV_DISP_PIN_DC #define ILI9481_DC CONFIG_LV_DISP_PIN_DC
#define ILI9481_RST CONFIG_LV_DISP_PIN_RST #define ILI9481_RST CONFIG_LV_DISP_PIN_RST
#define ILI9481_USE_RST CONFIG_LV_DISP_USE_RST #define ILI9481_BCKL CONFIG_LV_DISP_PIN_BCKL
#define ILI9481_INVERT_COLORS CONFIG_LV_INVERT_COLORS
#define ILI9481_ENABLE_BACKLIGHT_CONTROL CONFIG_LV_ENABLE_BACKLIGHT_CONTROL
#define ILI9481_INVERT_COLORS CONFIG_LV_INVERT_COLORS
#define ILI9481_DISPLAY_ORIENTATION CONFIG_LV_DISPLAY_ORIENTATION #define ILI9481_DISPLAY_ORIENTATION CONFIG_LV_DISPLAY_ORIENTATION
#if CONFIG_LV_BACKLIGHT_ACTIVE_LVL
#define ILI9481_BCKL_ACTIVE_LVL 1
#else
#define ILI9481_BCKL_ACTIVE_LVL 0
#endif
/******************* /*******************
* ILI9481 REGS * ILI9481 REGS
@ -110,6 +117,7 @@ extern "C" {
void ili9481_init(void); void ili9481_init(void);
void ili9481_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map); void ili9481_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);
void ili9481_enable_backlight(bool backlight);
/********************** /**********************
* MACROS * MACROS

View file

@ -60,25 +60,37 @@ void ili9486_init(void)
{0xE0, {0x0F, 0x1F, 0x1C, 0x0C, 0x0F, 0x08, 0x48, 0x98, 0x37, 0x0A, 0x13, 0x04, 0x11, 0x0D, 0x00}, 15}, {0xE0, {0x0F, 0x1F, 0x1C, 0x0C, 0x0F, 0x08, 0x48, 0x98, 0x37, 0x0A, 0x13, 0x04, 0x11, 0x0D, 0x00}, 15},
{0XE1, {0x0F, 0x32, 0x2E, 0x0B, 0x0D, 0x05, 0x47, 0x75, 0x37, 0x06, 0x10, 0x03, 0x24, 0x20, 0x00}, 15}, {0XE1, {0x0F, 0x32, 0x2E, 0x0B, 0x0D, 0x05, 0x47, 0x75, 0x37, 0x06, 0x10, 0x03, 0x24, 0x20, 0x00}, 15},
{0x20, {0}, 0}, /* display inversion OFF */ {0x20, {0}, 0}, /* display inversion OFF */
{0x36, {0x48}, 1}, {0x36, {0x48}, 1},
{0x29, {0}, 0x80}, /* display on */ {0x29, {0}, 0x80}, /* display on */
{0x00, {0}, 0xff}, {0x00, {0}, 0xff},
}; };
//Initialize non-SPI GPIOs #if ILI9486_BCKL == 15
gpio_pad_select_gpio(ILI9486_DC); gpio_config_t io_conf;
gpio_set_direction(ILI9486_DC, GPIO_MODE_OUTPUT); io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pin_bit_mask = GPIO_SEL_15;
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
gpio_config(&io_conf);
#endif
#if ILI9486_USE_RST //Initialize non-SPI GPIOs
gpio_pad_select_gpio(ILI9486_RST); gpio_pad_select_gpio(ILI9486_DC);
gpio_set_direction(ILI9486_DC, GPIO_MODE_OUTPUT);
gpio_pad_select_gpio(ILI9486_RST);
gpio_set_direction(ILI9486_RST, GPIO_MODE_OUTPUT); gpio_set_direction(ILI9486_RST, GPIO_MODE_OUTPUT);
#if ILI9486_ENABLE_BACKLIGHT_CONTROL
gpio_pad_select_gpio(ILI9486_BCKL);
gpio_set_direction(ILI9486_BCKL, GPIO_MODE_OUTPUT);
#endif
//Reset the display //Reset the display
gpio_set_level(ILI9486_RST, 0); gpio_set_level(ILI9486_RST, 0);
vTaskDelay(100 / portTICK_RATE_MS); vTaskDelay(100 / portTICK_RATE_MS);
gpio_set_level(ILI9486_RST, 1); gpio_set_level(ILI9486_RST, 1);
vTaskDelay(100 / portTICK_RATE_MS); vTaskDelay(100 / portTICK_RATE_MS);
#endif
ESP_LOGI(TAG, "ILI9486 Initialization."); ESP_LOGI(TAG, "ILI9486 Initialization.");
@ -93,7 +105,9 @@ void ili9486_init(void)
cmd++; cmd++;
} }
ili9486_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION); ili9486_enable_backlight(true);
ili9486_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION);
} }
void ili9486_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map) void ili9486_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map)
@ -121,10 +135,26 @@ void ili9486_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * col
ili9486_send_cmd(0x2C); ili9486_send_cmd(0x2C);
size = lv_area_get_width(area) * lv_area_get_height(area); size = lv_area_get_width(area) * lv_area_get_height(area);
ili9486_send_color((void*) color_map, size * 2); ili9486_send_color((void*) color_map, size * 2);
} }
void ili9486_enable_backlight(bool backlight)
{
#if ILI9486_ENABLE_BACKLIGHT_CONTROL
ESP_LOGI(TAG, "%s backlight.", backlight ? "Enabling" : "Disabling");
uint32_t tmp = 0;
#if (ILI9486_BCKL_ACTIVE_LVL==1)
tmp = backlight ? 1 : 0;
#else
tmp = backlight ? 0 : 1;
#endif
gpio_set_level(ILI9486_BCKL, tmp);
#endif
}
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/

View file

@ -25,10 +25,17 @@ extern "C" {
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
#define ILI9486_DC CONFIG_LV_DISP_PIN_DC #define ILI9486_DC CONFIG_LV_DISP_PIN_DC
#define ILI9486_RST CONFIG_LV_DISP_PIN_RST #define ILI9486_RST CONFIG_LV_DISP_PIN_RST
#define ILI9486_USE_RST CONFIG_LV_DISP_USE_RST #define ILI9486_BCKL CONFIG_LV_DISP_PIN_BCKL
#define ILI9486_ENABLE_BACKLIGHT_CONTROL CONFIG_LV_ENABLE_BACKLIGHT_CONTROL
#if CONFIG_LV_BACKLIGHT_ACTIVE_LVL
#define ILI9486_BCKL_ACTIVE_LVL 1
#else
#define ILI9486_BCKL_ACTIVE_LVL 0
#endif
/********************** /**********************
* TYPEDEFS * TYPEDEFS
@ -40,6 +47,7 @@ extern "C" {
void ili9486_init(void); void ili9486_init(void);
void ili9486_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map); void ili9486_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);
void ili9486_enable_backlight(bool backlight);
/********************** /**********************
* MACROS * MACROS

View file

@ -50,7 +50,7 @@ static void ili9488_send_color(void * data, uint16_t length);
/********************** /**********************
* GLOBAL FUNCTIONS * GLOBAL FUNCTIONS
**********************/ **********************/
// From github.com/jeremyjh/ESP32_TFT_library // From github.com/jeremyjh/ESP32_TFT_library
// From github.com/mvturnho/ILI9488-lvgl-ESP32-WROVER-B // From github.com/mvturnho/ILI9488-lvgl-ESP32-WROVER-B
void ili9488_init(void) void ili9488_init(void)
{ {
@ -76,26 +76,28 @@ void ili9488_init(void)
}; };
//Initialize non-SPI GPIOs //Initialize non-SPI GPIOs
gpio_pad_select_gpio(ILI9488_DC); gpio_pad_select_gpio(ILI9488_DC);
gpio_set_direction(ILI9488_DC, GPIO_MODE_OUTPUT); gpio_set_direction(ILI9488_DC, GPIO_MODE_OUTPUT);
gpio_pad_select_gpio(ILI9488_RST);
#if ILI9488_USE_RST
gpio_pad_select_gpio(ILI9488_RST);
gpio_set_direction(ILI9488_RST, GPIO_MODE_OUTPUT); gpio_set_direction(ILI9488_RST, GPIO_MODE_OUTPUT);
#if ILI9488_ENABLE_BACKLIGHT_CONTROL
gpio_pad_select_gpio(ILI9488_BCKL);
gpio_set_direction(ILI9488_BCKL, GPIO_MODE_OUTPUT);
#endif
//Reset the display //Reset the display
gpio_set_level(ILI9488_RST, 0); gpio_set_level(ILI9488_RST, 0);
vTaskDelay(100 / portTICK_RATE_MS); vTaskDelay(100 / portTICK_RATE_MS);
gpio_set_level(ILI9488_RST, 1); gpio_set_level(ILI9488_RST, 1);
vTaskDelay(100 / portTICK_RATE_MS); vTaskDelay(100 / portTICK_RATE_MS);
#endif
ESP_LOGI(TAG, "ILI9488 initialization."); ESP_LOGI(TAG, "ILI9488 initialization.");
// Exit sleep // Exit sleep
ili9488_send_cmd(0x01); /* Software reset */ ili9488_send_cmd(0x01); /* Software reset */
vTaskDelay(100 / portTICK_RATE_MS); vTaskDelay(100 / portTICK_RATE_MS);
//Send all the commands //Send all the commands
uint16_t cmd = 0; uint16_t cmd = 0;
while (ili_init_cmds[cmd].databytes!=0xff) { while (ili_init_cmds[cmd].databytes!=0xff) {
@ -107,7 +109,9 @@ void ili9488_init(void)
cmd++; cmd++;
} }
ili9488_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION); ili9488_enable_backlight(true);
ili9488_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION);
} }
// Flush function based on mvturnho repo // Flush function based on mvturnho repo
@ -142,7 +146,7 @@ void ili9488_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * col
(uint8_t) (area->x2 >> 8) & 0xFF, (uint8_t) (area->x2 >> 8) & 0xFF,
(uint8_t) (area->x2) & 0xFF, (uint8_t) (area->x2) & 0xFF,
}; };
/* Page addresses */ /* Page addresses */
uint8_t yb[] = { uint8_t yb[] = {
(uint8_t) (area->y1 >> 8) & 0xFF, (uint8_t) (area->y1 >> 8) & 0xFF,
@ -166,6 +170,22 @@ void ili9488_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * col
heap_caps_free(mybuf); heap_caps_free(mybuf);
} }
void ili9488_enable_backlight(bool backlight)
{
#if ILI9488_ENABLE_BACKLIGHT_CONTROL
ESP_LOGI(TAG, "%s backlight.", backlight ? "Enabling" : "Disabling");
uint32_t tmp = 0;
#if (ILI9488_BCKL_ACTIVE_LVL==1)
tmp = backlight ? 1 : 0;
#else
tmp = backlight ? 0 : 1;
#endif
gpio_set_level(ILI9488_BCKL, tmp);
#endif
}
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/

View file

@ -25,9 +25,17 @@ extern "C" {
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
#define ILI9488_DC CONFIG_LV_DISP_PIN_DC #define ILI9488_DC CONFIG_LV_DISP_PIN_DC
#define ILI9488_RST CONFIG_LV_DISP_PIN_RST #define ILI9488_RST CONFIG_LV_DISP_PIN_RST
#define ILI9488_USE_RST CONFIG_LV_DISP_USE_RSTS #define ILI9488_BCKL CONFIG_LV_DISP_PIN_BCKL
#define ILI9488_ENABLE_BACKLIGHT_CONTROL CONFIG_LV_ENABLE_BACKLIGHT_CONTROL
#if CONFIG_LV_BACKLIGHT_ACTIVE_LVL
#define ILI9488_BCKL_ACTIVE_LVL 1
#else
#define ILI9488_BCKL_ACTIVE_LVL 0
#endif
/******************* /*******************
* ILI9488 REGS * ILI9488 REGS
@ -146,6 +154,7 @@ typedef struct {
void ili9488_init(void); void ili9488_init(void);
void ili9488_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map); void ili9488_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);
void ili9488_enable_backlight(bool backlight);
/********************** /**********************
* MACROS * MACROS

View file

@ -148,18 +148,29 @@ void ra8875_init(void)
ESP_LOGI(TAG, "Initializing RA8875..."); ESP_LOGI(TAG, "Initializing RA8875...");
// Initialize non-SPI GPIOs #if (CONFIG_LV_DISP_PIN_BCKL == 15)
gpio_config_t io_conf;
io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pin_bit_mask = GPIO_SEL_15;
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
gpio_config(&io_conf);
#endif
#if RA8875_USE_RST // Initialize non-SPI GPIOs
gpio_pad_select_gpio(RA8875_RST); gpio_pad_select_gpio(RA8875_RST);
gpio_set_direction(RA8875_RST, GPIO_MODE_OUTPUT); gpio_set_direction(RA8875_RST, GPIO_MODE_OUTPUT);
#ifdef CONFIG_LV_DISP_PIN_BCKL
gpio_pad_select_gpio(CONFIG_LV_DISP_PIN_BCKL);
gpio_set_direction(CONFIG_LV_DISP_PIN_BCKL, GPIO_MODE_OUTPUT);
#endif
// Reset the RA8875 // Reset the RA8875
gpio_set_level(RA8875_RST, 0); gpio_set_level(RA8875_RST, 0);
vTaskDelay(DIV_ROUND_UP(100, portTICK_RATE_MS)); vTaskDelay(DIV_ROUND_UP(100, portTICK_RATE_MS));
gpio_set_level(RA8875_RST, 1); gpio_set_level(RA8875_RST, 1);
vTaskDelay(DIV_ROUND_UP(100, portTICK_RATE_MS)); vTaskDelay(DIV_ROUND_UP(100, portTICK_RATE_MS));
#endif
// Initalize RA8875 clocks (SPI must be decelerated before initializing clocks) // Initalize RA8875 clocks (SPI must be decelerated before initializing clocks)
disp_spi_change_device_speed(SPI_CLOCK_SPEED_SLOW_HZ); disp_spi_change_device_speed(SPI_CLOCK_SPEED_SLOW_HZ);
@ -183,8 +194,28 @@ void ra8875_init(void)
ESP_LOGW(TAG, "WARNING: Memory clear timed out; RA8875 may be unresponsive."); ESP_LOGW(TAG, "WARNING: Memory clear timed out; RA8875 may be unresponsive.");
} }
// Enable the display // Enable the display and backlight
ra8875_enable_display(true); ra8875_enable_display(true);
ra8875_enable_backlight(true);
}
void ra8875_enable_backlight(bool backlight)
{
#if CONFIG_LV_ENABLE_BACKLIGHT_CONTROL
ESP_LOGI(TAG, "%s backlight.", backlight ? "Enabling" : "Disabling");
uint32_t tmp = 0;
#if CONFIG_LV_BACKLIGHT_ACTIVE_LVL
tmp = backlight ? 1 : 0;
#else
tmp = backlight ? 0 : 1;
#endif
#ifdef CONFIG_LV_DISP_PIN_BCKL
gpio_set_level(CONFIG_LV_DISP_PIN_BCKL, tmp);
#endif
#endif
} }
void ra8875_enable_display(bool enable) void ra8875_enable_display(bool enable)

View file

@ -24,8 +24,7 @@ extern "C" {
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
#define RA8875_RST CONFIG_LV_DISP_PIN_RST #define RA8875_RST CONFIG_LV_DISP_PIN_RST
#define RA8875_USE_RST CONFIG_LV_DISP_USE_RST
// System & Configuration Registers // System & Configuration Registers
#define RA8875_REG_PWRR (0x01) // Power and Display Control Register (PWRR) #define RA8875_REG_PWRR (0x01) // Power and Display Control Register (PWRR)
@ -97,6 +96,7 @@ extern "C" {
**********************/ **********************/
void ra8875_init(void); void ra8875_init(void);
void ra8875_enable_backlight(bool backlight);
void ra8875_enable_display(bool enable); void ra8875_enable_display(bool enable);
void ra8875_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map); void ra8875_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);

View file

@ -94,8 +94,6 @@ void sh1107_init(void)
//Initialize non-SPI GPIOs //Initialize non-SPI GPIOs
gpio_pad_select_gpio(SH1107_DC); gpio_pad_select_gpio(SH1107_DC);
gpio_set_direction(SH1107_DC, GPIO_MODE_OUTPUT); gpio_set_direction(SH1107_DC, GPIO_MODE_OUTPUT);
#if SH1107_USE_RST
gpio_pad_select_gpio(SH1107_RST); gpio_pad_select_gpio(SH1107_RST);
gpio_set_direction(SH1107_RST, GPIO_MODE_OUTPUT); gpio_set_direction(SH1107_RST, GPIO_MODE_OUTPUT);
@ -104,7 +102,6 @@ void sh1107_init(void)
vTaskDelay(100 / portTICK_RATE_MS); vTaskDelay(100 / portTICK_RATE_MS);
gpio_set_level(SH1107_RST, 1); gpio_set_level(SH1107_RST, 1);
vTaskDelay(100 / portTICK_RATE_MS); vTaskDelay(100 / portTICK_RATE_MS);
#endif
//Send all the commands //Send all the commands
uint16_t cmd = 0; uint16_t cmd = 0;

View file

@ -25,9 +25,8 @@ extern "C" {
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
#define SH1107_DC CONFIG_LV_DISP_PIN_DC #define SH1107_DC CONFIG_LV_DISP_PIN_DC
#define SH1107_RST CONFIG_LV_DISP_PIN_RST #define SH1107_RST CONFIG_LV_DISP_PIN_RST
#define SH1107_USE_RST CONFIG_LV_DISP_USE_RST
/********************** /**********************
* TYPEDEFS * TYPEDEFS

110
lvgl_tft/sharp_mip.cpp Normal file
View file

@ -0,0 +1,110 @@
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "sharp_mip.h"
#include <Adafruit_SharpMem.h>
/** test Display dimensions
* Do not forget to set: menuconfig -> Components -> LVGL configuration
* Max. Horizontal resolution 400 -> WIDTH of your LCD
* Max. Vertical resolution 240 -> HEIGHT
*/
/*
* Return the draw_buf byte index corresponding to the pixel
* relatives coordinates (x, y) in the area.
* The area is rounded to a whole screen line.
*/
#define BUFIDX(x, y) (((x) >> 3) + ((y) * (2 + (LV_HOR_RES_MAX >> 3))) + 2)
// SHARP LCD Class
// PCB Pins for LCD SPI
#define SHARP_SCK 6
#define SHARP_MOSI 0
#define SHARP_SS 7
// External COM Inversion Signal
#define LCD_EXTMODE GPIO_NUM_3
#define LCD_DISP GPIO_NUM_2
// Set the size of the display here, e.g. 128x128
Adafruit_SharpMem display(SHARP_SCK, SHARP_MOSI, SHARP_SS, LV_HOR_RES_MAX, LV_VER_RES_MAX);
/*********************
* DEFINES
*********************/
#define TAG "SHARP"
uint16_t flushcalls = 0;
void delay(uint32_t period_ms) {
vTaskDelay(pdMS_TO_TICKS(period_ms));
}
/* Display initialization routine */
void sharp_init(void)
{
printf("SHAROP LCD init\n");
// Display pins config
gpio_set_direction(LCD_EXTMODE, GPIO_MODE_OUTPUT);
gpio_set_direction(LCD_DISP, GPIO_MODE_OUTPUT);// Display On(High)/Off(Low)
gpio_set_level(LCD_DISP, 1);
gpio_set_level(LCD_EXTMODE, 1);
display.begin();
}
/**
* @brief rounds area before writing
*
* @param disp_drv
* @param area
* @deprecated
*/
void sharp_mip_rounder(lv_disp_drv_t * disp_drv, lv_area_t * area) {
/* Round area to the whole LINE */
area->x1 = 0;
area->x2 = LV_HOR_RES_MAX - 1;
}
/* Required by LVGL */
void sharp_flush(lv_disp_drv_t *drv, lv_area_t *area, lv_color_t *color_map)
{
/* Round area to the whole LINE */
/* area->x1 = 0;
area->x2 = LV_HOR_RES_MAX - 1; */
//lv_refr_set_round_cb(sharp_mip_rounder); // NOT applicable to this version of LVGL
// FORCE Flushing Whole display (Really unnecesary, just a demo, since I don't know how to refresh an *LCD partial only*)
++flushcalls;
// x2:%d y2:%d
printf("flush %d x1:%d y1:%d x2:%d y2:%d w:%d h:%d\n",
flushcalls,area->x1,area->y1,area->x2,area->y2,lv_area_get_width(area),lv_area_get_height(area));
// FULL Refresh does not work nice unless you force it on newer versions of LVGL (see lv_refr_set_round_cb)
//display.refresh();
display.refreshLines(area->x1, area->x1, area->y1,area->y2);
/* IMPORTANT:
* Inform the graphics library that you are ready with the flushing */
lv_disp_flush_ready(drv);
}
/* Called for each pixel */
void sharp_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t* buf,
lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
lv_color_t color, lv_opa_t opa)
{
// Test using RGB232: Otherwise you can directly use color.full if MONOCHROME
int16_t lcd_color = 1; // WHITE
// Color setting use: RGB232
// Only monochrome: All what is not white, turn black
if (color.full<254) {
lcd_color = 0;
}
display.drawPixel((int16_t)x, (int16_t)y, lcd_color);
//If not drawing anything: Debug to see if this function is called:
//printf("set_px %d %d R:%d G:%d B:%d\n",(int16_t)x,(int16_t)y, color.ch.red, color.ch.green, color.ch.blue);
}

35
lvgl_tft/sharp_mip.h Normal file
View file

@ -0,0 +1,35 @@
/**
* Display class for generic e-Paper driven by EPDiy class
*/
#pragma once
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
#include "sdkconfig.h"
/* Configure your display */
void sharp_init(void);
/* LVGL callbacks */
void sharp_flush(lv_disp_drv_t *drv, lv_area_t *area, lv_color_t *color_map);
/* Only for monochrome displays. But we use epdiy_set_px also for epapers */
//void epdiy_rounder(lv_disp_drv_t *disp_drv, lv_area_t *area);
void sharp_set_px_cb(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa);
void sharp_rounder(lv_disp_drv_t * disp_drv, lv_area_t * area);
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

@ -13,9 +13,10 @@
/********************* /*********************
* INCLUDES * INCLUDES
*********************/ *********************/
#include "driver/i2c.h"
#include "assert.h" #include "assert.h"
#include "lvgl_i2c/i2c_manager.h" #include "lvgl_i2c_conf.h"
#include "ssd1306.h" #include "ssd1306.h"
@ -24,7 +25,6 @@
*********************/ *********************/
#define TAG "SSD1306" #define TAG "SSD1306"
#define OLED_I2C_PORT (CONFIG_LV_I2C_DISPLAY_PORT)
// SLA (0x3C) + WRITE_MODE (0x00) = 0x78 (0b01111000) // SLA (0x3C) + WRITE_MODE (0x00) = 0x78 (0b01111000)
#define OLED_I2C_ADDRESS 0x3C #define OLED_I2C_ADDRESS 0x3C
#define OLED_WIDTH 128 #define OLED_WIDTH 128
@ -70,6 +70,8 @@
// Charge Pump (pg.62) // Charge Pump (pg.62)
#define OLED_CMD_SET_CHARGE_PUMP 0x8D // follow with 0x14 #define OLED_CMD_SET_CHARGE_PUMP 0x8D // follow with 0x14
#define OLED_IIC_FREQ_HZ 400000 // I2C colock frequency
/********************** /**********************
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
@ -99,10 +101,10 @@ void ssd1306_init(void)
uint8_t orientation_1 = 0; uint8_t orientation_1 = 0;
uint8_t orientation_2 = 0; uint8_t orientation_2 = 0;
#if defined (CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE) #if defined (CONFIG_DISPLAY_ORIENTATION_LANDSCAPE)
orientation_1 = OLED_CMD_SET_SEGMENT_REMAP; orientation_1 = OLED_CMD_SET_SEGMENT_REMAP;
orientation_2 = OLED_CMD_SET_COM_SCAN_MODE_REMAP; orientation_2 = OLED_CMD_SET_COM_SCAN_MODE_REMAP;
#elif defined (CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED) #elif defined (CONFIG_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED)
orientation_1 = 0xA0; orientation_1 = 0xA0;
orientation_2 = OLED_CMD_SET_COM_SCAN_MODE_NORMAL; orientation_2 = OLED_CMD_SET_COM_SCAN_MODE_NORMAL;
#else #else
@ -211,15 +213,44 @@ void ssd1306_sleep_out(void)
static uint8_t send_data(lv_disp_drv_t *disp_drv, void *bytes, size_t bytes_len) static uint8_t send_data(lv_disp_drv_t *disp_drv, void *bytes, size_t bytes_len)
{ {
(void) disp_drv; (void) disp_drv;
esp_err_t err;
uint8_t *data = (uint8_t *) bytes; uint8_t *data = (uint8_t *) bytes;
return lvgl_i2c_write(OLED_I2C_PORT, OLED_I2C_ADDRESS, data[0], data + 1, bytes_len - 1 ); i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true);
for (size_t idx = 0; idx < bytes_len; idx++) {
i2c_master_write_byte(cmd, data[idx], true);
}
i2c_master_stop(cmd);
/* Send queued commands */
err = i2c_master_cmd_begin(DISP_I2C_PORT, cmd, 10 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
return ESP_OK == err ? 0 : 1;
} }
static uint8_t send_pixels(lv_disp_drv_t *disp_drv, void *color_buffer, size_t buffer_len) static uint8_t send_pixels(lv_disp_drv_t *disp_drv, void *color_buffer, size_t buffer_len)
{ {
(void) disp_drv; (void) disp_drv;
esp_err_t err;
return lvgl_i2c_write(OLED_I2C_PORT, OLED_I2C_ADDRESS, OLED_CONTROL_BYTE_DATA_STREAM, color_buffer, buffer_len); i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_DATA_STREAM, true);
i2c_master_write(cmd, (uint8_t *) color_buffer, buffer_len, true);
i2c_master_stop(cmd);
/* Send queued commands */
err = i2c_master_cmd_begin(DISP_I2C_PORT, cmd, 10 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
return ESP_OK == err ? 0 : 1;
} }

View file

@ -25,6 +25,8 @@ extern "C" {
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
#define SSD1306_SDA CONFIG_LV_DISP_PIN_SDA
#define SSD1306_SCL CONFIG_LV_DISP_PIN_SCL
#define SSD1306_DISPLAY_ORIENTATION TFT_ORIENTATION_LANDSCAPE #define SSD1306_DISPLAY_ORIENTATION TFT_ORIENTATION_LANDSCAPE
/********************** /**********************

View file

@ -8,15 +8,12 @@
*********************/ *********************/
#include "st7735s.h" #include "st7735s.h"
#include "disp_spi.h" #include "disp_spi.h"
#include "driver/i2c.h"
#include "driver/gpio.h" #include "driver/gpio.h"
#include "esp_log.h" #include "esp_log.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#ifdef CONFIG_LV_M5STICKC_HANDLE_AXP192
#include "lvgl_i2c/i2c_manager.h"
#endif
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
@ -41,6 +38,7 @@ static void st7735s_send_cmd(uint8_t cmd);
static void st7735s_send_data(void * data, uint16_t length); static void st7735s_send_data(void * data, uint16_t length);
static void st7735s_send_color(void * data, uint16_t length); static void st7735s_send_color(void * data, uint16_t length);
static void st7735s_set_orientation(uint8_t orientation); static void st7735s_set_orientation(uint8_t orientation);
static void i2c_master_init();
static void axp192_write_byte(uint8_t addr, uint8_t data); static void axp192_write_byte(uint8_t addr, uint8_t data);
static void axp192_init(); static void axp192_init();
static void axp192_sleep_in(); static void axp192_sleep_in();
@ -62,6 +60,7 @@ uint8_t st7735s_portrait_mode = 0;
void st7735s_init(void) void st7735s_init(void)
{ {
#ifdef CONFIG_LV_M5STICKC_HANDLE_AXP192 #ifdef CONFIG_LV_M5STICKC_HANDLE_AXP192
i2c_master_init();
axp192_init(); axp192_init();
#endif #endif
@ -100,8 +99,6 @@ void st7735s_init(void)
//Initialize non-SPI GPIOs //Initialize non-SPI GPIOs
gpio_pad_select_gpio(ST7735S_DC); gpio_pad_select_gpio(ST7735S_DC);
gpio_set_direction(ST7735S_DC, GPIO_MODE_OUTPUT); gpio_set_direction(ST7735S_DC, GPIO_MODE_OUTPUT);
#if ST7735S_USE_RST
gpio_pad_select_gpio(ST7735S_RST); gpio_pad_select_gpio(ST7735S_RST);
gpio_set_direction(ST7735S_RST, GPIO_MODE_OUTPUT); gpio_set_direction(ST7735S_RST, GPIO_MODE_OUTPUT);
@ -110,7 +107,6 @@ void st7735s_init(void)
vTaskDelay(100 / portTICK_RATE_MS); vTaskDelay(100 / portTICK_RATE_MS);
gpio_set_level(ST7735S_RST, 1); gpio_set_level(ST7735S_RST, 1);
vTaskDelay(100 / portTICK_RATE_MS); vTaskDelay(100 / portTICK_RATE_MS);
#endif
ESP_LOGI(TAG, "ST7735S initialization."); ESP_LOGI(TAG, "ST7735S initialization.");
@ -164,16 +160,12 @@ void st7735s_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * col
void st7735s_sleep_in() void st7735s_sleep_in()
{ {
st7735s_send_cmd(0x10); st7735s_send_cmd(0x10);
#ifdef CONFIG_LV_M5STICKC_HANDLE_AXP192 axp192_sleep_in();
axp192_sleep_in();
#endif
} }
void st7735s_sleep_out() void st7735s_sleep_out()
{ {
#ifdef CONFIG_LV_M5STICKC_HANDLE_AXP192 axp192_sleep_out();
axp192_sleep_out();
#endif
st7735s_send_cmd(0x11); st7735s_send_cmd(0x11);
} }
@ -223,35 +215,55 @@ static void st7735s_set_orientation(uint8_t orientation)
st7735s_send_data((void *) &data[orientation], 1); st7735s_send_data((void *) &data[orientation], 1);
} }
#ifdef CONFIG_LV_M5STICKC_HANDLE_AXP192 static void i2c_master_init()
{
i2c_config_t i2c_config = {
.mode = I2C_MODE_MASTER,
.sda_io_num = AXP192_SDA,
.scl_io_num = AXP192_SCL,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = 400000
};
i2c_param_config(I2C_NUM_0, &i2c_config);
i2c_driver_install(I2C_NUM_0, I2C_MODE_MASTER, 0, 0, 0);
}
static void axp192_write_byte(uint8_t addr, uint8_t data) static void axp192_write_byte(uint8_t addr, uint8_t data)
{ {
err = lvgl_i2c_write(CONFIG_LV_I2C_DISPLAY_PORT, AXP192_I2C_ADDRESS, addr, &data, 1); esp_err_t ret;
if (ret != ESP_OK) { i2c_cmd_handle_t cmd = i2c_cmd_link_create();
ESP_LOGE(TAG, "AXP192 send failed. code: 0x%.2X", ret);
}
}
static void axp192_init() i2c_master_start(cmd);
{ i2c_master_write_byte(cmd, (AXP192_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true);
// information on how to init and use AXP192 ifor M5StickC taken from i2c_master_write_byte(cmd, addr, true);
// https://forum.m5stack.com/topic/1025/m5stickc-turn-off-screen-completely i2c_master_write_byte(cmd, data, true);
i2c_master_stop(cmd);
axp192_write_byte(0x10, 0xFF); // OLED_VPP Enable ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 10/portTICK_PERIOD_MS);
axp192_write_byte(0x28, 0xCC); // Enable LDO2&LDO3, LED&TFT 3.0V if (ret != ESP_OK) {
axp192_sleep_out(); ESP_LOGE(TAG, "AXP192 send failed. code: 0x%.2X", ret);
ESP_LOGI(TAG, "AXP192 initialized, power enabled for LDO2 and LDO3"); }
} i2c_cmd_link_delete(cmd);
}
static void axp192_sleep_in() static void axp192_init()
{ {
axp192_write_byte(0x12, 0x4b); // information on how to init and use AXP192 ifor M5StickC taken from
} // https://forum.m5stack.com/topic/1025/m5stickc-turn-off-screen-completely
static void axp192_sleep_out() axp192_write_byte(0x10, 0xFF); // OLED_VPP Enable
{ axp192_write_byte(0x28, 0xCC); // Enable LDO2&LDO3, LED&TFT 3.0V
axp192_write_byte(0x12, 0x4d); axp192_sleep_out();
} ESP_LOGI(TAG, "AXP192 initialized, power enabled for LDO2 and LDO3");
}
#endif static void axp192_sleep_in()
{
axp192_write_byte(0x12, 0x4b);
}
static void axp192_sleep_out()
{
axp192_write_byte(0x12, 0x4d);
}

View file

@ -25,9 +25,11 @@ extern "C" {
*********************/ *********************/
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40) #define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
#define ST7735S_DC CONFIG_LV_DISP_PIN_DC #define ST7735S_DC CONFIG_LV_DISP_PIN_DC
#define ST7735S_RST CONFIG_LV_DISP_PIN_RST #define ST7735S_RST CONFIG_LV_DISP_PIN_RST
#define ST7735S_USE_RST CONFIG_LV_DISP_USE_RST
#define AXP192_SDA CONFIG_LV_AXP192_PIN_SDA
#define AXP192_SCL CONFIG_LV_AXP192_PIN_SCL
#define ST7735S_INVERT_COLORS CONFIG_LV_INVERT_COLORS #define ST7735S_INVERT_COLORS CONFIG_LV_INVERT_COLORS
@ -131,6 +133,7 @@ extern "C" {
void st7735s_init(void); void st7735s_init(void);
void st7735s_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map); void st7735s_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);
void st7735s_enable_backlight(bool backlight);
void st7735s_sleep_in(void); void st7735s_sleep_in(void);
void st7735s_sleep_out(void); void st7735s_sleep_out(void);

View file

@ -35,7 +35,9 @@ typedef struct {
**********************/ **********************/
static void st7789_set_orientation(uint8_t orientation); static void st7789_set_orientation(uint8_t orientation);
static void st7789_send_color(void *data, size_t length); static void st7789_send_cmd(uint8_t cmd);
static void st7789_send_data(void *data, uint16_t length);
static void st7789_send_color(void *data, uint16_t length);
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
@ -89,13 +91,18 @@ void st7789_init(void)
gpio_pad_select_gpio(ST7789_DC); gpio_pad_select_gpio(ST7789_DC);
gpio_set_direction(ST7789_DC, GPIO_MODE_OUTPUT); gpio_set_direction(ST7789_DC, GPIO_MODE_OUTPUT);
#if !defined(ST7789_SOFT_RST) #if !defined(CONFIG_LV_DISP_ST7789_SOFT_RESET)
gpio_pad_select_gpio(ST7789_RST); gpio_pad_select_gpio(ST7789_RST);
gpio_set_direction(ST7789_RST, GPIO_MODE_OUTPUT); gpio_set_direction(ST7789_RST, GPIO_MODE_OUTPUT);
#endif #endif
#if ST7789_ENABLE_BACKLIGHT_CONTROL
gpio_pad_select_gpio(ST7789_BCKL);
gpio_set_direction(ST7789_BCKL, GPIO_MODE_OUTPUT);
#endif
//Reset the display //Reset the display
#if !defined(ST7789_SOFT_RST) #if !defined(CONFIG_LV_DISP_ST7789_SOFT_RESET)
gpio_set_level(ST7789_RST, 0); gpio_set_level(ST7789_RST, 0);
vTaskDelay(100 / portTICK_RATE_MS); vTaskDelay(100 / portTICK_RATE_MS);
gpio_set_level(ST7789_RST, 1); gpio_set_level(ST7789_RST, 1);
@ -117,12 +124,30 @@ void st7789_init(void)
cmd++; cmd++;
} }
st7789_enable_backlight(true);
st7789_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION); st7789_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION);
} }
/* The ST7789 display controller can drive up to 320*240 displays, when using a 240*240 or 240*135 void st7789_enable_backlight(bool backlight)
* displays there's a gap of 80px or 40/52/53px respectively. 52px or 53x offset depends on display orientation. {
* We need to edit the coordinates to take into account those gaps, this is not necessary in all orientations. */ #if ST7789_ENABLE_BACKLIGHT_CONTROL
printf("%s backlight.\n", backlight ? "Enabling" : "Disabling");
uint32_t tmp = 0;
#if (ST7789_BCKL_ACTIVE_LVL==1)
tmp = backlight ? 1 : 0;
#else
tmp = backlight ? 0 : 1;
#endif
gpio_set_level(ST7789_BCKL, tmp);
#endif
}
/* The ST7789 display controller can drive 320*240 displays, when using a 240*240
* display there's a gap of 80px, we need to edit the coordinates to take into
* account that gap, this is not necessary in all orientations. */
void st7789_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map) void st7789_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map)
{ {
uint8_t data[4] = {0}; uint8_t data[4] = {0};
@ -139,29 +164,13 @@ void st7789_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * colo
offsety2 += CONFIG_LV_TFT_DISPLAY_Y_OFFSET; offsety2 += CONFIG_LV_TFT_DISPLAY_Y_OFFSET;
#elif (LV_HOR_RES_MAX == 240) && (LV_VER_RES_MAX == 240) #elif (LV_HOR_RES_MAX == 240) && (LV_VER_RES_MAX == 240)
#if (CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT) #if (CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT)
offsetx1 += 80; offsetx1 += 80;
offsetx2 += 80; offsetx2 += 80;
#elif (CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED) #elif (CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED)
offsety1 += 80; offsety1 += 80;
offsety2 += 80; offsety2 += 80;
#endif #endif
#elif (LV_HOR_RES_MAX == 240) && (LV_VER_RES_MAX == 135)
#if (CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT) || \
(CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
offsetx1 += 40;
offsetx2 += 40;
offsety1 += 53;
offsety2 += 53;
#endif
#elif (LV_HOR_RES_MAX == 135) && (LV_VER_RES_MAX == 240)
#if (CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE) || \
(CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED)
offsetx1 += 52;
offsetx2 += 52;
offsety1 += 40;
offsety2 += 40;
#endif
#endif #endif
/*Column addresses*/ /*Column addresses*/
@ -183,7 +192,7 @@ void st7789_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * colo
/*Memory write*/ /*Memory write*/
st7789_send_cmd(ST7789_RAMWR); st7789_send_cmd(ST7789_RAMWR);
size_t size = (size_t)lv_area_get_width(area) * (size_t)lv_area_get_height(area); uint32_t size = lv_area_get_width(area) * lv_area_get_height(area);
st7789_send_color((void*)color_map, size * 2); st7789_send_color((void*)color_map, size * 2);
@ -192,21 +201,21 @@ void st7789_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * colo
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
void st7789_send_cmd(uint8_t cmd) static void st7789_send_cmd(uint8_t cmd)
{ {
disp_wait_for_pending_transactions(); disp_wait_for_pending_transactions();
gpio_set_level(ST7789_DC, 0); gpio_set_level(ST7789_DC, 0);
disp_spi_send_data(&cmd, 1); disp_spi_send_data(&cmd, 1);
} }
void st7789_send_data(void * data, uint16_t length) static void st7789_send_data(void * data, uint16_t length)
{ {
disp_wait_for_pending_transactions(); disp_wait_for_pending_transactions();
gpio_set_level(ST7789_DC, 1); gpio_set_level(ST7789_DC, 1);
disp_spi_send_data(data, length); disp_spi_send_data(data, length);
} }
static void st7789_send_color(void * data, size_t length) static void st7789_send_color(void * data, uint16_t length)
{ {
disp_wait_for_pending_transactions(); disp_wait_for_pending_transactions();
gpio_set_level(ST7789_DC, 1); gpio_set_level(ST7789_DC, 1);

View file

@ -23,17 +23,17 @@ extern "C"
#define ST7789_DC CONFIG_LV_DISP_PIN_DC #define ST7789_DC CONFIG_LV_DISP_PIN_DC
#define ST7789_RST CONFIG_LV_DISP_PIN_RST #define ST7789_RST CONFIG_LV_DISP_PIN_RST
#define ST7789_BCKL CONFIG_LV_DISP_PIN_BCKL
#if CONFIG_LV_DISP_USE_RST #define ST7789_ENABLE_BACKLIGHT_CONTROL CONFIG_LV_ENABLE_BACKLIGHT_CONTROL
#if CONFIG_LV_DISP_ST7789_SOFT_RESET
#define ST7789_SOFT_RST
#endif
#else
#define ST7789_SOFT_RST
#endif
#define ST7789_INVERT_COLORS CONFIG_LV_INVERT_COLORS #define ST7789_INVERT_COLORS CONFIG_LV_INVERT_COLORS
#if CONFIG_LV_BACKLIGHT_ACTIVE_LVL
#define ST7789_BCKL_ACTIVE_LVL 1
#else
#define ST7789_BCKL_ACTIVE_LVL 0
#endif
/* ST7789 commands */ /* ST7789 commands */
#define ST7789_NOP 0x00 #define ST7789_NOP 0x00
#define ST7789_SWRESET 0x01 #define ST7789_SWRESET 0x01
@ -112,9 +112,7 @@ extern "C"
void st7789_init(void); void st7789_init(void);
void st7789_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map); void st7789_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map);
void st7789_enable_backlight(bool backlight);
void st7789_send_cmd(uint8_t cmd);
void st7789_send_data(void *data, uint16_t length);
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

View file

@ -81,20 +81,31 @@ void st7796s_init(void)
{0, {0}, 0xff}, {0, {0}, 0xff},
}; };
#if ST7796S_BCKL == 15
gpio_config_t io_conf;
io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pin_bit_mask = GPIO_SEL_15;
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
gpio_config(&io_conf);
#endif
//Initialize non-SPI GPIOs //Initialize non-SPI GPIOs
gpio_pad_select_gpio(ST7796S_DC); gpio_pad_select_gpio(ST7796S_DC);
gpio_set_direction(ST7796S_DC, GPIO_MODE_OUTPUT); gpio_set_direction(ST7796S_DC, GPIO_MODE_OUTPUT);
#if ST7796S_USE_RST
gpio_pad_select_gpio(ST7796S_RST); gpio_pad_select_gpio(ST7796S_RST);
gpio_set_direction(ST7796S_RST, GPIO_MODE_OUTPUT); gpio_set_direction(ST7796S_RST, GPIO_MODE_OUTPUT);
#if ST7796S_ENABLE_BACKLIGHT_CONTROL
gpio_pad_select_gpio(ST7796S_BCKL);
gpio_set_direction(ST7796S_BCKL, GPIO_MODE_OUTPUT);
#endif
//Reset the display //Reset the display
gpio_set_level(ST7796S_RST, 0); gpio_set_level(ST7796S_RST, 0);
vTaskDelay(100 / portTICK_RATE_MS); vTaskDelay(100 / portTICK_RATE_MS);
gpio_set_level(ST7796S_RST, 1); gpio_set_level(ST7796S_RST, 1);
vTaskDelay(100 / portTICK_RATE_MS); vTaskDelay(100 / portTICK_RATE_MS);
#endif
ESP_LOGI(TAG, "Initialization."); ESP_LOGI(TAG, "Initialization.");
@ -111,6 +122,8 @@ void st7796s_init(void)
cmd++; cmd++;
} }
st7796s_enable_backlight(true);
st7796s_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION); st7796s_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION);
#if ST7796S_INVERT_COLORS == 1 #if ST7796S_INVERT_COLORS == 1
@ -148,6 +161,22 @@ void st7796s_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_
st7796s_send_color((void *)color_map, size * 2); st7796s_send_color((void *)color_map, size * 2);
} }
void st7796s_enable_backlight(bool backlight)
{
#if ST7796S_ENABLE_BACKLIGHT_CONTROL
ESP_LOGI(TAG, "%s backlight.", backlight ? "Enabling" : "Disabling");
uint32_t tmp = 0;
#if (ST7796S_BCKL_ACTIVE_LVL == 1)
tmp = backlight ? 1 : 0;
#else
tmp = backlight ? 0 : 1;
#endif
gpio_set_level(ST7796S_BCKL, tmp);
#endif
}
void st7796s_sleep_in() void st7796s_sleep_in()
{ {
uint8_t data[] = {0x08}; uint8_t data[] = {0x08};

View file

@ -26,12 +26,19 @@ extern "C"
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
#define ST7796S_DC CONFIG_LV_DISP_PIN_DC #define ST7796S_DC CONFIG_LV_DISP_PIN_DC
#define ST7796S_RST CONFIG_LV_DISP_PIN_RST #define ST7796S_RST CONFIG_LV_DISP_PIN_RST
#define ST7796S_USE_RST CONFIG_LV_DISP_USE_RST #define ST7796S_BCKL CONFIG_LV_DISP_PIN_BCKL
#define ST7796S_INVERT_COLORS CONFIG_LV_INVERT_COLORS
#define ST7796S_ENABLE_BACKLIGHT_CONTROL CONFIG_LV_ENABLE_BACKLIGHT_CONTROL
#define ST7796S_INVERT_COLORS CONFIG_LV_INVERT_COLORS
#define ST7796S_DISPLAY_ORIENTATION CONFIG_LV_DISPLAY_ORIENTATION #define ST7796S_DISPLAY_ORIENTATION CONFIG_LV_DISPLAY_ORIENTATION
#if CONFIG_LV_BACKLIGHT_ACTIVE_LVL
#define ST7796S_BCKL_ACTIVE_LVL 1
#else
#define ST7796S_BCKL_ACTIVE_LVL 0
#endif
/******************* /*******************
* ST7796S REGS * ST7796S REGS
@ -111,6 +118,7 @@ extern "C"
void st7796s_init(void); void st7796s_init(void);
void st7796s_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map); void st7796s_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map);
void st7796s_enable_backlight(bool backlight);
/********************** /**********************
* MACROS * MACROS

View file

@ -1,29 +1,28 @@
menu "LVGL Touch controller" menu "LVGL Touch controller"
config LV_TOUCH_CONTROLLER config LV_TOUCH_CONTROLLER
int int
default 0 if LV_TOUCH_CONTROLLER_NONE default 0 if LV_TOUCH_CONTROLLER_NONE
default 1 if LV_TOUCH_CONTROLLER_XPT2046 default 1 if LV_TOUCH_CONTROLLER_XPT2046
default 2 if LV_TOUCH_CONTROLLER_FT6X06 default 2 if LV_TOUCH_CONTROLLER_FT6X06
default 3 if LV_TOUCH_CONTROLLER_STMPE610 default 3 if LV_TOUCH_CONTROLLER_STMPE610
default 4 if LV_TOUCH_CONTROLLER_ADCRAW default 4 if LV_TOUCH_CONTROLLER_ADCRAW
default 5 if LV_TOUCH_CONTROLLER_FT81X default 5 if LV_TOUCH_CONTROLLER_FT81X
default 6 if LV_TOUCH_CONTROLLER_RA8875 default 6 if LV_TOUCH_CONTROLLER_RA8875
default 7 if LV_TOUCH_CONTROLLER_GT911 default 7 if LV_TOUCH_CONTROLLER_L58
default 8 if LV_TOUCH_CONTROLLER_L58
choice choice
prompt "Select a touch panel controller model." prompt "Select a touch panel controller model."
default LV_TOUCH_CONTROLLER_NONE default LV_TOUCH_CONTROLLER_NONE
help help
Select the controller for your touch panel. Select the controller for your touch panel.
config LV_TOUCH_CONTROLLER_NONE config LV_TOUCH_CONTROLLER_NONE
bool "None" bool "None"
config LV_TOUCH_CONTROLLER_XPT2046 config LV_TOUCH_CONTROLLER_XPT2046
select LV_TOUCH_DRIVER_PROTOCOL_SPI select LV_TOUCH_DRIVER_PROTOCOL_SPI
bool "XPT2046" bool "XPT2046"
config LV_TOUCH_CONTROLLER_FT6X06 config LV_TOUCH_CONTROLLER_FT6X06
select LV_I2C_TOUCH select LV_TOUCH_DRIVER_PROTOCOL_I2C
bool "FT6X06" bool "FT6X06"
config LV_TOUCH_CONTROLLER_L58 config LV_TOUCH_CONTROLLER_L58
@ -43,17 +42,14 @@ menu "LVGL Touch controller"
config LV_TOUCH_CONTROLLER_RA8875 config LV_TOUCH_CONTROLLER_RA8875
select LV_TOUCH_DRIVER_DISPLAY select LV_TOUCH_DRIVER_DISPLAY
bool "RA8875" bool "RA8875"
config LV_TOUCH_CONTROLLER_GT911
select LV_I2C_TOUCH
bool "GT911"
endchoice endchoice
config LV_TOUCH_DRIVER_PROTOCOL_SPI config LV_TOUCH_DRIVER_PROTOCOL_SPI
bool bool
help help
Touch controller protocol SPI Touch controller protocol SPI
config LV_I2C_TOUCH config LV_TOUCH_DRIVER_PROTOCOL_I2C
bool bool
help help
Touch controller protocol I2C Touch controller protocol I2C
@ -67,20 +63,37 @@ menu "LVGL Touch controller"
bool bool
help help
Touch controller uses same interface/device as display Touch controller uses same interface/device as display
(Note: Display must be initialized before touch) (Note: Display must be initialized before touch)
choice
prompt "Touch I2C port"
depends on LV_TOUCH_DRIVER_PROTOCOL_I2C
default LV_TOUCH_I2C_PORT_0
help
Select the I2C port used by the touch controller.
config LV_TOUCH_I2C_PORT_0
bool "I2C PORT 0"
config LV_TOUCH_I2C_PORT_1
bool "I2C PORT 1"
endchoice
choice choice
prompt "Touch Controller SPI Bus." prompt "Touch Controller SPI Bus."
depends on LV_TOUCH_DRIVER_PROTOCOL_SPI depends on LV_TOUCH_DRIVER_PROTOCOL_SPI
default LV_TOUCH_CONTROLLER_SPI2_HOST default LV_TOUCH_CONTROLLER_SPI_VSPI if !IDF_TARGET_ESP32S2
default LV_TOUCH_CONTROLLER_SPI_FSPI if IDF_TARGET_ESP32S2
help help
Select the SPI Bus the touch controller is attached to. Select the SPI Bus the TFT Display is attached to.
config LV_TOUCH_CONTROLLER_SPI2_HOST config LV_TOUCH_CONTROLLER_SPI_HSPI
bool "SPI2_HOST" bool "HSPI"
config LV_TOUCH_CONTROLLER_SPI3_HOST config LV_TOUCH_CONTROLLER_SPI_VSPI
bool "SPI3_HOST" bool "VSPI" if !IDF_TARGET_ESP32S2
config LV_TOUCH_CONTROLLER_SPI_FSPI
bool "FSPI" if IDF_TARGET_ESP32S2
endchoice endchoice
menu "Touchpanel (L58) Lilygo Pin Assignments" menu "Touchpanel (L58) Lilygo Pin Assignments"
@ -120,7 +133,9 @@ menu "LVGL Touch controller"
config LV_TOUCH_SPI_MISO config LV_TOUCH_SPI_MISO
int int
prompt "GPIO for MISO (Master In Slave Out)" prompt "GPIO for MISO (Master In Slave Out)"
range 0 39 if IDF_TARGET_ESP32
range 0 43 if IDF_TARGET_ESP32S2
default 35 if LV_PREDEFINED_PINS_38V1 default 35 if LV_PREDEFINED_PINS_38V1
default 19 default 19
help help
@ -129,6 +144,8 @@ menu "LVGL Touch controller"
config LV_TOUCH_SPI_MOSI config LV_TOUCH_SPI_MOSI
int int
prompt "GPIO for MOSI (Master Out Slave In)" prompt "GPIO for MOSI (Master Out Slave In)"
range 0 39 if IDF_TARGET_ESP32
range 0 43 if IDF_TARGET_ESP32S2
default 32 if LV_PREDEFINED_PINS_38V1 default 32 if LV_PREDEFINED_PINS_38V1
default 23 default 23
@ -137,7 +154,9 @@ menu "LVGL Touch controller"
config LV_TOUCH_SPI_CLK config LV_TOUCH_SPI_CLK
int "GPIO for CLK (SCK / Serial Clock)" int "GPIO for CLK (SCK / Serial Clock)"
range 0 39 if IDF_TARGET_ESP32
range 0 43 if IDF_TARGET_ESP32S2
default 26 if LV_PREDEFINED_PINS_38V1 default 26 if LV_PREDEFINED_PINS_38V1
default 18 default 18
help help
@ -145,7 +164,9 @@ menu "LVGL Touch controller"
config LV_TOUCH_SPI_CS config LV_TOUCH_SPI_CS
int "GPIO for CS (Slave Select)" int "GPIO for CS (Slave Select)"
range 0 39 if IDF_TARGET_ESP32
range 0 43 if IDF_TARGET_ESP32S2
default 33 if LV_PREDEFINED_PINS_38V1 default 33 if LV_PREDEFINED_PINS_38V1
default 5 default 5
help help
@ -153,13 +174,15 @@ menu "LVGL Touch controller"
config LV_TOUCH_PIN_IRQ config LV_TOUCH_PIN_IRQ
int "GPIO for IRQ (Interrupt Request)" int "GPIO for IRQ (Interrupt Request)"
range 0 39 if IDF_TARGET_ESP32
range 0 43 if IDF_TARGET_ESP32S2
default 27 if LV_PREDEFINED_PINS_38V4 default 27 if LV_PREDEFINED_PINS_38V4
default 25 default 25
help help
Configure the touchpanel IRQ pin here. Configure the touchpanel IRQ pin here.
endmenu endmenu
menu "Touchpanel Configuration (XPT2046)" menu "Touchpanel Configuration (XPT2046)"
depends on LV_TOUCH_CONTROLLER_XPT2046 depends on LV_TOUCH_CONTROLLER_XPT2046
@ -186,11 +209,11 @@ menu "LVGL Touch controller"
prompt "Maximum Y coordinate value." prompt "Maximum Y coordinate value."
default 4095 if LV_PREDEFINED_PINS_38V4 default 4095 if LV_PREDEFINED_PINS_38V4
default 1900 default 1900
config LV_TOUCH_XY_SWAP config LV_TOUCH_XY_SWAP
bool bool
prompt "Swap XY." prompt "Swap XY."
default y default y
config LV_TOUCH_INVERT_X config LV_TOUCH_INVERT_X
bool bool
@ -217,13 +240,36 @@ menu "LVGL Touch controller"
endchoice endchoice
endmenu endmenu
menu "Touchpanel (FT6X06) Pin Assignments"
depends on LV_TOUCH_CONTROLLER_FT6X06
config LV_TOUCH_I2C_SDA
int
prompt "GPIO for SDA (I2C)"
range 0 39 if IDF_TARGET_ESP32
range 0 43 if IDF_TARGET_ESP32S2
default 21
help
Configure the I2C touchpanel SDA pin here.
config LV_TOUCH_I2C_SCL
int "GPIO for clock signal SCL (I2C)"
range 0 39 if IDF_TARGET_ESP32
range 0 43 if IDF_TARGET_ESP32S2
default 22
help
Configure the I2C touchpanel SCL pin here.
endmenu
menu "Touchpanel Configuration (FT6X06)" menu "Touchpanel Configuration (FT6X06)"
depends on LV_TOUCH_CONTROLLER_FT6X06 depends on LV_TOUCH_CONTROLLER_FT6X06
config LV_FT6X36_SWAPXY config LV_FT6X36_SWAPXY
bool bool
prompt "Swap X with Y coordinate." prompt "Swap X with Y coordinate."
default n default y
config LV_FT6X36_INVERT_X config LV_FT6X36_INVERT_X
bool bool
@ -233,24 +279,19 @@ menu "LVGL Touch controller"
config LV_FT6X36_INVERT_Y config LV_FT6X36_INVERT_Y
bool bool
prompt "Invert Y coordinate value." prompt "Invert Y coordinate value."
default n default y
config LV_FT6X36_COORDINATES_QUEUE
bool
prompt "Send coordinates to FreeRTOS queue."
default n
help
Receive from the FreeRTOS queue using the handle 'ft6x36_touch_queue_handle'.
endmenu endmenu
menu "Touchpanel (STMPE610) Pin Assignments" menu "Touchpanel (STMPE610) Pin Assignments"
depends on LV_TOUCH_CONTROLLER_STMPE610 depends on LV_TOUCH_CONTROLLER_STMPE610
config LV_TOUCH_SPI_MISO config LV_TOUCH_SPI_MISO
int int
prompt "GPIO for MISO (Master In Slave Out)" prompt "GPIO for MISO (Master In Slave Out)"
range 0 39 if IDF_TARGET_ESP32
range 0 43 if IDF_TARGET_ESP32S2
default 35 if LV_PREDEFINED_PINS_38V1 default 35 if LV_PREDEFINED_PINS_38V1
default 19 if LV_PREDEFINED_DISPLAY_ADA_FEATHERWING default 19 if LV_PREDEFINED_DISPLAY_ADA_FEATHERWING
default 19 default 19
@ -259,9 +300,10 @@ menu "LVGL Touch controller"
Configure the touchpanel MISO pin here. Configure the touchpanel MISO pin here.
config LV_TOUCH_SPI_MOSI config LV_TOUCH_SPI_MOSI
# TODO Fix default for ESP32C3
int int
prompt "GPIO for MOSI (Master Out Slave In)" prompt "GPIO for MOSI (Master Out Slave In)"
range 0 39 if IDF_TARGET_ESP32
range 0 43 if IDF_TARGET_ESP32S2
default 32 if LV_PREDEFINED_PINS_38V1 default 32 if LV_PREDEFINED_PINS_38V1
default 18 if LV_PREDEFINED_DISPLAY_ADA_FEATHERWING default 18 if LV_PREDEFINED_DISPLAY_ADA_FEATHERWING
@ -272,6 +314,8 @@ menu "LVGL Touch controller"
config LV_TOUCH_SPI_CLK config LV_TOUCH_SPI_CLK
int "GPIO for CLK (SCK / Serial Clock)" int "GPIO for CLK (SCK / Serial Clock)"
range 0 39 if IDF_TARGET_ESP32
range 0 43 if IDF_TARGET_ESP32S2
default 26 if LV_PREDEFINED_PINS_38V1 default 26 if LV_PREDEFINED_PINS_38V1
default 5 if LV_PREDEFINED_DISPLAY_ADA_FEATHERWING default 5 if LV_PREDEFINED_DISPLAY_ADA_FEATHERWING
@ -281,6 +325,9 @@ menu "LVGL Touch controller"
config LV_TOUCH_SPI_CS config LV_TOUCH_SPI_CS
int "GPIO for CS (Slave Select)" int "GPIO for CS (Slave Select)"
range 0 39 if IDF_TARGET_ESP32
range 0 43 if IDF_TARGET_ESP32S2
default 33 if LV_PREDEFINED_PINS_38V1 default 33 if LV_PREDEFINED_PINS_38V1
default 32 if LV_PREDEFINED_DISPLAY_ADA_FEATHERWING default 32 if LV_PREDEFINED_DISPLAY_ADA_FEATHERWING
default 5 default 5
@ -310,11 +357,11 @@ menu "LVGL Touch controller"
int int
prompt "Maximum Y coordinate value." prompt "Maximum Y coordinate value."
default 3800 default 3800
config LV_TOUCH_XY_SWAP config LV_TOUCH_XY_SWAP
bool bool
prompt "Swap XY." prompt "Swap XY."
default n default n
config LV_TOUCH_INVERT_X config LV_TOUCH_INVERT_X
bool bool
@ -326,7 +373,7 @@ menu "LVGL Touch controller"
prompt "Invert Y coordinate value." prompt "Invert Y coordinate value."
default y default y
endmenu endmenu
menu "Touchpanel (ADCRAW) Pin Assignments" menu "Touchpanel (ADCRAW) Pin Assignments"
depends on LV_TOUCH_CONTROLLER_ADCRAW depends on LV_TOUCH_CONTROLLER_ADCRAW
@ -347,7 +394,7 @@ menu "LVGL Touch controller"
help help
Configure the touchpanel Y- pin. Must be ADC input. Configure the touchpanel Y- pin. Must be ADC input.
config LV_TOUCHSCREEN_RESISTIVE_PIN_XL config LV_TOUCHSCREEN_RESISTIVE_PIN_XL
int int
prompt "GPIO X-" prompt "GPIO X-"
@ -413,25 +460,25 @@ menu "LVGL Touch controller"
config LV_TOUCH_X_MIN config LV_TOUCH_X_MIN
int int
prompt "Minimum X coordinate ADC value" prompt "Minimum X coordinate ADC value"
range 0 1023 range 0 1023
default 0 default 0
config LV_TOUCH_Y_MIN config LV_TOUCH_Y_MIN
int int
prompt "Minimum Y coordinate ADC value" prompt "Minimum Y coordinate ADC value"
range 0 1023 range 0 1023
default 0 default 0
config LV_TOUCH_X_MAX config LV_TOUCH_X_MAX
int int
prompt "Maximum X coordinate ADC value" prompt "Maximum X coordinate ADC value"
range 0 1023 range 0 1023
default 1023 default 1023
config LV_TOUCH_Y_MAX config LV_TOUCH_Y_MAX
int int
prompt "Maximum Y coordinate ADC value" prompt "Maximum Y coordinate ADC value"
range 0 1023 range 0 1023
default 1023 default 1023
config LV_TOUCH_XY_SWAP config LV_TOUCH_XY_SWAP
@ -452,13 +499,13 @@ menu "LVGL Touch controller"
config LV_TOUCH_RA8875_SAMPLE_TIME config LV_TOUCH_RA8875_SAMPLE_TIME
int int
prompt "TP Sample Time Adjusting" prompt "TP Sample Time Adjusting"
range 0 7 range 0 7
default 0 default 0
config LV_TOUCH_RA8875_ADC_CLOCK config LV_TOUCH_RA8875_ADC_CLOCK
int int
prompt "ADC Clock Setting" prompt "ADC Clock Setting"
range 0 7 range 0 7
default 0 default 0
config LV_TOUCH_RA8875_WAKEUP_ENABLE config LV_TOUCH_RA8875_WAKEUP_ENABLE
@ -478,57 +525,4 @@ menu "LVGL Touch controller"
endmenu endmenu
menu "Touchpanel Configuration (GT911)"
depends on LV_TOUCH_CONTROLLER_GT911
config LV_GT911_SWAPXY
bool
prompt "Swap X with Y coordinate."
default y
config LV_GT911_INVERT_X
bool
prompt "Invert X coordinate value."
default n
config LV_GT911_INVERT_Y
bool
prompt "Invert Y coordinate value."
default y
endmenu
choice
prompt "Select an I2C port for the touch panel"
default LV_I2C_TOUCH_PORT_0
depends on LV_I2C_TOUCH
config LV_I2C_TOUCH_PORT_0
bool
prompt "I2C port 0"
help
I2C is shared peripheral managed by I2C Manager. In order to configure I2C Manager (pinout, etc.) see menu
Component config->I2C Port Settings.
config LV_I2C_TOUCH_PORT_1
bool
prompt "I2C port 1"
help
I2C is shared peripheral managed by I2C Manager. In order to configure I2C Manager (pinout, etc.) see menu
Component config->I2C Port Settings.
endchoice
config LV_I2C
bool
default y if LV_I2C_TOUCH
config LV_I2C_TOUCH_PORT
int
default 1 if LV_I2C_TOUCH_PORT_1
default 0
endmenu endmenu

View file

@ -1,45 +1,55 @@
/* /*
* Copyright © 2020 Wolfgang Christl * Copyright © 2020 Wolfgang Christl
* Permission is hereby granted, free of charge, to any person obtaining a copy of this * Permission is hereby granted, free of charge, to any person obtaining a copy of this
* software and associated documentation files (the Software), to deal in the Software * software and associated documentation files (the Software), to deal in the Software
* without restriction, including without limitation the rights to use, copy, modify, merge, * without restriction, including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons * publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
* to whom the Software is furnished to do so, subject to the following conditions: * to whom the Software is furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all copies or * The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software. * substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
#include <esp_log.h> #include <esp_log.h>
#include <driver/i2c.h>
#ifdef LV_LVGL_H_INCLUDE_SIMPLE #ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include <lvgl.h> #include <lvgl.h>
#else #else
#include <lvgl/lvgl.h> #include <lvgl/lvgl.h>
#endif #endif
#include "ft6x36.h" #include "ft6x36.h"
#include "lvgl_i2c/i2c_manager.h" #include "tp_i2c.h"
#include "../lvgl_i2c_conf.h"
#define TAG "FT6X36" #define TAG "FT6X36"
#define FT6X36_TOUCH_QUEUE_ELEMENTS 1
static ft6x36_status_t ft6x36_status; ft6x36_status_t ft6x36_status;
static uint8_t current_dev_addr; // set during init uint8_t current_dev_addr; // set during init
static ft6x36_touch_t touch_inputs = { -1, -1, LV_INDEV_STATE_REL }; // -1 coordinates to designate it was never touched
#if CONFIG_LV_FT6X36_COORDINATES_QUEUE
QueueHandle_t ft6x36_touch_queue_handle;
#endif
static esp_err_t ft6x06_i2c_read8(uint8_t slave_addr, uint8_t register_addr, uint8_t *data_buf) { esp_err_t ft6x06_i2c_read8(uint8_t slave_addr, uint8_t register_addr, uint8_t *data_buf) {
return lvgl_i2c_read(CONFIG_LV_I2C_TOUCH_PORT, slave_addr, register_addr, data_buf, 1); i2c_cmd_handle_t i2c_cmd = i2c_cmd_link_create();
i2c_master_start(i2c_cmd);
i2c_master_write_byte(i2c_cmd, (slave_addr << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(i2c_cmd, register_addr, I2C_MASTER_ACK);
i2c_master_start(i2c_cmd);
i2c_master_write_byte(i2c_cmd, (slave_addr << 1) | I2C_MASTER_READ, true);
i2c_master_read_byte(i2c_cmd, data_buf, I2C_MASTER_NACK);
i2c_master_stop(i2c_cmd);
esp_err_t ret = i2c_master_cmd_begin(TOUCH_I2C_PORT, i2c_cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(i2c_cmd);
return ret;
} }
/** /**
@ -65,38 +75,42 @@ uint8_t ft6x36_get_gesture_id() {
* @retval None * @retval None
*/ */
void ft6x06_init(uint16_t dev_addr) { void ft6x06_init(uint16_t dev_addr) {
if (!ft6x36_status.inited) {
ft6x36_status.inited = true; /* I2C master is initialized before calling this function */
current_dev_addr = dev_addr; #if 0
uint8_t data_buf; esp_err_t code = i2c_master_init();
esp_err_t ret; #else
ESP_LOGI(TAG, "Found touch panel controller"); esp_err_t code = ESP_OK;
if ((ret = ft6x06_i2c_read8(dev_addr, FT6X36_PANEL_ID_REG, &data_buf) != ESP_OK))
ESP_LOGE(TAG, "Error reading from device: %s",
esp_err_to_name(ret)); // Only show error the first time
ESP_LOGI(TAG, "\tDevice ID: 0x%02x", data_buf);
ft6x06_i2c_read8(dev_addr, FT6X36_CHIPSELECT_REG, &data_buf);
ESP_LOGI(TAG, "\tChip ID: 0x%02x", data_buf);
ft6x06_i2c_read8(dev_addr, FT6X36_DEV_MODE_REG, &data_buf);
ESP_LOGI(TAG, "\tDevice mode: 0x%02x", data_buf);
ft6x06_i2c_read8(dev_addr, FT6X36_FIRMWARE_ID_REG, &data_buf);
ESP_LOGI(TAG, "\tFirmware ID: 0x%02x", data_buf);
ft6x06_i2c_read8(dev_addr, FT6X36_RELEASECODE_REG, &data_buf);
ESP_LOGI(TAG, "\tRelease code: 0x%02x", data_buf);
#if CONFIG_LV_FT6X36_COORDINATES_QUEUE
ft6x36_touch_queue_handle = xQueueCreate( FT6X36_TOUCH_QUEUE_ELEMENTS, sizeof( ft6x36_touch_t ) );
if( ft6x36_touch_queue_handle == NULL )
{
ESP_LOGE( TAG, "\tError creating touch input FreeRTOS queue" );
return;
}
xQueueSend( ft6x36_touch_queue_handle, &touch_inputs, 0 );
#endif #endif
if (code != ESP_OK) {
ft6x36_status.inited = false;
ESP_LOGE(TAG, "Error during I2C init %s", esp_err_to_name(code));
} else {
ft6x36_status.inited = true;
current_dev_addr = dev_addr;
uint8_t data_buf;
esp_err_t ret;
ESP_LOGI(TAG, "Found touch panel controller");
if ((ret = ft6x06_i2c_read8(dev_addr, FT6X36_PANEL_ID_REG, &data_buf) != ESP_OK))
ESP_LOGE(TAG, "Error reading from device: %s",
esp_err_to_name(ret)); // Only show error the first time
ESP_LOGI(TAG, "\tDevice ID: 0x%02x", data_buf);
ft6x06_i2c_read8(dev_addr, FT6X36_CHIPSELECT_REG, &data_buf);
ESP_LOGI(TAG, "\tChip ID: 0x%02x", data_buf);
ft6x06_i2c_read8(dev_addr, FT6X36_DEV_MODE_REG, &data_buf);
ESP_LOGI(TAG, "\tDevice mode: 0x%02x", data_buf);
ft6x06_i2c_read8(dev_addr, FT6X36_FIRMWARE_ID_REG, &data_buf);
ESP_LOGI(TAG, "\tFirmware ID: 0x%02x", data_buf);
ft6x06_i2c_read8(dev_addr, FT6X36_RELEASECODE_REG, &data_buf);
ESP_LOGI(TAG, "\tRelease code: 0x%02x", data_buf);
}
}
} }
/** /**
@ -106,55 +120,84 @@ void ft6x06_init(uint16_t dev_addr) {
* @retval Always false * @retval Always false
*/ */
bool ft6x36_read(lv_indev_drv_t *drv, lv_indev_data_t *data) { bool ft6x36_read(lv_indev_drv_t *drv, lv_indev_data_t *data) {
if (!ft6x36_status.inited) { uint8_t data_xy[4]; // 2 bytes X | 2 bytes Y
ESP_LOGE(TAG, "Init first!"); uint8_t touch_pnt_cnt; // Number of detected touch points
return 0x00; static int16_t last_x = 0; // 12bit pixel value
} static int16_t last_y = 0; // 12bit pixel value
uint8_t data_buf[5]; // 1 byte status, 2 bytes X, 2 bytes Y
esp_err_t ret = lvgl_i2c_read(CONFIG_LV_I2C_TOUCH_PORT, current_dev_addr, FT6X36_TD_STAT_REG, &data_buf[0], 5); ft6x06_i2c_read8(current_dev_addr, FT6X36_TD_STAT_REG, &touch_pnt_cnt);
if (ret != ESP_OK) { if (touch_pnt_cnt != 1) { // ignore no touch & multi touch
ESP_LOGE(TAG, "Error talking to touch IC: %s", esp_err_to_name(ret)); data->point.x = last_x;
} data->point.y = last_y;
uint8_t touch_pnt_cnt = data_buf[0]; // Number of detected touch points data->state = LV_INDEV_STATE_REL;
if (ret != ESP_OK || touch_pnt_cnt != 1) { // ignore no touch & multi touch
if ( touch_inputs.current_state != LV_INDEV_STATE_REL)
{
touch_inputs.current_state = LV_INDEV_STATE_REL;
#if CONFIG_LV_FT6X36_COORDINATES_QUEUE
xQueueOverwrite( ft6x36_touch_queue_handle, &touch_inputs );
#endif
}
data->point.x = touch_inputs.last_x;
data->point.y = touch_inputs.last_y;
data->state = touch_inputs.current_state;
return false; return false;
} }
touch_inputs.current_state = LV_INDEV_STATE_PR; // Read X value
touch_inputs.last_x = ((data_buf[1] & FT6X36_MSB_MASK) << 8) | (data_buf[2] & FT6X36_LSB_MASK); i2c_cmd_handle_t i2c_cmd = i2c_cmd_link_create();
touch_inputs.last_y = ((data_buf[3] & FT6X36_MSB_MASK) << 8) | (data_buf[4] & FT6X36_LSB_MASK);
i2c_master_start(i2c_cmd);
i2c_master_write_byte(i2c_cmd, (current_dev_addr << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(i2c_cmd, FT6X36_P1_XH_REG, I2C_MASTER_ACK);
i2c_master_start(i2c_cmd);
i2c_master_write_byte(i2c_cmd, (current_dev_addr << 1) | I2C_MASTER_READ, true);
i2c_master_read_byte(i2c_cmd, &data_xy[0], I2C_MASTER_ACK); // reads FT6X36_P1_XH_REG
i2c_master_read_byte(i2c_cmd, &data_xy[1], I2C_MASTER_NACK); // reads FT6X36_P1_XL_REG
i2c_master_stop(i2c_cmd);
esp_err_t ret = i2c_master_cmd_begin(TOUCH_I2C_PORT, i2c_cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(i2c_cmd);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Error getting X coordinates: %s", esp_err_to_name(ret));
data->point.x = last_x;
data->point.y = last_y;
data->state = LV_INDEV_STATE_REL; // no touch detected
return false;
}
// Read Y value
i2c_cmd = i2c_cmd_link_create();
i2c_master_start(i2c_cmd);
i2c_master_write_byte(i2c_cmd, (current_dev_addr << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(i2c_cmd, FT6X36_P1_YH_REG, I2C_MASTER_ACK);
i2c_master_start(i2c_cmd);
i2c_master_write_byte(i2c_cmd, (current_dev_addr << 1) | I2C_MASTER_READ, true);
i2c_master_read_byte(i2c_cmd, &data_xy[2], I2C_MASTER_ACK); // reads FT6X36_P1_YH_REG
i2c_master_read_byte(i2c_cmd, &data_xy[3], I2C_MASTER_NACK); // reads FT6X36_P1_YL_REG
i2c_master_stop(i2c_cmd);
ret = i2c_master_cmd_begin(TOUCH_I2C_PORT, i2c_cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(i2c_cmd);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Error getting Y coordinates: %s", esp_err_to_name(ret));
data->point.x = last_x;
data->point.y = last_y;
data->state = LV_INDEV_STATE_REL; // no touch detected
return false;
}
last_x = ((data_xy[0] & FT6X36_MSB_MASK) << 8) | (data_xy[1] & FT6X36_LSB_MASK);
last_y = ((data_xy[2] & FT6X36_MSB_MASK) << 8) | (data_xy[3] & FT6X36_LSB_MASK);
#if CONFIG_LV_FT6X36_SWAPXY #if CONFIG_LV_FT6X36_SWAPXY
int16_t swap_buf = touch_inputs.last_x; int16_t swap_buf = last_x;
touch_inputs.last_x = touch_inputs.last_y; last_x = last_y;
touch_inputs.last_y = swap_buf; last_y = swap_buf;
#endif #endif
#if CONFIG_LV_FT6X36_INVERT_X #if CONFIG_LV_FT6X36_INVERT_X
touch_inputs.last_x = LV_HOR_RES - touch_inputs.last_x; last_x = LV_HOR_RES - last_x;
#endif #endif
#if CONFIG_LV_FT6X36_INVERT_Y #if CONFIG_LV_FT6X36_INVERT_Y
touch_inputs.last_y = LV_VER_RES - touch_inputs.last_y; last_y = LV_VER_RES - last_y;
#endif #endif
data->point.x = touch_inputs.last_x; //uint16_t lcd_x = p.x *1.37; // Max 240
data->point.y = touch_inputs.last_y; //uint16_t lcd_y = p.y *1.51; // Max 400
data->state = touch_inputs.current_state; data->point.x = last_x *1.37;
ESP_LOGD(TAG, "X=%u Y=%u", data->point.x, data->point.y); data->point.y = last_y *1.51;
data->state = LV_INDEV_STATE_PR;
#if CONFIG_LV_FT6X36_COORDINATES_QUEUE ESP_LOGV(TAG, "X=%u Y=%u", data->point.x, data->point.y);
xQueueOverwrite( ft6x36_touch_queue_handle, &touch_inputs );
#endif
return false; return false;
} }

View file

@ -2,20 +2,20 @@
/* /*
* Copyright © 2020 Wolfgang Christl * Copyright © 2020 Wolfgang Christl
* Permission is hereby granted, free of charge, to any person obtaining a copy of this * Permission is hereby granted, free of charge, to any person obtaining a copy of this
* software and associated documentation files (the Software), to deal in the Software * software and associated documentation files (the Software), to deal in the Software
* without restriction, including without limitation the rights to use, copy, modify, merge, * without restriction, including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons * publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
* to whom the Software is furnished to do so, subject to the following conditions: * to whom the Software is furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all copies or * The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software. * substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
@ -23,10 +23,6 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#if CONFIG_LV_FT6X36_COORDINATES_QUEUE
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#endif
#ifdef LV_LVGL_H_INCLUDE_SIMPLE #ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h" #include "lvgl.h"
#else #else
@ -149,16 +145,6 @@ typedef struct {
bool inited; bool inited;
} ft6x36_status_t; } ft6x36_status_t;
typedef struct
{
int16_t last_x;
int16_t last_y;
lv_indev_state_t current_state;
} ft6x36_touch_t;
#if CONFIG_LV_FT6X36_COORDINATES_QUEUE
extern QueueHandle_t ft6x36_touch_queue_handle;
#endif
/** /**
* @brief Initialize for FT6x36 communication via I2C * @brief Initialize for FT6x36 communication via I2C
* @param dev_addr: Device address on communication Bus (I2C slave address of FT6X36). * @param dev_addr: Device address on communication Bus (I2C slave address of FT6X36).

View file

@ -25,6 +25,7 @@
#include <lvgl/lvgl.h> #include <lvgl/lvgl.h>
#endif #endif
#include "l58.h" #include "l58.h"
#include "../lvgl_i2c_conf.h"
// Cale touch implementation // Cale touch implementation
#include "L58Touch.h" #include "L58Touch.h"
L58Touch Touch(CONFIG_LV_TOUCH_INT); L58Touch Touch(CONFIG_LV_TOUCH_INT);

View file

@ -4,11 +4,10 @@
#include "touch_driver.h" #include "touch_driver.h"
#include "tp_spi.h" #include "tp_spi.h"
#include "tp_i2c.h"
// Is not being included in CMakeLists.txt (Research why) // Is not being included in CMakeLists.txt (Research why)
#include "l58.h" #include "l58.h"
void touch_driver_init(void) void touch_driver_init(void)
{ {
#if defined (CONFIG_LV_TOUCH_CONTROLLER_XPT2046) #if defined (CONFIG_LV_TOUCH_CONTROLLER_XPT2046)
@ -25,16 +24,10 @@ void touch_driver_init(void)
/* nothing to do */ /* nothing to do */
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_RA8875) #elif defined (CONFIG_LV_TOUCH_CONTROLLER_RA8875)
ra8875_touch_init(); ra8875_touch_init();
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_GT911)
gt911_init(GT911_I2C_SLAVE_ADDR);
#endif #endif
} }
#if LVGL_VERSION_MAJOR >= 8
void touch_driver_read(lv_indev_drv_t *drv, lv_indev_data_t *data)
#else
bool touch_driver_read(lv_indev_drv_t *drv, lv_indev_data_t *data) bool touch_driver_read(lv_indev_drv_t *drv, lv_indev_data_t *data)
#endif
{ {
bool res = false; bool res = false;
@ -53,14 +46,8 @@ bool touch_driver_read(lv_indev_drv_t *drv, lv_indev_data_t *data)
res = FT81x_read(drv, data); res = FT81x_read(drv, data);
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_RA8875) #elif defined (CONFIG_LV_TOUCH_CONTROLLER_RA8875)
res = ra8875_touch_read(drv, data); res = ra8875_touch_read(drv, data);
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_GT911)
res = gt911_read(drv, data);
#endif #endif
#if LVGL_VERSION_MAJOR >= 8
data->continue_reading = res;
#else
return res; return res;
#endif
} }

View file

@ -32,8 +32,6 @@ extern "C" {
#include "FT81x.h" #include "FT81x.h"
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_RA8875) #elif defined (CONFIG_LV_TOUCH_CONTROLLER_RA8875)
#include "ra8875_touch.h" #include "ra8875_touch.h"
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_GT911)
#include "gt911.h"
#endif #endif
/********************* /*********************
@ -44,12 +42,7 @@ extern "C" {
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
**********************/ **********************/
void touch_driver_init(void); void touch_driver_init(void);
#if LVGL_VERSION_MAJOR >= 8
void touch_driver_read(lv_indev_drv_t *drv, lv_indev_data_t *data);
#else
bool touch_driver_read(lv_indev_drv_t *drv, lv_indev_data_t *data); bool touch_driver_read(lv_indev_drv_t *drv, lv_indev_data_t *data);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

43
lvgl_touch/tp_i2c.c Normal file
View file

@ -0,0 +1,43 @@
/*
* Copyright © 2020 Wolfgang Christl
* Permission is hereby granted, free of charge, to any person obtaining a copy of this
* software and associated documentation files (the Software), to deal in the Software
* without restriction, including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
* to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <driver/i2c.h>
#include <esp_log.h>
#define I2C_MASTER_FREQ_HZ 100000 /* 100kHz*/
#define I2C_MASTER_TX_BUF_DISABLE 0 /* I2C master doesn't need buffer */
#define I2C_MASTER_RX_BUF_DISABLE 0 /* I2C master doesn't need buffer */
/**
* @brief ESP32 I2C init as master
* @ret ESP32 error code
*/
esp_err_t i2c_master_init(void) {
int i2c_master_port = I2C_NUM_0;
i2c_config_t conf;
conf.mode = I2C_MODE_MASTER;
conf.sda_io_num = CONFIG_LV_TOUCH_I2C_SDA;
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
conf.scl_io_num = CONFIG_LV_TOUCH_I2C_SCL;
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
conf.master.clk_speed = I2C_MASTER_FREQ_HZ;
i2c_param_config(i2c_master_port, &conf);
return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
}

36
lvgl_touch/tp_i2c.h Normal file
View file

@ -0,0 +1,36 @@
/*
* Copyright © 2020 Wolfgang Christl
* Permission is hereby granted, free of charge, to any person obtaining a copy of this
* software and associated documentation files (the Software), to deal in the Software
* without restriction, including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
* to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __TS_H
#define __TS_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
esp_err_t i2c_master_init(void);
#ifdef __cplusplus
}
#endif
#endif /* __TS_H */