Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESP32-S3 support | ILI9488 is working perfectly | esp-idf v4 and v5 compatible #227

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
20 changes: 20 additions & 0 deletions .github/workflows/deployment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Push component to https://components.espressif.com
on:
push:
tags:
- v*
jobs:
upload_components:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: "recursive"

- name: Upload component to the component registry
uses: espressif/upload-components-ci-action@v1
with:
name: "lvgl_esp32_drivers"
version: ${{ github.ref_name }}
namespace: "vitoralho"
api_token: ${{ secrets.IDF_COMPONENT_API_TOKEN }}
14 changes: 11 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,17 @@ 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)
if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "5.0")
idf_component_register( SRCS ${SOURCES}
INCLUDE_DIRS ${LVGL_INCLUDE_DIRS}
REQUIRES lvgl driver)
set(USE_PORT_TICK_PERIOD_MS)
else()
idf_component_register( SRCS ${SOURCES}
INCLUDE_DIRS ${LVGL_INCLUDE_DIRS}
REQUIRES lvgl)
set(USE_PORT_TICK_RATE_MS)
endif()

target_compile_definitions(${COMPONENT_LIB} PUBLIC "-DLV_LVGL_H_INCLUDE_SIMPLE")

Expand Down
14 changes: 6 additions & 8 deletions lvgl_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ void lvgl_driver_init(void)

lvgl_spi_driver_init(TFT_SPI_HOST,
DISP_SPI_MISO, DISP_SPI_MOSI, DISP_SPI_CLK,
SPI_BUS_MAX_TRANSFER_SZ, 1,
SPI_BUS_MAX_TRANSFER_SZ, SPI_DMA_CH_AUTO,
DISP_SPI_IO2, DISP_SPI_IO3);

disp_spi_add_device(TFT_SPI_HOST);
Expand All @@ -83,7 +83,7 @@ void lvgl_driver_init(void)

lvgl_spi_driver_init(TFT_SPI_HOST,
TP_SPI_MISO, DISP_SPI_MOSI, DISP_SPI_CLK,
SPI_BUS_MAX_TRANSFER_SZ, 1,
SPI_BUS_MAX_TRANSFER_SZ, SPI_DMA_CH_AUTO,
-1, -1);

disp_spi_add_device(TFT_SPI_HOST);
Expand All @@ -101,7 +101,7 @@ void lvgl_driver_init(void)

lvgl_spi_driver_init(TFT_SPI_HOST,
DISP_SPI_MISO, DISP_SPI_MOSI, DISP_SPI_CLK,
SPI_BUS_MAX_TRANSFER_SZ, 1,
SPI_BUS_MAX_TRANSFER_SZ, SPI_DMA_CH_AUTO,
DISP_SPI_IO2, DISP_SPI_IO3);

disp_spi_add_device(TFT_SPI_HOST);
Expand All @@ -120,7 +120,7 @@ void lvgl_driver_init(void)

lvgl_spi_driver_init(TOUCH_SPI_HOST,
TP_SPI_MISO, TP_SPI_MOSI, TP_SPI_CLK,
0 /* Defaults to 4094 */, 2,
0 /* Defaults to 4094 */, SPI_DMA_CH_AUTO,
-1, -1);

tp_spi_add_device(TOUCH_SPI_HOST);
Expand Down Expand Up @@ -175,10 +175,8 @@ bool lvgl_spi_driver_init(int host,
};

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, SPI_DMA_CH_AUTO);
assert(ret == ESP_OK);

