Skip to content

Commit

Permalink
Initial commit for LVGL v9.1
Browse files Browse the repository at this point in the history
  • Loading branch information
rzeldent committed Jun 16, 2024
1 parent 72c95c1 commit 21cdca4
Show file tree
Hide file tree
Showing 16 changed files with 744 additions and 512 deletions.
2 changes: 1 addition & 1 deletion boards
Submodule boards updated 1 files
+15 −3 README.md
2 changes: 2 additions & 0 deletions include/esp32_smartdisplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#include <Arduino.h>
#include <lvgl.h>
#include <display/lv_display_private.h>
#include <indev/lv_indev_private.h>

// Use last PWM_CHANNEL for backlight
#define PWM_CHANNEL_BCKL (SOC_LEDC_CHANNEL_NUM - 1)
Expand Down
6 changes: 3 additions & 3 deletions library.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"$schema": "https://raw.githubusercontent.com/platformio/platformio-core/develop/platformio/assets/schema/library.json",
"name": "esp32_smartdisplay",
"version": "2.0.9",
"description": "LVGL driver for Sunton ESP32 Cheap Yellow Display display boards",
"version": "3.0.0",
"description": "LVGL v9.1 driver for Sunton ESP32 Cheap Yellow Display display boards",
"keywords": "LVGL Sunton CYD LCD TFT Touch",
"repository": {
"type": "git",
Expand Down Expand Up @@ -35,6 +35,6 @@
"frameworks": "arduino",
"platforms": "espressif32",
"dependencies": {
"lvgl/lvgl": "^8.3.9"
"lvgl/lvgl": "^9.1.0"
}
}
2 changes: 1 addition & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ build_flags =
'-D ESP_LCD_PANEL_IO_ADDITIONS_VER_PATCH=1'

lib_deps =
lvgl/lvgl@^8.3.9
lvgl/lvgl@^9.1.0
# The platformio.test_dir contains the test_main.cpp just to have an setup() and loop() function
# so it will compile
${platformio.test_dir}
Expand Down
74 changes: 44 additions & 30 deletions src/esp32_smartdisplay.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,39 @@
#define BRIGHTNESS_DARK_ZONE 250

// Functions to be defined in the tft/touch driver
extern void lvgl_lcd_init(lv_disp_drv_t *disp_drv);
extern void lvgl_touch_init(lv_indev_drv_t *disp_drv);
extern lv_display_t *lvgl_lcd_init(uint32_t hor_res, uint32_t ver_res);
extern lv_indev_t *lvgl_touch_init();

lv_disp_drv_t disp_drv;
lv_timer_t *update_brightness_timer;
lv_display_t *display;

#ifdef BOARD_HAS_TOUCH
lv_indev_drv_t indev_drv;
lv_indev_t *indev;
touch_calibration_data_t touch_calibration_data;
void (*driver_touch_read_cb)(struct _lv_indev_drv_t *indev_drv, lv_indev_data_t *data);
void (*driver_touch_read_cb)(lv_indev_t *indev, lv_indev_data_t *data);
#endif

lv_timer_t *update_brightness_timer;

#ifdef LV_USE_LOG
void lvgl_log(const char *buf)
void lvgl_log(lv_log_level_t level, const char *buf)
{
log_printf("%s", buf);
switch (level)
{
case LV_LOG_LEVEL_TRACE:
log_printf("%s", buf);
break;
case LV_LOG_LEVEL_INFO:
log_i("%s", buf);
break;
case LV_LOG_LEVEL_WARN:
log_w("%s", buf);
break;
case LV_LOG_LEVEL_ERROR:
log_e("%s", buf);
break;
case LV_LOG_LEVEL_USER:
break;
}
}
#endif

Expand Down Expand Up @@ -100,12 +117,12 @@ void smartdisplay_led_set_rgb(bool r, bool g, bool b)

