From a0113e0d5cc59415ac03273ed2eb97a3c2c23aac Mon Sep 17 00:00:00 2001 From: martinberlin Date: Fri, 28 May 2021 20:53:08 +0200 Subject: [PATCH] Setup epdiy_epaper generic driver REF: https://github.com/martinberlin/lv_port_esp32-epaper/issues/2 Flushing too often, drawing only 40 px on top of display --- CMakeLists.txt | 2 ++ CONTRIBUTE_CONTROLLER_SUPPORT.md | 6 ++++ lvgl_helpers.c | 7 +++- lvgl_helpers.h | 2 ++ lvgl_tft/Kconfig | 17 ++++++++- lvgl_tft/disp_driver.c | 11 ++++++ lvgl_tft/epdiy_epaper.cpp | 62 ++++++++++++++++++++++++++++++++ lvgl_tft/epdiy_epaper.h | 37 +++++++++++++++++++ lvgl_tft/il3820.c | 4 +-- 9 files changed, 144 insertions(+), 4 deletions(-) create mode 100644 lvgl_tft/epdiy_epaper.cpp create mode 100644 lvgl_tft/epdiy_epaper.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d86bd33..ffd2871 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,8 @@ list(APPEND SOURCES "lvgl_tft/disp_driver.c") # 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_TFT_DISPLAY_CONTROLLER_ILI9481) list(APPEND SOURCES "lvgl_tft/ili9481.c") elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9486) diff --git a/CONTRIBUTE_CONTROLLER_SUPPORT.md b/CONTRIBUTE_CONTROLLER_SUPPORT.md index db4c647..fa7af3c 100644 --- a/CONTRIBUTE_CONTROLLER_SUPPORT.md +++ b/CONTRIBUTE_CONTROLLER_SUPPORT.md @@ -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. diff --git a/lvgl_helpers.c b/lvgl_helpers.c index 4125330..dc83c99 100644 --- a/lvgl_helpers.c +++ b/lvgl_helpers.c @@ -123,9 +123,14 @@ void lvgl_driver_init(void) 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 Parallel 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 */ diff --git a/lvgl_helpers.h b/lvgl_helpers.h index 70ef353..0fe8487 100644 --- a/lvgl_helpers.h +++ b/lvgl_helpers.h @@ -42,6 +42,8 @@ extern "C" { #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) +#elif defined (CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER) +#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40) #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 diff --git a/lvgl_tft/Kconfig b/lvgl_tft/Kconfig index ddd7f51..4d65114 100644 --- a/lvgl_tft/Kconfig +++ b/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. @@ -85,6 +85,11 @@ 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_TFT_DISPLAY_CONTROLLER_ILI9341 bool help @@ -173,6 +178,11 @@ 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 @@ -257,6 +267,11 @@ 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 + #select LV_TFT_DISPLAY_PROTOCOL_SPI config LV_TFT_DISPLAY_USER_CONTROLLER_ILI9341 bool "ILI9341" diff --git a/lvgl_tft/disp_driver.c b/lvgl_tft/disp_driver.c index 9f8e857..e0d636b 100644 --- a/lvgl_tft/disp_driver.c +++ b/lvgl_tft/disp_driver.c @@ -4,11 +4,15 @@ #include "disp_driver.h" #include "disp_spi.h" +// This should be included with CMakeLists but is not +#include "lvgl_tft/epdiy_epaper.h" 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_TFT_DISPLAY_CONTROLLER_ILI9481 ili9481_init(); #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488 @@ -46,6 +50,8 @@ 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_TFT_DISPLAY_CONTROLLER_ILI9481 ili9481_flush(drv, area, color_map); #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488 @@ -81,8 +87,11 @@ void disp_driver_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * 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_EPAPER_EPDIY_DISPLAY_CONTROLLER + epdiy_rounder(disp_drv, area); #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SH1107 sh1107_rounder(disp_drv, area); #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_IL3820 @@ -99,6 +108,8 @@ void disp_driver_set_px(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_ { #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_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 diff --git a/lvgl_tft/epdiy_epaper.cpp b/lvgl_tft/epdiy_epaper.cpp new file mode 100644 index 0000000..5359dff --- /dev/null +++ b/lvgl_tft/epdiy_epaper.cpp @@ -0,0 +1,62 @@ +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include "epdiy_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; + +/********************* + * DEFINES + *********************/ +#define TAG "EPDIY" + +uint16_t flushcalls = 0; + +/* Display initialization routine */ +void epdiy_init(void) +{ + printf("epdiy_init\n"); + display.init(); + display.setRotation(0); + //display.clearScreen(); +} + +/* Required by LVGL */ +void epdiy_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map) +{ + ++flushcalls; + printf("epdiy_flush %d\n", flushcalls); + display.update(); + /* IMPORTANT!!! + * Inform the graphics library that you are ready with the flushing */ + lv_disp_flush_ready(drv); +} + +/* Called for each pixel */ +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) +{ + // Is printing Y axis only till 40 px: And flushing too many times + //printf("%d ", (int16_t)y); // Works and prints "Hello world" + //printf("%d ",(int16_t)color.full); // Debug colors + // Test using RGB232 + int16_t epd_color = EPD_WHITE; + + // Color setting use: RGB232 + if ((int16_t)color.full<250) { + epd_color = (int16_t)color.full; + } + display.drawPixel((int16_t)x, (int16_t)y, epd_color); +} + +/* Required by LVGL. Not used in this implementation - deprecated, will be removed */ +void epdiy_rounder(lv_disp_drv_t * disp_drv, lv_area_t *area) { +} diff --git a/lvgl_tft/epdiy_epaper.h b/lvgl_tft/epdiy_epaper.h new file mode 100644 index 0000000..1cad34f --- /dev/null +++ b/lvgl_tft/epdiy_epaper.h @@ -0,0 +1,37 @@ +/** + * 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); + +/* 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 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); + +void epdiy_rounder(lv_disp_drv_t * disp_drv, lv_area_t *area); +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* EPDIY_H */ \ No newline at end of file diff --git a/lvgl_tft/il3820.c b/lvgl_tft/il3820.c index 45ae276..4295ae0 100644 --- a/lvgl_tft/il3820.c +++ b/lvgl_tft/il3820.c @@ -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;