return ESP_OK != ret;
Expand Down
72 changes: 55 additions & 17 deletions lvgl_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,32 @@ extern "C" {
#include "lvgl_tft/disp_driver.h"
#include "lvgl_tft/esp_lcd_backlight.h"
#include "lvgl_touch/touch_driver.h"

#include "hal/spi_hal.h"
#include "esp_idf_version.h"
/*********************
* DEFINES
*********************/
// Backwards compability with existing projects
#ifndef LV_HOR_RES_MAX
# ifdef CONFIG_LV_HOR_RES_MAX
# define LV_HOR_RES_MAX CONFIG_LV_HOR_RES_MAX
# else
# define LV_HOR_RES_MAX (480)
# endif
#endif
#ifndef LV_VER_RES_MAX
# ifdef CONFIG_LV_VER_RES_MAX
# define LV_VER_RES_MAX CONFIG_LV_VER_RES_MAX
# else
# define LV_VER_RES_MAX (320)
# endif
#endif

#if ESP_IDF_VERSION_MAJOR >= 5
#define portTICK_DELAY_MS portTICK_PERIOD_MS
#elif USE_PORT_TICK_RATE_MS
#define portTICK_DELAY_MS portTICK_RATE_MS
#endif

/* DISP_BUF_SIZE value doesn't have an special meaning, but it's the size
* of the buffer(s) passed to LVGL as display buffers. The default values used
Expand All @@ -34,48 +56,64 @@ extern "C" {
* color format being used, for RGB565 each pixel needs 2 bytes.
* When using the mono theme, the display pixels can be represented in one bit,
* so the buffer size can be divided by 8, e.g. see SSD1306 display size. */

#define TFT_DISPLAY_BUFFER_SIZE_IN_BITS (LV_HOR_RES_MAX * 40 * 3 * 8)
#define TFT_DISPLAY_BUFFER_SIZE (LV_HOR_RES_MAX * 40)

#if CONFIG_IDF_TARGET_ESP32S3
#define DMA_MAX_BIT_LENGHT (1<<18) // according with SPI_LL_DMA_MAX_BIT_LEN in spi_ll.h
#else
#define DMA_MAX_BIT_LENGHT (1<<24) // according with SPI_LL_DMA_MAX_BIT_LEN in spi_ll.h
#endif

#define TFT_DISPLAY_BUFFER_SIZE_OVERFLOW_PROTECTION ((TFT_DISPLAY_BUFFER_SIZE_IN_BITS>DMA_MAX_BIT_LENGHT)? (((DMA_MAX_BIT_LENGHT-1000)/8)/3) :TFT_DISPLAY_BUFFER_SIZE)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like this approach here. We can always break one larger buffer into multiple DMA requests. Limit the DISP_BUF_SIZE is not the best option. In SPI code, we can break one request into multiple without every driver to handle it.


#if defined (CONFIG_CUSTOM_DISPLAY_BUFFER_SIZE)
#define DISP_BUF_SIZE CONFIG_CUSTOM_DISPLAY_BUFFER_BYTES
#else
#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7789)
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
#define DISP_BUF_SIZE (TFT_DISPLAY_BUFFER_SIZE_OVERFLOW_PROTECTION)
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7735S
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
#define DISP_BUF_SIZE (TFT_DISPLAY_BUFFER_SIZE_OVERFLOW_PROTECTION)
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7796S
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
#define DISP_BUF_SIZE (TFT_DISPLAY_BUFFER_SIZE_OVERFLOW_PROTECTION)
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_HX8357
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
#define DISP_BUF_SIZE (TFT_DISPLAY_BUFFER_SIZE_OVERFLOW_PROTECTION)
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SH1107
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * LV_VER_RES_MAX)
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
#define DISP_BUF_SIZE (TFT_DISPLAY_BUFFER_SIZE_OVERFLOW_PROTECTION)
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9486
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
#define DISP_BUF_SIZE (TFT_DISPLAY_BUFFER_SIZE_OVERFLOW_PROTECTION)
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
#define DISP_BUF_SIZE (TFT_DISPLAY_BUFFER_SIZE_OVERFLOW_PROTECTION)
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
#define DISP_BUF_SIZE (TFT_DISPLAY_BUFFER_SIZE_OVERFLOW_PROTECTION)
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SSD1306
#if defined (CONFIG_LV_THEME_MONO)
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * (LV_VER_RES_MAX / 8))
#else
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * LV_VER_RES_MAX)
#endif
#if defined (CONFIG_LV_THEME_MONO)
#define TFT_DISPLAY_MONO_BUFFER_SIZE (LV_HOR_RES_MAX * (LV_VER_RES_MAX / 8))
#define TFT_DISPLAY_MONO_BUFFER_SIZE_OVERFLOW_PROTECTION (TFT_DISPLAY_MONO_BUFFER_SIZE>SPI_LL_DMA_MAX_BIT_LEN)? SPI_LL_DMA_MAX_BIT_LEN-1000 :
#define DISP_BUF_SIZE (TFT_DISPLAY_MONO_BUFFER_SIZE_OVERFLOW_PROTECTION)
#else
#define TFT_DISPLAY_MONO_BUFFER_SIZE (LV_HOR_RES_MAX * LV_VER_RES_MAX)
#define TFT_DISPLAY_MONO_BUFFER_SIZE_OVERFLOW_PROTECTION (TFT_DISPLAY_MONO_BUFFER_SIZE>SPI_LL_DMA_MAX_BIT_LEN)? SPI_LL_DMA_MAX_BIT_LEN-1000 :
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * LV_VER_RES_MAX)
#endif
#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X)
#define DISP_BUF_LINES 40
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * DISP_BUF_LINES)
#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_IL3820)
#define DISP_BUF_SIZE (LV_VER_RES_MAX * IL3820_COLUMNS)
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_RA8875
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
#define DISP_BUF_SIZE (TFT_DISPLAY_BUFFER_SIZE_OVERFLOW_PROTECTION)
#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_GC9A01)
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
#define DISP_BUF_SIZE (TFT_DISPLAY_BUFFER_SIZE_OVERFLOW_PROTECTION)
#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_JD79653A)
#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)
#define DISP_BUF_SIZE (TFT_DISPLAY_BUFFER_SIZE_OVERFLOW_PROTECTION)
#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_PCD8544)
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * (LV_VER_RES_MAX / 8))
#else
Expand Down
16 changes: 8 additions & 8 deletions lvgl_i2c/i2c_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ static const uint8_t ACK_CHECK_EN = 1;
#define I2C_MANAGER_0_PULLUPS false
#endif