#ifdef BOARD_HAS_TOUCH
// See: https://www.maximintegrated.com/en/design/technical-documents/app-notes/5/5296.html
void lvgl_touch_calibration_transform(lv_indev_drv_t *disp_drv, lv_indev_data_t *data)
void lvgl_touch_calibration_transform(lv_indev_t *indev, lv_indev_data_t *data)
{
log_v("disp_drv:0x%08x, data:0x%08x", disp_drv, data);
log_v("indev:0x%08x, data:0x%08x", indev, data);

// Call low level read from the driver
driver_touch_read_cb(disp_drv, data);
driver_touch_read_cb(indev, data);
// Check if transformation is required
if (touch_calibration_data.valid && data->state == LV_INDEV_STATE_PRESSED)
{
Expand Down Expand Up @@ -137,6 +154,7 @@ touch_calibration_data_t smartdisplay_compute_touch_calibration(const lv_point_t
};
#endif

/*
// Called when driver parameters are updated (rotation)
// Top of the display is top left when connector is at the bottom
// The rotation values are relative to how you would rotate the physical display in the clockwise direction.
Expand Down Expand Up @@ -167,6 +185,7 @@ void lvgl_update_callback(lv_disp_drv_t *drv)
}
}
}
*/

void smartdisplay_init()
{
Expand Down Expand Up @@ -206,31 +225,26 @@ void smartdisplay_init()
ledcAttachPin(GPIO_BCKL, PWM_CHANNEL_BCKL);
#endif
// Setup TFT display
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = DISPLAY_WIDTH;
disp_drv.ver_res = DISPLAY_HEIGHT;
// Create drawBuffer
disp_drv.draw_buf = (lv_disp_draw_buf_t *)malloc(sizeof(lv_disp_draw_buf_t));
void *drawBuffer = heap_caps_malloc(sizeof(lv_color_t) * LVGL_BUFFER_PIXELS, LVGL_BUFFER_MALLOC_FLAGS);
lv_disp_draw_buf_init(disp_drv.draw_buf, drawBuffer, NULL, LVGL_BUFFER_PIXELS);
// Register callback for changes to the driver parameters (rotation!)
disp_drv.drv_update_cb = lvgl_update_callback;
// Initialize specific driver
lvgl_lcd_init(&disp_drv);
__attribute__((unused)) lv_disp_t *display = lv_disp_drv_register(&disp_drv);
// Clear screen
display = lvgl_lcd_init(DISPLAY_WIDTH, DISPLAY_HEIGHT);
// Create drawBuffer
uint32_t dreawBufferSize = sizeof(lv_color_t) * LVGL_BUFFER_PIXELS;
void *drawBuffer = heap_caps_malloc(dreawBufferSize, LVGL_BUFFER_MALLOC_FLAGS);
lv_display_set_buffers(display, drawBuffer, NULL, dreawBufferSize, LV_DISPLAY_RENDER_MODE_PARTIAL);
// Register callback for changes to the driver parameters (rotation!)
// display->drv_update_cb = lvgl_update_callback;
// Initialize specific driver
// Clear screen
lv_obj_clean(lv_scr_act());
// Turn backlight on (50%)
smartdisplay_lcd_set_backlight(0.5f);

// If there is a touch controller defined
#ifdef BOARD_HAS_TOUCH
// Setup touch
lv_indev_drv_init(&indev_drv);
indev_drv.disp = display;
lvgl_touch_init(&indev_drv);
driver_touch_read_cb = indev_drv.read_cb;
indev_drv.read_cb = lvgl_touch_calibration_transform;
lv_indev_drv_register(&indev_drv);
indev = lvgl_touch_init();
indev->disp = display;
// Intercept callback
driver_touch_read_cb = indev->read_cb;
indev->read_cb = lvgl_touch_calibration_transform;
#endif
}
43 changes: 23 additions & 20 deletions src/lvgl_panel_gc9a01_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,34 @@ bool gc9a01_color_trans_done(esp_lcd_panel_io_handle_t panel_io_handle, esp_lcd_
{
log_v("panel_io_handle:0x%08x, panel_io_event_data:%0x%08x, user_ctx:0x%08x", panel_io_handle, panel_io_event_data, user_ctx);

lv_disp_drv_t *disp_driver = user_ctx;
lv_disp_flush_ready(disp_driver);
lv_display_t *display = user_ctx;
lv_disp_flush_ready(display);
return false;
}

void gc9a01_lv_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map)
void gc9a01_lv_flush(lv_display_t *display, const lv_area_t *area, uint8_t *px_map)
{
log_v("drv:0x%08x, area:%0x%08x, color_map:0x%08x", drv, area, color_map);
log_v("display:0x%08x, area:%0x%08x, color_map:0x%08x", display, area, px_map);

esp_lcd_panel_handle_t panel_handle = drv->user_data;
#if LV_COLOR_16_SWAP != 1
#warning "LV_COLOR_16_SWAP should be 1 for max performance"
ushort pixels = lv_area_get_size(area);
lv_color16_t *p = color_map;
while (pixels--)
p++->full = (uint16_t)((p->full >> 8) | (p->full << 8));
#endif
ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, area->x1, area->y1, area->x2 + 1, area->y2 + 1, color_map));
esp_lcd_panel_handle_t panel_handle = display->user_data;
uint32_t pixels = lv_area_get_size(area);
uint16_t *p = (uint16_t*)px_map;
while (pixels--) {
*p = (uint16_t)((*p >> 8) | (*p << 8));
p++;
}

ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, area->x1, area->y1, area->x2 + 1, area->y2 + 1, px_map));
};

