Merge 5ffb67f193
into 26fe6e7703
This commit is contained in:
commit
8aaebcb377
63 changed files with 2619 additions and 966 deletions
|
@ -3,12 +3,20 @@ if(ESP_PLATFORM)
|
|||
file(GLOB SOURCES *.c)
|
||||
set(LVGL_INCLUDE_DIRS . lvgl_tft)
|
||||
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
|
||||
# display controller.
|
||||
if(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341)
|
||||
list(APPEND SOURCES "lvgl_tft/ili9341.c")
|
||||
elseif(CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER)
|
||||
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)
|
||||
list(APPEND SOURCES "lvgl_tft/ili9481.c")
|
||||
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9486)
|
||||
|
@ -40,10 +48,6 @@ elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_RA8875)
|
|||
list(APPEND SOURCES "lvgl_tft/ra8875.c")
|
||||
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_GC9A01)
|
||||
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()
|
||||
message(WARNING "LVGL ESP32 drivers: Display controller not defined.")
|
||||
endif()
|
||||
|
@ -63,6 +67,10 @@ if(CONFIG_LV_TOUCH_CONTROLLER)
|
|||
list(APPEND SOURCES "lvgl_touch/xpt2046.c")
|
||||
elseif(CONFIG_LV_TOUCH_CONTROLLER_FT6X06)
|
||||
list(APPEND SOURCES "lvgl_touch/ft6x36.c")
|
||||
elseif(CONFIG_LV_TOUCH_CONTROLLER_L58)
|
||||
list(APPEND SOURCES "lvgl_touch/l58.cpp")
|
||||
elseif(CONFIG_LV_TOUCH_CONTROLLER_GT911)
|
||||
list(APPEND SOURCES "lvgl_touch/gt911.c")
|
||||
elseif(CONFIG_LV_TOUCH_CONTROLLER_STMPE610)
|
||||
list(APPEND SOURCES "lvgl_touch/stmpe610.c")
|
||||
elseif(CONFIG_LV_TOUCH_CONTROLLER_ADCRAW)
|
||||
|
@ -71,23 +79,21 @@ if(CONFIG_LV_TOUCH_CONTROLLER)
|
|||
list(APPEND SOURCES "lvgl_touch/FT81x.c")
|
||||
elseif(CONFIG_LV_TOUCH_CONTROLLER_RA8875)
|
||||
list(APPEND SOURCES "lvgl_touch/ra8875_touch.c")
|
||||
elseif(CONFIG_LV_TOUCH_CONTROLLER_GT911)
|
||||
list(APPEND SOURCES "lvgl_touch/gt911.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI)
|
||||
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()
|
||||
|
||||
if(CONFIG_LV_I2C)
|
||||
list(APPEND SOURCES "lvgl_i2c/i2c_manager.c")
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS ${SOURCES}
|
||||
INCLUDE_DIRS ${LVGL_INCLUDE_DIRS}
|
||||
REQUIRES lvgl)
|
||||
|
||||
REQUIRES epdiy
|
||||
lvgl CalEPD sharp-lcd espressif__esp_lcd_touch_gt911
|
||||
)
|
||||
|
||||
target_compile_definitions(${COMPONENT_LIB} PUBLIC "-DLV_LVGL_H_INCLUDE_SIMPLE")
|
||||
|
||||
else()
|
||||
|
|
|
@ -27,6 +27,12 @@ For more information on the function callbacks check LVGL documentation: (Displa
|
|||
|
||||
Add your display functions on `disp_driver_init`, `disp_driver_flush`, `disp_driver_rounder` and `disp_driver_set_px` on the `disp_driver.c` file.
|
||||
|
||||
**Additional notes**
|
||||
|
||||
New drivers should be also have some defines added in:
|
||||
lvgl_helpers.h
|
||||
(follow existing ones to add yours)
|
||||
|
||||
## Input device driver.
|
||||
|
||||
To enable LVGL to work with your touch controller you would need to implement an initialization function and one function to get the data out from your touch controller.
|
||||
|
|
16
Kconfig
16
Kconfig
|
@ -1,14 +1,2 @@
|
|||
menu "LVGL ESP Drivers"
|
||||
|
||||
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
|
||||
rsource "lvgl_tft/Kconfig"
|
||||
rsource "lvgl_touch/Kconfig"
|
||||
|
|
33
README.md
33
README.md
|
@ -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 indev controllers](#supported-indev-controllers)
|
||||
- [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
|
||||
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) |
|
||||
|---------------------------------------------|------------|------------------------|------------------------------|----------------------------------------|
|
||||
| ILI9341 | TFT | SPI | 16: RGB565 | Yes |
|
||||
| ILI9163C | TFT | SPI | 16: RGB565 | Yes |
|
||||
| ILI9486 | TFT | SPI | 16: RGB565 | Yes |
|
||||
| ILI9488 | TFT | SPI | 16: RGB565 | No |
|
||||
| HX8357B/HX8357D | TFT | SPI | 16: RGB565 | Yes |
|
||||
|
@ -30,7 +27,6 @@ swap of RGB565 color on the LVGL configuration menuconfig (it's not handled auto
|
|||
| RA8875 | TFT | SPI | 16: RGB565 | Yes |
|
||||
| SH1107 | Monochrome | SPI | 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 |
|
||||
| UC8151D/ GoodDisplay GDEW0154M10 DES | e-Paper | SPI | 1: 1byte per pixel | No |
|
||||
| FitiPower JD79653A/ GoodDisplay GDEW0154M09 | e-Paper | SPI | 1: 1byte per pixel | No |
|
||||
|
@ -38,8 +34,8 @@ swap of RGB565 color on the LVGL configuration menuconfig (it's not handled auto
|
|||
## Supported indev controllers
|
||||
|
||||
- XPT2046
|
||||
- FT3236, FT6X36
|
||||
- FT6206 controllers should work as well (not tested)
|
||||
- FT3236
|
||||
- other FT6X36 or the FT6206 controllers should work as well (not tested)
|
||||
- STMPE610
|
||||
- FT81x (Single, Dual, and Quad SPI)
|
||||
|
||||
|
@ -55,7 +51,6 @@ and sets the gpio numbers for the interface.
|
|||
|---------------------------|-----------------------|-----------|-----------|-----------|
|
||||
| ESP Wrover Kit v4.1 | ILI9341 | SPI | 240 | 320 |
|
||||
| M5Stack | ILI9341 | SPI | 240 | 320 |
|
||||
| M5Stack Core2 | ILI9341 | SPI | 240 | 320 |
|
||||
| M5Stick | SH1107 | SPI | - | - |
|
||||
| M5StickC | ST7735S | SPI | 80 | 160 |
|
||||
| Adafruit 3.5 Featherwing | HX8357 | SPI | 480 | 320 |
|
||||
|
@ -68,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 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)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# LVGL ESP32 drivers
|
||||
|
||||
# Define sources and include dirs
|
||||
COMPONENT_SRCDIRS := . lvgl_tft lvgl_touch lvgl_i2c
|
||||
COMPONENT_SRCDIRS := . lvgl_tft lvgl_touch
|
||||
COMPONENT_ADD_INCLUDEDIRS := .
|
||||
|
||||
# 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_DRIVER_PROTOCOL_SPI)), lvgl_touch/tp_spi.o)
|
||||
|
||||
# I2C Manager
|
||||
$(call compile_only_if,$(CONFIG_LV_I2C), lvgl_i2c/i2c_manager.o)
|
||||
$(call compile_only_if,$(and $(CONFIG_LV_TOUCH_CONTROLLER),$(CONFIG_LV_TOUCH_DRIVER_PROTOCOL_I2C)), lvgl_touch/tp_i2c.o)
|
||||
|
|
143
lvgl_helpers.c
143
lvgl_helpers.c
|
@ -14,13 +14,14 @@
|
|||
#include "lvgl_touch/tp_spi.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
|
||||
#include "lvgl.h"
|
||||
#include "src/lv_core/lv_refr.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl/src/lv_core/lv_refr.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
|
@ -52,12 +53,7 @@
|
|||
/* Interface and driver initialization */
|
||||
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);
|
||||
#endif
|
||||
|
||||
ESP_LOGI(TAG, "Display buffer size: %d", DISP_BUF_SIZE);
|
||||
|
||||
#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,
|
||||
SPI_BUS_MAX_TRANSFER_SZ, 1,
|
||||
DISP_SPI_IO2, DISP_SPI_IO3);
|
||||
|
||||
|
||||
disp_spi_add_device(TFT_SPI_HOST);
|
||||
disp_driver_init();
|
||||
|
||||
|
@ -85,81 +81,150 @@ void lvgl_driver_init(void)
|
|||
TP_SPI_MISO, DISP_SPI_MOSI, DISP_SPI_CLK,
|
||||
SPI_BUS_MAX_TRANSFER_SZ, 1,
|
||||
-1, -1);
|
||||
|
||||
|
||||
disp_spi_add_device(TFT_SPI_HOST);
|
||||
tp_spi_add_device(TOUCH_SPI_HOST);
|
||||
|
||||
|
||||
disp_driver_init();
|
||||
touch_driver_init();
|
||||
|
||||
return;
|
||||
#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 */
|
||||
#if defined CONFIG_LV_TFT_DISPLAY_PROTOCOL_SPI
|
||||
ESP_LOGI(TAG, "Initializing SPI master for display");
|
||||
|
||||
|
||||
lvgl_spi_driver_init(TFT_SPI_HOST,
|
||||
DISP_SPI_MISO, DISP_SPI_MOSI, DISP_SPI_CLK,
|
||||
SPI_BUS_MAX_TRANSFER_SZ, 1,
|
||||
DISP_SPI_IO2, DISP_SPI_IO3);
|
||||
|
||||
|
||||
disp_spi_add_device(TFT_SPI_HOST);
|
||||
|
||||
|
||||
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();
|
||||
#elif defined (CONFIG_LV_EPAPER_DISPLAY_PROTOCOL_PARALLEL)
|
||||
// Do not initialize SPI. Uses EPDiy
|
||||
ESP_LOGI(TAG, "Initializing driver for display");
|
||||
// Check how not to initialize SPI. disp_driver_init() call is needed:
|
||||
disp_driver_init();
|
||||
#else
|
||||
#error "No protocol defined for display controller"
|
||||
#error "No protocol defined for display controller"
|
||||
#endif
|
||||
|
||||
/* Touch controller initialization */
|
||||
#if CONFIG_LV_TOUCH_CONTROLLER != TOUCH_CONTROLLER_NONE
|
||||
#if defined (CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI)
|
||||
ESP_LOGI(TAG, "Initializing SPI master for touch");
|
||||
|
||||
|
||||
lvgl_spi_driver_init(TOUCH_SPI_HOST,
|
||||
TP_SPI_MISO, TP_SPI_MOSI, TP_SPI_CLK,
|
||||
0 /* Defaults to 4094 */, 2,
|
||||
-1, -1);
|
||||
|
||||
|
||||
tp_spi_add_device(TOUCH_SPI_HOST);
|
||||
|
||||
|
||||
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();
|
||||
#elif defined (CONFIG_LV_TOUCH_DRIVER_ADC)
|
||||
touch_driver_init();
|
||||
#elif defined (CONFIG_LV_TOUCH_DRIVER_DISPLAY)
|
||||
#elif defined (CONFIG_LV_TOUCH_DRIVER_DISPLAY) || defined (CONFIG_LV_TOUCH_CONTROLLER_L58)
|
||||
touch_driver_init();
|
||||
#else
|
||||
#error "No protocol defined for touch controller"
|
||||
#error "No protocol defined for touch controller"
|
||||
|
||||
#endif
|
||||
#else
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Initialize spi bus master
|
||||
/* Config the i2c master
|
||||
*
|
||||
* NOTE: dma_chan type and value changed to int instead of spi_dma_chan_t
|
||||
* for backwards compatibility with ESP-IDF versions prior v4.3.
|
||||
*
|
||||
* We could use the ESP_IDF_VERSION_VAL macro available in the "esp_idf_version.h"
|
||||
* header available since ESP-IDF v4.
|
||||
* This should init the i2c master to be used on display and touch controllers.
|
||||
* So we should be able to know if the display and touch controllers shares the
|
||||
* same i2c master.
|
||||
*/
|
||||
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,
|
||||
int miso_pin, int mosi_pin, int sclk_pin,
|
||||
int max_transfer_sz,
|
||||
int dma_channel,
|
||||
int quadwp_pin, int quadhd_pin)
|
||||
{
|
||||
assert((0 <= host) && (SPI_HOST_MAX > host));
|
||||
#if defined (CONFIG_IDF_TARGET_ESP32)
|
||||
assert((SPI_HOST <= host) && (VSPI_HOST >= host));
|
||||
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",
|
||||
miso_pin, mosi_pin, sclk_pin, quadwp_pin, quadhd_pin);
|
||||
|
||||
|
@ -167,19 +232,17 @@ bool lvgl_spi_driver_init(int host,
|
|||
|
||||
spi_bus_config_t buscfg = {
|
||||
.miso_io_num = miso_pin,
|
||||
.mosi_io_num = mosi_pin,
|
||||
.sclk_io_num = sclk_pin,
|
||||
.quadwp_io_num = quadwp_pin,
|
||||
.quadhd_io_num = quadhd_pin,
|
||||
.mosi_io_num = mosi_pin,
|
||||
.sclk_io_num = sclk_pin,
|
||||
.quadwp_io_num = quadwp_pin,
|
||||
.quadhd_io_num = quadhd_pin,
|
||||
.max_transfer_sz = max_transfer_sz
|
||||
};
|
||||
|
||||
ESP_LOGI(TAG, "Initializing SPI bus...");
|
||||
#if defined (CONFIG_IDF_TARGET_ESP32C3)
|
||||
dma_channel = SPI_DMA_CH_AUTO;
|
||||
#endif
|
||||
esp_err_t ret = spi_bus_initialize(host, &buscfg, (spi_dma_chan_t)dma_channel);
|
||||
esp_err_t ret = spi_bus_initialize(host, &buscfg, dma_channel);
|
||||
assert(ret == ESP_OK);
|
||||
|
||||
return ESP_OK != ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@ extern "C" {
|
|||
|
||||
#include "lvgl_spi_conf.h"
|
||||
#include "lvgl_tft/disp_driver.h"
|
||||
#include "lvgl_tft/esp_lcd_backlight.h"
|
||||
#include "lvgl_touch/touch_driver.h"
|
||||
|
||||
/*********************
|
||||
|
@ -42,7 +41,16 @@ extern "C" {
|
|||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7735S
|
||||
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
|
||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7796S
|
||||
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
|
||||
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * LV_VER_RES_MAX/3)
|
||||
// IMPORTANT: This will render the screen in 8 times (more and it skips lines, supposedly limited by PSRAM speed)
|
||||
#elif defined (CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER)
|
||||
#define DISP_BUF_SIZE LV_HOR_RES_MAX*(LV_VER_RES_MAX/ 8)
|
||||
|
||||
#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
|
||||
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
|
||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SH1107
|
||||
|
@ -74,10 +82,6 @@ extern "C" {
|
|||
#define DISP_BUF_SIZE ((LV_VER_RES_MAX * LV_VER_RES_MAX) / 8) // 5KB
|
||||
#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D)
|
||||
#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
|
||||
#error "No display controller selected"
|
||||
#endif
|
||||
|
@ -91,14 +95,14 @@ extern "C" {
|
|||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void lvgl_i2c_locking(void* leader);
|
||||
|
||||
/* Initialize detected SPI and I2C bus and devices */
|
||||
void lvgl_driver_init(void);
|
||||
|
||||
/* Initialize SPI master */
|
||||
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);
|
||||
/* Initialize I2C master */
|
||||
bool lvgl_i2c_driver_init(int port, int sda_pin, int scl_pin, int speed);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
|
116
lvgl_i2c_conf.h
Normal file
116
lvgl_i2c_conf.h
Normal 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*/
|
|
@ -64,10 +64,12 @@ extern "C" {
|
|||
|
||||
#define ENABLE_TOUCH_INPUT CONFIG_LV_ENABLE_TOUCH
|
||||
|
||||
#if defined (CONFIG_LV_TFT_DISPLAY_SPI2_HOST)
|
||||
#define TFT_SPI_HOST SPI2_HOST
|
||||
#elif defined (CONFIG_LV_TFT_DISPLAY_SPI3_HOST)
|
||||
#define TFT_SPI_HOST SPI3_HOST
|
||||
#if defined (CONFIG_LV_TFT_DISPLAY_SPI_HSPI)
|
||||
#define TFT_SPI_HOST HSPI_HOST
|
||||
#elif defined (CONFIG_LV_TFT_DISPLAY_SPI_VSPI)
|
||||
#define TFT_SPI_HOST VSPI_HOST
|
||||
#elif defined (CONFIG_LV_TFT_DISPLAY_SPI_FSPI)
|
||||
#define TFT_SPI_HOST FSPI_HOST
|
||||
#endif
|
||||
|
||||
#if defined (CONFIG_LV_TFT_DISPLAY_SPI_HALF_DUPLEX)
|
||||
|
@ -84,10 +86,12 @@ extern "C" {
|
|||
#define DISP_SPI_TRANS_MODE_SIO
|
||||
#endif
|
||||
|
||||
#if defined (CONFIG_LV_TOUCH_CONTROLLER_SPI2_HOST)
|
||||
#define TOUCH_SPI_HOST SPI2_HOST
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_SPI3_HOST)
|
||||
#define TOUCH_SPI_HOST SPI3_HOST
|
||||
#if defined (CONFIG_LV_TOUCH_CONTROLLER_SPI_HSPI)
|
||||
#define TOUCH_SPI_HOST HSPI_HOST
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_SPI_VSPI)
|
||||
#define TOUCH_SPI_HOST VSPI_HOST
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_SPI_FSPI)
|
||||
#define TOUCH_SPI_HOST FSPI_HOST
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
#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
|
||||
#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
|
||||
|
||||
#define SHARED_SPI_BUS
|
||||
|
@ -126,8 +130,7 @@ extern "C" {
|
|||
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_SH1107) || \
|
||||
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X) || \
|
||||
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_IL3820) || \
|
||||
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_JD79653A) || \
|
||||
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9163C)
|
||||
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_JD79653A)
|
||||
|
||||
#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)
|
||||
#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341)
|
||||
#define SPI_TFT_CLOCK_SPEED_HZ (40*1000*1000)
|
||||
#elif defined(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9163C)
|
||||
#define SPI_TFT_CLOCK_SPEED_HZ (40 * 1000 * 1000)
|
||||
#elif defined(CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X)
|
||||
#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X)
|
||||
#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
|
||||
#define SPI_TFT_CLOCK_SPEED_HZ (40*1000*1000)
|
||||
#endif
|
||||
|
|
|
@ -144,7 +144,7 @@ void DELAY_MS(uint16_t ms)
|
|||
vTaskDelay(ms / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
#if EVE_USE_PDN
|
||||
|
||||
void EVE_pdn_set(void)
|
||||
{
|
||||
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 */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void spi_acquire()
|
||||
{
|
||||
|
@ -841,13 +841,11 @@ uint8_t EVE_init(void)
|
|||
uint8_t chipid = 0;
|
||||
uint16_t timeout = 0;
|
||||
|
||||
#if EVE_USE_PDN
|
||||
EVE_pdn_set();
|
||||
DELAY_MS(6); /* minimum time for power-down is 5ms */
|
||||
|
||||
EVE_pdn_clear();
|
||||
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 */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
void DELAY_MS(uint16_t ms);
|
||||
|
||||
#if EVE_USE_PDN
|
||||
void EVE_pdn_set(void);
|
||||
void EVE_pdn_clear(void);
|
||||
#endif
|
||||
|
||||
void spi_acquire();
|
||||
void spi_release();
|
||||
|
||||
|
@ -68,7 +64,7 @@ void EVE_get_cmdoffset(void);
|
|||
/* commands to operate on memory: */
|
||||
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_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);
|
||||
|
||||
#if FT81X_FULL
|
||||
|
|
|
@ -44,12 +44,11 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH
|
|||
|
||||
#include "FT81x.h"
|
||||
|
||||
#define EVE_CLK DISP_SPI_CLK // orange
|
||||
#define EVE_MISO DISP_SPI_MISO // yellow
|
||||
#define EVE_MOSI DISP_SPI_MOSI // green
|
||||
#define EVE_CS DISP_SPI_CS // blue
|
||||
#define EVE_PDN CONFIG_LV_DISP_PIN_RST // grey
|
||||
#define EVE_USE_PDN CONFIG_LV_DISP_USE_RST
|
||||
#define EVE_CLK DISP_SPI_CLK // orange
|
||||
#define EVE_MISO DISP_SPI_MISO // yellow
|
||||
#define EVE_MOSI DISP_SPI_MOSI // green
|
||||
#define EVE_CS DISP_SPI_CS // blue
|
||||
#define EVE_PDN CONFIG_LV_DISP_PIN_RST // grey
|
||||
|
||||
#define SPI_TRANSER_SIZE (DISP_BUF_SIZE * (LV_COLOR_DEPTH / 8))
|
||||
|
||||
|
|
|
@ -250,7 +250,7 @@ void TFT_bitmap_display(void)
|
|||
EVE_cmd_dl(TAG(0));
|
||||
|
||||
EVE_cmd_dl(DL_DISPLAY); /* instruct the graphics processor to show the list */
|
||||
|
||||
|
||||
EVE_cmd_dl(CMD_SWAP); /* make this list active */
|
||||
|
||||
EVE_end_cmd_burst(); /* stop writing to the cmd-fifo */
|
||||
|
@ -262,18 +262,12 @@ void TFT_bitmap_display(void)
|
|||
|
||||
void FT81x_init(void)
|
||||
{
|
||||
#if EVE_USE_PDN
|
||||
gpio_pad_select_gpio(EVE_PDN);
|
||||
#endif
|
||||
|
||||
gpio_set_level(EVE_CS, 1);
|
||||
|
||||
#if EVE_USE_PDN
|
||||
gpio_set_direction(EVE_PDN, GPIO_MODE_OUTPUT);
|
||||
#endif
|
||||
|
||||
spi_acquire();
|
||||
|
||||
|
||||
if(EVE_init())
|
||||
{
|
||||
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_execute();
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
TFT_WriteBitmap((uint8_t*)color_map, area->x1, area->y1, lv_area_get_width(area), lv_area_get_height(area));
|
||||
}
|
||||
}
|
|
@ -111,20 +111,31 @@ void GC9A01_init(void)
|
|||
|
||||
};
|
||||
|
||||
//Initialize non-SPI GPIOs
|
||||
gpio_pad_select_gpio(GC9A01_DC);
|
||||
gpio_set_direction(GC9A01_DC, GPIO_MODE_OUTPUT);
|
||||
#if GC9A01_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 GC9A01_USE_RST
|
||||
gpio_pad_select_gpio(GC9A01_RST);
|
||||
//Initialize non-SPI GPIOs
|
||||
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);
|
||||
|
||||
#if GC9A01_ENABLE_BACKLIGHT_CONTROL
|
||||
gpio_pad_select_gpio(GC9A01_BCKL);
|
||||
gpio_set_direction(GC9A01_BCKL, GPIO_MODE_OUTPUT);
|
||||
#endif
|
||||
//Reset the display
|
||||
gpio_set_level(GC9A01_RST, 0);
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
gpio_set_level(GC9A01_RST, 1);
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
#endif
|
||||
|
||||
ESP_LOGI(TAG, "Initialization.");
|
||||
|
||||
|
@ -139,6 +150,8 @@ void GC9A01_init(void)
|
|||
cmd++;
|
||||
}
|
||||
|
||||
GC9A01_enable_backlight(true);
|
||||
|
||||
GC9A01_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION);
|
||||
|
||||
#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];
|
||||
|
||||
/*Column addresses*/
|
||||
GC9A01_send_cmd(0x2A); //0x2A
|
||||
GC9A01_send_cmd(0x2A); //0x2A
|
||||
data[0] = (area->x1 >> 8) & 0xFF;
|
||||
data[1] = area->x1 & 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);
|
||||
|
||||
/*Page addresses*/
|
||||
GC9A01_send_cmd(0x2B); //0x2B
|
||||
GC9A01_send_cmd(0x2B); //0x2B
|
||||
data[0] = (area->y1 >> 8) & 0xFF;
|
||||
data[1] = area->y1 & 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);
|
||||
|
||||
/*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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
uint8_t data[] = {0x08};
|
||||
GC9A01_send_cmd(0x10); //0x10 Enter Sleep Mode
|
||||
GC9A01_send_data(&data, 1);
|
||||
GC9A01_send_data(&data, 1);
|
||||
}
|
||||
|
||||
void GC9A01_sleep_out()
|
||||
|
|
|
@ -25,9 +25,18 @@ extern "C" {
|
|||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define GC9A01_DC CONFIG_LV_DISP_PIN_DC
|
||||
#define GC9A01_RST CONFIG_LV_DISP_PIN_RST
|
||||
#define GC9A01_USE_RST CONFIG_LV_DISP_USE_RST
|
||||
#define GC9A01_DC CONFIG_LV_DISP_PIN_DC
|
||||
#define GC9A01_RST CONFIG_LV_DISP_PIN_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
|
||||
|
||||
/**********************
|
||||
|
@ -40,6 +49,7 @@ extern "C" {
|
|||
|
||||
void GC9A01_init(void);
|
||||
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_out(void);
|
||||
|
||||
|
|
366
lvgl_tft/Kconfig
366
lvgl_tft/Kconfig
|
@ -1,7 +1,7 @@
|
|||
# NOTES:
|
||||
# - default <> if <> work only when no prompt is available for the user
|
||||
|
||||
menu "LVGL TFT Display controller"
|
||||
menu "LVGL TFT/Epaper Display controller"
|
||||
|
||||
# Predefined display configurations for multiple
|
||||
# evaluation/development boards.
|
||||
|
@ -21,10 +21,6 @@ menu "LVGL TFT Display controller"
|
|||
bool "M5Stack"
|
||||
select LV_TFT_DISPLAY_CONTROLLER_ILI9341
|
||||
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
|
||||
bool "M5Stick"
|
||||
select LV_TFT_DISPLAY_CONTROLLER_SH1107
|
||||
|
@ -50,7 +46,7 @@ menu "LVGL TFT Display controller"
|
|||
config LV_PREDEFINED_DISPLAY_WEMOS_LOLIN
|
||||
bool "Wemos Lolin OLED"
|
||||
select LV_TFT_DISPLAY_CONTROLLER_SSD1306
|
||||
select LV_I2C_DISPLAY
|
||||
select LV_TFT_DISPLAY_PROTOCOL_I2C
|
||||
select LV_TFT_DISPLAY_MONOCHROME
|
||||
select LV_THEME_MONO
|
||||
config LV_PREDEFINED_DISPLAY_ATAG
|
||||
|
@ -89,6 +85,18 @@ menu "LVGL TFT Display controller"
|
|||
#
|
||||
# If you add support for a new display controller to the repository
|
||||
# you must add a config option for it on this helper symbols section.
|
||||
config LV_EPAPER_EPDIY_DISPLAY_CONTROLLER
|
||||
bool
|
||||
help
|
||||
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
|
||||
bool
|
||||
help
|
||||
|
@ -169,15 +177,6 @@ menu "LVGL TFT Display controller"
|
|||
help
|
||||
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
|
||||
#
|
||||
# This symbols define the communication protocol used by the
|
||||
|
@ -186,12 +185,17 @@ menu "LVGL TFT Display controller"
|
|||
# - Know what peripherals to initialize.
|
||||
# - Know if the touch and display controllers share the same peripheral.
|
||||
# - Etc.
|
||||
config LV_EPAPER_DISPLAY_PROTOCOL_PARALLEL
|
||||
bool
|
||||
help
|
||||
Epaper controller protocol Parallel based on EPDiy 8 data lines
|
||||
|
||||
config LV_TFT_DISPLAY_PROTOCOL_SPI
|
||||
bool
|
||||
help
|
||||
Display controller protocol SPI
|
||||
|
||||
config LV_I2C_DISPLAY
|
||||
config LV_TFT_DISPLAY_PROTOCOL_I2C
|
||||
bool
|
||||
help
|
||||
Display controller protocol I2C
|
||||
|
@ -199,24 +203,24 @@ menu "LVGL TFT Display controller"
|
|||
# Used in display init function to send display orientation commands
|
||||
choice DISPLAY_ORIENTATION
|
||||
prompt "Display orientation"
|
||||
default LV_DISPLAY_ORIENTATION_PORTRAIT if !LV_TFT_DISPLAY_CONTROLLER_SSD1306
|
||||
default LV_DISPLAY_ORIENTATION_LANDSCAPE if LV_TFT_DISPLAY_CONTROLLER_SSD1306
|
||||
config LV_DISPLAY_ORIENTATION_PORTRAIT
|
||||
default DISPLAY_ORIENTATION_PORTRAIT if !LV_TFT_DISPLAY_CONTROLLER_SSD1306
|
||||
default DISPLAY_ORIENTATION_LANDSCAPE if LV_TFT_DISPLAY_CONTROLLER_SSD1306
|
||||
config DISPLAY_ORIENTATION_PORTRAIT
|
||||
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
|
||||
config LV_DISPLAY_ORIENTATION_LANDSCAPE
|
||||
config DISPLAY_ORIENTATION_LANDSCAPE
|
||||
bool "Landscape"
|
||||
config LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED
|
||||
config DISPLAY_ORIENTATION_LANDSCAPE_INVERTED
|
||||
bool "Landscape inverted"
|
||||
endchoice
|
||||
|
||||
config LV_DISPLAY_ORIENTATION
|
||||
int
|
||||
default 0 if LV_DISPLAY_ORIENTATION_PORTRAIT
|
||||
default 1 if LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED
|
||||
default 2 if LV_DISPLAY_ORIENTATION_LANDSCAPE
|
||||
default 3 if LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED
|
||||
default 0 if DISPLAY_ORIENTATION_PORTRAIT
|
||||
default 1 if DISPLAY_ORIENTATION_PORTRAIT_INVERTED
|
||||
default 2 if DISPLAY_ORIENTATION_LANDSCAPE
|
||||
default 3 if DISPLAY_ORIENTATION_LANDSCAPE_INVERTED
|
||||
|
||||
config LV_TFT_DISPLAY_OFFSETS
|
||||
bool
|
||||
|
@ -225,14 +229,14 @@ menu "LVGL TFT Display controller"
|
|||
|
||||
config LV_TFT_DISPLAY_X_OFFSET
|
||||
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 53 if LV_PREDEFINED_DISPLAY_TTGO && (LV_DISPLAY_ORIENTATION_PORTRAIT || LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
|
||||
default 0
|
||||
|
||||
config LV_TFT_DISPLAY_Y_OFFSET
|
||||
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 40 if LV_PREDEFINED_DISPLAY_TTGO && (LV_DISPLAY_ORIENTATION_PORTRAIT || LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
|
||||
default 0
|
||||
|
@ -270,6 +274,21 @@ menu "LVGL TFT Display controller"
|
|||
prompt "Select a display controller model." if LV_PREDEFINED_DISPLAY_NONE
|
||||
help
|
||||
Select the controller for your display.
|
||||
config LV_EPAPER_DISPLAY_USER_CONTROLLER_EPDIY
|
||||
bool "EPDIY_GENERIC"
|
||||
select LV_EPAPER_EPDIY_DISPLAY_CONTROLLER
|
||||
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
|
||||
bool "ILI9341"
|
||||
|
@ -315,7 +334,7 @@ menu "LVGL TFT Display controller"
|
|||
config LV_TFT_DISPLAY_USER_CONTROLLER_SSD1306
|
||||
bool "SSD1306"
|
||||
select LV_TFT_DISPLAY_CONTROLLER_SSD1306
|
||||
select LV_I2C_DISPLAY
|
||||
select LV_TFT_DISPLAY_PROTOCOL_I2C
|
||||
select LV_TFT_DISPLAY_MONOCHROME
|
||||
config LV_TFT_DISPLAY_USER_CONTROLLER_FT81X
|
||||
bool "FT81X"
|
||||
|
@ -340,15 +359,6 @@ menu "LVGL TFT Display controller"
|
|||
bool "RA8875"
|
||||
select LV_TFT_DISPLAY_CONTROLLER_RA8875
|
||||
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
|
||||
|
||||
config CUSTOM_DISPLAY_BUFFER_SIZE
|
||||
|
@ -468,15 +478,20 @@ menu "LVGL TFT Display controller"
|
|||
endchoice
|
||||
|
||||
choice
|
||||
prompt "TFT SPI Bus." if LV_TFT_DISPLAY_PROTOCOL_SPI
|
||||
default LV_TFT_DISPLAY_SPI2_HOST
|
||||
prompt "TFT SPI Bus." if LV_TFT_DISPLAY_PROTOCOL_SPI && \
|
||||
!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
|
||||
Select the SPI Bus the TFT Display is attached to.
|
||||
|
||||
config LV_TFT_DISPLAY_SPI2_HOST
|
||||
bool "SPI2_HOST"
|
||||
config LV_TFT_DISPLAY_SPI3_HOST
|
||||
bool "SPI3_HOST"
|
||||
config LV_TFT_DISPLAY_SPI_HSPI
|
||||
bool "HSPI"
|
||||
config LV_TFT_DISPLAY_SPI_VSPI
|
||||
bool "VSPI" if !IDF_TARGET_ESP32S2
|
||||
config LV_TFT_DISPLAY_SPI_FSPI
|
||||
bool "FSPI" if IDF_TARGET_ESP32S2
|
||||
endchoice
|
||||
|
||||
choice
|
||||
|
@ -507,6 +522,18 @@ menu "LVGL TFT Display controller"
|
|||
depends on LV_TFT_DISPLAY_SPI_TRANS_MODE_SIO
|
||||
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
|
||||
bool "Use custom SPI clock frequency." if LV_TFT_DISPLAY_PROTOCOL_SPI
|
||||
default n
|
||||
|
@ -584,16 +611,6 @@ menu "LVGL TFT Display controller"
|
|||
default 80 if LV_TFT_SPI_CLK_DIVIDER_80
|
||||
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
|
||||
bool "IN DEPRECATION - Invert display." if LV_TFT_DISPLAY_CONTROLLER_RA8875
|
||||
default n
|
||||
|
@ -601,12 +618,37 @@ menu "LVGL TFT Display controller"
|
|||
If text is backwards on your display, try enabling this.
|
||||
|
||||
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
|
||||
help
|
||||
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.
|
||||
|
||||
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 "Display RA8875 Configuration"
|
||||
|
@ -734,11 +776,11 @@ menu "LVGL TFT Display controller"
|
|||
|
||||
config LV_DISP_ST7789_SOFT_RESET
|
||||
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
|
||||
help
|
||||
Use software reset and ignores configured reset pin (some hardware does not use a reset pin).
|
||||
|
||||
|
||||
endmenu
|
||||
|
||||
# menu will be visible only when LV_PREDEFINED_DISPLAY_NONE is y
|
||||
|
@ -747,10 +789,12 @@ menu "LVGL TFT Display controller"
|
|||
|
||||
config LV_DISP_SPI_MOSI
|
||||
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_ATAG
|
||||
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 18 if LV_PREDEFINED_DISPLAY_ADA_FEATHERWING
|
||||
default 23 if LV_PREDEFINED_PINS_TKOALA
|
||||
|
@ -758,13 +802,13 @@ menu "LVGL TFT Display controller"
|
|||
default 19 if LV_PREDEFINED_DISPLAY_TTGO_CAMERA_PLUS
|
||||
default 13 if LV_PREDEFINED_DISPLAY_WT32_SC01
|
||||
default 13
|
||||
|
||||
help
|
||||
Configure the display MOSI pin here.
|
||||
|
||||
config LV_DISPLAY_USE_SPI_MISO
|
||||
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_DISPLAY_M5CORE2
|
||||
help
|
||||
Enable the MISO signal to control the display. You can disable
|
||||
it when the display does not need MISO signal to be controlled.
|
||||
|
@ -772,8 +816,10 @@ menu "LVGL TFT Display controller"
|
|||
config LV_DISP_SPI_MISO
|
||||
int "GPIO for MISO (Master In Slave Out)" if LV_TFT_DISPLAY_PROTOCOL_SPI
|
||||
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 38 if LV_PREDEFINED_DISPLAY_M5CORE2
|
||||
default 0
|
||||
|
||||
help
|
||||
|
@ -791,6 +837,9 @@ menu "LVGL TFT Display controller"
|
|||
config LV_DISP_SPI_IO2
|
||||
int "GPIO for Quad SPI IO2/WP" if LV_TFT_DISPLAY_PROTOCOL_SPI
|
||||
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 -1
|
||||
help
|
||||
|
@ -799,6 +848,9 @@ menu "LVGL TFT Display controller"
|
|||
config LV_DISP_SPI_IO3
|
||||
int "GPIO for Quad SPI IO3/HD" if LV_TFT_DISPLAY_PROTOCOL_SPI
|
||||
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 -1
|
||||
help
|
||||
|
@ -806,8 +858,10 @@ menu "LVGL TFT Display controller"
|
|||
|
||||
config LV_DISP_SPI_CLK
|
||||
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_M5CORE2
|
||||
default 13 if LV_PREDEFINED_DISPLAY_M5STICKC
|
||||
default 18 if LV_PREDEFINED_DISPLAY_ATAG
|
||||
default 19 if LV_PREDEFINED_DISPLAY_WROVER4
|
||||
|
@ -831,9 +885,11 @@ menu "LVGL TFT Display controller"
|
|||
config LV_DISP_SPI_CS
|
||||
int "GPIO for CS (Slave Select)" if LV_TFT_DISPLAY_PROTOCOL_SPI
|
||||
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 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 22 if LV_PREDEFINED_DISPLAY_WROVER4
|
||||
default 15 if LV_PREDEFINED_DISPLAY_ADA_FEATHERWING
|
||||
|
@ -856,11 +912,13 @@ menu "LVGL TFT Display controller"
|
|||
|
||||
config LV_DISP_PIN_DC
|
||||
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
|
||||
default 19 if LV_PREDEFINED_PINS_38V1
|
||||
default 17 if LV_PREDEFINED_PINS_38V4
|
||||
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 21 if LV_PREDEFINED_DISPLAY_WROVER4
|
||||
default 21 if LV_PREDEFINED_DISPLAY_WT32_SC01
|
||||
|
@ -874,22 +932,11 @@ menu "LVGL TFT Display controller"
|
|||
help
|
||||
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
|
||||
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 25 if LV_PREDEFINED_PINS_38V4
|
||||
default 33 if LV_PREDEFINED_DISPLAY_M5STACK || LV_PREDEFINED_DISPLAY_M5STICK
|
||||
|
@ -908,103 +955,84 @@ menu "LVGL TFT Display controller"
|
|||
|
||||
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
|
||||
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 IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2
|
||||
default 21 if IDF_TARGET_ESP32C3
|
||||
default 35
|
||||
|
||||
help
|
||||
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
|
||||
|
||||
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
|
||||
|
|
95
lvgl_tft/calepd_epaper.cpp
Normal file
95
lvgl_tft/calepd_epaper.cpp
Normal 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
38
lvgl_tft/calepd_epaper.h
Normal 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 */
|
|
@ -4,13 +4,18 @@
|
|||
|
||||
#include "disp_driver.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
|
||||
ili9341_init();
|
||||
#elif defined CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER
|
||||
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
|
||||
ili9481_init();
|
||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488
|
||||
|
@ -23,7 +28,7 @@ void *disp_driver_init(void)
|
|||
st7735s_init();
|
||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_HX8357
|
||||
hx8357_init();
|
||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9486
|
||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9486
|
||||
ili9486_init();
|
||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SH1107
|
||||
sh1107_init();
|
||||
|
@ -41,35 +46,6 @@ void *disp_driver_init(void)
|
|||
jd79653a_init();
|
||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -77,6 +53,12 @@ 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
|
||||
ili9341_flush(drv, area, color_map);
|
||||
#elif defined CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER
|
||||
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
|
||||
ili9481_flush(drv, area, color_map);
|
||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488
|
||||
|
@ -107,15 +89,12 @@ 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);
|
||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D
|
||||
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
|
||||
}
|
||||
|
||||
void disp_driver_rounder(lv_disp_drv_t * disp_drv, lv_area_t * area)
|
||||
{
|
||||
// Does not apply so far to epdiy
|
||||
#if defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SSD1306
|
||||
ssd1306_rounder(disp_drv, area);
|
||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SH1107
|
||||
|
@ -126,16 +105,22 @@ void disp_driver_rounder(lv_disp_drv_t * disp_drv, lv_area_t * area)
|
|||
jd79653a_lv_rounder_cb(disp_drv, area);
|
||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D
|
||||
uc8151d_lv_rounder_cb(disp_drv, area);
|
||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_PCD8544
|
||||
pcd8544_rounder(disp_drv, area);
|
||||
#elif defined CONFIG_LV_SHARP_DISPLAY_CONTROLLER
|
||||
sharp_rounder(disp_drv, area);
|
||||
#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,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
#if defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SSD1306
|
||||
ssd1306_set_px_cb(disp_drv, buf, buf_w, x, y, color, opa);
|
||||
#elif defined CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER
|
||||
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
|
||||
sh1107_set_px_cb(disp_drv, buf, buf_w, x, y, color, opa);
|
||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_IL3820
|
||||
|
@ -144,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);
|
||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D
|
||||
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
|
||||
}
|
||||
|
|
|
@ -20,6 +20,13 @@ extern "C" {
|
|||
|
||||
#if defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341
|
||||
#include "ili9341.h"
|
||||
#elif defined CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER
|
||||
#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
|
||||
#include "ili9481.h"
|
||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488
|
||||
|
@ -50,10 +57,6 @@ extern "C" {
|
|||
#include "jd79653a.h"
|
||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D
|
||||
#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
|
||||
|
||||
/*********************
|
||||
|
@ -69,7 +72,7 @@ extern "C" {
|
|||
**********************/
|
||||
|
||||
/* Initialize display */
|
||||
void *disp_driver_init(void);
|
||||
void disp_driver_init(void);
|
||||
|
||||
/* Display flush callback */
|
||||
void disp_driver_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);
|
||||
|
|
|
@ -310,12 +310,7 @@ static void IRAM_ATTR spi_ready(spi_transaction_t *trans)
|
|||
disp = lv_refr_get_disp_refreshing();
|
||||
#endif
|
||||
|
||||
#if LVGL_VERSION_MAJOR < 8
|
||||
lv_disp_flush_ready(&disp->driver);
|
||||
#else
|
||||
lv_disp_flush_ready(disp->driver);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
if (chained_post_cb) {
|
||||
|
|
127
lvgl_tft/epdiy_epaper.c
Normal file
127
lvgl_tft/epdiy_epaper.c
Normal file
|
@ -0,0 +1,127 @@
|
|||
/**************************************************************************************************
|
||||
* NOTE: This file is the first version that writes directly on the set_px callback
|
||||
* each pixel into the epaper display buffer. The second version is 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
|
||||
*
|
||||
* BOTH are oriented to latest version of epdiy driver that uses LCD module for parallel communication
|
||||
* BRANCH: s3_lcd
|
||||
**************************************************************************************************/
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "epdiy_epaper.h"
|
||||
#include "epd_driver.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_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<250) {
|
||||
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);
|
||||
}
|
||||
}
|
119
lvgl_tft/epdiy_epaper.cpp
Normal file
119
lvgl_tft/epdiy_epaper.cpp
Normal file
|
@ -0,0 +1,119 @@
|
|||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "epdiy_epaper.h"
|
||||
#include "epdiy.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);
|
||||
hl = epd_hl_init(EPD_BUILTIN_WAVEFORM);
|
||||
framebuffer = epd_hl_get_framebuffer(&hl);
|
||||
epd_poweron();
|
||||
//Clear all display in initialization to remove any ghosts
|
||||
epd_fullclear(&hl, temperature);
|
||||
}
|
||||
|
||||
/* Suggested by @kisvegabor https://forum.lvgl.io/t/lvgl-port-to-be-used-with-epaper-displays/5630/26
|
||||
* @deprecated
|
||||
*/
|
||||
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]);
|
||||
} */
|
||||
// This is the slower version that works good without leaving any white line
|
||||
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);
|
||||
}
|
||||
}
|
35
lvgl_tft/epdiy_epaper.h
Normal file
35
lvgl_tft/epdiy_epaper.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
* Display class for generic e-Paper driven by EPDiy class
|
||||
*/
|
||||
#ifndef EPDIY_H
|
||||
#define EPDIY_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 epdiy_init(void);
|
||||
|
||||
/* LVGL callbacks */
|
||||
void epdiy_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map);
|
||||
|
||||
/* Sets a pixel in *buf temporary buffer that comes afterwards in flush as *image_map */
|
||||
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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* EPDIY_H */
|
|
@ -160,19 +160,21 @@ static uint8_t displayType = HX8357D;
|
|||
void hx8357_init(void)
|
||||
{
|
||||
//Initialize non-SPI GPIOs
|
||||
gpio_pad_select_gpio(HX8357_DC);
|
||||
gpio_pad_select_gpio(HX8357_DC);
|
||||
gpio_set_direction(HX8357_DC, GPIO_MODE_OUTPUT);
|
||||
|
||||
#if HX8357_USE_RST
|
||||
gpio_pad_select_gpio(HX8357_RST);
|
||||
gpio_pad_select_gpio(HX8357_RST);
|
||||
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
|
||||
gpio_set_level(HX8357_RST, 0);
|
||||
vTaskDelay(10 / portTICK_RATE_MS);
|
||||
gpio_set_level(HX8357_RST, 1);
|
||||
vTaskDelay(120 / portTICK_RATE_MS);
|
||||
#endif
|
||||
|
||||
ESP_LOGI(TAG, "Initialization.");
|
||||
|
||||
|
@ -203,6 +205,8 @@ void hx8357_init(void)
|
|||
#else
|
||||
hx8357_send_cmd(HX8357_INVOFF);
|
||||
#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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
r = r & 3; // can't be higher than 3
|
||||
|
|
|
@ -35,10 +35,18 @@ extern "C" {
|
|||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define HX8357_DC CONFIG_LV_DISP_PIN_DC
|
||||
#define HX8357_RST CONFIG_LV_DISP_PIN_RST
|
||||
#define HX8357_USE_RST CONFIG_LV_DISP_USE_RST
|
||||
#define HX8357_INVERT_COLORS CONFIG_LV_INVERT_COLORS
|
||||
#define HX8357_DC CONFIG_LV_DISP_PIN_DC
|
||||
#define HX8357_RST CONFIG_LV_DISP_PIN_RST
|
||||
#define HX8357_BCKL CONFIG_LV_DISP_PIN_BCKL
|
||||
|
||||
#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_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);
|
||||
|
||||
/**********************
|
||||
|
|
|
@ -73,9 +73,9 @@ static uint8_t il3820_lut_initial[] = {
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static uint8_t il3820_lut_default[] = {
|
||||
0x10, 0x18, 0x18, 0x08, 0x18, 0x18,
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x10, 0x18, 0x18, 0x08, 0x18, 0x18,
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x13, 0x14, 0x44, 0x12,
|
||||
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;
|
||||
uint16_t x_addr_counter = 0;
|
||||
uint16_t y_addr_counter = 0;
|
||||
|
||||
|
||||
/* Configure entry mode */
|
||||
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_send_cmd(IL3820_CMD_WRITE_RAM);
|
||||
|
||||
|
||||
/* Write the pixel data to graphic RAM, linelen bytes at the time. */
|
||||
for(size_t row = 0; row <= (EPD_PANEL_HEIGHT - 1); row++){
|
||||
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_update_display();
|
||||
|
||||
/* 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
|
||||
* the display buffer.
|
||||
* 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,
|
||||
lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
|
@ -160,7 +160,7 @@ void il3820_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t* buf,
|
|||
uint16_t byte_index = 0;
|
||||
uint8_t bit_index = 0;
|
||||
|
||||
#if defined (CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT)
|
||||
#if defined (CONFIG_DISPLAY_ORIENTATION_PORTRAIT)
|
||||
byte_index = x + ((y >> 3) * EPD_PANEL_HEIGHT);
|
||||
bit_index = y & 0x7;
|
||||
|
||||
|
@ -170,7 +170,7 @@ void il3820_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t* buf,
|
|||
uint16_t mirrored_idx = (EPD_PANEL_HEIGHT - x) + ((y >> 3) * EPD_PANEL_HEIGHT);
|
||||
BIT_CLEAR(buf[mirrored_idx], 7 - bit_index);
|
||||
}
|
||||
#elif defined (CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE)
|
||||
#elif defined (CONFIG_DISPLAY_ORIENTATION_LANDSCAPE)
|
||||
byte_index = y + ((x >> 3) * EPD_PANEL_HEIGHT);
|
||||
bit_index = x & 0x7;
|
||||
|
||||
|
@ -198,24 +198,20 @@ void il3820_init(void)
|
|||
/* Initialize non-SPI GPIOs */
|
||||
gpio_pad_select_gpio(IL3820_DC_PIN);
|
||||
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_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 */
|
||||
gpio_set_level( IL3820_RST_PIN, 0);
|
||||
vTaskDelay(IL3820_RESET_DELAY / portTICK_RATE_MS);
|
||||
gpio_set_level( IL3820_RST_PIN, 1);
|
||||
vTaskDelay(IL3820_RESET_DELAY / portTICK_RATE_MS);
|
||||
#endif
|
||||
|
||||
/* Software reset */
|
||||
il3820_write_cmd(IL3820_CMD_SW_RESET, NULL, 0);
|
||||
|
||||
|
||||
/* Busy wait for the BUSY signal to go low */
|
||||
il3820_waitbusy(IL3820_WAIT);
|
||||
|
||||
|
@ -243,10 +239,10 @@ void il3820_init(void)
|
|||
|
||||
// allow partial updates now
|
||||
il3820_partial = true;
|
||||
|
||||
|
||||
/* Update LUT */
|
||||
il3820_write_cmd(IL3820_CMD_UPDATE_LUT, il3820_lut_default, sizeof(il3820_lut_default));
|
||||
|
||||
|
||||
/* Clear control memory and update */
|
||||
il3820_clear_cntlr_mem(IL3820_CMD_WRITE_RAM, true);
|
||||
}
|
||||
|
@ -255,10 +251,10 @@ void il3820_init(void)
|
|||
void il3820_sleep_in(void)
|
||||
{
|
||||
uint8_t data[] = {0x01};
|
||||
|
||||
|
||||
/* Wait for the BUSY signal to go low */
|
||||
il3820_waitbusy(IL3820_WAIT);
|
||||
|
||||
|
||||
il3820_write_cmd(IL3820_CMD_SLEEP_MODE, data, 1);
|
||||
}
|
||||
|
||||
|
@ -268,15 +264,15 @@ static void il3820_waitbusy(int wait_ms)
|
|||
int i = 0;
|
||||
|
||||
vTaskDelay(10 / portTICK_RATE_MS); // 10ms delay
|
||||
|
||||
|
||||
for(i = 0; i < (wait_ms * 10); i++) {
|
||||
if(gpio_get_level(IL3820_BUSY_PIN) != IL3820_BUSY_LEVEL) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
vTaskDelay(10 / portTICK_RATE_MS);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
|
||||
il3820_command_mode();
|
||||
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 */
|
||||
static inline void il3820_send_cmd(uint8_t cmd)
|
||||
static inline void il3820_send_cmd(uint8_t cmd)
|
||||
{
|
||||
disp_wait_for_pending_transactions();
|
||||
|
||||
|
||||
il3820_command_mode();
|
||||
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)
|
||||
{
|
||||
disp_wait_for_pending_transactions();
|
||||
|
||||
|
||||
il3820_data_mode();
|
||||
disp_spi_send_colors(data, length);
|
||||
}
|
||||
|
||||
/* Specify the start/end positions of the window address in the X and Y
|
||||
* directions by an address unit.
|
||||
*
|
||||
*
|
||||
* @param sx: X Start position.
|
||||
* @param ex: X End 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)
|
||||
{
|
||||
uint8_t tmp[4] = {0};
|
||||
|
||||
|
||||
tmp[0] = sx / 8;
|
||||
tmp[1] = ex / 8;
|
||||
|
||||
|
@ -382,7 +378,7 @@ static void il3820_update_display(void)
|
|||
} else {
|
||||
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_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 */
|
||||
WORD_ALIGNED_ATTR uint8_t clear_page[IL3820_COLUMNS];
|
||||
memset(clear_page, 0xff, sizeof clear_page);
|
||||
|
||||
|
||||
/* Configure entry mode */
|
||||
il3820_write_cmd(IL3820_CMD_ENTRY_MODE, &il3820_scan_mode, 1);
|
||||
|
||||
|
||||
/* Configure the window */
|
||||
il3820_set_window(0, EPD_PANEL_WIDTH - 1, 0, EPD_PANEL_HEIGHT - 1);
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ extern "C"
|
|||
|
||||
#define IL3820_DC_PIN CONFIG_LV_DISP_PIN_DC
|
||||
#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_LEVEL 1
|
||||
|
||||
|
|
|
@ -80,20 +80,31 @@ void ili9341_init(void)
|
|||
{0, {0}, 0xff},
|
||||
};
|
||||
|
||||
//Initialize non-SPI GPIOs
|
||||
gpio_pad_select_gpio(ILI9341_DC);
|
||||
gpio_set_direction(ILI9341_DC, GPIO_MODE_OUTPUT);
|
||||
#if ILI9341_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 ILI9341_USE_RST
|
||||
gpio_pad_select_gpio(ILI9341_RST);
|
||||
//Initialize non-SPI GPIOs
|
||||
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);
|
||||
|
||||
#if ILI9341_ENABLE_BACKLIGHT_CONTROL
|
||||
gpio_pad_select_gpio(ILI9341_BCKL);
|
||||
gpio_set_direction(ILI9341_BCKL, GPIO_MODE_OUTPUT);
|
||||
#endif
|
||||
//Reset the display
|
||||
gpio_set_level(ILI9341_RST, 0);
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
gpio_set_level(ILI9341_RST, 1);
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
#endif
|
||||
|
||||
ESP_LOGI(TAG, "Initialization.");
|
||||
|
||||
|
@ -108,7 +119,9 @@ void ili9341_init(void)
|
|||
cmd++;
|
||||
}
|
||||
|
||||
ili9341_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION);
|
||||
ili9341_enable_backlight(true);
|
||||
|
||||
ili9341_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION);
|
||||
|
||||
#if ILI9341_INVERT_COLORS == 1
|
||||
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*/
|
||||
ili9341_send_cmd(0x2C);
|
||||
|
||||
|
||||
uint32_t size = lv_area_get_width(area) * lv_area_get_height(area);
|
||||
|
||||
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()
|
||||
{
|
||||
uint8_t data[] = {0x08};
|
||||
|
@ -196,8 +228,6 @@ static void ili9341_set_orientation(uint8_t orientation)
|
|||
|
||||
#if defined CONFIG_LV_PREDEFINED_DISPLAY_M5STACK
|
||||
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)
|
||||
uint8_t data[] = {0x6C, 0xEC, 0xCC, 0x4C};
|
||||
#elif defined (CONFIG_LV_PREDEFINED_DISPLAY_NONE)
|
||||
|
|
|
@ -20,15 +20,23 @@ extern "C" {
|
|||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "../lvgl_helpers.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#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_DC CONFIG_LV_DISP_PIN_DC
|
||||
#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
|
||||
|
||||
/**********************
|
||||
|
@ -41,6 +49,7 @@ extern "C" {
|
|||
|
||||
void ili9341_init(void);
|
||||
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_out(void);
|
||||
|
||||
|
|
|
@ -76,17 +76,19 @@ void ili9481_init(void)
|
|||
//Initialize non-SPI GPIOs
|
||||
gpio_pad_select_gpio(ILI9481_DC);
|
||||
gpio_set_direction(ILI9481_DC, GPIO_MODE_OUTPUT);
|
||||
|
||||
#if ILI9481_USE_RST
|
||||
gpio_pad_select_gpio(ILI9481_RST);
|
||||
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
|
||||
gpio_set_level(ILI9481_RST, 0);
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
gpio_set_level(ILI9481_RST, 1);
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
#endif
|
||||
|
||||
ESP_LOGI(TAG, "ILI9481 initialization.");
|
||||
|
||||
|
@ -105,6 +107,8 @@ void ili9481_init(void)
|
|||
cmd++;
|
||||
}
|
||||
|
||||
ili9481_enable_backlight(true);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
**********************/
|
||||
|
|
|
@ -25,12 +25,19 @@ extern "C" {
|
|||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define ILI9481_DC CONFIG_LV_DISP_PIN_DC
|
||||
#define ILI9481_RST CONFIG_LV_DISP_PIN_RST
|
||||
#define ILI9481_USE_RST CONFIG_LV_DISP_USE_RST
|
||||
#define ILI9481_INVERT_COLORS CONFIG_LV_INVERT_COLORS
|
||||
#define ILI9481_DC CONFIG_LV_DISP_PIN_DC
|
||||
#define ILI9481_RST CONFIG_LV_DISP_PIN_RST
|
||||
#define ILI9481_BCKL CONFIG_LV_DISP_PIN_BCKL
|
||||
|
||||
#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
|
||||
|
||||
#if CONFIG_LV_BACKLIGHT_ACTIVE_LVL
|
||||
#define ILI9481_BCKL_ACTIVE_LVL 1
|
||||
#else
|
||||
#define ILI9481_BCKL_ACTIVE_LVL 0
|
||||
#endif
|
||||
|
||||
/*******************
|
||||
* ILI9481 REGS
|
||||
|
@ -110,6 +117,7 @@ extern "C" {
|
|||
|
||||
void ili9481_init(void);
|
||||
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
|
||||
|
|
|
@ -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},
|
||||
{0XE1, {0x0F, 0x32, 0x2E, 0x0B, 0x0D, 0x05, 0x47, 0x75, 0x37, 0x06, 0x10, 0x03, 0x24, 0x20, 0x00}, 15},
|
||||
{0x20, {0}, 0}, /* display inversion OFF */
|
||||
{0x36, {0x48}, 1},
|
||||
{0x29, {0}, 0x80}, /* display on */
|
||||
{0x36, {0x48}, 1},
|
||||
{0x29, {0}, 0x80}, /* display on */
|
||||
{0x00, {0}, 0xff},
|
||||
};
|
||||
|
||||
//Initialize non-SPI GPIOs
|
||||
gpio_pad_select_gpio(ILI9486_DC);
|
||||
gpio_set_direction(ILI9486_DC, GPIO_MODE_OUTPUT);
|
||||
#if ILI9486_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 ILI9486_USE_RST
|
||||
gpio_pad_select_gpio(ILI9486_RST);
|
||||
//Initialize non-SPI GPIOs
|
||||
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);
|
||||
|
||||
#if ILI9486_ENABLE_BACKLIGHT_CONTROL
|
||||
gpio_pad_select_gpio(ILI9486_BCKL);
|
||||
gpio_set_direction(ILI9486_BCKL, GPIO_MODE_OUTPUT);
|
||||
#endif
|
||||
|
||||
//Reset the display
|
||||
gpio_set_level(ILI9486_RST, 0);
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
gpio_set_level(ILI9486_RST, 1);
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
#endif
|
||||
|
||||
ESP_LOGI(TAG, "ILI9486 Initialization.");
|
||||
|
||||
|
@ -93,7 +105,9 @@ void ili9486_init(void)
|
|||
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)
|
||||
|
@ -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);
|
||||
|
||||
size = lv_area_get_width(area) * lv_area_get_height(area);
|
||||
|
||||
|
||||
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
|
||||
**********************/
|
||||
|
|
|
@ -25,10 +25,17 @@ extern "C" {
|
|||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define ILI9486_DC CONFIG_LV_DISP_PIN_DC
|
||||
#define ILI9486_RST CONFIG_LV_DISP_PIN_RST
|
||||
#define ILI9486_USE_RST CONFIG_LV_DISP_USE_RST
|
||||
#define ILI9486_DC CONFIG_LV_DISP_PIN_DC
|
||||
#define ILI9486_RST CONFIG_LV_DISP_PIN_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
|
||||
|
@ -40,6 +47,7 @@ extern "C" {
|
|||
|
||||
void ili9486_init(void);
|
||||
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
|
||||
|
|
|
@ -50,7 +50,7 @@ static void ili9488_send_color(void * data, uint16_t length);
|
|||
/**********************
|
||||
* 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
|
||||
void ili9488_init(void)
|
||||
{
|
||||
|
@ -76,26 +76,28 @@ void ili9488_init(void)
|
|||
};
|
||||
|
||||
//Initialize non-SPI GPIOs
|
||||
gpio_pad_select_gpio(ILI9488_DC);
|
||||
gpio_pad_select_gpio(ILI9488_DC);
|
||||
gpio_set_direction(ILI9488_DC, GPIO_MODE_OUTPUT);
|
||||
|
||||
#if ILI9488_USE_RST
|
||||
gpio_pad_select_gpio(ILI9488_RST);
|
||||
gpio_pad_select_gpio(ILI9488_RST);
|
||||
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
|
||||
gpio_set_level(ILI9488_RST, 0);
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
gpio_set_level(ILI9488_RST, 1);
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
#endif
|
||||
|
||||
ESP_LOGI(TAG, "ILI9488 initialization.");
|
||||
|
||||
// Exit sleep
|
||||
ili9488_send_cmd(0x01); /* Software reset */
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
|
||||
|
||||
//Send all the commands
|
||||
uint16_t cmd = 0;
|
||||
while (ili_init_cmds[cmd].databytes!=0xff) {
|
||||
|
@ -107,7 +109,9 @@ void ili9488_init(void)
|
|||
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
|
||||
|
@ -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) & 0xFF,
|
||||
};
|
||||
|
||||
|
||||
/* Page addresses */
|
||||
uint8_t yb[] = {
|
||||
(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);
|
||||
}
|
||||
|
||||
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
|
||||
**********************/
|
||||
|
|
|
@ -25,9 +25,17 @@ extern "C" {
|
|||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define ILI9488_DC CONFIG_LV_DISP_PIN_DC
|
||||
#define ILI9488_RST CONFIG_LV_DISP_PIN_RST
|
||||
#define ILI9488_USE_RST CONFIG_LV_DISP_USE_RSTS
|
||||
#define ILI9488_DC CONFIG_LV_DISP_PIN_DC
|
||||
#define ILI9488_RST CONFIG_LV_DISP_PIN_RST
|
||||
#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
|
||||
|
@ -146,6 +154,7 @@ typedef struct {
|
|||
|
||||
void ili9488_init(void);
|
||||
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
|
||||
|
|
|
@ -148,18 +148,29 @@ void ra8875_init(void)
|
|||
|
||||
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_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
|
||||
gpio_set_level(RA8875_RST, 0);
|
||||
vTaskDelay(DIV_ROUND_UP(100, portTICK_RATE_MS));
|
||||
gpio_set_level(RA8875_RST, 1);
|
||||
vTaskDelay(DIV_ROUND_UP(100, portTICK_RATE_MS));
|
||||
#endif
|
||||
|
||||
// Initalize RA8875 clocks (SPI must be decelerated before initializing clocks)
|
||||
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.");
|
||||
}
|
||||
|
||||
// Enable the display
|
||||
// Enable the display and backlight
|
||||
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)
|
||||
|
|
|
@ -24,8 +24,7 @@ extern "C" {
|
|||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define RA8875_RST CONFIG_LV_DISP_PIN_RST
|
||||
#define RA8875_USE_RST CONFIG_LV_DISP_USE_RST
|
||||
#define RA8875_RST CONFIG_LV_DISP_PIN_RST
|
||||
|
||||
// System & Configuration Registers
|
||||
#define RA8875_REG_PWRR (0x01) // Power and Display Control Register (PWRR)
|
||||
|
@ -97,6 +96,7 @@ extern "C" {
|
|||
**********************/
|
||||
|
||||
void ra8875_init(void);
|
||||
void ra8875_enable_backlight(bool backlight);
|
||||
void ra8875_enable_display(bool enable);
|
||||
void ra8875_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);
|
||||
|
||||
|
|
|
@ -94,8 +94,6 @@ void sh1107_init(void)
|
|||
//Initialize non-SPI GPIOs
|
||||
gpio_pad_select_gpio(SH1107_DC);
|
||||
gpio_set_direction(SH1107_DC, GPIO_MODE_OUTPUT);
|
||||
|
||||
#if SH1107_USE_RST
|
||||
gpio_pad_select_gpio(SH1107_RST);
|
||||
gpio_set_direction(SH1107_RST, GPIO_MODE_OUTPUT);
|
||||
|
||||
|
@ -104,7 +102,6 @@ void sh1107_init(void)
|
|||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
gpio_set_level(SH1107_RST, 1);
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
#endif
|
||||
|
||||
//Send all the commands
|
||||
uint16_t cmd = 0;
|
||||
|
|
|
@ -25,9 +25,8 @@ extern "C" {
|
|||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define SH1107_DC CONFIG_LV_DISP_PIN_DC
|
||||
#define SH1107_RST CONFIG_LV_DISP_PIN_RST
|
||||
#define SH1107_USE_RST CONFIG_LV_DISP_USE_RST
|
||||
#define SH1107_DC CONFIG_LV_DISP_PIN_DC
|
||||
#define SH1107_RST CONFIG_LV_DISP_PIN_RST
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
|
|
110
lvgl_tft/sharp_mip.cpp
Normal file
110
lvgl_tft/sharp_mip.cpp
Normal 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
35
lvgl_tft/sharp_mip.h
Normal 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
|
||||
|
|
@ -13,9 +13,10 @@
|
|||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "driver/i2c.h"
|
||||
#include "assert.h"
|
||||
|
||||
#include "lvgl_i2c/i2c_manager.h"
|
||||
#include "lvgl_i2c_conf.h"
|
||||
|
||||
#include "ssd1306.h"
|
||||
|
||||
|
@ -24,7 +25,6 @@
|
|||
*********************/
|
||||
#define TAG "SSD1306"
|
||||
|
||||
#define OLED_I2C_PORT (CONFIG_LV_I2C_DISPLAY_PORT)
|
||||
// SLA (0x3C) + WRITE_MODE (0x00) = 0x78 (0b01111000)
|
||||
#define OLED_I2C_ADDRESS 0x3C
|
||||
#define OLED_WIDTH 128
|
||||
|
@ -70,6 +70,8 @@
|
|||
// Charge Pump (pg.62)
|
||||
#define OLED_CMD_SET_CHARGE_PUMP 0x8D // follow with 0x14
|
||||
|
||||
#define OLED_IIC_FREQ_HZ 400000 // I2C colock frequency
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
@ -99,10 +101,10 @@ void ssd1306_init(void)
|
|||
uint8_t orientation_1 = 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_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_2 = OLED_CMD_SET_COM_SCAN_MODE_NORMAL;
|
||||
#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)
|
||||
{
|
||||
(void) disp_drv;
|
||||
esp_err_t err;
|
||||
|
||||
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)
|
||||
{
|
||||
(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;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ extern "C" {
|
|||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define SSD1306_SDA CONFIG_LV_DISP_PIN_SDA
|
||||
#define SSD1306_SCL CONFIG_LV_DISP_PIN_SCL
|
||||
#define SSD1306_DISPLAY_ORIENTATION TFT_ORIENTATION_LANDSCAPE
|
||||
|
||||
/**********************
|
||||
|
|
|
@ -8,15 +8,12 @@
|
|||
*********************/
|
||||
#include "st7735s.h"
|
||||
#include "disp_spi.h"
|
||||
#include "driver/i2c.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#ifdef CONFIG_LV_M5STICKC_HANDLE_AXP192
|
||||
#include "lvgl_i2c/i2c_manager.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* 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_color(void * data, uint16_t length);
|
||||
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_init();
|
||||
static void axp192_sleep_in();
|
||||
|
@ -62,6 +60,7 @@ uint8_t st7735s_portrait_mode = 0;
|
|||
void st7735s_init(void)
|
||||
{
|
||||
#ifdef CONFIG_LV_M5STICKC_HANDLE_AXP192
|
||||
i2c_master_init();
|
||||
axp192_init();
|
||||
#endif
|
||||
|
||||
|
@ -100,8 +99,6 @@ void st7735s_init(void)
|
|||
//Initialize non-SPI GPIOs
|
||||
gpio_pad_select_gpio(ST7735S_DC);
|
||||
gpio_set_direction(ST7735S_DC, GPIO_MODE_OUTPUT);
|
||||
|
||||
#if ST7735S_USE_RST
|
||||
gpio_pad_select_gpio(ST7735S_RST);
|
||||
gpio_set_direction(ST7735S_RST, GPIO_MODE_OUTPUT);
|
||||
|
||||
|
@ -110,7 +107,6 @@ void st7735s_init(void)
|
|||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
gpio_set_level(ST7735S_RST, 1);
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
#endif
|
||||
|
||||
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()
|
||||
{
|
||||
st7735s_send_cmd(0x10);
|
||||
#ifdef CONFIG_LV_M5STICKC_HANDLE_AXP192
|
||||
axp192_sleep_in();
|
||||
#endif
|
||||
axp192_sleep_in();
|
||||
}
|
||||
|
||||
void st7735s_sleep_out()
|
||||
{
|
||||
#ifdef CONFIG_LV_M5STICKC_HANDLE_AXP192
|
||||
axp192_sleep_out();
|
||||
#endif
|
||||
axp192_sleep_out();
|
||||
st7735s_send_cmd(0x11);
|
||||
}
|
||||
|
||||
|
@ -223,35 +215,55 @@ static void st7735s_set_orientation(uint8_t orientation)
|
|||
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)
|
||||
{
|
||||
err = lvgl_i2c_write(CONFIG_LV_I2C_DISPLAY_PORT, AXP192_I2C_ADDRESS, addr, &data, 1);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "AXP192 send failed. code: 0x%.2X", ret);
|
||||
}
|
||||
}
|
||||
static void axp192_write_byte(uint8_t addr, uint8_t data)
|
||||
{
|
||||
esp_err_t ret;
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
|
||||
static void axp192_init()
|
||||
{
|
||||
// information on how to init and use AXP192 ifor M5StickC taken from
|
||||
// https://forum.m5stack.com/topic/1025/m5stickc-turn-off-screen-completely
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (AXP192_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||||
i2c_master_write_byte(cmd, addr, true);
|
||||
i2c_master_write_byte(cmd, data, true);
|
||||
i2c_master_stop(cmd);
|
||||
|
||||
axp192_write_byte(0x10, 0xFF); // OLED_VPP Enable
|
||||
axp192_write_byte(0x28, 0xCC); // Enable LDO2&LDO3, LED&TFT 3.0V
|
||||
axp192_sleep_out();
|
||||
ESP_LOGI(TAG, "AXP192 initialized, power enabled for LDO2 and LDO3");
|
||||
}
|
||||
ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 10/portTICK_PERIOD_MS);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "AXP192 send failed. code: 0x%.2X", ret);
|
||||
}
|
||||
i2c_cmd_link_delete(cmd);
|
||||
}
|
||||
|
||||
static void axp192_sleep_in()
|
||||
{
|
||||
axp192_write_byte(0x12, 0x4b);
|
||||
}
|
||||
static void axp192_init()
|
||||
{
|
||||
// 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(0x12, 0x4d);
|
||||
}
|
||||
axp192_write_byte(0x10, 0xFF); // OLED_VPP Enable
|
||||
axp192_write_byte(0x28, 0xCC); // Enable LDO2&LDO3, LED&TFT 3.0V
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -25,9 +25,11 @@ extern "C" {
|
|||
*********************/
|
||||
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
|
||||
|
||||
#define ST7735S_DC CONFIG_LV_DISP_PIN_DC
|
||||
#define ST7735S_RST CONFIG_LV_DISP_PIN_RST
|
||||
#define ST7735S_USE_RST CONFIG_LV_DISP_USE_RST
|
||||
#define ST7735S_DC CONFIG_LV_DISP_PIN_DC
|
||||
#define ST7735S_RST CONFIG_LV_DISP_PIN_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
|
||||
|
||||
|
@ -131,6 +133,7 @@ extern "C" {
|
|||
|
||||
void st7735s_init(void);
|
||||
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_out(void);
|
||||
|
||||
|
|
|
@ -35,7 +35,9 @@ typedef struct {
|
|||
**********************/
|
||||
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
|
||||
|
@ -89,13 +91,18 @@ void st7789_init(void)
|
|||
gpio_pad_select_gpio(ST7789_DC);
|
||||
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_set_direction(ST7789_RST, GPIO_MODE_OUTPUT);
|
||||
#endif
|
||||
|
||||
#if ST7789_ENABLE_BACKLIGHT_CONTROL
|
||||
gpio_pad_select_gpio(ST7789_BCKL);
|
||||
gpio_set_direction(ST7789_BCKL, GPIO_MODE_OUTPUT);
|
||||
#endif
|
||||
|
||||
//Reset the display
|
||||
#if !defined(ST7789_SOFT_RST)
|
||||
#if !defined(CONFIG_LV_DISP_ST7789_SOFT_RESET)
|
||||
gpio_set_level(ST7789_RST, 0);
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
gpio_set_level(ST7789_RST, 1);
|
||||
|
@ -117,12 +124,30 @@ void st7789_init(void)
|
|||
cmd++;
|
||||
}
|
||||
|
||||
st7789_enable_backlight(true);
|
||||
|
||||
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
|
||||
* 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. */
|
||||
void st7789_enable_backlight(bool backlight)
|
||||
{
|
||||
#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)
|
||||
{
|
||||
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;
|
||||
|
||||
#elif (LV_HOR_RES_MAX == 240) && (LV_VER_RES_MAX == 240)
|
||||
#if (CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT)
|
||||
offsetx1 += 80;
|
||||
offsetx2 += 80;
|
||||
#elif (CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED)
|
||||
offsety1 += 80;
|
||||
offsety2 += 80;
|
||||
#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
|
||||
#if (CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT)
|
||||
offsetx1 += 80;
|
||||
offsetx2 += 80;
|
||||
#elif (CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED)
|
||||
offsety1 += 80;
|
||||
offsety2 += 80;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*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*/
|
||||
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);
|
||||
|
||||
|
@ -192,21 +201,21 @@ void st7789_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * colo
|
|||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
void st7789_send_cmd(uint8_t cmd)
|
||||
static void st7789_send_cmd(uint8_t cmd)
|
||||
{
|
||||
disp_wait_for_pending_transactions();
|
||||
gpio_set_level(ST7789_DC, 0);
|
||||
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();
|
||||
gpio_set_level(ST7789_DC, 1);
|
||||
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();
|
||||
gpio_set_level(ST7789_DC, 1);
|
||||
|
|
|
@ -23,17 +23,17 @@ extern "C"
|
|||
|
||||
#define ST7789_DC CONFIG_LV_DISP_PIN_DC
|
||||
#define ST7789_RST CONFIG_LV_DISP_PIN_RST
|
||||
#define ST7789_BCKL CONFIG_LV_DISP_PIN_BCKL
|
||||
|
||||
#if CONFIG_LV_DISP_USE_RST
|
||||
#if CONFIG_LV_DISP_ST7789_SOFT_RESET
|
||||
#define ST7789_SOFT_RST
|
||||
#endif
|
||||
#else
|
||||
#define ST7789_SOFT_RST
|
||||
#endif
|
||||
|
||||
#define ST7789_ENABLE_BACKLIGHT_CONTROL CONFIG_LV_ENABLE_BACKLIGHT_CONTROL
|
||||
#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 */
|
||||
#define ST7789_NOP 0x00
|
||||
#define ST7789_SWRESET 0x01
|
||||
|
@ -112,9 +112,7 @@ extern "C"
|
|||
|
||||
void st7789_init(void);
|
||||
void st7789_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map);
|
||||
|
||||
void st7789_send_cmd(uint8_t cmd);
|
||||
void st7789_send_data(void *data, uint16_t length);
|
||||
void st7789_enable_backlight(bool backlight);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
|
|
@ -81,20 +81,31 @@ void st7796s_init(void)
|
|||
{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
|
||||
gpio_pad_select_gpio(ST7796S_DC);
|
||||
gpio_set_direction(ST7796S_DC, GPIO_MODE_OUTPUT);
|
||||
|
||||
#if ST7796S_USE_RST
|
||||
gpio_pad_select_gpio(ST7796S_RST);
|
||||
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
|
||||
gpio_set_level(ST7796S_RST, 0);
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
gpio_set_level(ST7796S_RST, 1);
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
#endif
|
||||
|
||||
ESP_LOGI(TAG, "Initialization.");
|
||||
|
||||
|
@ -111,6 +122,8 @@ void st7796s_init(void)
|
|||
cmd++;
|
||||
}
|
||||
|
||||
st7796s_enable_backlight(true);
|
||||
|
||||
st7796s_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION);
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
uint8_t data[] = {0x08};
|
||||
|
|
|
@ -26,12 +26,19 @@ extern "C"
|
|||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define ST7796S_DC CONFIG_LV_DISP_PIN_DC
|
||||
#define ST7796S_RST CONFIG_LV_DISP_PIN_RST
|
||||
#define ST7796S_USE_RST CONFIG_LV_DISP_USE_RST
|
||||
#define ST7796S_INVERT_COLORS CONFIG_LV_INVERT_COLORS
|
||||
#define ST7796S_DC CONFIG_LV_DISP_PIN_DC
|
||||
#define ST7796S_RST CONFIG_LV_DISP_PIN_RST
|
||||
#define ST7796S_BCKL CONFIG_LV_DISP_PIN_BCKL
|
||||
|
||||
#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
|
||||
|
||||
#if CONFIG_LV_BACKLIGHT_ACTIVE_LVL
|
||||
#define ST7796S_BCKL_ACTIVE_LVL 1
|
||||
#else
|
||||
#define ST7796S_BCKL_ACTIVE_LVL 0
|
||||
#endif
|
||||
|
||||
/*******************
|
||||
* ST7796S REGS
|
||||
|
@ -111,6 +118,7 @@ extern "C"
|
|||
|
||||
void st7796s_init(void);
|
||||
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
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
menu "LVGL Touch controller"
|
||||
|
||||
config LV_TOUCH_CONTROLLER
|
||||
int
|
||||
int
|
||||
default 0 if LV_TOUCH_CONTROLLER_NONE
|
||||
default 1 if LV_TOUCH_CONTROLLER_XPT2046
|
||||
default 2 if LV_TOUCH_CONTROLLER_FT6X06
|
||||
|
@ -9,22 +9,30 @@ menu "LVGL Touch controller"
|
|||
default 4 if LV_TOUCH_CONTROLLER_ADCRAW
|
||||
default 5 if LV_TOUCH_CONTROLLER_FT81X
|
||||
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_GT911
|
||||
choice
|
||||
prompt "Select a touch panel controller model."
|
||||
default LV_TOUCH_CONTROLLER_NONE
|
||||
help
|
||||
Select the controller for your touch panel.
|
||||
prompt "Select a touch panel controller model."
|
||||
default LV_TOUCH_CONTROLLER_NONE
|
||||
help
|
||||
Select the controller for your touch panel.
|
||||
|
||||
config LV_TOUCH_CONTROLLER_NONE
|
||||
bool "None"
|
||||
config LV_TOUCH_CONTROLLER_XPT2046
|
||||
config LV_TOUCH_CONTROLLER_NONE
|
||||
bool "None"
|
||||
config LV_TOUCH_CONTROLLER_XPT2046
|
||||
select LV_TOUCH_DRIVER_PROTOCOL_SPI
|
||||
bool "XPT2046"
|
||||
config LV_TOUCH_CONTROLLER_FT6X06
|
||||
select LV_I2C_TOUCH
|
||||
config LV_TOUCH_CONTROLLER_FT6X06
|
||||
select LV_TOUCH_DRIVER_PROTOCOL_I2C
|
||||
bool "FT6X06"
|
||||
|
||||
config LV_TOUCH_CONTROLLER_L58
|
||||
# Start only touch without protocol:
|
||||
select CONFIG_LV_TOUCH_DRIVER_DISPLAY
|
||||
bool "L58"
|
||||
config LV_TOUCH_CONTROLLER_GT911
|
||||
select LV_TOUCH_DRIVER_PROTOCOL_I2C
|
||||
bool "GT911"
|
||||
config LV_TOUCH_CONTROLLER_STMPE610
|
||||
select LV_TOUCH_DRIVER_PROTOCOL_SPI
|
||||
bool "STMPE610"
|
||||
|
@ -37,17 +45,14 @@ menu "LVGL Touch controller"
|
|||
config LV_TOUCH_CONTROLLER_RA8875
|
||||
select LV_TOUCH_DRIVER_DISPLAY
|
||||
bool "RA8875"
|
||||
config LV_TOUCH_CONTROLLER_GT911
|
||||
select LV_I2C_TOUCH
|
||||
bool "GT911"
|
||||
endchoice
|
||||
|
||||
|
||||
config LV_TOUCH_DRIVER_PROTOCOL_SPI
|
||||
bool
|
||||
help
|
||||
Touch controller protocol SPI
|
||||
|
||||
config LV_I2C_TOUCH
|
||||
config LV_TOUCH_DRIVER_PROTOCOL_I2C
|
||||
bool
|
||||
help
|
||||
Touch controller protocol I2C
|
||||
|
@ -61,21 +66,69 @@ menu "LVGL Touch controller"
|
|||
bool
|
||||
help
|
||||
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
|
||||
prompt "Touch Controller SPI Bus."
|
||||
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
|
||||
Select the SPI Bus the touch controller is attached to.
|
||||
|
||||
config LV_TOUCH_CONTROLLER_SPI2_HOST
|
||||
bool "SPI2_HOST"
|
||||
config LV_TOUCH_CONTROLLER_SPI3_HOST
|
||||
bool "SPI3_HOST"
|
||||
Select the SPI Bus the TFT Display is attached to.
|
||||
|
||||
config LV_TOUCH_CONTROLLER_SPI_HSPI
|
||||
bool "HSPI"
|
||||
config LV_TOUCH_CONTROLLER_SPI_VSPI
|
||||
bool "VSPI" if !IDF_TARGET_ESP32S2
|
||||
config LV_TOUCH_CONTROLLER_SPI_FSPI
|
||||
bool "FSPI" if IDF_TARGET_ESP32S2
|
||||
endchoice
|
||||
|
||||
menu "Touchpanel (L58) Lilygo Pin Assignments"
|
||||
depends on LV_TOUCH_CONTROLLER_L58
|
||||
|
||||
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 15
|
||||
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 14
|
||||
help
|
||||
Configure the I2C touchpanel SCL pin here.
|
||||
config LV_TOUCH_INT
|
||||
int "GPIO for Interrupt pin (INT)"
|
||||
range 0 39 if IDF_TARGET_ESP32
|
||||
range 0 43 if IDF_TARGET_ESP32S2
|
||||
|
||||
default 13
|
||||
help
|
||||
Configure the INT Pin (Low on event)
|
||||
endmenu
|
||||
|
||||
menu "Touchpanel (XPT2046) Pin Assignments"
|
||||
depends on LV_TOUCH_CONTROLLER_XPT2046
|
||||
|
@ -83,7 +136,9 @@ menu "LVGL Touch controller"
|
|||
config LV_TOUCH_SPI_MISO
|
||||
int
|
||||
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 19
|
||||
help
|
||||
|
@ -92,6 +147,8 @@ menu "LVGL Touch controller"
|
|||
config LV_TOUCH_SPI_MOSI
|
||||
int
|
||||
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 23
|
||||
|
@ -100,7 +157,9 @@ menu "LVGL Touch controller"
|
|||
|
||||
config LV_TOUCH_SPI_CLK
|
||||
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 18
|
||||
help
|
||||
|
@ -108,7 +167,9 @@ menu "LVGL Touch controller"
|
|||
|
||||
config LV_TOUCH_SPI_CS
|
||||
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 5
|
||||
help
|
||||
|
@ -116,13 +177,15 @@ menu "LVGL Touch controller"
|
|||
|
||||
config LV_TOUCH_PIN_IRQ
|
||||
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 25
|
||||
help
|
||||
Configure the touchpanel IRQ pin here.
|
||||
endmenu
|
||||
|
||||
|
||||
menu "Touchpanel Configuration (XPT2046)"
|
||||
depends on LV_TOUCH_CONTROLLER_XPT2046
|
||||
|
||||
|
@ -149,11 +212,11 @@ menu "LVGL Touch controller"
|
|||
prompt "Maximum Y coordinate value."
|
||||
default 4095 if LV_PREDEFINED_PINS_38V4
|
||||
default 1900
|
||||
|
||||
config LV_TOUCH_XY_SWAP
|
||||
bool
|
||||
prompt "Swap XY."
|
||||
default y
|
||||
|
||||
config LV_TOUCH_XY_SWAP
|
||||
bool
|
||||
prompt "Swap XY."
|
||||
default y
|
||||
|
||||
config LV_TOUCH_INVERT_X
|
||||
bool
|
||||
|
@ -180,13 +243,36 @@ menu "LVGL Touch controller"
|
|||
endchoice
|
||||
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)"
|
||||
depends on LV_TOUCH_CONTROLLER_FT6X06
|
||||
|
||||
config LV_FT6X36_SWAPXY
|
||||
bool
|
||||
prompt "Swap X with Y coordinate."
|
||||
default n
|
||||
config LV_FT6X36_SWAPXY
|
||||
bool
|
||||
prompt "Swap X with Y coordinate."
|
||||
default y
|
||||
|
||||
config LV_FT6X36_INVERT_X
|
||||
bool
|
||||
|
@ -196,24 +282,19 @@ menu "LVGL Touch controller"
|
|||
config LV_FT6X36_INVERT_Y
|
||||
bool
|
||||
prompt "Invert Y coordinate value."
|
||||
default n
|
||||
|
||||
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'.
|
||||
default y
|
||||
|
||||
endmenu
|
||||
|
||||
|
||||
menu "Touchpanel (STMPE610) Pin Assignments"
|
||||
depends on LV_TOUCH_CONTROLLER_STMPE610
|
||||
|
||||
config LV_TOUCH_SPI_MISO
|
||||
int
|
||||
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 19 if LV_PREDEFINED_DISPLAY_ADA_FEATHERWING
|
||||
default 19
|
||||
|
@ -222,9 +303,10 @@ menu "LVGL Touch controller"
|
|||
Configure the touchpanel MISO pin here.
|
||||
|
||||
config LV_TOUCH_SPI_MOSI
|
||||
# TODO Fix default for ESP32C3
|
||||
int
|
||||
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 18 if LV_PREDEFINED_DISPLAY_ADA_FEATHERWING
|
||||
|
@ -235,6 +317,8 @@ menu "LVGL Touch controller"
|
|||
|
||||
config LV_TOUCH_SPI_CLK
|
||||
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 5 if LV_PREDEFINED_DISPLAY_ADA_FEATHERWING
|
||||
|
@ -244,6 +328,9 @@ menu "LVGL Touch controller"
|
|||
|
||||
config LV_TOUCH_SPI_CS
|
||||
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 32 if LV_PREDEFINED_DISPLAY_ADA_FEATHERWING
|
||||
default 5
|
||||
|
@ -273,11 +360,11 @@ menu "LVGL Touch controller"
|
|||
int
|
||||
prompt "Maximum Y coordinate value."
|
||||
default 3800
|
||||
|
||||
|
||||
config LV_TOUCH_XY_SWAP
|
||||
bool
|
||||
prompt "Swap XY."
|
||||
default n
|
||||
bool
|
||||
prompt "Swap XY."
|
||||
default n
|
||||
|
||||
config LV_TOUCH_INVERT_X
|
||||
bool
|
||||
|
@ -289,7 +376,7 @@ menu "LVGL Touch controller"
|
|||
prompt "Invert Y coordinate value."
|
||||
default y
|
||||
endmenu
|
||||
|
||||
|
||||
menu "Touchpanel (ADCRAW) Pin Assignments"
|
||||
depends on LV_TOUCH_CONTROLLER_ADCRAW
|
||||
|
||||
|
@ -310,7 +397,7 @@ menu "LVGL Touch controller"
|
|||
|
||||
help
|
||||
Configure the touchpanel Y- pin. Must be ADC input.
|
||||
|
||||
|
||||
config LV_TOUCHSCREEN_RESISTIVE_PIN_XL
|
||||
int
|
||||
prompt "GPIO X-"
|
||||
|
@ -376,25 +463,25 @@ menu "LVGL Touch controller"
|
|||
config LV_TOUCH_X_MIN
|
||||
int
|
||||
prompt "Minimum X coordinate ADC value"
|
||||
range 0 1023
|
||||
range 0 1023
|
||||
default 0
|
||||
|
||||
config LV_TOUCH_Y_MIN
|
||||
int
|
||||
prompt "Minimum Y coordinate ADC value"
|
||||
range 0 1023
|
||||
range 0 1023
|
||||
default 0
|
||||
|
||||
config LV_TOUCH_X_MAX
|
||||
int
|
||||
prompt "Maximum X coordinate ADC value"
|
||||
range 0 1023
|
||||
range 0 1023
|
||||
default 1023
|
||||
|
||||
config LV_TOUCH_Y_MAX
|
||||
int
|
||||
prompt "Maximum Y coordinate ADC value"
|
||||
range 0 1023
|
||||
range 0 1023
|
||||
default 1023
|
||||
|
||||
config LV_TOUCH_XY_SWAP
|
||||
|
@ -415,13 +502,13 @@ menu "LVGL Touch controller"
|
|||
config LV_TOUCH_RA8875_SAMPLE_TIME
|
||||
int
|
||||
prompt "TP Sample Time Adjusting"
|
||||
range 0 7
|
||||
range 0 7
|
||||
default 0
|
||||
|
||||
config LV_TOUCH_RA8875_ADC_CLOCK
|
||||
int
|
||||
prompt "ADC Clock Setting"
|
||||
range 0 7
|
||||
range 0 7
|
||||
default 0
|
||||
|
||||
config LV_TOUCH_RA8875_WAKEUP_ENABLE
|
||||
|
@ -438,60 +525,27 @@ menu "LVGL Touch controller"
|
|||
bool
|
||||
prompt "De-bounce Circuit Enable for Touch Panel Interrupt"
|
||||
default y
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Touchpanel Configuration (GT911)"
|
||||
menu "Touchpanel GT911 Pin Assignments"
|
||||
depends on LV_TOUCH_CONTROLLER_GT911
|
||||
|
||||
config LV_GT911_SWAPXY
|
||||
bool
|
||||
prompt "Swap X with Y coordinate."
|
||||
default y
|
||||
config LV_TOUCH_I2C_SDA
|
||||
int
|
||||
prompt "GPIO for SDA (I2C)"
|
||||
range 0 39 if IDF_TARGET_ESP32
|
||||
range 0 43 if IDF_TARGET_ESP32S3
|
||||
|
||||
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
|
||||
default 39
|
||||
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_ESP32S3
|
||||
|
||||
default 40
|
||||
help
|
||||
Configure the I2C touchpanel SCL pin here.
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
|
316
lvgl_touch/L58/L58Touch.cpp
Normal file
316
lvgl_touch/L58/L58Touch.cpp
Normal file
|
@ -0,0 +1,316 @@
|
|||
// This is the first experimental Touch component for the LILYGO EPD47 touch overlay
|
||||
// Controller: L58 -> https://github.com/Xinyuan-LilyGO/LilyGo-EPD47/files/6059098/L58.V1.0.pdf
|
||||
// Note: Rotation is only working for certain angles (0 works alright, 2 also) Others still need to be corrected
|
||||
#include "L58Touch.h"
|
||||
|
||||
#define CONFIG_L58_DEBUG 0
|
||||
|
||||
L58Touch *L58Touch::_instance = nullptr;
|
||||
static const char *TAG = "i2c-touch";
|
||||
|
||||
L58Touch::L58Touch(int8_t intPin)
|
||||
{
|
||||
_instance = this;
|
||||
printf("I2C sda:%d scl:%d int:%d\n\n",
|
||||
CONFIG_LV_TOUCH_I2C_SDA, CONFIG_LV_TOUCH_I2C_SCL, intPin);
|
||||
i2c_config_t conf;
|
||||
conf.mode = I2C_MODE_MASTER;
|
||||
conf.sda_io_num = (gpio_num_t)CONFIG_LV_TOUCH_I2C_SDA;
|
||||
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
|
||||
conf.scl_io_num = (gpio_num_t)CONFIG_LV_TOUCH_I2C_SCL;
|
||||
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
|
||||
conf.master.clk_speed = 50000;
|
||||
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 0)
|
||||
// !< Optional, you can use I2C_SCLK_SRC_FLAG_* flags to choose i2c source clock here.
|
||||
conf.clk_flags = 0;
|
||||
#endif
|
||||
|
||||
i2c_param_config(I2C_NUM_0, &conf);
|
||||
esp_err_t i2c_driver = i2c_driver_install(I2C_NUM_0, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
|
||||
if (i2c_driver == ESP_OK) {
|
||||
printf("i2c_driver started correctly\n");
|
||||
} else {
|
||||
printf("i2c_driver error: %d\n", i2c_driver);
|
||||
}
|
||||
_intPin = intPin;
|
||||
}
|
||||
|
||||
// Destructor does nothing for now
|
||||
L58Touch::~L58Touch()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool L58Touch::begin(uint16_t width, uint16_t height)
|
||||
{
|
||||
_touch_width = width;
|
||||
_touch_height = height;
|
||||
if (width == 0 || height ==0) {
|
||||
ESP_LOGE(TAG,"begin(uint8_t threshold, uint16_t width, uint16_t height) did not receive the width / height so touch cannot be rotation aware");
|
||||
}
|
||||
|
||||
// INT pin triggers the callback function on the Falling edge of the GPIO
|
||||
gpio_config_t io_conf;
|
||||
io_conf.intr_type = GPIO_INTR_POSEDGE;
|
||||
io_conf.pin_bit_mask = 1ULL<< CONFIG_LV_TOUCH_INT;
|
||||
io_conf.mode = GPIO_MODE_INPUT;
|
||||
io_conf.pull_down_en = (gpio_pulldown_t) 0; // disable pull-down mode
|
||||
io_conf.pull_up_en = (gpio_pullup_t) 1; // pull-up mode
|
||||
gpio_config(&io_conf);
|
||||
/* INT gpio is not declared as an interrupt PIN in this touch version since we cannot do
|
||||
blocking functions in LVGL:
|
||||
*/
|
||||
uint8_t buf[2] = {0xD1, 0X06};
|
||||
writeData(buf, sizeof(buf));
|
||||
return true;
|
||||
}
|
||||
|
||||
void L58Touch::registerTouchHandler(void (*fn)(TPoint point, TEvent e))
|
||||
{
|
||||
_touchHandler = fn;
|
||||
if (CONFIG_L58_DEBUG) printf("Touch handler function registered\n");
|
||||
}
|
||||
|
||||
TPoint L58Touch::loop()
|
||||
{
|
||||
_point = processTouch();
|
||||
return _point;
|
||||
}
|
||||
|
||||
TPoint L58Touch::processTouch()
|
||||
{
|
||||
TPoint point;
|
||||
point.x = lastX;
|
||||
point.y = lastY;
|
||||
point.event = lastEvent;
|
||||
|
||||
if (gpio_get_level((gpio_num_t)CONFIG_LV_TOUCH_INT) == 0) {
|
||||
TPoint point = scanPoint();
|
||||
lastX = point.x;
|
||||
lastY = point.y;
|
||||
lastEvent = point.event;
|
||||
}
|
||||
|
||||
return point;
|
||||
}
|
||||
|
||||
uint8_t L58Touch::read8(uint8_t regName) {
|
||||
uint8_t buf;
|
||||
readRegister8(regName, &buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
TPoint L58Touch::scanPoint()
|
||||
{
|
||||
TPoint point{0,0,0};
|
||||
uint8_t pointIdx = 0;
|
||||
uint8_t buffer[40] = {0};
|
||||
uint32_t sumL = 0, sumH = 0;
|
||||
|
||||
buffer[0] = 0xD0;
|
||||
buffer[1] = 0x00;
|
||||
readBytes(buffer, 7);
|
||||
|
||||
if (buffer[0] == 0xAB) {
|
||||
clearFlags();
|
||||
return point;
|
||||
}
|
||||
|
||||
pointIdx = buffer[5] & 0xF;
|
||||
|
||||
if (pointIdx == 1) {
|
||||
buffer[5] = 0xD0;
|
||||
buffer[6] = 0x07;
|
||||
readBytes( &buffer[5], 2);
|
||||
sumL = buffer[5] << 8 | buffer [6];
|
||||
|
||||
} else if (pointIdx > 1) {
|
||||
buffer[5] = 0xD0;
|
||||
buffer[6] = 0x07;
|
||||
readBytes( &buffer[5], 5 * (pointIdx - 1) + 3);
|
||||
sumL = buffer[5 * pointIdx + 1] << 8 | buffer[5 * pointIdx + 2];
|
||||
}
|
||||
clearFlags();
|
||||
|
||||
for (int i = 0 ; i < 5 * pointIdx; ++i) {
|
||||
sumH += buffer[i];
|
||||
}
|
||||
|
||||
if (sumH != sumL) {
|
||||
pointIdx = 0;
|
||||
}
|
||||
if (pointIdx) {
|
||||
uint8_t offset;
|
||||
for (int i = 0; i < pointIdx; ++i) {
|
||||
if (i == 0) {
|
||||
offset = 0;
|
||||
} else {
|
||||
offset = 4;
|
||||
}
|
||||
data[i].id = (buffer[i * 5 + offset] >> 4) & 0x0F;
|
||||
data[i].event = buffer[i * 5 + offset] & 0x0F;
|
||||
data[i].y = (uint16_t)((buffer[i * 5 + 1 + offset] << 4) | ((buffer[i * 5 + 3 + offset] >> 4) & 0x0F));
|
||||
data[i].x = (uint16_t)((buffer[i * 5 + 2 + offset] << 4) | (buffer[i * 5 + 3 + offset] & 0x0F));
|
||||
|
||||
//printf("X[%d]:%d Y:%d E:%d\n", i, data[i].x, data[i].y, data[i].event);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Only this one seems to be working (even pressing with 2 fingers)
|
||||
pointIdx = 1;
|
||||
data[0].id = (buffer[0] >> 4) & 0x0F;
|
||||
data[0].event = (buffer[0] & 0x0F) >>1;
|
||||
data[0].y = (uint16_t)((buffer[0 * 5 + 1] << 4) | ((buffer[0 * 5 + 3] >> 4) & 0x0F));
|
||||
data[0].x = (uint16_t)((buffer[0 * 5 + 2] << 4) | (buffer[0 * 5 + 3] & 0x0F));
|
||||
if (data[0].event == 3) { /** Press */
|
||||
_touchStartTime = esp_timer_get_time()/1000;
|
||||
}
|
||||
if (data[0].event == 0) { /** Lift up */
|
||||
_touchEndTime = esp_timer_get_time()/1000;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_L58_DEBUG) && CONFIG_L58_DEBUG==1
|
||||
printf("X:%d Y:%d E:%d\n", data[0].x, data[0].y, data[0].event);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint16_t x = data[0].x;
|
||||
uint16_t y = data[0].y;
|
||||
|
||||
// Had some hope that state was event, but always come:
|
||||
// id:1 st:6
|
||||
// printf("id:%d st:%d\n", data[0].id, data[0].state);
|
||||
// Make touch rotation aware
|
||||
switch (_rotation)
|
||||
{
|
||||
// 0- no rotation: Works OK inverting Y axis
|
||||
case 0:
|
||||
y = _touch_height - y;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
swap(x, y);
|
||||
y = _touch_width - y;
|
||||
x = _touch_height - x;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
x = _touch_width - x;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
swap(x, y);
|
||||
break;
|
||||
}
|
||||
|
||||
point = {x, y, data[0].event};
|
||||
return point;
|
||||
}
|
||||
|
||||
void L58Touch::writeRegister8(uint8_t reg, uint8_t value)
|
||||
{
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, L58_ADDR << 1 | I2C_MASTER_WRITE, ACK_CHECK_EN);
|
||||
i2c_master_write_byte(cmd, reg , ACK_CHECK_EN);
|
||||
i2c_master_write_byte(cmd, value , ACK_CHECK_EN);
|
||||
i2c_master_stop(cmd);
|
||||
i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS);
|
||||
i2c_cmd_link_delete(cmd);
|
||||
}
|
||||
|
||||
void L58Touch::writeData(uint8_t *data, int len)
|
||||
{
|
||||
if (len==0) return;
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write(cmd, data, len, ACK_CHECK_EN);
|
||||
i2c_master_stop(cmd);
|
||||
i2c_cmd_link_delete(cmd);
|
||||
}
|
||||
|
||||
uint8_t L58Touch::readRegister8(uint8_t reg, uint8_t *data_buf)
|
||||
{
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, L58_ADDR << 1 | I2C_MASTER_WRITE, ACK_CHECK_EN);
|
||||
i2c_master_write_byte(cmd, reg, I2C_MASTER_ACK);
|
||||
// Research: Why it's started a 2nd time here
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (L58_ADDR << 1) | I2C_MASTER_READ, true);
|
||||
|
||||
i2c_master_read_byte(cmd, data_buf, I2C_MASTER_NACK);
|
||||
i2c_master_stop(cmd);
|
||||
esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS);
|
||||
i2c_cmd_link_delete(cmd);
|
||||
|
||||
#if defined(CONFIG_L58_DEBUG) && CONFIG_L58_DEBUG==1
|
||||
printf("REG 0x%x: 0x%x\n",reg,ret);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void L58Touch::readBytes(uint8_t *data, int len) {
|
||||
if (len==0) return;
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, L58_ADDR << 1 | I2C_MASTER_WRITE, ACK_CHECK_EN);
|
||||
i2c_master_write(cmd, data, 2, ACK_CHECK_EN);
|
||||
|
||||
i2c_master_start(cmd);
|
||||
|
||||
i2c_master_write_byte(cmd, L58_ADDR << 1 | I2C_MASTER_READ, ACK_CHECK_EN);
|
||||
i2c_master_read(cmd, data, len, (i2c_ack_type_t) ACK_VAL);
|
||||
i2c_master_stop(cmd);
|
||||
esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS);
|
||||
i2c_cmd_link_delete(cmd);
|
||||
|
||||
if (ret == ESP_OK) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
printf("0x%02x ", data[i]);
|
||||
if ((i + 1) % 16 == 0) {
|
||||
printf("\r\n");
|
||||
}
|
||||
}
|
||||
if (len % 16) {
|
||||
printf("\r\n");
|
||||
}
|
||||
} else if (ret == ESP_ERR_TIMEOUT) {
|
||||
// Getting a lot of this!
|
||||
//ESP_LOGW(TAG, "Bus is busy");
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Read failed");
|
||||
}
|
||||
}
|
||||
|
||||
void L58Touch::fireEvent(TPoint point, TEvent e)
|
||||
{
|
||||
if (_touchHandler)
|
||||
_touchHandler(point, e);
|
||||
}
|
||||
|
||||
void L58Touch::setRotation(uint8_t rotation) {
|
||||
_rotation = rotation;
|
||||
}
|
||||
|
||||
void L58Touch::setTouchWidth(uint16_t width) {
|
||||
printf("touch w:%d\n",width);
|
||||
_touch_width = width;
|
||||
}
|
||||
|
||||
void L58Touch::setTouchHeight(uint16_t height) {
|
||||
printf("touch h:%d\n",height);
|
||||
_touch_height = height;
|
||||
}
|
||||
|
||||
void L58Touch::clearFlags() {
|
||||
uint8_t buf[3] = {0xD0, 0X00, 0XAB};
|
||||
writeData(buf, sizeof(buf));
|
||||
}
|
||||
|
||||
void L58Touch::sleep() {
|
||||
uint8_t buf[2] = {0xD1, 0X05};
|
||||
writeData(buf, sizeof(buf));
|
||||
}
|
125
lvgl_touch/L58/include/L58Touch.h
Normal file
125
lvgl_touch/L58/include/L58Touch.h
Normal file
|
@ -0,0 +1,125 @@
|
|||
// This is the first experimental Touch component for the LILYGO EPD47 touch overlay
|
||||
// NOTE: As in LVGL we cannot use blocking functions this is a variation of original library here:
|
||||
// https://github.com/martinberlin/FT6X36-IDF
|
||||
// More info about this epaper:
|
||||
// https://github.com/martinberlin/cale-idf/wiki/Model-parallel-ED047TC1.h
|
||||
#include <stdint.h>
|
||||
//#include <cstdlib>
|
||||
#include "driver/gpio.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include <stdio.h>
|
||||
#include "esp_log.h"
|
||||
#include "driver/i2c.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_idf_version.h"
|
||||
#ifndef touch_ttgo_h
|
||||
#define touch_ttgo_h
|
||||
// I2C Constants
|
||||
#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 */
|
||||
|
||||
#define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/
|
||||
#define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */
|
||||
#define ACK_VAL 0x0 /*!< I2C ack value */
|
||||
#define NACK_VAL 0x1 /*!< I2C nack value */
|
||||
|
||||
#define L58_ADDR 0x5A
|
||||
|
||||
// Note: We still could not read proper events, so we simulate Tap
|
||||
enum class TEvent
|
||||
{
|
||||
None,
|
||||
TouchStart,
|
||||
TouchMove,
|
||||
TouchEnd,
|
||||
Tap
|
||||
};
|
||||
|
||||
struct TPoint
|
||||
{
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
uint8_t event;
|
||||
};
|
||||
|
||||
class L58Touch
|
||||
{
|
||||
|
||||
typedef struct {
|
||||
uint8_t id;
|
||||
uint8_t event;
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
} TouchData_t;
|
||||
|
||||
|
||||
|
||||
public:
|
||||
// TwoWire * wire will be replaced by ESP-IDF https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/i2c.html
|
||||
L58Touch(int8_t intPin);
|
||||
~L58Touch();
|
||||
|
||||
bool begin(uint16_t width = 0, uint16_t height = 0);
|
||||
void registerTouchHandler(void(*fn)(TPoint point, TEvent e));
|
||||
uint8_t touched();
|
||||
TPoint loop();
|
||||
TPoint processTouch();
|
||||
// Helper functions to make the touch display aware
|
||||
void setRotation(uint8_t rotation);
|
||||
void setTouchWidth(uint16_t width);
|
||||
void setTouchHeight(uint16_t height);
|
||||
// Pending implementation. How much x->touch y↓touch is placed (In case is smaller than display)
|
||||
void setXoffset(uint16_t x_offset);
|
||||
void setYoffset(uint16_t y_offset);
|
||||
void sleep();
|
||||
// Smart template from EPD to swap x,y:
|
||||
template <typename T> static inline void
|
||||
swap(T& a, T& b)
|
||||
{
|
||||
T t = a;
|
||||
a = b;
|
||||
b = t;
|
||||
}
|
||||
|
||||
void(*_touchHandler)(TPoint point, TEvent e) = nullptr;
|
||||
TouchData_t data[5];
|
||||
// Tap detection is enabled by default
|
||||
bool tapDetectionEnabled = true;
|
||||
// Only if the time difference between press and release is minor than this milliseconds a Tap even is triggered
|
||||
uint16_t tapDetectionMillisDiff = 100;
|
||||
|
||||
private:
|
||||
TPoint scanPoint();
|
||||
void writeRegister8(uint8_t reg, uint8_t val);
|
||||
void writeData(uint8_t *data, int len);
|
||||
void readBytes(uint8_t *data, int len);
|
||||
uint8_t readRegister8(uint8_t reg, uint8_t *data_buf);
|
||||
void fireEvent(TPoint point, TEvent e);
|
||||
uint8_t read8(uint8_t regName);
|
||||
void clearFlags();
|
||||
|
||||
static L58Touch * _instance;
|
||||
uint8_t _intPin;
|
||||
|
||||
// Make touch rotation aware:
|
||||
uint8_t _rotation = 0;
|
||||
uint16_t _touch_width = 0;
|
||||
uint16_t _touch_height = 0;
|
||||
|
||||
uint8_t _touches;
|
||||
uint16_t _touchX[2], _touchY[2], _touchEvent[2];
|
||||
TPoint _points[10];
|
||||
TPoint _point;
|
||||
uint8_t _pointIdx = 0;
|
||||
unsigned long _touchStartTime = 0;
|
||||
unsigned long _touchEndTime = 0;
|
||||
uint8_t lastEvent = 3; // No event
|
||||
uint16_t lastX = 0;
|
||||
uint16_t lastY = 0;
|
||||
bool _dragMode = false;
|
||||
const uint8_t maxDeviation = 5;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,45 +1,55 @@
|
|||
/*
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
*
|
||||
* 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 <esp_log.h>
|
||||
#include <driver/i2c.h>
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include <lvgl.h>
|
||||
#else
|
||||
#include <lvgl/lvgl.h>
|
||||
#endif
|
||||
#include "ft6x36.h"
|
||||
#include "lvgl_i2c/i2c_manager.h"
|
||||
#include "tp_i2c.h"
|
||||
#include "../lvgl_i2c_conf.h"
|
||||
|
||||
#define TAG "FT6X36"
|
||||
#define FT6X36_TOUCH_QUEUE_ELEMENTS 1
|
||||
|
||||
|
||||
static ft6x36_status_t ft6x36_status;
|
||||
static 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
|
||||
ft6x36_status_t ft6x36_status;
|
||||
uint8_t current_dev_addr; // set during init
|
||||
|
||||
static 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);
|
||||
esp_err_t ft6x06_i2c_read8(uint8_t slave_addr, uint8_t register_addr, uint8_t *data_buf) {
|
||||
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
|
||||
*/
|
||||
void ft6x06_init(uint16_t dev_addr) {
|
||||
if (!ft6x36_status.inited) {
|
||||
|
||||
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);
|
||||
|
||||
#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 );
|
||||
/* I2C master is initialized before calling this function */
|
||||
#if 0
|
||||
esp_err_t code = i2c_master_init();
|
||||
#else
|
||||
esp_err_t code = ESP_OK;
|
||||
#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
|
||||
*/
|
||||
bool ft6x36_read(lv_indev_drv_t *drv, lv_indev_data_t *data) {
|
||||
if (!ft6x36_status.inited) {
|
||||
ESP_LOGE(TAG, "Init first!");
|
||||
return 0x00;
|
||||
}
|
||||
uint8_t data_buf[5]; // 1 byte status, 2 bytes X, 2 bytes Y
|
||||
uint8_t data_xy[4]; // 2 bytes X | 2 bytes Y
|
||||
uint8_t touch_pnt_cnt; // Number of detected touch points
|
||||
static int16_t last_x = 0; // 12bit pixel value
|
||||
static int16_t last_y = 0; // 12bit pixel value
|
||||
|
||||
esp_err_t ret = lvgl_i2c_read(CONFIG_LV_I2C_TOUCH_PORT, current_dev_addr, FT6X36_TD_STAT_REG, &data_buf[0], 5);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error talking to touch IC: %s", esp_err_to_name(ret));
|
||||
}
|
||||
uint8_t touch_pnt_cnt = data_buf[0]; // Number of detected touch points
|
||||
|
||||
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;
|
||||
ft6x06_i2c_read8(current_dev_addr, FT6X36_TD_STAT_REG, &touch_pnt_cnt);
|
||||
if (touch_pnt_cnt != 1) { // ignore no touch & multi touch
|
||||
data->point.x = last_x;
|
||||
data->point.y = last_y;
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
return false;
|
||||
}
|
||||
|
||||
touch_inputs.current_state = LV_INDEV_STATE_PR;
|
||||
touch_inputs.last_x = ((data_buf[1] & FT6X36_MSB_MASK) << 8) | (data_buf[2] & FT6X36_LSB_MASK);
|
||||
touch_inputs.last_y = ((data_buf[3] & FT6X36_MSB_MASK) << 8) | (data_buf[4] & FT6X36_LSB_MASK);
|
||||
// Read X value
|
||||
i2c_cmd_handle_t 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_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
|
||||
int16_t swap_buf = touch_inputs.last_x;
|
||||
touch_inputs.last_x = touch_inputs.last_y;
|
||||
touch_inputs.last_y = swap_buf;
|
||||
int16_t swap_buf = last_x;
|
||||
last_x = last_y;
|
||||
last_y = swap_buf;
|
||||
#endif
|
||||
#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
|
||||
#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
|
||||
data->point.x = touch_inputs.last_x;
|
||||
data->point.y = touch_inputs.last_y;
|
||||
data->state = touch_inputs.current_state;
|
||||
ESP_LOGD(TAG, "X=%u Y=%u", data->point.x, data->point.y);
|
||||
|
||||
#if CONFIG_LV_FT6X36_COORDINATES_QUEUE
|
||||
xQueueOverwrite( ft6x36_touch_queue_handle, &touch_inputs );
|
||||
#endif
|
||||
|
||||
//uint16_t lcd_x = p.x *1.37; // Max 240
|
||||
//uint16_t lcd_y = p.y *1.51; // Max 400
|
||||
data->point.x = last_x *1.37;
|
||||
data->point.y = last_y *1.51;
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
ESP_LOGV(TAG, "X=%u Y=%u", data->point.x, data->point.y);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -2,20 +2,20 @@
|
|||
/*
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
@ -23,10 +23,6 @@
|
|||
|
||||
#include <stdint.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
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
|
@ -149,16 +145,6 @@ typedef struct {
|
|||
bool inited;
|
||||
} 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
|
||||
* @param dev_addr: Device address on communication Bus (I2C slave address of FT6X36).
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2021 Sturnus Inc.
|
||||
* Copyright © 2023 Fasani Corp.
|
||||
|
||||
* 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
|
||||
|
@ -17,8 +17,12 @@
|
|||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_lcd_touch_gt911.h"
|
||||
#include <esp_log.h>
|
||||
#include "driver/i2c.h"
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include <lvgl.h>
|
||||
#else
|
||||
|
@ -26,62 +30,46 @@
|
|||
#endif
|
||||
#include "gt911.h"
|
||||
|
||||
#include "lvgl_i2c/i2c_manager.h"
|
||||
|
||||
#define TAG "GT911"
|
||||
|
||||
gt911_status_t gt911_status;
|
||||
|
||||
//TODO: handle multibyte read and refactor to just one read transaction
|
||||
esp_err_t gt911_i2c_read(uint8_t slave_addr, uint16_t register_addr, uint8_t *data_buf, uint8_t len) {
|
||||
return lvgl_i2c_read(CONFIG_LV_I2C_TOUCH_PORT, slave_addr, register_addr | I2C_REG_16, data_buf, len);
|
||||
}
|
||||
|
||||
esp_err_t gt911_i2c_write8(uint8_t slave_addr, uint16_t register_addr, uint8_t data) {
|
||||
uint8_t buffer = data;
|
||||
return lvgl_i2c_write(CONFIG_LV_I2C_TOUCH_PORT, slave_addr, register_addr | I2C_REG_16, &buffer, 1);
|
||||
}
|
||||
#ifdef CONFIG_LV_TOUCH_I2C_PORT_0
|
||||
#define I2C_PORT I2C_NUM_0
|
||||
#endif
|
||||
#ifdef CONFIG_LV_TOUCH_I2C_PORT_1
|
||||
#define I2C_PORT I2C_NUM_1
|
||||
#endif
|
||||
// When the touch panel has different pixels definition
|
||||
float x_adjust = 1.55;
|
||||
float y_adjust = 0.8;
|
||||
esp_lcd_touch_handle_t tp;
|
||||
|
||||
/**
|
||||
* @brief Initialize for GT911 communication via I2C
|
||||
* @param dev_addr: Device address on communication Bus (I2C slave address of GT911).
|
||||
* @retval None
|
||||
*/
|
||||
void gt911_init(uint8_t dev_addr) {
|
||||
if (!gt911_status.inited) {
|
||||
gt911_status.i2c_dev_addr = dev_addr;
|
||||
uint8_t data_buf;
|
||||
esp_err_t ret;
|
||||
esp_lcd_panel_io_handle_t tp_io_handle = NULL;
|
||||
esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_GT911_CONFIG();
|
||||
|
||||
ESP_LOGI(TAG, "Checking for GT911 Touch Controller");
|
||||
if ((ret = gt911_i2c_read(dev_addr, GT911_PRODUCT_ID1, &data_buf, 1) != ESP_OK)) {
|
||||
ESP_LOGE(TAG, "Error reading from device: %s",
|
||||
esp_err_to_name(ret)); // Only show error the first time
|
||||
return;
|
||||
}
|
||||
esp_lcd_touch_config_t tp_cfg = {
|
||||
.x_max = 1025,
|
||||
.y_max = 770,
|
||||
.rst_gpio_num = -1,
|
||||
.int_gpio_num = -1,
|
||||
.levels = {
|
||||
.reset = 0,
|
||||
.interrupt = 0,
|
||||
},
|
||||
.flags = {
|
||||
.swap_xy = 1,
|
||||
.mirror_x = 1,
|
||||
.mirror_y = 0,
|
||||
},
|
||||
};
|
||||
|
||||
esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)I2C_PORT, &tp_io_config, &tp_io_handle);
|
||||
|
||||
// Read 4 bytes for Product ID in ASCII
|
||||
for (int i = 0; i < GT911_PRODUCT_ID_LEN; i++) {
|
||||
gt911_i2c_read(dev_addr, (GT911_PRODUCT_ID1 + i), (uint8_t *)&(gt911_status.product_id[i]), 1);
|
||||
}
|
||||
ESP_LOGI(TAG, "\tProduct ID: %s", gt911_status.product_id);
|
||||
|
||||
gt911_i2c_read(dev_addr, GT911_VENDOR_ID, &data_buf, 1);
|
||||
ESP_LOGI(TAG, "\tVendor ID: 0x%02x", data_buf);
|
||||
|
||||
gt911_i2c_read(dev_addr, GT911_X_COORD_RES_L, &data_buf, 1);
|
||||
gt911_status.max_x_coord = data_buf;
|
||||
gt911_i2c_read(dev_addr, GT911_X_COORD_RES_H, &data_buf, 1);
|
||||
gt911_status.max_x_coord |= ((uint16_t)data_buf << 8);
|
||||
ESP_LOGI(TAG, "\tX Resolution: %d", gt911_status.max_x_coord);
|
||||
|
||||
gt911_i2c_read(dev_addr, GT911_Y_COORD_RES_L, &data_buf, 1);
|
||||
gt911_status.max_y_coord = data_buf;
|
||||
gt911_i2c_read(dev_addr, GT911_Y_COORD_RES_H, &data_buf, 1);
|
||||
gt911_status.max_y_coord |= ((uint16_t)data_buf << 8);
|
||||
ESP_LOGI(TAG, "\tY Resolution: %d", gt911_status.max_y_coord);
|
||||
gt911_status.inited = true;
|
||||
}
|
||||
esp_lcd_touch_new_i2c_gt911(tp_io_handle, &tp_cfg, &tp);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -91,54 +79,22 @@ void gt911_init(uint8_t dev_addr) {
|
|||
* @retval Always false
|
||||
*/
|
||||
bool gt911_read(lv_indev_drv_t *drv, lv_indev_data_t *data) {
|
||||
uint8_t touch_pnt_cnt; // Number of detected touch points
|
||||
static int16_t last_x = 0; // 12bit pixel value
|
||||
static int16_t last_y = 0; // 12bit pixel value
|
||||
uint8_t data_buf;
|
||||
uint8_t status_reg;
|
||||
esp_lcd_touch_read_data(tp);
|
||||
|
||||
gt911_i2c_read(gt911_status.i2c_dev_addr, GT911_STATUS_REG, &status_reg, 1);
|
||||
// ESP_LOGI(TAG, "\tstatus: 0x%02x", status_reg);
|
||||
touch_pnt_cnt = status_reg & 0x0F;
|
||||
if ((status_reg & 0x80) || (touch_pnt_cnt < 6)) {
|
||||
//Reset Status Reg Value
|
||||
gt911_i2c_write8(gt911_status.i2c_dev_addr, GT911_STATUS_REG, 0x00);
|
||||
}
|
||||
if (touch_pnt_cnt != 1) { // ignore no touch & multi touch
|
||||
data->point.x = last_x;
|
||||
data->point.y = last_y;
|
||||
uint16_t touch_x[2];
|
||||
uint16_t touch_y[2];
|
||||
uint16_t touch_strength[2];
|
||||
uint8_t touch_cnt = 0;
|
||||
bool touchpad_pressed = esp_lcd_touch_get_coordinates(tp, touch_x, touch_y, touch_strength, &touch_cnt, 2);
|
||||
if (touchpad_pressed) {
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
data->point.x = (int)(touch_x[0]*x_adjust);
|
||||
data->point.y = (int)(touch_y[0]*y_adjust);
|
||||
ESP_LOGI(TAG, "X=%d Y=%d", (int)data->point.x, (int)data->point.y);
|
||||
} else {
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
return false;
|
||||
data->point.x = -1;
|
||||
data->point.y = -1;
|
||||
}
|
||||
|
||||
// gt911_i2c_read(gt911_status.i2c_dev_addr, GT911_TRACK_ID1, &data_buf, 1);
|
||||
// ESP_LOGI(TAG, "\ttrack_id: %d", data_buf);
|
||||
|
||||
gt911_i2c_read(gt911_status.i2c_dev_addr, GT911_PT1_X_COORD_L, &data_buf, 1);
|
||||
last_x = data_buf;
|
||||
gt911_i2c_read(gt911_status.i2c_dev_addr, GT911_PT1_X_COORD_H, &data_buf, 1);
|
||||
last_x |= ((uint16_t)data_buf << 8);
|
||||
|
||||
gt911_i2c_read(gt911_status.i2c_dev_addr, GT911_PT1_Y_COORD_L, &data_buf, 1);
|
||||
last_y = data_buf;
|
||||
gt911_i2c_read(gt911_status.i2c_dev_addr, GT911_PT1_Y_COORD_H, &data_buf, 1);
|
||||
last_y |= ((uint16_t)data_buf << 8);
|
||||
|
||||
#if CONFIG_LV_GT911_INVERT_X
|
||||
last_x = gt911_status.max_x_coord - last_x;
|
||||
#endif
|
||||
#if CONFIG_LV_GT911_INVERT_Y
|
||||
last_y = gt911_status.max_y_coord - last_y;
|
||||
#endif
|
||||
#if CONFIG_LV_GT911_SWAPXY
|
||||
int16_t swap_buf = last_x;
|
||||
last_x = last_y;
|
||||
last_y = swap_buf;
|
||||
#endif
|
||||
data->point.x = last_x;
|
||||
data->point.y = last_y;
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
ESP_LOGI(TAG, "X=%u Y=%u", data->point.x, data->point.y);
|
||||
ESP_LOGV(TAG, "X=%u Y=%u", data->point.x, data->point.y);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#define __GT911_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
|
@ -33,46 +32,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define GT911_I2C_SLAVE_ADDR 0x5D
|
||||
|
||||
#define GT911_PRODUCT_ID_LEN 4
|
||||
|
||||
/* Register Map of GT911 */
|
||||
#define GT911_PRODUCT_ID1 0x8140
|
||||
#define GT911_PRODUCT_ID2 0x8141
|
||||
#define GT911_PRODUCT_ID3 0x8142
|
||||
#define GT911_PRODUCT_ID4 0x8143
|
||||
#define GT911_FIRMWARE_VER_L 0x8144
|
||||
#define GT911_FIRMWARE_VER_H 0x8145
|
||||
#define GT911_X_COORD_RES_L 0x8146
|
||||
#define GT911_X_COORD_RES_H 0x8147
|
||||
#define GT911_Y_COORD_RES_L 0x8148
|
||||
#define GT911_Y_COORD_RES_H 0x8149
|
||||
#define GT911_VENDOR_ID 0x814A
|
||||
|
||||
#define GT911_STATUS_REG 0x814E
|
||||
#define GT911_STATUS_REG_BUF 0x80
|
||||
#define GT911_STATUS_REG_LARGE 0x40
|
||||
#define GT911_STATUS_REG_PROX_VALID 0x20
|
||||
#define GT911_STATUS_REG_HAVEKEY 0x10
|
||||
#define GT911_STATUS_REG_PT_MASK 0x0F
|
||||
|
||||
#define GT911_TRACK_ID1 0x814F
|
||||
#define GT911_PT1_X_COORD_L 0x8150
|
||||
#define GT911_PT1_X_COORD_H 0x8151
|
||||
#define GT911_PT1_Y_COORD_L 0x8152
|
||||
#define GT911_PT1_Y_COORD_H 0x8153
|
||||
#define GT911_PT1_X_SIZE_L 0x8154
|
||||
#define GT911_PT1_X_SIZE_H 0x8155
|
||||
|
||||
typedef struct {
|
||||
bool inited;
|
||||
char product_id[GT911_PRODUCT_ID_LEN];
|
||||
uint16_t max_x_coord;
|
||||
uint16_t max_y_coord;
|
||||
uint8_t i2c_dev_addr;
|
||||
} gt911_status_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize for GT911 communication via I2C
|
||||
* @param dev_addr: Device address on communication Bus (I2C slave address of GT911).
|
||||
|
|
62
lvgl_touch/l58.cpp
Normal file
62
lvgl_touch/l58.cpp
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright © 2020 Martin Fasani
|
||||
* 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 <esp_log.h>
|
||||
#include <driver/i2c.h>
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include <lvgl.h>
|
||||
#else
|
||||
#include <lvgl/lvgl.h>
|
||||
#endif
|
||||
#include "l58.h"
|
||||
#include "../lvgl_i2c_conf.h"
|
||||
// Cale touch implementation
|
||||
#include "L58Touch.h"
|
||||
L58Touch Touch(CONFIG_LV_TOUCH_INT);
|
||||
#define TAG "L58"
|
||||
|
||||
TPoint point;
|
||||
|
||||
/**
|
||||
* @brief Initialize for FT6x36 communication via I2C
|
||||
* @param dev_addr: Device address on communication Bus (I2C slave address of FT6X36).
|
||||
* @retval None
|
||||
*/
|
||||
void l58_init() {
|
||||
ESP_LOGI(TAG, "l58_init() Touch initialized");
|
||||
Touch.begin(960, 540);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the touch screen X and Y positions values. Ignores multi touch
|
||||
* @param drv:
|
||||
* @param data: Store data here
|
||||
* @retval Always false
|
||||
*/
|
||||
bool l58_read(lv_indev_drv_t *drv, lv_indev_data_t *data) {
|
||||
point = Touch.loop();
|
||||
data->point.x = point.x;
|
||||
data->point.y = point.y;
|
||||
if (point.event == 3) {
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
} else {
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
}
|
||||
return false;
|
||||
}
|
57
lvgl_touch/l58.h
Normal file
57
lvgl_touch/l58.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
#ifndef __L58_H
|
||||
/*
|
||||
* Copyright © 2020 Martin Fasani. Refectored from original driver in https://github.com/martinberlin/FT6X36-IDF (C++)
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define __L58_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initialize for FT6x36 communication via I2C
|
||||
* @retval None
|
||||
*/
|
||||
void l58_init();
|
||||
|
||||
/**
|
||||
* @brief Get the touch screen X and Y positions values. Ignores multi touch
|
||||
* @param drv:
|
||||
* @param data: Store data here
|
||||
* @retval Always false
|
||||
*/
|
||||
bool l58_read(lv_indev_drv_t *drv, lv_indev_data_t *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __FT6X06_H */
|
|
@ -4,7 +4,9 @@
|
|||
|
||||
#include "touch_driver.h"
|
||||
#include "tp_spi.h"
|
||||
|
||||
#include "tp_i2c.h"
|
||||
// Is not being included in CMakeLists.txt (Research why)
|
||||
#include "l58.h"
|
||||
|
||||
void touch_driver_init(void)
|
||||
{
|
||||
|
@ -12,6 +14,10 @@ void touch_driver_init(void)
|
|||
xpt2046_init();
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_FT6X06)
|
||||
ft6x06_init(FT6236_I2C_SLAVE_ADDR);
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_L58)
|
||||
l58_init();
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_GT911)
|
||||
gt911_init(0x5d);
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_STMPE610)
|
||||
stmpe610_init();
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_ADCRAW)
|
||||
|
@ -20,16 +26,10 @@ void touch_driver_init(void)
|
|||
/* nothing to do */
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_RA8875)
|
||||
ra8875_touch_init();
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_GT911)
|
||||
gt911_init(GT911_I2C_SLAVE_ADDR);
|
||||
#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)
|
||||
#endif
|
||||
{
|
||||
bool res = false;
|
||||
|
||||
|
@ -37,6 +37,10 @@ bool touch_driver_read(lv_indev_drv_t *drv, lv_indev_data_t *data)
|
|||
res = xpt2046_read(drv, data);
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_FT6X06)
|
||||
res = ft6x36_read(drv, data);
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_L58)
|
||||
res = l58_read(drv, data);
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_GT911)
|
||||
res = gt911_read(drv, data);
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_STMPE610)
|
||||
res = stmpe610_read(drv, data);
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_ADCRAW)
|
||||
|
@ -45,14 +49,8 @@ bool touch_driver_read(lv_indev_drv_t *drv, lv_indev_data_t *data)
|
|||
res = FT81x_read(drv, data);
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_RA8875)
|
||||
res = ra8875_touch_read(drv, data);
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_GT911)
|
||||
res = gt911_read(drv, data);
|
||||
#endif
|
||||
|
||||
#if LVGL_VERSION_MAJOR >= 8
|
||||
data->continue_reading = res;
|
||||
#else
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -44,12 +44,7 @@ extern "C" {
|
|||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
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);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
|
43
lvgl_touch/tp_i2c.c
Normal file
43
lvgl_touch/tp_i2c.c
Normal 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
36
lvgl_touch/tp_i2c.h
Normal 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 */
|
Loading…
Add table
Add a link
Reference in a new issue