#define I2C_MANAGER_0_TIMEOUT ( CONFIG_I2C_MANAGER_0_TIMEOUT / portTICK_RATE_MS )
#define I2C_MANAGER_0_LOCK_TIMEOUT ( CONFIG_I2C_MANAGER_0_LOCK_TIMEOUT / portTICK_RATE_MS )
#define I2C_MANAGER_0_TIMEOUT ( CONFIG_I2C_MANAGER_0_TIMEOUT / portTICK_DELAY_MS )
#define I2C_MANAGER_0_LOCK_TIMEOUT ( CONFIG_I2C_MANAGER_0_LOCK_TIMEOUT / portTICK_DELAY_MS )
#endif


Expand All @@ -79,8 +79,8 @@ static const uint8_t ACK_CHECK_EN = 1;
#define I2C_MANAGER_1_PULLUPS false
#endif

#define I2C_MANAGER_1_TIMEOUT ( CONFIG_I2C_MANAGER_1_TIMEOUT / portTICK_RATE_MS )
#define I2C_MANAGER_1_LOCK_TIMEOUT ( CONFIG_I2C_MANAGER_1_LOCK_TIMEOUT / portTICK_RATE_MS )
#define I2C_MANAGER_1_TIMEOUT ( CONFIG_I2C_MANAGER_1_TIMEOUT / portTICK_DELAY_MS )
#define I2C_MANAGER_1_LOCK_TIMEOUT ( CONFIG_I2C_MANAGER_1_LOCK_TIMEOUT / portTICK_DELAY_MS )
#endif