void lvgl_lcd_init(lv_disp_drv_t *drv)
lv_display_t *lvgl_lcd_init(uint32_t hor_res, uint32_t ver_res)
{
log_v("disp_drv:0x%08x", drv);
lv_display_t *display = lv_display_create(hor_res, ver_res);
log_v("display:0x%08x", display);

// Hardware rotation is supported
drv->sw_rotate = 0;
drv->rotated = LV_DISP_ROT_NONE;
display->sw_rotate = 0;
display->rotation = LV_DISPLAY_ROTATION_0;

// Create SPI bus
const spi_bus_config_t spi_bus_config = {
Expand All @@ -58,7 +59,7 @@ void lvgl_lcd_init(lv_disp_drv_t *drv)
.spi_mode = GC9A01_SPI_CONFIG_SPI_MODE,
.pclk_hz = GC9A01_SPI_CONFIG_PCLK_HZ,
.trans_queue_depth = GC9A01_SPI_CONFIG_TRANS_QUEUE_DEPTH,
.user_ctx = drv,
.user_ctx = display,
.on_color_trans_done = gc9a01_color_trans_done,
.lcd_cmd_bits = GC9A01_SPI_CONFIG_LCD_CMD_BITS,
.lcd_param_bits = GC9A01_SPI_CONFIG_LCD_PARAM_BITS,
Expand Down Expand Up @@ -100,8 +101,10 @@ void lvgl_lcd_init(lv_disp_drv_t *drv)
// Turn display on
ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle, true));

drv->user_data = panel_handle;
drv->flush_cb = gc9a01_lv_flush;
display->user_data = panel_handle;
display->flush_cb = gc9a01_lv_flush;

return display;
}

#endif
43 changes: 23 additions & 20 deletions src/lvgl_panel_ili9341_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,34 @@
#include <esp_lcd_panel_io.h>
#include <esp_lcd_panel_ops.h>

static bool ili9341_color_trans_done(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_io_event_data_t *edata, void *user_ctx)
bool ili9341_color_trans_done(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_io_event_data_t *edata, void *user_ctx)
{
lv_disp_drv_t *disp_driver = user_ctx;
lv_disp_flush_ready(disp_driver);
lv_display_t *display = user_ctx;
lv_disp_flush_ready(display);
return false;
}

static void ili9341_lv_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map)
void ili9341_lv_flush(lv_display_t *display, const lv_area_t *area, uint8_t *px_map)
{
esp_lcd_panel_handle_t panel_handle = drv->user_data;
#if LV_COLOR_16_SWAP != 1
#warning "LV_COLOR_16_SWAP should be 1 for max performance"
ushort pixels = lv_area_get_size(area);
lv_color16_t *p = color_map;
while (pixels--)
p++->full = (uint16_t)((p->full >> 8) | (p->full << 8));
#endif
ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, area->x1, area->y1, area->x2 + 1, area->y2 + 1, color_map));
esp_lcd_panel_handle_t panel_handle = display->user_data;
uint32_t pixels = lv_area_get_size(area);
uint16_t *p = (uint16_t*)px_map;
while (pixels--) {
*p = (uint16_t)((*p >> 8) | (*p << 8));
p++;
}

ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, area->x1, area->y1, area->x2 + 1, area->y2 + 1, px_map));
};

