bezier and power level based stepping of backlight was not possible, used esp lcdc to fade the backlight off and on

This commit is contained in:
Timo Niemann
2026-07-02 12:00:32 +02:00
parent 28e6d42f05
commit 3c086037f6
5 changed files with 61 additions and 9 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
idf_component_register(SRCS main.c lcd/lcd.c sd/sd.c lcd/ui.c lcd/ui_log.c lcd/ui_image_browser.c
PRIV_REQUIRES spi_flash esp_psram esp_lcd esp_driver_gpio esp_driver_i2c esp_driver_sdspi esp_driver_spi esp_lvgl_port esp_lcd_touch_gt911 fatfs sdmmc
PRIV_REQUIRES spi_flash esp_psram esp_lcd esp_driver_gpio esp_driver_i2c esp_driver_ledc esp_driver_sdspi esp_driver_spi esp_lvgl_port esp_lcd_touch_gt911 fatfs sdmmc
INCLUDE_DIRS "." "include")
+1
View File
@@ -12,6 +12,7 @@ extern "C" {
esp_err_t lcd_init(void);
lv_display_t *lcd_get_display(void);
void lcd_backlight_set(uint8_t level);
#ifdef __cplusplus
}
+38 -7
View File
@@ -2,6 +2,7 @@
#include "driver/gpio.h"
#include "driver/i2c_master.h"
#include "driver/ledc.h"
#include "esp_check.h"
#include "esp_idf_version.h"
#include "esp_lcd_panel_io.h"
@@ -27,6 +28,13 @@
#define LCD_GPIO_DISP (GPIO_NUM_NC)
#define LCD_GPIO_BACKLIGHT (GPIO_NUM_2)
#define LCD_BACKLIGHT_ON_LEVEL (1)
#define LCD_BACKLIGHT_LEDC_MODE (LEDC_LOW_SPEED_MODE)
#define LCD_BACKLIGHT_LEDC_TIMER (LEDC_TIMER_0)
#define LCD_BACKLIGHT_LEDC_CHANNEL (LEDC_CHANNEL_0)
#define LCD_BACKLIGHT_LEDC_RESOLUTION (LEDC_TIMER_8_BIT)
#define LCD_BACKLIGHT_LEDC_DUTY_MAX ((1 << 8) - 1)
#define LCD_BACKLIGHT_LEDC_FREQ_HZ (5000)
#define LCD_BACKLIGHT_FADE_MS (150)
#define LCD_GPIO_DATA0 (GPIO_NUM_8)
#define LCD_GPIO_DATA1 (GPIO_NUM_3)
#define LCD_GPIO_DATA2 (GPIO_NUM_46)
@@ -72,14 +80,28 @@ static lv_display_t *lvgl_display;
static lv_indev_t *lvgl_touch_indev;
static esp_err_t init_backlight(void){
const gpio_config_t backlight_config = {
.mode = GPIO_MODE_OUTPUT,
.pin_bit_mask = 1ULL << LCD_GPIO_BACKLIGHT,
const ledc_timer_config_t timer_config = {
.speed_mode = LCD_BACKLIGHT_LEDC_MODE,
.timer_num = LCD_BACKLIGHT_LEDC_TIMER,
.duty_resolution = LCD_BACKLIGHT_LEDC_RESOLUTION,
.freq_hz = LCD_BACKLIGHT_LEDC_FREQ_HZ,
.clk_cfg = LEDC_AUTO_CLK,
};
ESP_RETURN_ON_ERROR(gpio_config(&backlight_config), TAG, "Backlight GPIO config failed");
ESP_RETURN_ON_ERROR(gpio_set_level(LCD_GPIO_BACKLIGHT, LCD_BACKLIGHT_ON_LEVEL), TAG, "Backlight GPIO set failed");
ESP_LOGI(TAG, "Backlight enabled on GPIO%d", LCD_GPIO_BACKLIGHT);
return ESP_OK;
ESP_RETURN_ON_ERROR(ledc_timer_config(&timer_config), TAG, "Backlight LEDC timer config failed");
const ledc_channel_config_t channel_config = {
.gpio_num = LCD_GPIO_BACKLIGHT,
.speed_mode = LCD_BACKLIGHT_LEDC_MODE,
.channel = LCD_BACKLIGHT_LEDC_CHANNEL,
.timer_sel = LCD_BACKLIGHT_LEDC_TIMER,
.intr_type = LEDC_INTR_DISABLE,
.duty = (LCD_BACKLIGHT_ON_LEVEL != 0) ? LCD_BACKLIGHT_LEDC_DUTY_MAX : 0,
.hpoint = 0,
};
ESP_RETURN_ON_ERROR(ledc_channel_config(&channel_config), TAG, "Backlight LEDC channel config failed");
ESP_RETURN_ON_ERROR(ledc_fade_func_install(0), TAG, "Backlight LEDC fade install failed");
ESP_LOGI(TAG, "Backlight PWM enabled on GPIO%d", LCD_GPIO_BACKLIGHT);
return ESP_OK;
}
static esp_err_t probe_gt911_address(i2c_master_bus_handle_t i2c_handle, uint32_t *dev_addr){
@@ -272,6 +294,15 @@ static esp_err_t init_lvgl(void){
return ESP_OK;
}
void lcd_backlight_set(uint8_t level){
const uint32_t duty = (LCD_BACKLIGHT_ON_LEVEL != 0) ? level : (LCD_BACKLIGHT_LEDC_DUTY_MAX - level);
esp_err_t err = ledc_set_fade_with_time(LCD_BACKLIGHT_LEDC_MODE, LCD_BACKLIGHT_LEDC_CHANNEL, duty, LCD_BACKLIGHT_FADE_MS);
if(err == ESP_OK){
err = ledc_fade_start(LCD_BACKLIGHT_LEDC_MODE, LCD_BACKLIGHT_LEDC_CHANNEL, LEDC_FADE_WAIT_DONE);
}
if(err != ESP_OK) ESP_LOGW(TAG, "Backlight set failed: %s", esp_err_to_name(err));
}
esp_err_t lcd_init(void){
ESP_RETURN_ON_ERROR(init_rgb_panel(), TAG, "LCD panel init failed");
const esp_err_t touch_ret = init_touch();
+14 -1
View File
@@ -15,6 +15,7 @@
#include "lcd/ui_internal.h"
#include "lcd/ui_log.h"
#include "sd/sd.h"
#include "lcd/lcd.h"
#define UI_IMAGE_PATH_PREFIX "A:/sdcard/"
#define UI_IMAGE_PATH_MAX_LENGTH 160
@@ -349,6 +350,7 @@ static bool ui_image_browser_display_prefetched(void){
/* Warm up the next image so the following switch is instant too. */
ui_prefetch_next(index, slot);
return true;
}
@@ -395,11 +397,22 @@ static void ui_image_browser_load_via_path(void){
static void ui_image_browser_display_current(void){
if(image_widget == NULL || image_browser_names == NULL || image_browser_image_count == 0) return;
if(ui_image_browser_display_prefetched()) return;
ESP_LOGI(TAG, "Backlight sweep: turning off backlight");
ui_log_append("Backlight sweep: turning off backlight");
lcd_backlight_set(0);
if(ui_image_browser_display_prefetched()) goto done;
ESP_LOGW(TAG, "Prefetched image unavailable: falling back to on-demand decoding");
ui_log_append("Prefetched image unavailable: falling back to on-demand decoding");
/* Prefetch unavailable or render failed: fall back to on-demand decoding. */
visible_slot = -1;
ui_image_browser_load_via_path();
done:
ESP_LOGI(TAG, "Backlight sweep: turning on backlight");
ui_log_append("Backlight sweep: turning on backlight");
lcd_backlight_set(255);
}
void ui_image_browser_build_view(lv_obj_t *screen){