#define ERROR_PORT(port, fail) { \
Expand Down Expand Up @@ -244,12 +244,12 @@ esp_err_t I2C_FN(_write)(i2c_port_t port, uint16_t addr, uint32_t reg, const uin
TickType_t timeout = 0;
#if defined (I2C_ZERO)
if (port == I2C_NUM_0) {
timeout = (CONFIG_I2C_MANAGER_0_TIMEOUT) / portTICK_RATE_MS;
timeout = (CONFIG_I2C_MANAGER_0_TIMEOUT) / portTICK_DELAY_MS;
}
#endif
#if defined (I2C_ONE)
if (port == I2C_NUM_1) {
timeout = (CONFIG_I2C_MANAGER_1_TIMEOUT) / portTICK_RATE_MS;
timeout = (CONFIG_I2C_MANAGER_1_TIMEOUT) / portTICK_DELAY_MS;
}
#endif

Expand Down Expand Up @@ -294,12 +294,12 @@ esp_err_t I2C_FN(_lock)(i2c_port_t port) {
TickType_t timeout;
#if defined (I2C_ZERO)
if (port == I2C_NUM_0) {
timeout = (CONFIG_I2C_MANAGER_0_LOCK_TIMEOUT) / portTICK_RATE_MS;
timeout = (CONFIG_I2C_MANAGER_0_LOCK_TIMEOUT) / portTICK_DELAY_MS;
}
#endif
#if defined (I2C_ONE)
if (port == I2C_NUM_1) {
timeout = (CONFIG_I2C_MANAGER_1_LOCK_TIMEOUT) / portTICK_RATE_MS;
timeout = (CONFIG_I2C_MANAGER_1_LOCK_TIMEOUT) / portTICK_DELAY_MS;
}
#endif

Expand Down
6 changes: 3 additions & 3 deletions lvgl_tft/GC9A01.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ void GC9A01_init(void)

//Reset the display
gpio_set_level(GC9A01_RST, 0);
vTaskDelay(100 / portTICK_RATE_MS);
vTaskDelay(100 / portTICK_DELAY_MS);
gpio_set_level(GC9A01_RST, 1);
vTaskDelay(100 / portTICK_RATE_MS);
vTaskDelay(100 / portTICK_DELAY_MS);
#endif

ESP_LOGI(TAG, "Initialization.");
Expand All @@ -134,7 +134,7 @@ void GC9A01_init(void)
GC9A01_send_cmd(GC_init_cmds[cmd].cmd);
GC9A01_send_data(GC_init_cmds[cmd].data, GC_init_cmds[cmd].databytes&0x1F);
if (GC_init_cmds[cmd].databytes & 0x80) {
vTaskDelay(100 / portTICK_RATE_MS);
vTaskDelay(100 / portTICK_DELAY_MS);
}
cmd++;
}
Expand Down
8 changes: 8 additions & 0 deletions lvgl_tft/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,14 @@ menu "LVGL TFT Display controller"
default 40 if LV_PREDEFINED_DISPLAY_TTGO && (LV_DISPLAY_ORIENTATION_PORTRAIT || LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
default 0

config LV_HOR_RES_MAX
int "Maximal horizontal resolution to support by the library."
default 480

config LV_VER_RES_MAX
int "Maximal vertical resolution to support by the library."
default 320


# Display colors(?)
# Useful to know when the display being used is a monochrome
Expand Down
19 changes: 18 additions & 1 deletion lvgl_tft/esp_lcd_backlight.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "driver/gpio.h"
#include "esp_log.h"
#include "soc/ledc_periph.h" // to invert LEDC output on IDF version < v4.3
#include "soc/gpio_sig_map.h"
#include "esp_idf_version.h"

typedef struct {
bool pwm_control; // true: LEDC is used, false: GPIO is used
Expand Down Expand Up @@ -49,22 +51,37 @@ disp_backlight_h disp_backlight_new(const disp_backlight_config_t *config)
};
const ledc_timer_config_t LCD_backlight_timer = {
.speed_mode = LEDC_LOW_SPEED_MODE,
#if ESP_IDF_VERSION_MAJOR >= 5
.duty_resolution = LEDC_TIMER_10_BIT,
#else
.bit_num = LEDC_TIMER_10_BIT,
#endif
.timer_num = config->timer_idx,
.freq_hz = 5000,
.clk_cfg = LEDC_AUTO_CLK};

ESP_ERROR_CHECK(ledc_timer_config(&LCD_backlight_timer));
ESP_ERROR_CHECK(ledc_channel_config(&LCD_backlight_channel));
gpio_matrix_out(config->gpio_num, ledc_periph_signal[LEDC_LOW_SPEED_MODE].sig_out0_idx + config->channel_idx, config->output_invert, 0);
#if ESP_IDF_VERSION_MAJOR >= 5
esp_rom_gpio_connect_out_signal(config->gpio_num, ledc_periph_signal[LEDC_LOW_SPEED_MODE].sig_out0_idx + config->channel_idx, config->output_invert,0);
#else
gpio_matrix_out(config->gpio_num, ledc_periph_signal[LEDC_LOW_SPEED_MODE].sig_out0_idx + config->channel_idx, config->output_invert, 0);
#endif
}
else
{
// Configure GPIO for output
bckl_dev->index = config->gpio_num;

#if ESP_IDF_VERSION_MAJOR >= 5
esp_rom_gpio_connect_out_signal(config->gpio_num, SIG_GPIO_OUT_IDX, config->output_invert, false);
esp_rom_gpio_pad_select_gpio(config->gpio_num);
ESP_ERROR_CHECK(gpio_set_direction(config->gpio_num, GPIO_MODE_OUTPUT));
#else
gpio_pad_select_gpio(config->gpio_num);
ESP_ERROR_CHECK(gpio_set_direction(config->gpio_num, GPIO_MODE_OUTPUT));
gpio_matrix_out(config->gpio_num, SIG_GPIO_OUT_IDX, config->output_invert, false);
#endif
}

return (disp_backlight_h)bckl_dev;
Expand Down
6 changes: 3 additions & 3 deletions lvgl_tft/hx8357.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,9 @@ void hx8357_init(void)

//Reset the display
gpio_set_level(HX8357_RST, 0);
vTaskDelay(10 / portTICK_RATE_MS);
vTaskDelay(10 / portTICK_DELAY_MS);
gpio_set_level(HX8357_RST, 1);
vTaskDelay(120 / portTICK_RATE_MS);
vTaskDelay(120 / portTICK_DELAY_MS);
#endif

ESP_LOGI(TAG, "Initialization.");
Expand All @@ -192,7 +192,7 @@ void hx8357_init(void)
}
}
if (x & 0x80) { // If high bit set...
vTaskDelay(numArgs * 5 / portTICK_RATE_MS); // numArgs is actually a delay time (5ms units)
vTaskDelay(numArgs * 5 / portTICK_DELAY_MS); // numArgs is actually a delay time (5ms units)
}
}

Expand Down
8 changes: 4 additions & 4 deletions lvgl_tft/il3820.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,9 @@ void il3820_init(void)

/* Harware reset */
gpio_set_level( IL3820_RST_PIN, 0);
vTaskDelay(IL3820_RESET_DELAY / portTICK_RATE_MS);
vTaskDelay(IL3820_RESET_DELAY / portTICK_DELAY_MS);
gpio_set_level( IL3820_RST_PIN, 1);
vTaskDelay(IL3820_RESET_DELAY / portTICK_RATE_MS);
vTaskDelay(IL3820_RESET_DELAY / portTICK_DELAY_MS);
#endif

/* Software reset */
Expand Down Expand Up @@ -267,14 +267,14 @@ static void il3820_waitbusy(int wait_ms)
{
int i = 0;

vTaskDelay(10 / portTICK_RATE_MS); // 10ms delay
vTaskDelay(10 / portTICK_DELAY_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);
vTaskDelay(10 / portTICK_DELAY_MS);
}

ESP_LOGE( TAG, "busy exceeded %dms", i*10 );
Expand Down
Loading