void lvgl_lcd_init(lv_disp_drv_t *drv)
lv_display_t *lvgl_lcd_init(uint32_t hor_res, uint32_t ver_res)
{
log_v("drv:0x%08x");
lv_display_t *display = lv_display_create(hor_res, ver_res);
log_v("display:0x%08x", display);

// Hardware rotation is supported
drv->sw_rotate = 0;
drv->rotated = LV_DISP_ROT_NONE;
display->sw_rotate = 0;
display->rotation = LV_DISPLAY_ROTATION_0;

// Create SPI bus
const spi_bus_config_t spi_bus_config = {
Expand All @@ -55,7 +56,7 @@ void lvgl_lcd_init(lv_disp_drv_t *drv)
.pclk_hz = ILI9341_SPI_CONFIG_PCLK_HZ,
.trans_queue_depth = ILI9341_SPI_CONFIG_TRANS_QUEUE_DEPTH,
.on_color_trans_done = ili9341_color_trans_done,
.user_ctx = drv,
.user_ctx = display,
.lcd_cmd_bits = ILI9341_SPI_CONFIG_LCD_CMD_BITS,
.lcd_param_bits = ILI9341_SPI_CONFIG_LCD_PARAM_BITS,
.flags = {
Expand Down Expand Up @@ -96,8 +97,10 @@ void lvgl_lcd_init(lv_disp_drv_t *drv)
// Turn display on
ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle, true));

drv->user_data = panel_handle;
drv->flush_cb = ili9341_lv_flush;
display->user_data = panel_handle;
display->flush_cb = ili9341_lv_flush;

return display;
}

#endif
29 changes: 16 additions & 13 deletions src/lvgl_panel_st7262_par.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,26 @@

bool direct_io_frame_trans_done(esp_lcd_panel_handle_t panel, esp_lcd_rgb_panel_event_data_t *edata, void *user_ctx)
{
lv_disp_drv_t *disp_driver = user_ctx;
lv_disp_flush_ready(disp_driver);
lv_display_t *display = user_ctx;
lv_disp_flush_ready(display);
return false;
}

void direct_io_lv_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map)
void direct_io_lv_flush(lv_display_t *display, const lv_area_t *area, uint8_t *px_map)
{
const esp_lcd_panel_handle_t panel_handle = drv->user_data;
const esp_lcd_panel_handle_t panel_handle = display->user_data;
// LV_COLOR_16_SWAP is handled by mapping of the data
ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, area->x1, area->y1, area->x2 + 1, area->y2 + 1, color_map));
ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, area->x1, area->y1, area->x2 + 1, area->y2 + 1, px_map));
};

void lvgl_lcd_init(lv_disp_drv_t *drv)
lv_display_t *lvgl_lcd_init(uint32_t hor_res, uint32_t ver_res)
{
log_v("drv:0x%08x");
lv_display_t *display = lv_display_create(hor_res, ver_res);
log_v("display:0x%08x", display);

// Hardware rotation is NOT supported
drv->sw_rotate = 1;
drv->rotated = LV_DISP_ROT_NONE;
// Hardware rotation is supported
display->sw_rotate = 1;
display->rotation = LV_DISPLAY_ROTATION_0;

// Create direct_io panel handle
const esp_lcd_rgb_panel_config_t rgb_panel_config = {
Expand Down Expand Up @@ -59,7 +60,7 @@ void lvgl_lcd_init(lv_disp_drv_t *drv)
#endif
.disp_gpio_num = ST7262_PANEL_CONFIG_DISP_GPIO_NUM,
.on_frame_trans_done = direct_io_frame_trans_done,
.user_ctx = drv,
.user_ctx = display,
.flags = {.disp_active_low = ST7262_PANEL_CONFIG_FLAGS_DISP_ACTIVE_LOW, .relax_on_idle = ST7262_PANEL_CONFIG_FLAGS_RELAX_ON_IDLE, .fb_in_psram = ST7262_PANEL_CONFIG_FLAGS_FB_IN_PSRAM}
};
log_d("rgb_panel_config: clk_src:%d, timings:{pclk_hz:%d, h_res:%d, v_res:%d, hsync_pulse_width:%d, hsync_back_porch:%d, hsync_front_porch:%d, vsync_pulse_width:%d, vsync_back_porch:%d, vsync_front_porch:%d, flags:{hsync_idle_low:%d, vsync_idle_low:%d, de_idle_high:%d, pclk_active_neg:%d, pclk_idle_high:%d}}, data_width:%d, sram_trans_align:%d, psram_trans_align:%d, hsync_gpio_num:%d, vsync_gpio_num:%d, de_gpio_num:%d, pclk_gpio_num:%d, data_gpio_nums:[%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,], disp_gpio_num:%d, on_frame_trans_done:0x%08x, user_ctx:0x%08x, flags:{disp_active_low:%d, relax_on_idle:%d, fb_in_psram:%d}", rgb_panel_config.clk_src, rgb_panel_config.timings.pclk_hz, rgb_panel_config.timings.h_res, rgb_panel_config.timings.v_res, rgb_panel_config.timings.hsync_pulse_width, rgb_panel_config.timings.hsync_back_porch, rgb_panel_config.timings.hsync_front_porch, rgb_panel_config.timings.vsync_pulse_width, rgb_panel_config.timings.vsync_back_porch, rgb_panel_config.timings.vsync_front_porch, rgb_panel_config.timings.flags.hsync_idle_low, rgb_panel_config.timings.flags.vsync_idle_low, rgb_panel_config.timings.flags.de_idle_high, rgb_panel_config.timings.flags.pclk_active_neg, rgb_panel_config.timings.flags.pclk_idle_high, rgb_panel_config.data_width, rgb_panel_config.sram_trans_align, rgb_panel_config.psram_trans_align, rgb_panel_config.hsync_gpio_num, rgb_panel_config.vsync_gpio_num, rgb_panel_config.de_gpio_num, rgb_panel_config.pclk_gpio_num, rgb_panel_config.data_gpio_nums[0], rgb_panel_config.data_gpio_nums[1], rgb_panel_config.data_gpio_nums[2], rgb_panel_config.data_gpio_nums[3], rgb_panel_config.data_gpio_nums[4], rgb_panel_config.data_gpio_nums[5], rgb_panel_config.data_gpio_nums[6], rgb_panel_config.data_gpio_nums[7], rgb_panel_config.data_gpio_nums[8], rgb_panel_config.data_gpio_nums[9], rgb_panel_config.data_gpio_nums[10], rgb_panel_config.data_gpio_nums[11], rgb_panel_config.data_gpio_nums[12], rgb_panel_config.data_gpio_nums[13], rgb_panel_config.data_gpio_nums[14], rgb_panel_config.data_gpio_nums[15], rgb_panel_config.disp_gpio_num, rgb_panel_config.on_frame_trans_done, rgb_panel_config.user_ctx, rgb_panel_config.flags.disp_active_low, rgb_panel_config.flags.relax_on_idle, rgb_panel_config.flags.fb_in_psram);
Expand All @@ -75,8 +76,10 @@ void lvgl_lcd_init(lv_disp_drv_t *drv)
#if defined(DISPLAY_GAP_X) || defined(DISPLAY_GAP_Y)
ESP_ERROR_CHECK(esp_lcd_panel_set_gap(panel_handle, DISPLAY_GAP_X, DISPLAY_GAP_Y));
#endif
drv->user_data = panel_handle;
drv->flush_cb = direct_io_lv_flush;
display->user_data = panel_handle;
display->flush_cb = direct_io_lv_flush;

return display;
}

#endif
Loading

0 comments on commit 21cdca4

Please sign in to comment.