diff --git a/.github/workflows/build_examples.yml b/.github/workflows/build_examples.yml deleted file mode 100644 index c1bf26b..0000000 --- a/.github/workflows/build_examples.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: 'build' - -on: [push, pull_request] - -jobs: - build: - strategy: - matrix: - idf_ver: ["v4.1", "v4.2", "v4.3", "v4.4"] - idf_target: ["esp32", "esp32s2", "esp32c3"] - exclude: - - idf_ver: "v4.1" - idf_target: esp32s2 - - idf_ver: "v4.1" - idf_target: esp32c3 - - idf_ver: "v4.2" - idf_target: esp32c3 - runs-on: ubuntu-20.04 - container: espressif/idf:release-${{ matrix.idf_ver }} - steps: - - uses: actions/checkout@v1 - with: - submodules: recursive - - name: Build ESP examples - env: - IDF_TARGET: ${{ matrix.idf_target }} - shell: bash - run: | - cd examples/wemos_lolin_oled/hello_world - . ${IDF_PATH}/export.sh - idf.py build diff --git a/.gitignore b/.gitignore index c2ff946..3c4910f 100644 --- a/.gitignore +++ b/.gitignore @@ -59,4 +59,4 @@ build # Kconfig files sdkconfig -sdkconfig.old +sdkconfig.old \ No newline at end of file diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 61a933b..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "examples/common_components/lvgl"] - path = examples/common_components/lvgl - url = https://github.com/lvgl/lvgl.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f6cd98..14c29c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,38 +3,55 @@ if(ESP_PLATFORM) file(GLOB SOURCES *.c) set(LVGL_INCLUDE_DIRS . lvgl_tft) list(APPEND SOURCES "lvgl_tft/disp_driver.c") -list(APPEND SOURCES "lv_port/esp_lcd_backlight.c") +list(APPEND SOURCES "lvgl_tft/esp_lcd_backlight.c") -# This are the source files used for mcu abstraction -set(LV_PORT_PATH "lv_port") - -list(APPEND SOURCES "${LV_PORT_PATH}/lv_port_display_espressif.c") - -#@todo add SimleInclude macro here - -# Build all display drivers +# 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_TFT_DISPLAY_CONTROLLER_ILI9481) list(APPEND SOURCES "lvgl_tft/ili9481.c") +elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9486) list(APPEND SOURCES "lvgl_tft/ili9486.c") +elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488) list(APPEND SOURCES "lvgl_tft/ili9488.c") +elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7789) list(APPEND SOURCES "lvgl_tft/st7789.c") +elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7735S) list(APPEND SOURCES "lvgl_tft/st7735s.c") +elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7796S) list(APPEND SOURCES "lvgl_tft/st7796s.c") +elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_HX8357) list(APPEND SOURCES "lvgl_tft/hx8357.c") +elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_SH1107) list(APPEND SOURCES "lvgl_tft/sh1107.c") +elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_SSD1306) list(APPEND SOURCES "lvgl_tft/ssd1306.c") +elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X) list(APPEND SOURCES "lvgl_tft/EVE_commands.c") list(APPEND SOURCES "lvgl_tft/FT81x.c") +elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_IL3820) list(APPEND SOURCES "lvgl_tft/il3820.c") +elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_JD79653A) list(APPEND SOURCES "lvgl_tft/jd79653a.c") +elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D) list(APPEND SOURCES "lvgl_tft/uc8151d.c") +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") +elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_SCHMITT) + list(APPEND SOURCES "lvgl_tft/schmitt.c") +else() + message(WARNING "LVGL ESP32 drivers: Display controller not defined.") +endif() if(CONFIG_LV_TFT_DISPLAY_PROTOCOL_SPI) - list(APPEND SOURCES "lv_port/disp_spi.c") + list(APPEND SOURCES "lvgl_tft/disp_spi.c") endif() # Add touch driver to compilation only if it is selected in menuconfig @@ -61,7 +78,7 @@ if(CONFIG_LV_TOUCH_CONTROLLER) endif() if(CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI) - list(APPEND SOURCES "lv_port/tp_spi.c") + list(APPEND SOURCES "lvgl_touch/tp_spi.c") endif() endif() @@ -69,11 +86,9 @@ if(CONFIG_LV_I2C) list(APPEND SOURCES "lvgl_i2c/i2c_manager.c") endif() -list(APPEND LVGL_INCLUDE_DIRS lv_port) - idf_component_register(SRCS ${SOURCES} INCLUDE_DIRS ${LVGL_INCLUDE_DIRS} - REQUIRES lvgl) + REQUIRES lvgl driver esp_common log freertos esp_rom soc) target_compile_definitions(${COMPONENT_LIB} PUBLIC "-DLV_LVGL_H_INCLUDE_SIMPLE") diff --git a/README.md b/README.md index e41ab85..522c0e1 100644 --- a/README.md +++ b/README.md @@ -12,11 +12,6 @@ For a ready to use ESP32 project take look at the [lv_port_esp32](https://github **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). -## MCU Configuration - -Example of SPI/I2C configuration peripherals is done with `lvgl_interface_init`. -Example of display gpios configuration, such as the DC, RST, Backlight is done with `lvgl_display_gpios_init` - ## Supported display controllers diff --git a/display_config.h b/display_config.h deleted file mode 100644 index cdc3374..0000000 --- a/display_config.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef DISPLAY_CONFIG_H_ -#define DISPLAY_CONFIG_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "sdkconfig.h" - -/* Configuration options for ST7789 display controllers */ -#if defined CONFIG_LV_DISP_USE_RST - #if defined CONFIG_LV_DISP_ST7789_SOFT_RESET - #define ST7789_SOFT_RST - #endif -#else - #define ST7789_SOFT_RST -#endif - -#if defined (CONFIG_LV_INVERT_COLORS) -#define ST7789_INVERT_COLORS 1U -#define ILI9341_INVERT_COLORS 1U -#endif - -#define ST7789_INITIAL_ORIENTATION CONFIG_LV_DISPLAY_ORIENTATION - -#if CONFIG_LV_DISP_USE_RST -#define ILI9341_USE_RST -#endif - -#define ILI9341_INITIAL_ORIENTATION CONFIG_LV_DISPLAY_ORIENTATION - -/* ILI9488 Configuration */ -#if CONFIG_LV_DISP_USE_RST -#define ILI9488_USE_RST -#endif - -#define ILI9488_INITIAL_ORIENTATION CONFIG_LV_DISPLAY_ORIENTATION - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* DISPLAY_CONFIG_H_ */ diff --git a/examples/common_components/lvgl b/examples/common_components/lvgl deleted file mode 160000 index 2e94206..0000000 --- a/examples/common_components/lvgl +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2e942060f077de19667ec200afcfd2b32352064b diff --git a/examples/wemos_lolin_oled/hello_world/CMakeLists.txt b/examples/wemos_lolin_oled/hello_world/CMakeLists.txt deleted file mode 100644 index b65f74e..0000000 --- a/examples/wemos_lolin_oled/hello_world/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# For more information about build system see -# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html -# The following five lines of boilerplate have to be in your project's -# CMakeLists in this exact order for cmake to work correctly -cmake_minimum_required(VERSION 3.5) - -set(EXTRA_COMPONENT_DIRS ../../common_components ../../..) -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(hello_world) diff --git a/examples/wemos_lolin_oled/hello_world/main/CMakeLists.txt b/examples/wemos_lolin_oled/hello_world/main/CMakeLists.txt deleted file mode 100644 index 4e8dbcf..0000000 --- a/examples/wemos_lolin_oled/hello_world/main/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -idf_component_register(SRCS "hello_world.c" - INCLUDE_DIRS ".") diff --git a/examples/wemos_lolin_oled/hello_world/main/hello_world.c b/examples/wemos_lolin_oled/hello_world/main/hello_world.c deleted file mode 100644 index 9e573b9..0000000 --- a/examples/wemos_lolin_oled/hello_world/main/hello_world.c +++ /dev/null @@ -1,110 +0,0 @@ -/* Hello world on Wemos Lolin32 board - * - * This example code is in the Public Domain (or CC0 licensed, at your option.) - * - * Unless required by applicable law or agreed to in writing, this - * software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. - */ -#include -#include -#include -#include - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "esp_freertos_hooks.h" -#include "freertos/semphr.h" -#include "esp_system.h" -#include "driver/gpio.h" - -/* Littlevgl specific */ -#ifdef LV_LVGL_H_INCLUDE_SIMPLE -#include "lvgl.h" -#else -#include "lvgl/lvgl.h" -#endif - -#include "lvgl_helpers.h" - -/********************* - * DEFINES - *********************/ -#define LV_TICK_PERIOD_MS 1 - -/********************** - * STATIC PROTOTYPES - **********************/ -static void lvgl_tick_inc(void *arg); -static void guiTask(void *pvParameter); - -/********************** - * APPLICATION MAIN - **********************/ -void app_main() -{ - xTaskCreatePinnedToCore(guiTask, "gui", 4096*2, NULL, 0, NULL, 1); -} - -static void guiTask(void *pvParameter) -{ - (void) pvParameter; - lv_init(); - - /* Initialize the needed peripherals */ - lvgl_interface_init(); - /* Initialize needed GPIOs, e.g. backlight, reset GPIOs */ - lvgl_display_gpios_init(); - - /* ToDo Initialize used display driver passing registered lv_disp_drv_t as parameter */ - - size_t display_buffer_size = lvgl_get_display_buffer_size(); - lv_color_t* buf1 = heap_caps_malloc(display_buffer_size * sizeof(lv_color_t), MALLOC_CAP_DMA); - assert(buf1 != NULL); - - static lv_disp_draw_buf_t disp_buf; - lv_disp_draw_buf_init(&disp_buf, buf1, NULL, display_buffer_size * 8); - - lv_disp_drv_t disp_drv; - lv_disp_drv_init(&disp_drv); - disp_drv.flush_cb = disp_driver_flush; - disp_drv.rounder_cb = disp_driver_rounder; - disp_drv.set_px_cb = disp_driver_set_px; - disp_drv.draw_buf = &disp_buf; - /* LVGL v8: Set display horizontal and vertical resolution (in pixels), it's no longer done with lv_conf.h */ - disp_drv.hor_res = 128u; - disp_drv.ver_res = 64u; - lv_disp_drv_register(&disp_drv); - - /* Create and start a periodic timer interrupt to call lv_tick_inc */ - const esp_timer_create_args_t periodic_timer_args = { - .callback = &lvgl_tick_inc, - .name = "lvgl_tick" - }; - esp_timer_handle_t periodic_timer; - ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer)); - ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, LV_TICK_PERIOD_MS * 1000)); - - /* Create a Hellow World label on the currently active screen */ - lv_obj_t *scr = lv_disp_get_scr_act(NULL); - - /* LVGL v8 lv_label_create no longer takes 2 parameters */ - lv_obj_t *label1 = lv_label_create(scr); - lv_label_set_text(label1, "Hello\nworld"); - - /* Align the Label to the center - * NULL means align on parent (which is the screen now) - * 0, 0 at the end means an x, y offset after alignment*/ - lv_obj_align(label1, LV_ALIGN_CENTER, 0, 0); - - while (1) { - vTaskDelay(pdMS_TO_TICKS(10)); - lv_task_handler(); - } - free(buf1); -} - -static void lvgl_tick_inc(void *arg) { - (void) arg; - lv_tick_inc(LV_TICK_PERIOD_MS); -} diff --git a/examples/wemos_lolin_oled/hello_world/sdkconfig.defaults b/examples/wemos_lolin_oled/hello_world/sdkconfig.defaults deleted file mode 100644 index b92d2d5..0000000 --- a/examples/wemos_lolin_oled/hello_world/sdkconfig.defaults +++ /dev/null @@ -1,11 +0,0 @@ -CONFIG_LV_HOR_RES_MAX=128 -CONFIG_LV_VER_RES_MAX=64 -CONFIG_LV_COLOR_DEPTH_1=y -CONFIG_LV_THEME_MONO=y - -CONFIG_LV_PREDEFINED_DISPLAY_WEMOS_LOLIN=y - -CONFIG_I2C_MANAGER_0_ENABLED=y -CONFIG_I2C_MANAGER_0_SDA=5 -CONFIG_I2C_MANAGER_0_SCL=4 -CONFIG_I2C_MANAGER_0_FREQ_HZ=100000 diff --git a/lv_port/lv_port_display_espressif.c b/lv_port/lv_port_display_espressif.c deleted file mode 100644 index 1684767..0000000 --- a/lv_port/lv_port_display_espressif.c +++ /dev/null @@ -1,57 +0,0 @@ -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" - -#include "display_port.h" - -#include "sdkconfig.h" -#include "driver/gpio.h" - -void display_port_delay(lv_disp_drv_t *drv, uint32_t delay_ms) -{ - (void) drv; - - vTaskDelay(pdMS_TO_TICKS(delay_ms)); -} - -void display_port_backlight(lv_disp_drv_t *drv, uint8_t state) -{ - (void) drv; - -#ifdef CONFIG_LV_DISP_PIN_BCKL - gpio_set_level(CONFIG_LV_DISP_PIN_BCKL, state); -#endif -} - -void display_port_gpio_dc(lv_disp_drv_t *drv, uint8_t state) -{ - (void) drv; - -#ifdef CONFIG_LV_DISPLAY_USE_DC - gpio_set_level(CONFIG_LV_DISP_PIN_DC, state); -#endif -} - -void display_port_gpio_rst(lv_disp_drv_t *drv, uint8_t state) -{ - (void) drv; - -#ifdef CONFIG_LV_DISP_USE_RST - gpio_set_level(CONFIG_LV_DISP_PIN_RST, state); -#endif -} - -bool display_port_gpio_is_busy(lv_disp_drv_t *drv) -{ - (void) drv; - - bool device_busy = false; - -#ifdef CONFIG_LV_DISP_PIN_BUSY - /* FIXME Assuming the busy signal in logic 1 means the device is busy */ - if (gpio_get_level(CONFIG_LV_DISP_PIN_BUSY) == 1) { - device_busy = true; - } -#endif - - return device_busy; -} diff --git a/lvgl_helpers.c b/lvgl_helpers.c index 3839af1..4f220d4 100644 --- a/lvgl_helpers.c +++ b/lvgl_helpers.c @@ -6,16 +6,12 @@ /********************* * INCLUDES *********************/ -#include "lvgl_helpers.h" - #include "sdkconfig.h" - -#include "driver/spi_common.h" +#include "lvgl_helpers.h" #include "esp_log.h" -#include "esp_idf_version.h" -#include "disp_spi.h" -#include "tp_spi.h" +#include "lvgl_tft/disp_spi.h" +#include "lvgl_touch/tp_spi.h" #include "lvgl_spi_conf.h" @@ -33,8 +29,6 @@ #define TAG "lvgl_helpers" -#define GPIO_NOT_USED (-1) -#define DMA_DEFAULT_TRANSFER_SIZE (0u) /********************** * TYPEDEFS **********************/ @@ -43,20 +37,6 @@ * STATIC PROTOTYPES **********************/ -/** - * Calculates the SPI max transfer size based on the display buffer size - * - * @return SPI max transfer size in bytes - */ -static int calculate_spi_max_transfer_size(const int display_buffer_size); - -#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X) -/** - * Handle FT81X initialization as it's a particular case - */ -static void init_ft81x(int dma_channel); -#endif - /********************** * STATIC VARIABLES **********************/ @@ -69,8 +49,8 @@ static void init_ft81x(int dma_channel); * GLOBAL FUNCTIONS **********************/ -/* Interface (SPI, I2C) initialization */ -void lvgl_interface_init(void) +/* 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. */ @@ -78,174 +58,87 @@ void lvgl_interface_init(void) ESP_LOGI(TAG, "Display hor size: %d, ver size: %d", LV_HOR_RES_MAX, LV_VER_RES_MAX); #endif - size_t display_buffer_size = lvgl_get_display_buffer_size(); - - ESP_LOGI(TAG, "Display buffer size: %d", display_buffer_size); + ESP_LOGI(TAG, "Display buffer size: %d", DISP_BUF_SIZE); #if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X) - init_ft81x(dma_channel); + ESP_LOGI(TAG, "Initializing SPI master for FT81X"); + + 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(); + +#if defined (CONFIG_LV_TOUCH_CONTROLLER_FT81X) + touch_driver_init(); +#endif + return; #endif -/* Display controller initialization */ -#if defined (CONFIG_LV_TFT_DISPLAY_PROTOCOL_SPI) || defined (SHARED_SPI_BUS) - ESP_LOGI(TAG, "Initializing SPI master"); - - int miso = DISP_SPI_MISO; - int spi_max_transfer_size = calculate_spi_max_transfer_size(display_buffer_size); - - /* Set the miso signal to be the selected for the touch driver */ #if defined (SHARED_SPI_BUS) - miso = TP_SPI_MISO; -#endif + ESP_LOGI(TAG, "Initializing shared SPI master"); - // We use DMA channel 1 for all cases - lvgl_spi_driver_init(TFT_SPI_HOST, miso, DISP_SPI_MOSI, DISP_SPI_CLK, - spi_max_transfer_size, 1, DISP_SPI_IO2, DISP_SPI_IO3); + lvgl_spi_driver_init(TFT_SPI_HOST, + TP_SPI_MISO, DISP_SPI_MOSI, DISP_SPI_CLK, + SPI_BUS_MAX_TRANSFER_SZ, 1, + -1, -1); disp_spi_add_device(TFT_SPI_HOST); - - /* Add device for touch driver */ -#if defined (SHARED_SPI_BUS) tp_spi_add_device(TOUCH_SPI_HOST); + + 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) + disp_driver_init(); #else #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"); + #if defined (CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI) + ESP_LOGI(TAG, "Initializing SPI master for touch"); -#if defined (CONFIG_IDF_TARGET_ESP32) - dma_channel = 2; -#endif + lvgl_spi_driver_init(TOUCH_SPI_HOST, + TP_SPI_MISO, TP_SPI_MOSI, TP_SPI_CLK, + 0 /* Defaults to 4094 */, 2, + -1, -1); - lvgl_spi_driver_init(TOUCH_SPI_HOST, TP_SPI_MISO, TP_SPI_MOSI, TP_SPI_CLK, - DMA_DEFAULT_TRANSFER_SIZE, dma_channel, GPIO_NOT_USED, GPIO_NOT_USED); + tp_spi_add_device(TOUCH_SPI_HOST); - tp_spi_add_device(TOUCH_SPI_HOST); - - touch_driver_init(); -#elif defined (CONFIG_LV_I2C_TOUCH) - touch_driver_init(); -#elif defined (CONFIG_LV_TOUCH_DRIVER_ADC) - touch_driver_init(); -#elif defined (CONFIG_LV_TOUCH_DRIVER_DISPLAY) - touch_driver_init(); -#else -#error "No protocol defined for touch controller" -#endif + touch_driver_init(); + #elif defined (CONFIG_LV_I2C_TOUCH) + touch_driver_init(); + #elif defined (CONFIG_LV_TOUCH_DRIVER_ADC) + touch_driver_init(); + #elif defined (CONFIG_LV_TOUCH_DRIVER_DISPLAY) + touch_driver_init(); + #else + #error "No protocol defined for touch controller" + #endif #else #endif } -void lvgl_display_gpios_init(void) -{ - esp_err_t err = ESP_OK; - gpio_config_t io_conf = { - .pull_up_en = GPIO_PULLUP_DISABLE, - .pull_down_en = GPIO_PULLDOWN_DISABLE, - .intr_type = GPIO_INTR_DISABLE, - }; - -#ifdef CONFIG_LV_DISPLAY_USE_DC - io_conf.mode = GPIO_MODE_OUTPUT; - io_conf.pin_bit_mask = (1ULL << CONFIG_LV_DISP_PIN_DC); - err = gpio_config(&io_conf); - ESP_ERROR_CHECK(err); -#endif - -#ifdef CONFIG_LV_DISP_USE_RST - io_conf.mode = GPIO_MODE_OUTPUT; - io_conf.pin_bit_mask = (1ULL << CONFIG_LV_DISP_PIN_RST); - err = gpio_config(&io_conf); - ESP_ERROR_CHECK(err); -#endif - -#if !defined(CONFIG_LV_DISP_BACKLIGHT_OFF) && defined(CONFIG_LV_DISP_PIN_BCKL) && \ - (CONFIG_LV_DISP_PIN_BCKL > 0) - io_conf.mode = GPIO_MODE_OUTPUT; - io_conf.pin_bit_mask = (1ULL << CONFIG_LV_DISP_PIN_BCKL); - err = gpio_config(&io_conf); - ESP_ERROR_CHECK(err); -#endif - -#ifdef CONFIG_LV_DISP_USE_BUSY - io_conf.mode = GPIO_MODE_INPUT; - io_conf.pin_bit_mask = (1ULL << CONFIG_LV_DISP_PIN_BUSY); - err = gpio_config(&io_conf); - ESP_ERROR_CHECK(err); -#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 - * were the values working for the contributor of the display controller. - * - * As LVGL supports partial display updates the DISP_BUF_SIZE doesn't - * necessarily need to be equal to the display size. - * - * When using RGB displays the display buffer size will also depends on the - * 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. */ -size_t lvgl_get_display_buffer_size(void) -{ - size_t disp_buffer_size = 0; - -#if LVGL_VERSION_MAJOR < 8 -#if defined (CONFIG_CUSTOM_DISPLAY_BUFFER_SIZE) - disp_buffer_size = CONFIG_CUSTOM_DISPLAY_BUFFER_BYTES; -#else - /* Calculate total of 40 lines of display horizontal size */ -#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7789) || \ - defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7735S) || \ - defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7796S) || \ - defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_HX8357) || \ - defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481) || \ - defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9486) || \ - defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488) || \ - defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341) || \ - defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X) || \ - defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_RA8875) || \ - defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_GC9A01) || \ - defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9163C) - disp_buffer_size = LV_HOR_RES_MAX * 40; -#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SH1107 - disp_buffer_size = LV_HOR_RES_MAX * LV_VER_RES_MAX; -#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SSD1306 -#if defined (CONFIG_LV_THEME_MONO) - disp_buffer_size = LV_HOR_RES_MAX * (LV_VER_RES_MAX / 8); -#else - disp_buffer_size = LV_HOR_RES_MAX * LV_VER_RES_MAX); -#endif -#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_IL3820) - disp_buffer_size = LV_VER_RES_MAX * IL3820_COLUMNS; -#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_JD79653A) - disp_buffer_size = ((LV_VER_RES_MAX * LV_VER_RES_MAX) / 8); // 5KB -#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D) - disp_buffer_size = ((LV_VER_RES_MAX * LV_VER_RES_MAX) / 8); // 2888 bytes -#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_PCD8544) - disp_buffer_size = (LV_HOR_RES_MAX * (LV_VER_RES_MAX / 8)); -#else -#error "No display controller selected" -#endif -#endif - -#else /* LVGL v8 */ - /* ToDo: Implement display buffer size calculation with configuration values from the display driver */ - disp_buffer_size = 320*40; // Reasonable for start -#endif - - return disp_buffer_size; -} /* Initialize spi bus master * @@ -261,6 +154,7 @@ bool lvgl_spi_driver_init(int host, int dma_channel, int quadwp_pin, int quadhd_pin) { + assert((0 <= host) && (3 > host)); const char *spi_names[] = { "SPI1_HOST", "SPI2_HOST", "SPI3_HOST" }; @@ -281,49 +175,11 @@ bool lvgl_spi_driver_init(int host, }; ESP_LOGI(TAG, "Initializing SPI bus..."); - esp_err_t ret = spi_bus_initialize((spi_host_device_t) host, &buscfg, dma_channel); + #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); assert(ret == ESP_OK); return ESP_OK != ret; } - -static int calculate_spi_max_transfer_size(const int display_buffer_size) -{ - int retval = 0; - -#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481) || \ - defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488) - retval = display_buffer_size * 3; -#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341) || \ - defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7789) || \ - defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7735S) || \ - defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_HX8357) || \ - 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) - retval = display_buffer_size * 2; -#else - retval = display_buffer_size * 2; -#endif - - return retval; -} - -#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X) -static void init_ft81x(int dma_channel) -{ - size_t display_buffer_size = lvgl_get_display_buffer_size(); - int spi_max_transfer_size = calculate_spi_max_transfer_size(display_buffer_size); - - lvgl_spi_driver_init(TFT_SPI_HOST, DISP_SPI_MISO, DISP_SPI_MOSI, DISP_SPI_CLK, - spi_max_transfer_size, dma_channel, DISP_SPI_IO2, DISP_SPI_IO3); - - disp_spi_add_device(TFT_SPI_HOST); - -#if defined (CONFIG_LV_TOUCH_CONTROLLER_FT81X) - touch_driver_init(); -#endif -} -#endif diff --git a/lvgl_helpers.h b/lvgl_helpers.h index c166a23..eeea580 100644 --- a/lvgl_helpers.h +++ b/lvgl_helpers.h @@ -23,6 +23,68 @@ extern "C" { * DEFINES *********************/ +/* 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 + * were the values working for the contributor of the display controller. + * + * As LVGL supports partial display updates the DISP_BUF_SIZE doesn't + * necessarily need to be equal to the display size. + * + * When using RGB displays the display buffer size will also depends on the + * 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. */ +#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) +#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) +#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 +#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) +#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9486 +#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40) +#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488 +#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40) +#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341 +#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40) +#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 +#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) +#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_GC9A01) +#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40) +#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) +#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_PCD8544) +#define DISP_BUF_SIZE (LV_HOR_RES_MAX * (LV_VER_RES_MAX / 8)) +#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_SCHMITT) +#define DISP_BUF_SIZE (LV_HOR_RES_MAX * LV_VER_RES_MAX) +#else +#error "No display controller selected" +#endif +#endif + /********************** * TYPEDEFS **********************/ @@ -34,18 +96,12 @@ extern "C" { void lvgl_i2c_locking(void* leader); /* Initialize detected SPI and I2C bus and devices */ -void lvgl_interface_init(void); +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 display GPIOs, e.g. DC and RST pins */ -void lvgl_display_gpios_init(void); - -/* Get display buffer size */ -size_t lvgl_get_display_buffer_size(void); - /********************** * MACROS **********************/ diff --git a/lvgl_i2c/i2c_manager.c b/lvgl_i2c/i2c_manager.c index 441eef1..080d81a 100644 --- a/lvgl_i2c/i2c_manager.c +++ b/lvgl_i2c/i2c_manager.c @@ -66,8 +66,8 @@ static const uint8_t ACK_CHECK_EN = 1; #define I2C_MANAGER_0_PULLUPS false #endif - #define I2C_MANAGER_0_TIMEOUT ( pdMS_TO_TICKS( CONFIG_I2C_MANAGER_0_TIMEOUT ) ) - #define I2C_MANAGER_0_LOCK_TIMEOUT ( pdMS_TO_TICKS( CONFIG_I2C_MANAGER_0_LOCK_TIMEOUT ) ) + #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 ) #endif @@ -79,8 +79,8 @@ static const uint8_t ACK_CHECK_EN = 1; #define I2C_MANAGER_1_PULLUPS false #endif - #define I2C_MANAGER_1_TIMEOUT ( pdMS_TO_TICKS( CONFIG_I2C_MANAGER_1_TIMEOUT ) ) - #define I2C_MANAGER_1_LOCK_TIMEOUT ( pdMS_TO_TICKS( CONFIG_I2C_MANAGER_1_LOCK_TIMEOUT ) ) + #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 ) #endif #define ERROR_PORT(port, fail) { \ @@ -222,7 +222,7 @@ esp_err_t I2C_FN(_read)(i2c_port_t port, uint16_t addr, uint32_t reg, uint8_t *b } if (result != ESP_OK) { - ESP_LOGD(TAG, "Error: %d", result); + ESP_LOGW(TAG, "Error: %d", result); } ESP_LOG_BUFFER_HEX_LEVEL(TAG, buffer, size, ESP_LOG_VERBOSE); @@ -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 = pdMS_TO_TICKS( CONFIG_I2C_MANAGER_0_TIMEOUT ); + timeout = (CONFIG_I2C_MANAGER_0_TIMEOUT) / portTICK_RATE_MS; } #endif #if defined (I2C_ONE) if (port == I2C_NUM_1) { - timeout = pdMS_TO_TICKS( CONFIG_I2C_MANAGER_1_TIMEOUT ); + timeout = (CONFIG_I2C_MANAGER_1_TIMEOUT) / portTICK_RATE_MS; } #endif @@ -271,7 +271,7 @@ esp_err_t I2C_FN(_write)(i2c_port_t port, uint16_t addr, uint32_t reg, const uin } if (result != ESP_OK) { - ESP_LOGD(TAG, "Error: %d", result); + ESP_LOGW(TAG, "Error: %d", result); } ESP_LOG_BUFFER_HEX_LEVEL(TAG, buffer, size, ESP_LOG_VERBOSE); @@ -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 = pdMS_TO_TICKS( CONFIG_I2C_MANAGER_0_LOCK_TIMEOUT ); + timeout = (CONFIG_I2C_MANAGER_0_LOCK_TIMEOUT) / portTICK_RATE_MS; } #endif #if defined (I2C_ONE) if (port == I2C_NUM_1) { - timeout = pdMS_TO_TICKS( CONFIG_I2C_MANAGER_1_LOCK_TIMEOUT ); + timeout = (CONFIG_I2C_MANAGER_1_LOCK_TIMEOUT) / portTICK_RATE_MS; } #endif diff --git a/lvgl_spi_conf.h b/lvgl_spi_conf.h index 1abf623..2754d58 100644 --- a/lvgl_spi_conf.h +++ b/lvgl_spi_conf.h @@ -6,8 +6,6 @@ #ifndef LVGL_SPI_CONF_H #define LVGL_SPI_CONF_H -#include - #ifdef __cplusplus extern "C" { #endif @@ -20,32 +18,25 @@ extern "C" { * DEFINES *********************/ // DISPLAY PINS - -/* Mandatory pins are MOSI and CLK */ #define DISP_SPI_MOSI CONFIG_LV_DISP_SPI_MOSI -#define DISP_SPI_CLK CONFIG_LV_DISP_SPI_CLK - -/* Optional pins */ #if defined (CONFIG_LV_DISPLAY_USE_SPI_MISO) -#define DISP_SPI_MISO CONFIG_LV_DISP_SPI_MISO -#define DISP_SPI_INPUT_DELAY_NS CONFIG_LV_DISP_SPI_INPUT_DELAY_NS + #define DISP_SPI_MISO CONFIG_LV_DISP_SPI_MISO + #define DISP_SPI_INPUT_DELAY_NS CONFIG_LV_DISP_SPI_INPUT_DELAY_NS #else -#define DISP_SPI_MISO (-1) -#define DISP_SPI_INPUT_DELAY_NS (0U) + #define DISP_SPI_MISO (-1) + #define DISP_SPI_INPUT_DELAY_NS (0) #endif - #if defined(CONFIG_LV_DISP_SPI_IO2) #define DISP_SPI_IO2 CONFIG_LV_DISP_SPI_IO2 #else #define DISP_SPI_IO2 (-1) #endif - #if defined(CONFIG_LV_DISP_SPI_IO3) #define DISP_SPI_IO3 CONFIG_LV_DISP_SPI_IO3 #else #define DISP_SPI_IO3 (-1) #endif - +#define DISP_SPI_CLK CONFIG_LV_DISP_SPI_CLK #if defined (CONFIG_LV_DISPLAY_USE_SPI_CS) #define DISP_SPI_CS CONFIG_LV_DISP_SPI_CS #else @@ -59,38 +50,24 @@ extern "C" { #if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X) && \ defined (CONFIG_LV_TOUCH_CONTROLLER_FT81X) -#define SHARED_SPI_BUS - -#define TP_SPI_MOSI CONFIG_LV_DISP_SPI_MOSI -#define TP_SPI_MISO CONFIG_LV_DISP_SPI_MISO -#define TP_SPI_CLK CONFIG_LV_DISP_SPI_CLK -#define TP_SPI_CS CONFIG_LV_DISP_SPI_CS + #define TP_SPI_MOSI CONFIG_LV_DISP_SPI_MOSI + #define TP_SPI_MISO CONFIG_LV_DISP_SPI_MISO + #define TP_SPI_CLK CONFIG_LV_DISP_SPI_CLK + #define TP_SPI_CS CONFIG_LV_DISP_SPI_CS #else -#define TP_SPI_MOSI CONFIG_LV_TOUCH_SPI_MOSI -#define TP_SPI_MISO CONFIG_LV_TOUCH_SPI_MISO -#define TP_SPI_CLK CONFIG_LV_TOUCH_SPI_CLK -#define TP_SPI_CS CONFIG_LV_TOUCH_SPI_CS + #define TP_SPI_MOSI CONFIG_LV_TOUCH_SPI_MOSI + #define TP_SPI_MISO CONFIG_LV_TOUCH_SPI_MISO + #define TP_SPI_CLK CONFIG_LV_TOUCH_SPI_CLK + #define TP_SPI_CS CONFIG_LV_TOUCH_SPI_CS #endif #endif #define ENABLE_TOUCH_INPUT CONFIG_LV_ENABLE_TOUCH -#if defined (CONFIG_LV_TFT_DISPLAY_PROTOCOL_SPI) -/* Display controller SPI host configuration */ #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 -#else -#error SPI host not defined -#endif -#endif - -/* Touch controller SPI host configuration */ -#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 #endif #if defined (CONFIG_LV_TFT_DISPLAY_SPI_HALF_DUPLEX) @@ -107,34 +84,61 @@ extern "C" { #define DISP_SPI_TRANS_MODE_SIO #endif -/* Detect usage of shared SPI bus between display and indev controllers - * - * If the user sets the same MOSI and CLK pins for both display and indev - * controllers then we can assume the user is using the same SPI bus - * If so verify the user specified the same SPI bus for both */ #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 #endif -#if defined (CONFIG_LV_TFT_DISPLAY_PROTOCOL_SPI) && \ - (CONFIG_LV_TFT_DISPLAY_PROTOCOL_SPI == 1) && \ - defined (CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI) && \ - (TP_SPI_MOSI == DISP_SPI_MOSI) && (TP_SPI_CLK == DISP_SPI_CLK) +/* Handle the FT81X Special case */ +#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X) +#if defined (CONFIG_LV_TOUCH_CONTROLLER_FT81X) +#define SHARED_SPI_BUS +#else +/* Empty */ +#endif + +#else +// 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 -#else +#endif + #define SHARED_SPI_BUS #endif -#endif #endif /********************** * TYPEDEFS **********************/ +#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_SCHMITT) + +#define SPI_BUS_MAX_TRANSFER_SZ (DISP_BUF_SIZE * 4) + +#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481) || \ + defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488) + +#define SPI_BUS_MAX_TRANSFER_SZ (DISP_BUF_SIZE * 3) + +#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341) || \ + defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7789) || \ + defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7735S) || \ + defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_HX8357) || \ + 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) + +#define SPI_BUS_MAX_TRANSFER_SZ (DISP_BUF_SIZE * 2) + +#else +#define SPI_BUS_MAX_TRANSFER_SZ (DISP_BUF_SIZE * 2) +#endif + #if defined (CONFIG_LV_TFT_USE_CUSTOM_SPI_CLK_DIVIDER) #define SPI_TFT_CLOCK_SPEED_HZ ((80 * 1000 * 1000) / CONFIG_LV_TFT_CUSTOM_SPI_CLK_DIVIDER) #else @@ -155,33 +159,31 @@ extern "C" { #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) +#define SPI_TFT_CLOCK_SPEED_HZ (40 * 1000 * 1000) #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) +#define SPI_TFT_CLOCK_SPEED_HZ (5*1000*1000) // Set to 40 later +#endif + #endif -#endif /* CONFIG_LV_TFT_USE_CUSTOM_SPI_CLK_DIVIDER */ -#if defined (CONFIG_LV_TFT_DISPLAY_USE_CUSTOM_SPI_MODE) -#define SPI_TFT_SPI_MODE (CONFIG_LV_TFT_DISPLAY_CUSTOM_SPI_MODE) -#else #if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7789) -#define SPI_TFT_SPI_MODE (2U) +#define SPI_TFT_SPI_MODE (2) #else -#define SPI_TFT_SPI_MODE (0U) +#define SPI_TFT_SPI_MODE (0) #endif /* Touch driver */ #if (CONFIG_LV_TOUCH_CONTROLLER == TOUCH_CONTROLLER_STMPE610) #define SPI_TOUCH_CLOCK_SPEED_HZ (1*1000*1000) -#define SPI_TOUCH_SPI_MODE (1U) +#define SPI_TOUCH_SPI_MODE (1) #else #define SPI_TOUCH_CLOCK_SPEED_HZ (2*1000*1000) -#define SPI_TOUCH_SPI_MODE (0U) +#define SPI_TOUCH_SPI_MODE (0) #endif /********************** diff --git a/lvgl_tft/EVE_commands.c b/lvgl_tft/EVE_commands.c index 6c7a083..2a93efa 100644 --- a/lvgl_tft/EVE_commands.c +++ b/lvgl_tft/EVE_commands.c @@ -41,11 +41,6 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #include -#include - -#if defined (BT81X_ENABLE) -#include -#endif #include "EVE.h" #include "EVE_commands.h" @@ -55,8 +50,19 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #include "driver/gpio.h" #include "esp_log.h" #include "soc/soc_memory_layout.h" + +#include "esp_log.h" + #include "disp_spi.h" +#include + +#if defined (BT81X_ENABLE) +#include +#endif + +#define TAG_LOG "FT81X" + /* data structure for SPI reading that has (optional) space for inserted dummy byte */ typedef struct _spi_read_data { #if defined(DISP_SPI_FULL_DUPLEX) @@ -267,13 +273,7 @@ void EVE_memWrite_buffer(uint32_t ftAddress, const uint8_t *data, uint32_t len, uint32_t bytes_left = len; while(bytes_left > 0) { - uint32_t block_len = 0; - -#if defined (SPI_TRANSFER_SIZE) - block_len = (bytes_left > SPI_TRANSER_SIZE ? SPI_TRANSER_SIZE : bytes_left); -#else - /* ToDo Update SPI_TRANSFER_SIZE calculation, it's based on the DISP_BUF_SIZE */ -#endif + uint32_t block_len = (bytes_left > SPI_TRANSER_SIZE ? SPI_TRANSER_SIZE : bytes_left); // only send flush on last chunk disp_spi_send_flag_t flush_flag = 0; @@ -334,6 +334,7 @@ uint8_t EVE_busy(void) cmdOffset += 8; + BUFFER_SPI_BYTE BUFFER_SPI_BYTE(MEM_WRITE | 0x30); /* send Memory Write plus high address byte of REG_CMD_WRITE for EVE81x */ BUFFER_SPI_BYTE(0x20); /* send middle address byte of REG_CMD_WRITE for EVE81x */ BUFFER_SPI_BYTE(0xfc); /* send low address byte of REG_CMD_WRITE for EVE81x */ @@ -874,13 +875,13 @@ uint8_t EVE_init(void) /* The most reliable DIO/QIO switching point is after EVE start up but before reading the ChipID. */ #if defined(DISP_SPI_TRANS_MODE_DIO) - LV_LOG_INFO("Switching to DIO mode"); + ESP_LOGI(TAG_LOG, "Switching to DIO mode"); DELAY_MS(20); /* different boards may take a different delay but this generally seems to work */ EVE_memWrite16(REG_SPI_WIDTH, SPI_WIDTH_DIO); SPIInherentSendFlags = DISP_SPI_MODE_DIO | DISP_SPI_MODE_DIOQIO_ADDR; SPIDummyReadBits = 4; /* Esp32 DMA SPI transaction dummy_bits works more like clock cycles, so in DIO 4 dummy_bits == 8 total bits */ #elif defined(DISP_SPI_TRANS_MODE_QIO) - LV_LOG_INFO("Switching to QIO mode"); + ESP_LOGI(TAG_LOG, "Switching to QIO mode"); DELAY_MS(20); /* different boards may take a different delay but this generally seems to work */ EVE_memWrite16(REG_SPI_WIDTH, SPI_WIDTH_QIO); SPIInherentSendFlags = DISP_SPI_MODE_QIO | DISP_SPI_MODE_DIOQIO_ADDR; @@ -896,7 +897,7 @@ uint8_t EVE_init(void) timeout++; if(timeout > 400) { - LV_LOG_WARN("Failed to read ChipID...aborting initialization."); + ESP_LOGI(TAG_LOG, "Failed to read ChipID...aborting initialization."); return 0; } } @@ -908,7 +909,7 @@ uint8_t EVE_init(void) timeout++; if(timeout > 50) /* experimental, 10 was the lowest value to get the BT815 started with, the touch-controller was the last to get out of reset */ { - LV_LOG_WARN("Failed to read CPU status...aborting initialization."); + ESP_LOGI(TAG_LOG, "Failed to read CPU status...aborting initialization."); return 0; } } diff --git a/lvgl_tft/EVE_config.h b/lvgl_tft/EVE_config.h index af7e305..386edb9 100644 --- a/lvgl_tft/EVE_config.h +++ b/lvgl_tft/EVE_config.h @@ -51,11 +51,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #define EVE_PDN CONFIG_LV_DISP_PIN_RST // grey #define EVE_USE_PDN CONFIG_LV_DISP_USE_RST -#if defined (DISP_BUF_SIZE) #define SPI_TRANSER_SIZE (DISP_BUF_SIZE * (LV_COLOR_DEPTH / 8)) -#else - /* ToDo Update using new API */ -#endif #define BYTES_PER_PIXEL (LV_COLOR_DEPTH / 8) // bytes per pixel for (16 for RGB565) #define BYTES_PER_LINE (EVE_HSIZE * BYTES_PER_PIXEL) @@ -212,8 +208,6 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #define EVE_SUNFLOWER #elif defined(CONFIG_LV_FT81X_CONFIG_EVE_CONNECTEVE) #define EVE_CONNECTEVE -#else -#define EVE_EVE2_35 // Define something if there is no Kconfig option selected #endif /* display timing parameters below */ diff --git a/lvgl_tft/FT81x.c b/lvgl_tft/FT81x.c index a809665..63e0dee 100644 --- a/lvgl_tft/FT81x.c +++ b/lvgl_tft/FT81x.c @@ -2,7 +2,6 @@ #include #include "driver/gpio.h" -#include "esp_idf_version.h" #include "FT81x.h" @@ -264,11 +263,7 @@ void TFT_bitmap_display(void) void FT81x_init(void) { #if EVE_USE_PDN -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) - esp_rom_gpio_pad_select_gpio(EVE_PDN); -#else gpio_pad_select_gpio(EVE_PDN); -#endif #endif gpio_set_level(EVE_CS, 1); diff --git a/lvgl_tft/GC9A01.c b/lvgl_tft/GC9A01.c index c269d0a..c807233 100644 --- a/lvgl_tft/GC9A01.c +++ b/lvgl_tft/GC9A01.c @@ -16,6 +16,7 @@ /********************* * DEFINES *********************/ + #define TAG "GC9A01" /********************** * TYPEDEFS @@ -36,7 +37,6 @@ static void GC9A01_set_orientation(uint8_t orientation); static void GC9A01_send_cmd(uint8_t cmd); static void GC9A01_send_data(void * data, uint16_t length); static void GC9A01_send_color(void * data, uint16_t length); -static void GC9A01_reset(void); /********************** * STATIC VARIABLES @@ -111,9 +111,22 @@ void GC9A01_init(void) }; - GC9A01_reset(); + //Initialize non-SPI GPIOs + gpio_pad_select_gpio(GC9A01_DC); + gpio_set_direction(GC9A01_DC, GPIO_MODE_OUTPUT); - LV_LOG_INFO("Initialization."); +#if GC9A01_USE_RST + gpio_pad_select_gpio(GC9A01_RST); + gpio_set_direction(GC9A01_RST, GPIO_MODE_OUTPUT); + + //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."); //Send all the commands uint16_t cmd = 0; @@ -121,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(pdMS_TO_TICKS(100)); + vTaskDelay(100 / portTICK_RATE_MS); } cmd++; } @@ -207,36 +220,24 @@ static void GC9A01_send_color(void * data, uint16_t length) static void GC9A01_set_orientation(uint8_t orientation) { - assert(orientation < 4); + // ESP_ASSERT(orientation < 4); -#if defined CONFIG_LV_PREDEFINED_DISPLAY_M5STACK - const uint8_t data[] = {0x68, 0x68, 0x08, 0x08}; -#elif defined (CONFIG_LV_PREDEFINED_DISPLAY_WROVER4) - const uint8_t data[] = {0x4C, 0x88, 0x28, 0xE8}; -#else - const uint8_t data[] = {0x08, 0xC8, 0x68, 0xA8}; -#endif - -#if (LV_USE_LOG == 1) const char *orientation_str[] = { "PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED" }; - LV_LOG_INFO("Display orientation: %s", orientation_str[orientation]); - LV_LOG_INFO("0x36 command value: 0x%02X", data[orientation]); + ESP_LOGI(TAG, "Display orientation: %s", orientation_str[orientation]); + +#if defined CONFIG_LV_PREDEFINED_DISPLAY_M5STACK + uint8_t data[] = {0x68, 0x68, 0x08, 0x08}; /// +#elif defined (CONFIG_LV_PREDEFINED_DISPLAY_WROVER4) + uint8_t data[] = {0x4C, 0x88, 0x28, 0xE8}; /// +#elif defined (CONFIG_LV_PREDEFINED_DISPLAY_NONE) + uint8_t data[] = {0x08, 0xC8, 0x68, 0xA8}; ///ggggg #endif + ESP_LOGI(TAG, "0x36 command value: 0x%02X", data[orientation]); + GC9A01_send_cmd(0x36); GC9A01_send_data((void *) &data[orientation], 1); } - -static void GC9A01_reset(void) -{ -#if GC9A01_USE_RST - //Reset the display - gpio_set_level(GC9A01_RST, 0); - vTaskDelay(pdMS_TO_TICKS(100)); - gpio_set_level(GC9A01_RST, 1); - vTaskDelay(pdMS_TO_TICKS(100)); -#endif -} diff --git a/lvgl_tft/Kconfig b/lvgl_tft/Kconfig index ad90095..c0ad817 100644 --- a/lvgl_tft/Kconfig +++ b/lvgl_tft/Kconfig @@ -178,6 +178,10 @@ menu "LVGL TFT Display controller" bool help PCD8544 display controller (Nokia 3110/5110) + config LV_TFT_DISPLAY_CONTROLLER_SCHMITT + bool + help + Schmitt's display controller # Display controller communication protocol # # This symbols define the communication protocol used by the @@ -214,8 +218,8 @@ menu "LVGL TFT Display controller" config LV_DISPLAY_ORIENTATION int default 0 if LV_DISPLAY_ORIENTATION_PORTRAIT - default 2 if LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED - default 1 if LV_DISPLAY_ORIENTATION_LANDSCAPE + default 1 if LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED + default 2 if LV_DISPLAY_ORIENTATION_LANDSCAPE default 3 if LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED config LV_TFT_DISPLAY_OFFSETS @@ -226,15 +230,15 @@ menu "LVGL TFT Display controller" config LV_TFT_DISPLAY_X_OFFSET depends on LV_TFT_DISPLAY_OFFSETS int "X offset" - default 40 if LV_PREDEFINED_DISPLAY_TTGO && (DISPLAY_ORIENTATION_LANDSCAPE || DISPLAY_ORIENTATION_LANDSCAPE_INVERTED) - default 53 if LV_PREDEFINED_DISPLAY_TTGO && (DISPLAY_ORIENTATION_PORTRAIT || DISPLAY_ORIENTATION_PORTRAIT_INVERTED) + 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" - default 53 if LV_PREDEFINED_DISPLAY_TTGO && (DISPLAY_ORIENTATION_LANDSCAPE || DISPLAY_ORIENTATION_LANDSCAPE_INVERTED) - default 40 if LV_PREDEFINED_DISPLAY_TTGO && (DISPLAY_ORIENTATION_PORTRAIT || DISPLAY_ORIENTATION_PORTRAIT_INVERTED) + 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 @@ -349,6 +353,10 @@ menu "LVGL TFT Display controller" select LV_TFT_DISPLAY_CONTROLLER_PCD8544 select LV_TFT_DISPLAY_PROTOCOL_SPI select LV_TFT_DISPLAY_MONOCHROME + config LV_TFT_DISPLAY_USER_CONTROLLER_SCHMITT + bool "SCHMITT" + select LV_TFT_DISPLAY_CONTROLLER_SCHMITT + select LV_TFT_DISPLAY_PROTOCOL_SPI endchoice config CUSTOM_DISPLAY_BUFFER_SIZE @@ -476,9 +484,7 @@ menu "LVGL TFT Display controller" config LV_TFT_DISPLAY_SPI2_HOST bool "SPI2_HOST" config LV_TFT_DISPLAY_SPI3_HOST - bool "SPI3_HOST" if !IDF_TARGET_ESP32C3 - help - Select the SPI Bus the TFT Display is attached to. + bool "SPI3_HOST" endchoice choice @@ -495,18 +501,6 @@ menu "LVGL TFT Display controller" bool "QIO (4-bit Quad SPI)" endchoice - config LV_TFT_DISPLAY_USE_CUSTOM_SPI_MODE - bool "Use custom SPI Mode" if LV_TFT_DISPLAY_PROTOCOL_SPI - help - Allow user to choose a custom SPI mode - - config LV_TFT_DISPLAY_CUSTOM_SPI_MODE - int "Custom SPI Mode" - range 0 3 - depends on LV_TFT_DISPLAY_USE_CUSTOM_SPI_MODE - help - Custom SPI mode, representing a pair of (CPOL, CPHA) configuration. - choice prompt "TFT SPI Duplex Mode" if LV_TFT_DISPLAY_PROTOCOL_SPI default LV_TFT_DISPLAY_SPI_FULL_DUPLEX if LV_PREDEFINED_DISPLAY_RPI_RA8875 || LV_TFT_DISPLAY_CONTROLLER_FT81X @@ -920,13 +914,6 @@ menu "LVGL TFT Display controller" help Configure the display Reset pin here. - config LV_DISP_USE_BUSY - bool "Use a GPIO for busy signal" if LV_TFT_DISPLAY_CONTROLLER_IL3820 || LV_TFT_DISPLAY_CONTROLLER_JD79653A || LV_TFT_DISPLAY_CONTROLLER_UC8151D - default y if LV_TFT_DISPLAY_CONTROLLER_IL3820 || LV_TFT_DISPLAY_CONTROLLER_JD79653A || LV_TFT_DISPLAY_CONTROLLER_UC8151D - default n - help - Use a GPIO for busy signal available in e-ink display controllers. - 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 default 35 if LV_TFT_DISPLAY_CONTROLLER_IL3820 || LV_TFT_DISPLAY_CONTROLLER_JD79653A || LV_TFT_DISPLAY_CONTROLLER_UC8151D diff --git a/lvgl_tft/disp_driver.c b/lvgl_tft/disp_driver.c index cae5768..c087059 100644 --- a/lvgl_tft/disp_driver.c +++ b/lvgl_tft/disp_driver.c @@ -7,16 +7,16 @@ #include "esp_lcd_backlight.h" #include "sdkconfig.h" -void *disp_driver_init(lv_disp_drv_t *drv) +void *disp_driver_init(void) { #if defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341 - ili9341_init(drv); + ili9341_init(); #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481 ili9481_init(); #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488 - ili9488_init(drv); + ili9488_init(); #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7789 - st7789_init(drv); + st7789_init(); #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7796S st7796s_init(); #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7735S @@ -44,14 +44,11 @@ void *disp_driver_init(lv_disp_drv_t *drv) #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9163C ili9163c_init(); #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_PCD8544 - pcd8544_init(drv); + pcd8544_init(); +#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SCHMITT + schmitt_init(); #endif - return disp_backlight_init(); -} - -void *disp_backlight_init(void) -{ // 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)) @@ -116,6 +113,8 @@ void disp_driver_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * ili9163c_flush(drv, area, color_map); #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_PCD8544 pcd8544_flush(drv, area, color_map); +#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SCHMITT + schmitt_flush(drv, area, color_map); #endif } diff --git a/lvgl_tft/disp_driver.h b/lvgl_tft/disp_driver.h index 7f43b46..a7624b9 100644 --- a/lvgl_tft/disp_driver.h +++ b/lvgl_tft/disp_driver.h @@ -54,6 +54,8 @@ extern "C" { #include "ili9163c.h" #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_PCD8544 #include "pcd8544.h" +#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SCHMITT +#include "schmitt.h" #endif /********************* @@ -69,7 +71,7 @@ extern "C" { **********************/ /* Initialize display */ -void *disp_driver_init(lv_disp_drv_t *drv); +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); @@ -81,8 +83,6 @@ void disp_driver_rounder(lv_disp_drv_t * disp_drv, lv_area_t * area); 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); -/* Display backlight configuration */ -void *disp_backlight_init(void); /********************** * MACROS **********************/ diff --git a/lv_port/disp_spi.c b/lvgl_tft/disp_spi.c similarity index 100% rename from lv_port/disp_spi.c rename to lvgl_tft/disp_spi.c diff --git a/lv_port/disp_spi.h b/lvgl_tft/disp_spi.h similarity index 100% rename from lv_port/disp_spi.h rename to lvgl_tft/disp_spi.h diff --git a/lvgl_tft/display_port.h b/lvgl_tft/display_port.h deleted file mode 100644 index f0004d6..0000000 --- a/lvgl_tft/display_port.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef DISPLAY_PORT_H_ -#define DISPLAY_PORT_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#ifdef LV_LVGL_H_INCLUDE_SIMPLE -#include "lvgl.h" -#else -#include "lvgl/lvgl.h" -#endif - -#include -#include - -/** - * Busy wait delay port - * - * @param drv Pointer to driver See @ref lv_disp_drv_t - * @param delay_ms Delay duration in milliseconds - */ -void display_port_delay(lv_disp_drv_t *drv, uint32_t delay_ms); - -/** - * Backlight control port - * - * @param drv Pointer to driver See @ref lv_disp_drv_t - * @param state State of the backlight signal - */ -void display_port_backlight(lv_disp_drv_t *drv, uint8_t state); - -/** - * DC signal control port - * - * @param drv Pointer to driver See @ref lv_disp_drv_t - * @param state State of the DC signal, 1 for logic high, 0 for logic low - */ -void display_port_gpio_dc(lv_disp_drv_t *drv, uint8_t state); - -/** - * Hardware reset control port - * - * @param drv Pointer to driver See @ref lv_disp_drv_t - * @param state State of the reset signal, 1 for logic high, 0 for logic low - */ -void display_port_gpio_rst(lv_disp_drv_t *drv, uint8_t state); - -/** - * Display is busy port - * - * @param drv Pointer to driver See @ref lv_disp_drv_t - * - * @retval Returns false when display is not busy, true otherwise. - */ -bool display_port_gpio_is_busy(lv_disp_drv_t *drv); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/lv_port/esp_lcd_backlight.c b/lvgl_tft/esp_lcd_backlight.c similarity index 83% rename from lv_port/esp_lcd_backlight.c rename to lvgl_tft/esp_lcd_backlight.c index 03b1924..2d74f36 100644 --- a/lv_port/esp_lcd_backlight.c +++ b/lvgl_tft/esp_lcd_backlight.c @@ -8,14 +8,11 @@ *********************/ #include "esp_lcd_backlight.h" #include "driver/ledc.h" -#include "driver/gpio.h" +#include "rom/gpio.h" #include "esp_log.h" #include "soc/ledc_periph.h" // to invert LEDC output on IDF version < v4.3 -#include "esp_idf_version.h" -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) -#include "soc/gpio_sig_map.h" -#endif +#define SIG_GPIO_OUT_IDX 128 typedef struct { bool pwm_control; // true: LEDC is used, false: GPIO is used @@ -54,32 +51,22 @@ 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, - .bit_num = LEDC_TIMER_10_BIT, + .duty_resolution = LEDC_TIMER_10_BIT, .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)); - - #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) - 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; - ESP_ERROR_CHECK(gpio_set_direction(config->gpio_num, GPIO_MODE_OUTPUT)); - #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) - esp_rom_gpio_pad_select_gpio(config->gpio_num); - esp_rom_gpio_connect_out_signal(config->gpio_num, SIG_GPIO_OUT_IDX, config->output_invert, false); - #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; diff --git a/lvgl_tft/hx8357.c b/lvgl_tft/hx8357.c index f144d16..bb9ea58 100644 --- a/lvgl_tft/hx8357.c +++ b/lvgl_tft/hx8357.c @@ -18,12 +18,15 @@ #include "hx8357.h" #include "disp_spi.h" #include "driver/gpio.h" +#include #include "freertos/FreeRTOS.h" #include "freertos/task.h" /********************* * DEFINES *********************/ +#define TAG "HX8357" + #define MADCTL_MY 0x80 ///< Bottom to top #define MADCTL_MX 0x40 ///< Right to left #define MADCTL_MV 0x20 ///< Reverse Mode @@ -49,7 +52,7 @@ typedef struct { static void hx8357_send_cmd(uint8_t cmd); static void hx8357_send_data(void * data, uint16_t length); static void hx8357_send_color(void * data, uint16_t length); -static void hx8357_reset(void); + /********************** * INITIALIZATION ARRAYS @@ -156,31 +159,44 @@ static uint8_t displayType = HX8357D; void hx8357_init(void) { - hx8357_reset(); + //Initialize non-SPI GPIOs + gpio_pad_select_gpio(HX8357_DC); + gpio_set_direction(HX8357_DC, GPIO_MODE_OUTPUT); - LV_LOG_INFO("Initialization."); +#if HX8357_USE_RST + gpio_pad_select_gpio(HX8357_RST); + gpio_set_direction(HX8357_RST, GPIO_MODE_OUTPUT); - //Send all the commands - const uint8_t *addr = (displayType == HX8357B) ? initb : initd; - uint8_t cmd, x, numArgs; - while((cmd = *addr++) > 0) { // '0' command ends list - x = *addr++; - numArgs = x & 0x7F; - if (cmd != 0xFF) { // '255' is ignored - if (x & 0x80) { // If high bit set, numArgs is a delay time - hx8357_send_cmd(cmd); - } else { - hx8357_send_cmd(cmd); - hx8357_send_data((void *) addr, numArgs); - addr += numArgs; - } - } - if (x & 0x80) { // If high bit set... - vTaskDelay(numArgs * pdMS_TO_TICKS(5)); // numArgs is actually a delay time (5ms units) - } - } + //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 - hx8357_set_rotation(1); + ESP_LOGI(TAG, "Initialization."); + + //Send all the commands + const uint8_t *addr = (displayType == HX8357B) ? initb : initd; + uint8_t cmd, x, numArgs; + while((cmd = *addr++) > 0) { // '0' command ends list + x = *addr++; + numArgs = x & 0x7F; + if (cmd != 0xFF) { // '255' is ignored + if (x & 0x80) { // If high bit set, numArgs is a delay time + hx8357_send_cmd(cmd); + } else { + hx8357_send_cmd(cmd); + hx8357_send_data((void *) addr, numArgs); + addr += numArgs; + } + } + if (x & 0x80) { // If high bit set... + vTaskDelay(numArgs * 5 / portTICK_RATE_MS); // numArgs is actually a delay time (5ms units) + } + } + + hx8357_set_rotation(1); #if HX8357_INVERT_COLORS hx8357_send_cmd(HX8357_INVON); @@ -273,13 +289,3 @@ static void hx8357_send_color(void * data, uint16_t length) gpio_set_level(HX8357_DC, 1); /*Data mode*/ disp_spi_send_colors(data, length); } - -static void hx8357_reset(void) -{ -#if HX8357_USE_RST - gpio_set_level(HX8357_RST, 0); - vTaskDelay(pdMS_TO_TICKS(10)); - gpio_set_level(HX8357_RST, 1); - vTaskDelay(pdMS_TO_TICKS(120)); -#endif -} diff --git a/lvgl_tft/il3820.c b/lvgl_tft/il3820.c index d2e0496..1ce0b39 100644 --- a/lvgl_tft/il3820.c +++ b/lvgl_tft/il3820.c @@ -30,6 +30,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH *********************/ #include "disp_spi.h" #include "driver/gpio.h" +#include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -38,6 +39,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH /********************* * DEFINES *********************/ + #define TAG "IL3820" /** * SSD1673, SSD1608 compatible EPD controller driver. @@ -100,7 +102,6 @@ static inline void il3820_set_window( uint16_t sx, uint16_t ex, uint16_t ys, uin static inline void il3820_set_cursor(uint16_t sx, uint16_t ys); static void il3820_update_display(void); static void il3820_clear_cntlr_mem(uint8_t ram_cmd, bool update); -static void il3820_reset(void); /* Required by LVGL */ void il3820_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map) @@ -179,9 +180,7 @@ void il3820_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t* buf, BIT_CLEAR(buf[byte_index], 7 - bit_index); } #else - (void)byte_index; - (void)bit_index; - assert(false); // Unsupported orientation configured. Crash if we get here, but allow compilation for CI +#error "Unsupported orientation used" #endif } @@ -196,7 +195,26 @@ void il3820_init(void) { uint8_t tmp[3] = {0}; - il3820_reset(); + /* 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); + + /* 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); @@ -249,17 +267,17 @@ static void il3820_waitbusy(int wait_ms) { int i = 0; - vTaskDelay(pdMS_TO_TICKS(10)); // 10ms delay + 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(pdMS_TO_TICKS(10)); + vTaskDelay(10 / portTICK_RATE_MS); } - LV_LOG_ERROR("Busy exceeded %dms", i*10 ); + ESP_LOGE( TAG, "busy exceeded %dms", i*10 ); } /* Set DC signal to command mode */ @@ -398,17 +416,3 @@ static void il3820_clear_cntlr_mem(uint8_t ram_cmd, bool update) il3820_update_display(); } } - -static void il3820_reset(void) -{ -#if IL3820_USE_RST - /* Harware reset */ - gpio_set_level( IL3820_RST_PIN, 0); - vTaskDelay(pdMS_TO_TICKS(IL3820_RESET_DELAY)); - gpio_set_level( IL3820_RST_PIN, 1); - vTaskDelay(pdMS_TO_TICKS(IL3820_RESET_DELAY)); -#endif - - /* Software reset */ - il3820_write_cmd(IL3820_CMD_SW_RESET, NULL, 0); -} diff --git a/lvgl_tft/il3820.h b/lvgl_tft/il3820.h index d175c5d..f77ffb4 100644 --- a/lvgl_tft/il3820.h +++ b/lvgl_tft/il3820.h @@ -20,19 +20,8 @@ extern "C" /* Values for Waveshare 2.9inch e-Paper Module, this values shouldn't be * swapped to change display orientation */ -#if defined (LV_HOR_RES_MAX) #define EPD_PANEL_WIDTH LV_HOR_RES_MAX /* 128 */ -#else - /* Fallback to default value */ -#define EPD_PANEL_WIDTH 128u -#endif - -#if defined (LV_VER_RES_MAX) #define EPD_PANEL_HEIGHT LV_VER_RES_MAX /* 296 */ -#else - /* Fallback to default value */ -#define EPD_PANEL_HEIGHT 296u -#endif /* 128 = panel width */ #define IL3820_COLUMNS (EPD_PANEL_WIDTH / 8) diff --git a/lvgl_tft/ili9163c.c b/lvgl_tft/ili9163c.c index 12701c8..059d076 100644 --- a/lvgl_tft/ili9163c.c +++ b/lvgl_tft/ili9163c.c @@ -9,6 +9,7 @@ #include "ili9163c.h" #include "disp_spi.h" #include "driver/gpio.h" +#include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "assert.h" @@ -16,6 +17,8 @@ /********************* * DEFINES *********************/ +#define TAG "ILI9163C" + // ILI9163C specific commands used in init #define ILI9163C_NOP 0x00 #define ILI9163C_SWRESET 0x01 @@ -66,7 +69,7 @@ #define ST77XX_MADCTL_MY 0x80 #define ST77XX_MADCTL_MX 0x40 -#define ST77XX_MADCTL_MV 0x20 +#define ST77XX_MADCTL_MV 0x20 #define #define ST77XX_MADCTL_ML 0x10 #define ST77XX_MADCTL_RGB 0x00 #define ST77XX_MADCTL_BGR 0x08 @@ -91,7 +94,7 @@ static void ili9163c_set_orientation(uint8_t orientation); static void ili9163c_send_cmd(uint8_t cmd); static void ili9163c_send_data(void *data, uint16_t length); static void ili9163c_send_color(void *data, uint16_t length); -static void ili9163c_reset(void); + /********************** * STATIC VARIABLES **********************/ @@ -106,7 +109,7 @@ static void ili9163c_reset(void); void ili9163c_init(void) { - LV_LOG_INFO("Init"); + ESP_LOGD(TAG, "Init"); lcd_init_cmd_t ili_init_cmds[] = { {ILI9163C_SWRESET, {0}, 0x80}, // Software reset, 0 args, w/delay 120ms @@ -133,8 +136,18 @@ void ili9163c_init(void) {ILI9163C_DISPON, {0}, 0x80}, // Main screen turn on, no args w/delay 100 ms delay {0, {0}, 0xff} }; - - ili9163c_reset(); + + //Initialize non-SPI GPIOs + gpio_pad_select_gpio(ILI9163C_DC); + gpio_set_direction(ILI9163C_DC, GPIO_MODE_OUTPUT); + gpio_pad_select_gpio(ILI9163C_RST); + gpio_set_direction(ILI9163C_RST, GPIO_MODE_OUTPUT); + + //Reset the display + gpio_set_level(ILI9163C_RST, 0); + vTaskDelay(100 / portTICK_RATE_MS); + gpio_set_level(ILI9163C_RST, 1); + vTaskDelay(150 / portTICK_RATE_MS); //Send all the commands uint16_t cmd = 0; @@ -144,7 +157,7 @@ void ili9163c_init(void) ili9163c_send_data(ili_init_cmds[cmd].data, ili_init_cmds[cmd].databytes & 0x1F); if (ili_init_cmds[cmd].databytes & 0x80) { - vTaskDelay(pdMS_TO_TICKS(150)); + vTaskDelay(150 / portTICK_RATE_MS); } cmd++; } @@ -223,25 +236,13 @@ static void ili9163c_set_orientation(uint8_t orientation) { assert(orientation < 4); -#if (LV_USE_LOG == 1) const char *orientation_str[] = { "PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED"}; - LV_LOG_INFO("Display orientation: %s", orientation_str[orientation]); -#endif + ESP_LOGD(TAG, "Display orientation: %s", orientation_str[orientation]); + uint8_t data[] = {0x48, 0x88, 0xA8, 0x68}; ili9163c_send_cmd(ILI9163C_MADCTL); ili9163c_send_data((void *)&data[orientation], 1); } - -static void ili9163c_reset(void) -{ -#if CONFIG_LV_DISP_USE_RST - gpio_set_level(ILI9163C_RST, 0); - vTaskDelay(pdMS_TO_TICKS(100)); - gpio_set_level(ILI9163C_RST, 1); - vTaskDelay(pdMS_TO_TICKS(150)); -#else -#endif -} diff --git a/lvgl_tft/ili9341.c b/lvgl_tft/ili9341.c index 4c02f40..e91680f 100644 --- a/lvgl_tft/ili9341.c +++ b/lvgl_tft/ili9341.c @@ -7,24 +7,22 @@ * INCLUDES *********************/ #include "ili9341.h" - #include "disp_spi.h" -#include "display_port.h" +#include "driver/gpio.h" +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" /********************* * DEFINES *********************/ -#define END_OF_CMD_MARKER 0xFFU - -#define MEMORY_ACCESS_CONTROL_REG 0x36U -#define SOFTWARE_RESET_REG 0x01U + #define TAG "ILI9341" /********************** * TYPEDEFS **********************/ /*The LCD needs a bunch of command/argument values to be initialized. They are stored in this struct. */ - typedef struct { uint8_t cmd; uint8_t data[16]; @@ -34,13 +32,12 @@ typedef struct { /********************** * STATIC PROTOTYPES **********************/ -static void ili9341_set_orientation(lv_disp_drv_t * drv, uint8_t orientation); +static void ili9341_set_orientation(uint8_t orientation); -static void ili9341_send_cmd(lv_disp_drv_t * drv, uint8_t cmd); -static void ili9341_send_data(lv_disp_drv_t * drv, void * data, uint16_t length); -static void ili9341_send_color(lv_disp_drv_t * drv, void * data, uint16_t length); +static void ili9341_send_cmd(uint8_t cmd); +static void ili9341_send_data(void * data, uint16_t length); +static void ili9341_send_color(void * data, uint16_t length); -static void ili9341_reset(lv_disp_drv_t * drv); /********************** * STATIC VARIABLES **********************/ @@ -53,172 +50,162 @@ static void ili9341_reset(lv_disp_drv_t * drv); * GLOBAL FUNCTIONS **********************/ -void ili9341_init(lv_disp_drv_t * drv) +void ili9341_init(void) { - lcd_init_cmd_t ili_init_cmds[] = { - {0xCF, {0x00, 0x83, 0X30}, 3}, - {0xED, {0x64, 0x03, 0X12, 0X81}, 4}, - {0xE8, {0x85, 0x01, 0x79}, 3}, - {0xCB, {0x39, 0x2C, 0x00, 0x34, 0x02}, 5}, - {0xF7, {0x20}, 1}, - {0xEA, {0x00, 0x00}, 2}, - /* Power control */ - {0xC0, {0x26}, 1}, - /* Power control */ - {0xC1, {0x11}, 1}, - /* VCOM control */ - {0xC5, {0x35, 0x3E}, 2}, - /* VCOM control */ - {0xC7, {0xBE}, 1}, - /* Memory Access Control */ - {0x36, {0x28}, 1}, - /* Pixel Format Set */ - {0x3A, {0x55}, 1}, - {0xB1, {0x00, 0x1B}, 2}, - {0xF2, {0x08}, 1}, - {0x26, {0x01}, 1}, - {0xE0, {0x1F, 0x1A, 0x18, 0x0A, 0x0F, 0x06, 0x45, 0X87, 0x32, 0x0A, 0x07, 0x02, 0x07, 0x05, 0x00}, 15}, - {0XE1, {0x00, 0x25, 0x27, 0x05, 0x10, 0x09, 0x3A, 0x78, 0x4D, 0x05, 0x18, 0x0D, 0x38, 0x3A, 0x1F}, 15}, - {0x2A, {0x00, 0x00, 0x00, 0xEF}, 4}, - {0x2B, {0x00, 0x00, 0x01, 0x3f}, 4}, - {0x2C, {0}, 0}, - {0xB7, {0x07}, 1}, - {0xB6, {0x0A, 0x82, 0x27, 0x00}, 4}, - {0x11, {0}, 0x80}, - {0x29, {0}, 0x80}, - {0, {0}, END_OF_CMD_MARKER}, - }; + lcd_init_cmd_t ili_init_cmds[]={ + {0xCF, {0x00, 0x83, 0X30}, 3}, + {0xED, {0x64, 0x03, 0X12, 0X81}, 4}, + {0xE8, {0x85, 0x01, 0x79}, 3}, + {0xCB, {0x39, 0x2C, 0x00, 0x34, 0x02}, 5}, + {0xF7, {0x20}, 1}, + {0xEA, {0x00, 0x00}, 2}, + {0xC0, {0x26}, 1}, /*Power control*/ + {0xC1, {0x11}, 1}, /*Power control */ + {0xC5, {0x35, 0x3E}, 2}, /*VCOM control*/ + {0xC7, {0xBE}, 1}, /*VCOM control*/ + {0x36, {0x28}, 1}, /*Memory Access Control*/ + {0x3A, {0x55}, 1}, /*Pixel Format Set*/ + {0xB1, {0x00, 0x1B}, 2}, + {0xF2, {0x08}, 1}, + {0x26, {0x01}, 1}, + {0xE0, {0x1F, 0x1A, 0x18, 0x0A, 0x0F, 0x06, 0x45, 0X87, 0x32, 0x0A, 0x07, 0x02, 0x07, 0x05, 0x00}, 15}, + {0XE1, {0x00, 0x25, 0x27, 0x05, 0x10, 0x09, 0x3A, 0x78, 0x4D, 0x05, 0x18, 0x0D, 0x38, 0x3A, 0x1F}, 15}, + {0x2A, {0x00, 0x00, 0x00, 0xEF}, 4}, + {0x2B, {0x00, 0x00, 0x01, 0x3f}, 4}, + {0x2C, {0}, 0}, + {0xB7, {0x07}, 1}, + {0xB6, {0x0A, 0x82, 0x27, 0x00}, 4}, + {0x11, {0}, 0x80}, + {0x29, {0}, 0x80}, + {0, {0}, 0xff}, + }; - ili9341_reset(drv); + //Initialize non-SPI GPIOs + gpio_pad_select_gpio(ILI9341_DC); + gpio_set_direction(ILI9341_DC, GPIO_MODE_OUTPUT); - //Send all the commands - uint16_t cmd = 0; - while (ili_init_cmds[cmd].databytes != END_OF_CMD_MARKER) { - ili9341_send_cmd(drv, ili_init_cmds[cmd].cmd); - ili9341_send_data(drv, ili_init_cmds[cmd].data, ili_init_cmds[cmd].databytes & 0x1F); - - if (ili_init_cmds[cmd].databytes & 0x80) { - display_port_delay(drv, 100); - } +#if ILI9341_USE_RST + gpio_pad_select_gpio(ILI9341_RST); + gpio_set_direction(ILI9341_RST, GPIO_MODE_OUTPUT); - cmd++; - } + //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 - ili9341_set_orientation(drv, ILI9341_INITIAL_ORIENTATION); + ESP_LOGI(TAG, "Initialization."); -#if ILI9341_INVERT_COLORS == 1U - ili9341_send_cmd(drv, 0x21); + //Send all the commands + uint16_t cmd = 0; + while (ili_init_cmds[cmd].databytes!=0xff) { + ili9341_send_cmd(ili_init_cmds[cmd].cmd); + ili9341_send_data(ili_init_cmds[cmd].data, ili_init_cmds[cmd].databytes&0x1F); + if (ili_init_cmds[cmd].databytes & 0x80) { + vTaskDelay(100 / portTICK_RATE_MS); + } + cmd++; + } + + ili9341_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION); + +#if ILI9341_INVERT_COLORS == 1 + ili9341_send_cmd(0x21); #else - ili9341_send_cmd(drv, 0x20); + ili9341_send_cmd(0x20); #endif } void ili9341_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map) { - uint8_t data[4] = {0}; - uint32_t size = lv_area_get_width(area) * lv_area_get_height(area); + uint8_t data[4]; - /*Column addresses*/ - data[0] = (area->x1 >> 8) & 0xFF; - data[1] = area->x1 & 0xFF; - data[2] = (area->x2 >> 8) & 0xFF; - data[3] = area->x2 & 0xFF; + /*Column addresses*/ + ili9341_send_cmd(0x2A); + data[0] = (area->x1 >> 8) & 0xFF; + data[1] = area->x1 & 0xFF; + data[2] = (area->x2 >> 8) & 0xFF; + data[3] = area->x2 & 0xFF; + ili9341_send_data(data, 4); - ili9341_send_cmd(drv, 0x2A); - ili9341_send_data(drv, data, 4); + /*Page addresses*/ + ili9341_send_cmd(0x2B); + data[0] = (area->y1 >> 8) & 0xFF; + data[1] = area->y1 & 0xFF; + data[2] = (area->y2 >> 8) & 0xFF; + data[3] = area->y2 & 0xFF; + ili9341_send_data(data, 4); - /* Page addresses */ - data[0] = (area->y1 >> 8) & 0xFF; - data[1] = area->y1 & 0xFF; - data[2] = (area->y2 >> 8) & 0xFF; - data[3] = area->y2 & 0xFF; - - ili9341_send_cmd(drv, 0x2B); - ili9341_send_data(drv, data, 4); - - /* Memory write */ - ili9341_send_cmd(drv, 0x2C); - ili9341_send_color(drv, (void*)color_map, size * 2); + /*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_sleep_in(lv_disp_drv_t * drv) +void ili9341_sleep_in() { - uint8_t data[] = {0x08}; - ili9341_send_cmd(drv, 0x10); - ili9341_send_data(drv, data, 1); + uint8_t data[] = {0x08}; + ili9341_send_cmd(0x10); + ili9341_send_data(&data, 1); } -void ili9341_sleep_out(lv_disp_drv_t * drv) +void ili9341_sleep_out() { - uint8_t data[] = {0x08}; - ili9341_send_cmd(drv, 0x11); - ili9341_send_data(drv, data, 1); + uint8_t data[] = {0x08}; + ili9341_send_cmd(0x11); + ili9341_send_data(&data, 1); } /********************** * STATIC FUNCTIONS **********************/ -static inline void set_cmd_mode(lv_disp_drv_t * drv) -{ - display_port_gpio_dc(drv, 0); -} -static inline void set_data_mode(lv_disp_drv_t * drv) -{ - display_port_gpio_dc(drv, 1); -} - -static void ili9341_send_cmd(lv_disp_drv_t * drv, uint8_t cmd) +static void ili9341_send_cmd(uint8_t cmd) { disp_wait_for_pending_transactions(); - set_cmd_mode(drv); + gpio_set_level(ILI9341_DC, 0); /*Command mode*/ disp_spi_send_data(&cmd, 1); } -static void ili9341_send_data(lv_disp_drv_t *drv, void * data, uint16_t length) +static void ili9341_send_data(void * data, uint16_t length) { disp_wait_for_pending_transactions(); - set_data_mode(drv); + gpio_set_level(ILI9341_DC, 1); /*Data mode*/ disp_spi_send_data(data, length); } -static void ili9341_send_color(lv_disp_drv_t *drv, void * data, uint16_t length) +static void ili9341_send_color(void * data, uint16_t length) { disp_wait_for_pending_transactions(); - set_data_mode(drv); + gpio_set_level(ILI9341_DC, 1); /*Data mode*/ disp_spi_send_colors(data, length); } -static void ili9341_set_orientation(lv_disp_drv_t *drv, uint8_t orientation) +static void ili9341_set_orientation(uint8_t orientation) { - assert(orientation < 4); + // ESP_ASSERT(orientation < 4); + + const char *orientation_str[] = { + "PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED" + }; + + ESP_LOGI(TAG, "Display orientation: %s", orientation_str[orientation]); #if defined CONFIG_LV_PREDEFINED_DISPLAY_M5STACK - const uint8_t data[] = {0x68, 0x68, 0x08, 0x08}; + uint8_t data[] = {0x68, 0x68, 0x08, 0x08}; #elif defined (CONFIG_LV_PREDEFINED_DISPLAY_M5CORE2) - const uint8_t data[] = {0x08, 0x88, 0x28, 0xE8}; + uint8_t data[] = {0x08, 0x88, 0x28, 0xE8}; #elif defined (CONFIG_LV_PREDEFINED_DISPLAY_WROVER4) - const uint8_t data[] = {0x6C, 0xEC, 0xCC, 0x4C}; -#else - const uint8_t data[] = {0x48, 0x88, 0x28, 0xE8}; + uint8_t data[] = {0x6C, 0xEC, 0xCC, 0x4C}; +#elif defined (CONFIG_LV_PREDEFINED_DISPLAY_NONE) + uint8_t data[] = {0x48, 0x88, 0x28, 0xE8}; #endif - ili9341_send_cmd(drv, MEMORY_ACCESS_CONTROL_REG); - ili9341_send_data(drv, (void *) &data[orientation], 1); -} + ESP_LOGI(TAG, "0x36 command value: 0x%02X", data[orientation]); -/* Reset the display, if we don't have a reset pin we use software reset */ -static void ili9341_reset(lv_disp_drv_t *drv) -{ -#if defined(ILI9341_USE_RST) - display_port_gpio_rst(drv, 0); - display_port_delay(drv, 100); - display_port_gpio_rst(drv, 1); - display_port_delay(drv, 100); -#else - ili9341_send_cmd(drv, SOFTWARE_RESET_REG); - display_port_delay(drv, 5); -#endif + ili9341_send_cmd(0x36); + ili9341_send_data((void *) &data[orientation], 1); } diff --git a/lvgl_tft/ili9341.h b/lvgl_tft/ili9341.h index 0f8c58b..62317e8 100644 --- a/lvgl_tft/ili9341.h +++ b/lvgl_tft/ili9341.h @@ -13,17 +13,23 @@ extern "C" { /********************* * INCLUDES *********************/ +#include + #ifdef LV_LVGL_H_INCLUDE_SIMPLE #include "lvgl.h" #else #include "lvgl/lvgl.h" #endif -#include "display_config.h" +#include "sdkconfig.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_INVERT_COLORS CONFIG_LV_INVERT_COLORS /********************** * TYPEDEFS @@ -33,10 +39,10 @@ extern "C" { * GLOBAL PROTOTYPES **********************/ -void ili9341_init(lv_disp_drv_t * drv); +void ili9341_init(void); void ili9341_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map); -void ili9341_sleep_in(lv_disp_drv_t * drv); -void ili9341_sleep_out(lv_disp_drv_t *drv); +void ili9341_sleep_in(void); +void ili9341_sleep_out(void); /********************** * MACROS diff --git a/lvgl_tft/ili9481.c b/lvgl_tft/ili9481.c index 0255621..74bda98 100644 --- a/lvgl_tft/ili9481.c +++ b/lvgl_tft/ili9481.c @@ -8,13 +8,16 @@ #include "ili9481.h" #include "disp_spi.h" #include "driver/gpio.h" +#include "esp_log.h" #include "esp_heap_caps.h" + #include "freertos/FreeRTOS.h" #include "freertos/task.h" /********************* * DEFINES *********************/ + #define TAG "ILI9481" /********************** * TYPEDEFS @@ -35,7 +38,6 @@ static void ili9481_set_orientation(uint8_t orientation); static void ili9481_send_cmd(uint8_t cmd); static void ili9481_send_data(void * data, uint16_t length); static void ili9481_send_color(void * data, uint16_t length); -static void ili9481_reset(void); /********************** * STATIC VARIABLES @@ -71,9 +73,26 @@ void ili9481_init(void) {0, {0}, 0xff}, }; - ili9481_reset(); + //Initialize non-SPI GPIOs + gpio_pad_select_gpio(ILI9481_DC); + gpio_set_direction(ILI9481_DC, GPIO_MODE_OUTPUT); - LV_LOG_INFO("Initialization."); +#if ILI9481_USE_RST + gpio_pad_select_gpio(ILI9481_RST); + gpio_set_direction(ILI9481_RST, GPIO_MODE_OUTPUT); + + //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."); + + // Exit sleep + ili9481_send_cmd(0x01); /* Software reset */ + vTaskDelay(100 / portTICK_RATE_MS); //Send all the commands uint16_t cmd = 0; @@ -81,7 +100,7 @@ void ili9481_init(void) ili9481_send_cmd(ili_init_cmds[cmd].cmd); ili9481_send_data(ili_init_cmds[cmd].data, ili_init_cmds[cmd].databytes&0x1F); if (ili_init_cmds[cmd].databytes & 0x80) { - vTaskDelay(pdMS_TO_TICKS(100)); + vTaskDelay(100 / portTICK_RATE_MS); } cmd++; } @@ -92,16 +111,13 @@ void ili9481_init(void) // Flush function based on mvturnho repo void ili9481_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map) { - /* 3 is number of bytes in lv_color_t */ - uint32_t size = lv_area_get_width(area) * lv_area_get_height(area) * 3; + uint32_t size = lv_area_get_width(area) * lv_area_get_height(area); lv_color16_t *buffer_16bit = (lv_color16_t *) color_map; uint8_t *mybuf; do { mybuf = (uint8_t *) heap_caps_malloc(3 * size * sizeof(uint8_t), MALLOC_CAP_DMA); - if (mybuf == NULL) { - LV_LOG_WARN("Could not allocate enough DMA memory!"); - } + if (mybuf == NULL) ESP_LOGW(TAG, "Could not allocate enough DMA memory!"); } while (mybuf == NULL); uint32_t LD = 0; @@ -144,9 +160,7 @@ void ili9481_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * col /*Memory write*/ ili9481_send_cmd(ILI9481_CMD_MEMORY_WRITE); - ili9481_send_color((void *) mybuf, size); - - /* FIXME: Can we free the memory even when it's being transferred? */ + ili9481_send_color((void *) mybuf, size * 3); heap_caps_free(mybuf); } @@ -178,29 +192,13 @@ static void ili9481_send_color(void * data, uint16_t length) static void ili9481_set_orientation(uint8_t orientation) { -#if (LV_USE_LOG == 1) const char *orientation_str[] = { "PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED" }; - LV_LOG_INFO("Display orientation: %s", orientation_str[orientation]); -#endif + ESP_LOGI(TAG, "Display orientation: %s", orientation_str[orientation]); uint8_t data[] = {0x48, 0x4B, 0x28, 0x2B}; ili9481_send_cmd(ILI9481_CMD_MEMORY_ACCESS_CONTROL); ili9481_send_data((void *) &data[orientation], 1); } - -static void ili9481_reset(void) -{ -#if ILI9481_USE_RST - gpio_set_level(ILI9481_RST, 0); - vTaskDelay(pdMS_TO_TICKS(100)); - gpio_set_level(ILI9481_RST, 1); - vTaskDelay(pdMS_TO_TICKS(100)); -#else - // Exit sleep, software reset - ili9481_send_cmd(0x01); - vTaskDelay(pdMS_TO_TICKS(100)); -#endif -} diff --git a/lvgl_tft/ili9486.c b/lvgl_tft/ili9486.c index 623bc04..829f0bd 100644 --- a/lvgl_tft/ili9486.c +++ b/lvgl_tft/ili9486.c @@ -9,12 +9,14 @@ #include "ili9486.h" #include "disp_spi.h" #include "driver/gpio.h" +#include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" /********************* * DEFINES *********************/ + #define TAG "ILI9486" /********************** * TYPEDEFS @@ -35,7 +37,7 @@ static void ili9486_set_orientation(uint8_t orientation); static void ili9486_send_cmd(uint8_t cmd); static void ili9486_send_data(void * data, uint16_t length); static void ili9486_send_color(void * data, uint16_t length); -static void ili9486_reset(void); + /********************** * STATIC VARIABLES **********************/ @@ -50,62 +52,77 @@ static void ili9486_reset(void); void ili9486_init(void) { - lcd_init_cmd_t ili_init_cmds[]={ - {0x11, {0}, 0x80}, - {0x3A, {0x55}, 1}, - {0x2C, {0x44}, 1}, - {0xC5, {0x00, 0x00, 0x00, 0x00}, 4}, - {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 */ - {0x00, {0}, 0xff}, - }; + lcd_init_cmd_t ili_init_cmds[]={ + {0x11, {0}, 0x80}, + {0x3A, {0x55}, 1}, + {0x2C, {0x44}, 1}, + {0xC5, {0x00, 0x00, 0x00, 0x00}, 4}, + {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 */ + {0x00, {0}, 0xff}, + }; - ili9486_reset(); + //Initialize non-SPI GPIOs + gpio_pad_select_gpio(ILI9486_DC); + gpio_set_direction(ILI9486_DC, GPIO_MODE_OUTPUT); - LV_LOG_INFO("ILI9486 Initialization."); +#if ILI9486_USE_RST + gpio_pad_select_gpio(ILI9486_RST); + gpio_set_direction(ILI9486_RST, GPIO_MODE_OUTPUT); - //Send all the commands - uint16_t cmd = 0; - while (ili_init_cmds[cmd].databytes!=0xff) { - ili9486_send_cmd(ili_init_cmds[cmd].cmd); - ili9486_send_data(ili_init_cmds[cmd].data, ili_init_cmds[cmd].databytes&0x1F); - if (ili_init_cmds[cmd].databytes & 0x80) { - vTaskDelay(pdMS_TO_TICKS(100)); - } - cmd++; - } + //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."); + + //Send all the commands + uint16_t cmd = 0; + while (ili_init_cmds[cmd].databytes!=0xff) { + ili9486_send_cmd(ili_init_cmds[cmd].cmd); + ili9486_send_data(ili_init_cmds[cmd].data, ili_init_cmds[cmd].databytes&0x1F); + if (ili_init_cmds[cmd].databytes & 0x80) { + vTaskDelay(100 / portTICK_RATE_MS); + } + cmd++; + } 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) { - uint8_t data[4] = {0}; - /* 2 is the number of bytes in color depth */ - uint32_t size = lv_area_get_width(area) * lv_area_get_height(area) * 2; + uint8_t data[4] = {0}; + uint32_t size = 0; - /*Column addresses*/ - ili9486_send_cmd(0x2A); - data[0] = (area->x1 >> 8) & 0xFF; - data[1] = area->x1 & 0xFF; - data[2] = (area->x2 >> 8) & 0xFF; - data[3] = area->x2 & 0xFF; - ili9486_send_data(data, 4); + /*Column addresses*/ + ili9486_send_cmd(0x2A); + data[0] = (area->x1 >> 8) & 0xFF; + data[1] = area->x1 & 0xFF; + data[2] = (area->x2 >> 8) & 0xFF; + data[3] = area->x2 & 0xFF; + ili9486_send_data(data, 4); - /*Page addresses*/ - ili9486_send_cmd(0x2B); - data[0] = (area->y1 >> 8) & 0xFF; - data[1] = area->y1 & 0xFF; - data[2] = (area->y2 >> 8) & 0xFF; - data[3] = area->y2 & 0xFF; - ili9486_send_data(data, 4); + /*Page addresses*/ + ili9486_send_cmd(0x2B); + data[0] = (area->y1 >> 8) & 0xFF; + data[1] = area->y1 & 0xFF; + data[2] = (area->y2 >> 8) & 0xFF; + data[3] = area->y2 & 0xFF; + ili9486_send_data(data, 4); - /*Memory write*/ - ili9486_send_cmd(0x2C); - ili9486_send_color((void*) color_map, size); + /*Memory write*/ + ili9486_send_cmd(0x2C); + + size = lv_area_get_width(area) * lv_area_get_height(area); + + ili9486_send_color((void*) color_map, size * 2); } /********************** @@ -113,30 +130,30 @@ void ili9486_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * col **********************/ static void ili9486_send_cmd(uint8_t cmd) { - uint8_t to16bit[] = { - 0x00, cmd - }; + uint8_t to16bit[] = { + 0x00, cmd + }; - disp_wait_for_pending_transactions(); - gpio_set_level(ILI9486_DC, 0); /*Command mode*/ - disp_spi_send_data(to16bit, sizeof to16bit); + disp_wait_for_pending_transactions(); + gpio_set_level(ILI9486_DC, 0); /*Command mode*/ + disp_spi_send_data(to16bit, sizeof to16bit); } static void ili9486_send_data(void * data, uint16_t length) { - uint32_t i; - uint8_t to16bit[32]; - uint8_t * dummy = data; + uint32_t i; + uint8_t to16bit[32]; + uint8_t * dummy = data; - for(i=0; i < (length); i++) - { - to16bit[2*i+1] = dummy[i]; - to16bit[2*i] = 0x00; - } + for(i=0; i < (length); i++) + { + to16bit[2*i+1] = dummy[i]; + to16bit[2*i] = 0x00; + } - disp_wait_for_pending_transactions(); - gpio_set_level(ILI9486_DC, 1); /*Data mode*/ - disp_spi_send_data(to16bit, (length*2)); + disp_wait_for_pending_transactions(); + gpio_set_level(ILI9486_DC, 1); /*Data mode*/ + disp_spi_send_data(to16bit, (length*2)); } static void ili9486_send_color(void * data, uint16_t length) @@ -148,29 +165,20 @@ static void ili9486_send_color(void * data, uint16_t length) static void ili9486_set_orientation(uint8_t orientation) { - assert(orientation < 4); + // ESP_ASSERT(orientation < 4); - const uint8_t data[] = {0x48, 0x88, 0x28, 0xE8}; - -#if (LV_USE_LOG == 1) const char *orientation_str[] = { "PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED" }; - LV_LOG_INFO("Display orientation: %s", orientation_str[orientation]); - LV_LOG_INFO("0x36 command value: 0x%02X", data[orientation]); + ESP_LOGI(TAG, "Display orientation: %s", orientation_str[orientation]); + +#if defined (CONFIG_LV_PREDEFINED_DISPLAY_NONE) + uint8_t data[] = {0x48, 0x88, 0x28, 0xE8}; #endif + ESP_LOGI(TAG, "0x36 command value: 0x%02X", data[orientation]); + ili9486_send_cmd(0x36); ili9486_send_data((void *) &data[orientation], 1); } - -static void ili9486_reset(void) -{ -#if ILI9486_USE_RST - gpio_set_level(ILI9486_RST, 0); - vTaskDelay(pdMS_TO_TICKS(100)); - gpio_set_level(ILI9486_RST, 1); - vTaskDelay(pdMS_TO_TICKS(100)); -#endif -} diff --git a/lvgl_tft/ili9488.c b/lvgl_tft/ili9488.c index 66c0496..feb9fba 100644 --- a/lvgl_tft/ili9488.c +++ b/lvgl_tft/ili9488.c @@ -6,14 +6,18 @@ * INCLUDES *********************/ #include "ili9488.h" - #include "disp_spi.h" -#include "display_port.h" +#include "driver/gpio.h" +#include "esp_log.h" #include "esp_heap_caps.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + /********************* * DEFINES *********************/ + #define TAG "ILI9488" /********************** * TYPEDEFS @@ -29,12 +33,11 @@ typedef struct { /********************** * STATIC PROTOTYPES **********************/ -static void ili9488_set_orientation(lv_disp_drv_t * drv, uint8_t orientation); +static void ili9488_set_orientation(uint8_t orientation); -static void ili9488_send_cmd(lv_disp_drv_t * drv, uint8_t cmd); -static void ili9488_send_data(lv_disp_drv_t * drv, void * data, uint16_t length); -static void ili9488_send_color(lv_disp_drv_t * drv, void * data, uint16_t length); -static void ili9488_reset(lv_disp_drv_t * drv); +static void ili9488_send_cmd(uint8_t cmd); +static void ili9488_send_data(void * data, uint16_t length); +static void ili9488_send_color(void * data, uint16_t length); /********************** * STATIC VARIABLES @@ -49,47 +52,62 @@ static void ili9488_reset(lv_disp_drv_t * drv); **********************/ // From github.com/jeremyjh/ESP32_TFT_library // From github.com/mvturnho/ILI9488-lvgl-ESP32-WROVER-B -void ili9488_init(lv_disp_drv_t * drv) +void ili9488_init(void) { - lcd_init_cmd_t ili_init_cmds[]={ - {ILI9488_CMD_SLEEP_OUT, {0x00}, 0x80}, - {ILI9488_CMD_POSITIVE_GAMMA_CORRECTION, {0x00, 0x03, 0x09, 0x08, 0x16, 0x0A, 0x3F, 0x78, 0x4C, 0x09, 0x0A, 0x08, 0x16, 0x1A, 0x0F}, 15}, - {ILI9488_CMD_NEGATIVE_GAMMA_CORRECTION, {0x00, 0x16, 0x19, 0x03, 0x0F, 0x05, 0x32, 0x45, 0x46, 0x04, 0x0E, 0x0D, 0x35, 0x37, 0x0F}, 15}, - {ILI9488_CMD_POWER_CONTROL_1, {0x17, 0x15}, 2}, - {ILI9488_CMD_POWER_CONTROL_2, {0x41}, 1}, - {ILI9488_CMD_VCOM_CONTROL_1, {0x00, 0x12, 0x80}, 3}, - {ILI9488_CMD_MEMORY_ACCESS_CONTROL, {(0x20 | 0x08)}, 1}, - {ILI9488_CMD_COLMOD_PIXEL_FORMAT_SET, {0x66}, 1}, - {ILI9488_CMD_INTERFACE_MODE_CONTROL, {0x00}, 1}, - {ILI9488_CMD_FRAME_RATE_CONTROL_NORMAL, {0xA0}, 1}, - {ILI9488_CMD_DISPLAY_INVERSION_CONTROL, {0x02}, 1}, - {ILI9488_CMD_DISPLAY_FUNCTION_CONTROL, {0x02, 0x02}, 2}, - {ILI9488_CMD_SET_IMAGE_FUNCTION, {0x00}, 1}, - {ILI9488_CMD_WRITE_CTRL_DISPLAY, {0x28}, 1}, - {ILI9488_CMD_WRITE_DISPLAY_BRIGHTNESS, {0x7F}, 1}, - {ILI9488_CMD_ADJUST_CONTROL_3, {0xA9, 0x51, 0x2C, 0x02}, 4}, - {ILI9488_CMD_DISPLAY_ON, {0x00}, 0x80}, - {0, {0}, 0xff}, - }; + lcd_init_cmd_t ili_init_cmds[]={ + {ILI9488_CMD_SLEEP_OUT, {0x00}, 0x80}, + {ILI9488_CMD_POSITIVE_GAMMA_CORRECTION, {0x00, 0x03, 0x09, 0x08, 0x16, 0x0A, 0x3F, 0x78, 0x4C, 0x09, 0x0A, 0x08, 0x16, 0x1A, 0x0F}, 15}, + {ILI9488_CMD_NEGATIVE_GAMMA_CORRECTION, {0x00, 0x16, 0x19, 0x03, 0x0F, 0x05, 0x32, 0x45, 0x46, 0x04, 0x0E, 0x0D, 0x35, 0x37, 0x0F}, 15}, + {ILI9488_CMD_POWER_CONTROL_1, {0x17, 0x15}, 2}, + {ILI9488_CMD_POWER_CONTROL_2, {0x41}, 1}, + {ILI9488_CMD_VCOM_CONTROL_1, {0x00, 0x12, 0x80}, 3}, + {ILI9488_CMD_MEMORY_ACCESS_CONTROL, {(0x20 | 0x08)}, 1}, + {ILI9488_CMD_COLMOD_PIXEL_FORMAT_SET, {0x66}, 1}, + {ILI9488_CMD_INTERFACE_MODE_CONTROL, {0x00}, 1}, + {ILI9488_CMD_FRAME_RATE_CONTROL_NORMAL, {0xA0}, 1}, + {ILI9488_CMD_DISPLAY_INVERSION_CONTROL, {0x02}, 1}, + {ILI9488_CMD_DISPLAY_FUNCTION_CONTROL, {0x02, 0x02}, 2}, + {ILI9488_CMD_SET_IMAGE_FUNCTION, {0x00}, 1}, + {ILI9488_CMD_WRITE_CTRL_DISPLAY, {0x28}, 1}, + {ILI9488_CMD_WRITE_DISPLAY_BRIGHTNESS, {0x7F}, 1}, + {ILI9488_CMD_ADJUST_CONTROL_3, {0xA9, 0x51, 0x2C, 0x02}, 4}, + {ILI9488_CMD_DISPLAY_ON, {0x00}, 0x80}, + {0, {0}, 0xff}, + }; - ili9488_reset(drv); + //Initialize non-SPI GPIOs + gpio_pad_select_gpio(ILI9488_DC); + gpio_set_direction(ILI9488_DC, GPIO_MODE_OUTPUT); - LV_LOG_INFO("ILI9488 initialization."); +#if ILI9488_USE_RST + gpio_pad_select_gpio(ILI9488_RST); + gpio_set_direction(ILI9488_RST, GPIO_MODE_OUTPUT); - //Send all the commands - uint16_t cmd = 0; - while (ili_init_cmds[cmd].databytes!=0xff) { - ili9488_send_cmd(drv, ili_init_cmds[cmd].cmd); - ili9488_send_data(drv, ili_init_cmds[cmd].data, ili_init_cmds[cmd].databytes&0x1F); - - if (ili_init_cmds[cmd].databytes & 0x80) { - display_port_delay(drv, 100); - } + //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 - cmd++; - } + ESP_LOGI(TAG, "ILI9488 initialization."); - ili9488_set_orientation(drv, ILI9488_INITIAL_ORIENTATION); + // 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) { + ili9488_send_cmd(ili_init_cmds[cmd].cmd); + ili9488_send_data(ili_init_cmds[cmd].data, ili_init_cmds[cmd].databytes&0x1F); + if (ili_init_cmds[cmd].databytes & 0x80) { + vTaskDelay(100 / portTICK_RATE_MS); + } + cmd++; + } + + ili9488_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION); } // Flush function based on mvturnho repo @@ -101,9 +119,7 @@ void ili9488_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * col uint8_t *mybuf; do { mybuf = (uint8_t *) heap_caps_malloc(3 * size * sizeof(uint8_t), MALLOC_CAP_DMA); - if (mybuf == NULL) { - LV_LOG_WARN("Could not allocate enough DMA memory!"); - } + if (mybuf == NULL) ESP_LOGW(TAG, "Could not allocate enough DMA memory!"); } while (mybuf == NULL); uint32_t LD = 0; @@ -136,17 +152,17 @@ void ili9488_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * col }; /*Column addresses*/ - ili9488_send_cmd(drv, ILI9488_CMD_COLUMN_ADDRESS_SET); - ili9488_send_data(drv, xb, 4); + ili9488_send_cmd(ILI9488_CMD_COLUMN_ADDRESS_SET); + ili9488_send_data(xb, 4); /*Page addresses*/ - ili9488_send_cmd(drv, ILI9488_CMD_PAGE_ADDRESS_SET); - ili9488_send_data(drv, yb, 4); + ili9488_send_cmd(ILI9488_CMD_PAGE_ADDRESS_SET); + ili9488_send_data(yb, 4); /*Memory write*/ - ili9488_send_cmd(drv, ILI9488_CMD_MEMORY_WRITE); + ili9488_send_cmd(ILI9488_CMD_MEMORY_WRITE); - ili9488_send_color(drv, (void *) mybuf, size * 3); + ili9488_send_color((void *) mybuf, size * 3); heap_caps_free(mybuf); } @@ -154,65 +170,44 @@ void ili9488_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * col * STATIC FUNCTIONS **********************/ -static inline void set_cmd_mode(lv_disp_drv_t * drv) -{ - display_port_gpio_dc(drv, 0); -} -static inline void set_data_mode(lv_disp_drv_t * drv) -{ - display_port_gpio_dc(drv, 1); -} - -static void ili9488_send_cmd(lv_disp_drv_t * drv, uint8_t cmd) +static void ili9488_send_cmd(uint8_t cmd) { disp_wait_for_pending_transactions(); - set_cmd_mode(drv); + gpio_set_level(ILI9488_DC, 0); /*Command mode*/ disp_spi_send_data(&cmd, 1); } -static void ili9488_send_data(lv_disp_drv_t * drv, void * data, uint16_t length) +static void ili9488_send_data(void * data, uint16_t length) { disp_wait_for_pending_transactions(); - set_data_mode(drv); + gpio_set_level(ILI9488_DC, 1); /*Data mode*/ disp_spi_send_data(data, length); } -static void ili9488_send_color(lv_disp_drv_t * drv, void * data, uint16_t length) +static void ili9488_send_color(void * data, uint16_t length) { disp_wait_for_pending_transactions(); - set_data_mode(drv); + gpio_set_level(ILI9488_DC, 1); /*Data mode*/ disp_spi_send_colors(data, length); } -static void ili9488_set_orientation(lv_disp_drv_t * drv, uint8_t orientation) +static void ili9488_set_orientation(uint8_t orientation) { - assert(orientation < 4); - const uint8_t data[] = {0x48, 0x88, 0x28, 0xE8}; + // ESP_ASSERT(orientation < 4); -#if (LV_USE_LOG == 1) const char *orientation_str[] = { "PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED" }; - LV_LOG_INFO("Display orientation: %s", orientation_str[orientation]); - LV_LOG_INFO("0x36 command value: 0x%02X", data[orientation]); + ESP_LOGI(TAG, "Display orientation: %s", orientation_str[orientation]); + +#if defined (CONFIG_LV_PREDEFINED_DISPLAY_NONE) + uint8_t data[] = {0x48, 0x88, 0x28, 0xE8}; #endif - ili9488_send_cmd(drv, 0x36); - ili9488_send_data(drv, (void *) &data[orientation], 1); -} + ESP_LOGI(TAG, "0x36 command value: 0x%02X", data[orientation]); -/* Reset the display, if we don't have a reset pin we use software reset */ -static void ili9488_reset(lv_disp_drv_t *drv) -{ -#if defined(ILI9488_USE_RST) - display_port_gpio_rst(drv, 0); - display_port_delay(drv, 100); - display_port_gpio_rst(drv, 1); - display_port_delay(drv, 100); -#else - ili9488_send_cmd(drv, 0x01); - display_port_delay(drv, 5); -#endif + ili9488_send_cmd(0x36); + ili9488_send_data((void *) &data[orientation], 1); } diff --git a/lvgl_tft/ili9488.h b/lvgl_tft/ili9488.h index fd393b8..1c6c6f9 100644 --- a/lvgl_tft/ili9488.h +++ b/lvgl_tft/ili9488.h @@ -20,13 +20,14 @@ extern "C" { #else #include "lvgl/lvgl.h" #endif - #include "../lvgl_helpers.h" -#include "display_config.h" /********************* * 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 /******************* * ILI9488 REGS @@ -143,7 +144,7 @@ typedef struct { * GLOBAL PROTOTYPES **********************/ -void ili9488_init(lv_disp_drv_t * drv); +void ili9488_init(void); void ili9488_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map); /********************** diff --git a/lvgl_tft/jd79653a.c b/lvgl_tft/jd79653a.c index 55737f9..0f4be67 100644 --- a/lvgl_tft/jd79653a.c +++ b/lvgl_tft/jd79653a.c @@ -29,39 +29,23 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #include #include #include +#include #include "disp_spi.h" #include "jd79653a.h" +#define TAG "lv_jd79653a" + #define PIN_DC CONFIG_LV_DISP_PIN_DC #define PIN_DC_BIT ((1ULL << (uint8_t)(CONFIG_LV_DISP_PIN_DC))) - -#if defined CONFIG_LV_DISP_PIN_RST #define PIN_RST CONFIG_LV_DISP_PIN_RST #define PIN_RST_BIT ((1ULL << (uint8_t)(CONFIG_LV_DISP_PIN_RST))) -#endif - #define PIN_BUSY CONFIG_LV_DISP_PIN_BUSY #define PIN_BUSY_BIT ((1ULL << (uint8_t)(CONFIG_LV_DISP_PIN_BUSY))) #define EVT_BUSY (1UL << 0UL) - -#if defined (LV_HOR_RES_MAX) #define EPD_WIDTH LV_HOR_RES_MAX -#else - /* ToDo Remove magic number */ -#define EPD_WIDTH 256u -#endif - -#if defined (LV_VER_RES_MAX) #define EPD_HEIGHT LV_VER_RES_MAX -#else - /* ToDo Remove magic number */ -#define EPD_HEIGHT 128u -#endif - #define EPD_ROW_LEN (EPD_HEIGHT / 8u) - -/* ToDo Remove semicolon */ #define EPD_PARTIAL_CNT 5; #define BIT_SET(a, b) ((a) |= (1U << (b))) @@ -139,9 +123,10 @@ static const uint8_t lut_bb1[] = { static const jd79653a_seq_t init_seq[] = { #if defined (CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED) {0x00, {0xd3, 0x0e}, 2}, // Panel settings -//#elif defined(CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT) -#else +#elif defined(CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT) {0x00, {0xdf, 0x0e}, 2}, // Panel settings +#else +#error "Unsupported orientation - only portrait modes are supported for now" #endif {0x4d, {0x55}, 1}, // Undocumented secret from demo code {0xaa, {0x0f}, 1}, // Undocumented secret from demo code @@ -191,9 +176,16 @@ static void jd79653a_spi_send_data(uint8_t *data, size_t len) disp_spi_send_data(data, len); } +static void jd79653a_spi_send_fb(uint8_t *data, size_t len) +{ + disp_wait_for_pending_transactions(); + gpio_set_level(PIN_DC, 1); // DC = 1 for data + disp_spi_send_colors(data, len); +} + static void jd79653a_spi_send_seq(const jd79653a_seq_t *seq, size_t len) { - LV_LOG_INFO("Writing cmd/data sequence, count %u", len); + ESP_LOGD(TAG, "Writing cmd/data sequence, count %u", len); if (!seq || len < 1) return; for (size_t cmd_idx = 0; cmd_idx < len; cmd_idx++) { @@ -215,21 +207,21 @@ static esp_err_t jd79653a_wait_busy(uint32_t timeout_ms) return ((bits & EVT_BUSY) != 0) ? ESP_OK : ESP_ERR_TIMEOUT; } -static void jd79653a_power_on(void) +static void jd79653a_power_on() { jd79653a_spi_send_seq(power_on_seq, EPD_SEQ_LEN(power_on_seq)); vTaskDelay(pdMS_TO_TICKS(10)); jd79653a_wait_busy(0); } -static void jd79653a_power_off(void) +static void jd79653a_power_off() { jd79653a_spi_send_seq(power_off_seq, EPD_SEQ_LEN(power_off_seq)); vTaskDelay(pdMS_TO_TICKS(10)); jd79653a_wait_busy(0); } -static void jd79653a_load_partial_lut(void) +static void jd79653a_load_partial_lut() { jd79653a_spi_send_cmd(0x20); // LUT VCOM register jd79653a_spi_send_data((uint8_t *)lut_vcom_dc1, sizeof(lut_vcom_dc1)); @@ -247,9 +239,9 @@ static void jd79653a_load_partial_lut(void) jd79653a_spi_send_data((uint8_t *)lut_bb1, sizeof(lut_bb1)); } -static void jd79653a_partial_in(void) +static void jd79653a_partial_in() { - LV_LOG_INFO("Partial in!"); + ESP_LOGD(TAG, "Partial in!"); // Panel setting: accept LUT from registers instead of OTP #if defined (CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED) @@ -257,8 +249,7 @@ static void jd79653a_partial_in(void) #elif defined(CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT) uint8_t pst_use_reg_lut[] = { 0xff, 0x0e }; #else - assert(false); // Unsupported orientation configured. Crash if we get here, but allow compilation for CI - uint8_t pst_use_reg_lut[] = { 0,0 }; +#error "Unsupported orientation - only portrait modes are supported for now" #endif jd79653a_spi_send_cmd(0x00); jd79653a_spi_send_data(pst_use_reg_lut, sizeof(pst_use_reg_lut)); @@ -275,9 +266,9 @@ static void jd79653a_partial_in(void) jd79653a_spi_send_cmd(0x91); } -static void jd79653a_partial_out(void) +static void jd79653a_partial_out() { - LV_LOG_INFO("Partial out!"); + ESP_LOGD(TAG, "Partial out!"); // Panel setting: use LUT from OTP #if defined (CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED) @@ -285,8 +276,7 @@ static void jd79653a_partial_out(void) #elif defined(CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT) uint8_t pst_use_otp_lut[] = { 0xdf, 0x0e }; #else - assert(false); // Unsupported orientation configured. Crash if we get here, but allow compilation for CI - uint8_t pst_use_otp_lut[] = { 0,0 }; +#error "Unsupported orientation - only portrait modes are supported for now" #endif jd79653a_spi_send_cmd(0x00); jd79653a_spi_send_data(pst_use_otp_lut, sizeof(pst_use_otp_lut)); @@ -304,10 +294,10 @@ static void jd79653a_update_partial(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t { jd79653a_power_on(); jd79653a_partial_in(); - LV_LOG_INFO("x1: 0x%x, x2: 0x%x, y1: 0x%x, y2: 0x%x", x1, x2, y1, y2); + ESP_LOGD(TAG, "x1: 0x%x, x2: 0x%x, y1: 0x%x, y2: 0x%x", x1, x2, y1, y2); size_t len = ((x2 - x1 + 1) * (y2 - y1 + 1)) / 8; - LV_LOG_INFO("Writing PARTIAL LVGL fb with len: %u", len); + ESP_LOGD(TAG, "Writing PARTIAL LVGL fb with len: %u", len); // Set partial window uint8_t ptl_setting[7] = { x1, x2, 0, y1, 0, y2, 0x01 }; @@ -323,18 +313,16 @@ static void jd79653a_update_partial(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t len -= EPD_ROW_LEN; } - LV_LOG_INFO("Partial wait start"); + ESP_LOGD(TAG, "Partial wait start"); jd79653a_spi_send_cmd(0x12); jd79653a_wait_busy(0); - LV_LOG_INFO("Partial updated"); + ESP_LOGD(TAG, "Partial updated"); jd79653a_partial_out(); jd79653a_power_off(); } -static void jd79653a_reset(void); - void jd79653a_fb_set_full_color(uint8_t color) { jd79653a_power_on(); @@ -365,7 +353,7 @@ void jd79653a_fb_set_full_color(uint8_t color) void jd79653a_fb_full_update(uint8_t *data, size_t len) { jd79653a_power_on(); - LV_LOG_INFO("Performing full update, len: %u", len); + ESP_LOGD(TAG, "Performing full update, len: %u", len); uint8_t *data_ptr = data; @@ -384,7 +372,7 @@ void jd79653a_fb_full_update(uint8_t *data, size_t len) len -= EPD_ROW_LEN; } - LV_LOG_INFO("Rest len: %u", len); + ESP_LOGD(TAG, "Rest len: %u", len); jd79653a_spi_send_cmd(0x12); // Issue refresh command vTaskDelay(pdMS_TO_TICKS(100)); @@ -393,7 +381,7 @@ void jd79653a_fb_full_update(uint8_t *data, size_t len) jd79653a_power_off(); } -void jd79653a_lv_set_fb_cb(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, +void jd79653a_lv_set_fb_cb(struct _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) { uint16_t byte_index = (x >> 3u) + (y * EPD_ROW_LEN); @@ -406,7 +394,7 @@ void jd79653a_lv_set_fb_cb(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf } } -void jd79653a_lv_rounder_cb(lv_disp_drv_t *disp_drv, lv_area_t *area) +void jd79653a_lv_rounder_cb(struct _disp_drv_t *disp_drv, lv_area_t *area) { // Always send full framebuffer if it's not in partial mode area->x1 = 0; @@ -417,16 +405,15 @@ void jd79653a_lv_rounder_cb(lv_disp_drv_t *disp_drv, lv_area_t *area) void jd79653a_lv_fb_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map) { -#if LV_USE_LOG size_t len = ((area->x2 - area->x1 + 1) * (area->y2 - area->y1 + 1)) / 8; - LV_LOG_INFO("x1: 0x%x, x2: 0x%x, y1: 0x%x, y2: 0x%x", area->x1, area->x2, area->y1, area->y2); - LV_LOG_INFO("Writing LVGL fb with len: %u, partial counter: %u", len, partial_counter); -#endif + + ESP_LOGD(TAG, "x1: 0x%x, x2: 0x%x, y1: 0x%x, y2: 0x%x", area->x1, area->x2, area->y1, area->y2); + ESP_LOGD(TAG, "Writing LVGL fb with len: %u, partial counter: %u", len, partial_counter); uint8_t *buf = (uint8_t *) color_map; if (partial_counter == 0) { - LV_LOG_INFO("Refreshing in FULL"); + ESP_LOGD(TAG, "Refreshing in FULL"); jd79653a_fb_full_update(buf, ((EPD_HEIGHT * EPD_WIDTH) / 8)); partial_counter = EPD_PARTIAL_CNT; // Reset partial counter here } else { @@ -437,7 +424,7 @@ void jd79653a_lv_fb_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t lv_disp_flush_ready(drv); } -void jd79653a_deep_sleep(void) +void jd79653a_deep_sleep() { jd79653a_spi_send_seq(power_off_seq, EPD_SEQ_LEN(power_off_seq)); jd79653a_wait_busy(1000); @@ -447,15 +434,25 @@ void jd79653a_deep_sleep(void) jd79653a_spi_send_data(&check_code, sizeof(check_code)); } -void jd79653a_init(void) +void jd79653a_init() { // Initialise event group jd79653a_evts = xEventGroupCreate(); if (!jd79653a_evts) { - LV_LOG_ERROR("Failed when initialising event group!"); + ESP_LOGE(TAG, "Failed when initialising event group!"); return; } + // Setup output pins, output (PP) + gpio_config_t out_io_conf = { + .intr_type = GPIO_INTR_DISABLE, + .mode = GPIO_MODE_OUTPUT, + .pin_bit_mask = PIN_DC_BIT | PIN_RST_BIT, + .pull_down_en = 0, + .pull_up_en = 0, + }; + ESP_ERROR_CHECK(gpio_config(&out_io_conf)); + // Setup input pin, pull-up, input gpio_config_t in_io_conf = { .intr_type = GPIO_INTR_POSEDGE, @@ -468,25 +465,18 @@ void jd79653a_init(void) gpio_install_isr_service(0); gpio_isr_handler_add(PIN_BUSY, jd79653a_busy_intr, (void *) PIN_BUSY); - jd79653a_reset(); + // Hardware reset + gpio_set_level(PIN_RST, 0); + vTaskDelay(pdMS_TO_TICKS(15)); // At least 10ms, leave 15ms for now just in case... + gpio_set_level(PIN_RST, 1); + vTaskDelay(pdMS_TO_TICKS(120)); // Dump in initialise sequence jd79653a_spi_send_seq(init_seq, EPD_SEQ_LEN(init_seq)); - LV_LOG_INFO("Panel init sequence sent"); + ESP_LOGI(TAG, "Panel init sequence sent"); // Check BUSY status here jd79653a_wait_busy(0); - LV_LOG_INFO("Panel is up!"); -} - -static void jd79653a_reset(void) -{ -#if defined CONFIG_LV_DISP_PIN_RST - gpio_set_level(PIN_RST, 0); - // At least 10ms, leave 15ms for now just in case... - vTaskDelay(pdMS_TO_TICKS(15)); - gpio_set_level(PIN_RST, 1); - vTaskDelay(pdMS_TO_TICKS(120)); -#endif + ESP_LOGI(TAG, "Panel is up!"); } diff --git a/lvgl_tft/jd79653a.h b/lvgl_tft/jd79653a.h index b25e805..6a2065a 100644 --- a/lvgl_tft/jd79653a.h +++ b/lvgl_tft/jd79653a.h @@ -17,12 +17,12 @@ extern "C" #include "lvgl/lvgl.h" #endif -void jd79653a_init(void); -void jd79653a_deep_sleep(void); +void jd79653a_init(); +void jd79653a_deep_sleep(); -void jd79653a_lv_set_fb_cb(lv_disp_drv_t * disp_drv, uint8_t* buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, +void jd79653a_lv_set_fb_cb(struct _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 jd79653a_lv_rounder_cb(lv_disp_drv_t * disp_drv, lv_area_t *area); +void jd79653a_lv_rounder_cb(struct _disp_drv_t * disp_drv, lv_area_t *area); void jd79653a_lv_fb_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map); void jd79653a_fb_set_full_color(uint8_t color); diff --git a/lvgl_tft/pcd8544.c b/lvgl_tft/pcd8544.c index 77321d8..49d067e 100644 --- a/lvgl_tft/pcd8544.c +++ b/lvgl_tft/pcd8544.c @@ -6,10 +6,14 @@ * https://github.com/olikraus/u8g2 */ -#include "pcd8544.h" - #include "disp_spi.h" -#include "display_port.h" +#include "driver/gpio.h" + +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include "pcd8544.h" #define TAG "lv_pcd8544" @@ -23,33 +27,24 @@ /********************** * STATIC FUNCTIONS **********************/ -static inline void set_cmd_mode(lv_disp_drv_t * drv) -{ - display_port_gpio_dc(drv, 0); -} -static inline void set_data_mode(lv_disp_drv_t * drv) -{ - display_port_gpio_dc(drv, 1); -} - -static void pcd8544_send_cmd(lv_disp_drv_t *drv, uint8_t cmd) +static void pcd8544_send_cmd(uint8_t cmd) { disp_wait_for_pending_transactions(); - set_cmd_mode(drv); + gpio_set_level(PCD8544_DC, 0); /*Command mode*/ disp_spi_send_data(&cmd, 1); } -static void pcd8544_send_data(lv_disp_drv_t *drv, void * data, uint16_t length) +static void pcd8544_send_data(void * data, uint16_t length) { disp_wait_for_pending_transactions(); - set_data_mode(drv); + gpio_set_level(PCD8544_DC, 1); /*Data mode*/ disp_spi_send_data(data, length); } -static void pcd8544_send_colors(lv_disp_drv_t *drv, void * data, uint16_t length) +static void pcd8544_send_colors(void * data, uint16_t length) { - set_data_mode(drv); + gpio_set_level(PCD8544_DC, 1); /*Data mode*/ disp_spi_send_colors(data, length); } @@ -57,38 +52,37 @@ static void pcd8544_send_colors(lv_disp_drv_t *drv, void * data, uint16_t length * GLOBAL FUNCTIONS **********************/ -void pcd8544_reset(lv_disp_drv_t *drv) -{ - display_port_gpio_rst(drv, 0); - display_port_delay(drv, 100); - display_port_gpio_rst(drv, 1); - display_port_delay(drv, 100); -} +void pcd8544_init(void){ -void pcd8544_init(lv_disp_drv_t *drv) -{ // TODO: orientation + // Initialize non-SPI GPIOs + gpio_pad_select_gpio(PCD8544_DC); + gpio_set_direction(PCD8544_DC, GPIO_MODE_OUTPUT); + gpio_pad_select_gpio(PCD8544_RST); + gpio_set_direction(PCD8544_RST, GPIO_MODE_OUTPUT); + // Reset the display - pcd8544_reset(drv); + gpio_set_level(PCD8544_RST, 0); + vTaskDelay(100 / portTICK_RATE_MS); + gpio_set_level(PCD8544_RST, 1); + vTaskDelay(100 / portTICK_RATE_MS); - pcd8544_send_cmd(drv, 0x21); /* activate chip (PD=0), horizontal increment (V=0), enter extended command set (H=1) */ - pcd8544_send_cmd(drv, 0x06); /* temp. control: b10 = 2 */ - pcd8544_send_cmd(drv, 0x13); /* bias system 1:48 */ - pcd8544_send_cmd(drv, 0xc0); /* medium Vop = Contrast 0x40 = 64 */ + pcd8544_send_cmd(0x21); /* activate chip (PD=0), horizontal increment (V=0), enter extended command set (H=1) */ + pcd8544_send_cmd(0x06); /* temp. control: b10 = 2 */ + pcd8544_send_cmd(0x13); /* bias system 1:48 */ + pcd8544_send_cmd(0xc0); /* medium Vop = Contrast 0x40 = 64 */ - pcd8544_send_cmd(drv, 0x20); /* activate chip (PD=0), horizontal increment (V=0), enter extended command set (H=0) */ - pcd8544_send_cmd(drv, 0x0c); /* display mode normal */ + pcd8544_send_cmd(0x20); /* activate chip (PD=0), horizontal increment (V=0), enter extended command set (H=0) */ + pcd8544_send_cmd(0x0c); /* display mode normal */ } -void pcd8544_set_contrast(lv_disp_drv_t *drv, uint8_t contrast) -{ +void pcd8544_set_contrast (uint8_t contrast){ if (contrast > 0x7f){ contrast = 0x7f; } - - pcd8544_send_cmd(drv, 0x21); /* activate chip (PD=0), horizontal increment (V=0), enter extended command set (H=1) */ - pcd8544_send_cmd(drv, 0x80 | contrast); /* medium Vop = Contrast */ + pcd8544_send_cmd(0x21); /* activate chip (PD=0), horizontal increment (V=0), enter extended command set (H=1) */ + pcd8544_send_cmd(0x80 | contrast); /* medium Vop = Contrast */ } void pcd8544_rounder(lv_disp_drv_t * disp_drv, lv_area_t *area){ @@ -118,7 +112,7 @@ void pcd8544_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w void pcd8544_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_map){ - pcd8544_send_cmd(disp_drv, 0x20); /* activate chip (PD=0), horizontal increment (V=0), enter extended command set (H=0) */ + pcd8544_send_cmd(0x20); /* activate chip (PD=0), horizontal increment (V=0), enter extended command set (H=0) */ uint8_t * buf = (uint8_t *) color_map; @@ -129,9 +123,9 @@ void pcd8544_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t // send complete frame buffer at once. // NOTE: disp_spi_send_colors triggers lv_disp_flush_ready - pcd8544_send_cmd(disp_drv, 0x40); /* set Y address */ - pcd8544_send_cmd(disp_drv, 0x80); /* set X address */ - pcd8544_send_colors(disp_drv, buf, disp_drv->hor_res * disp_drv->ver_res / 8); + pcd8544_send_cmd(0x40); /* set Y address */ + pcd8544_send_cmd(0x80); /* set X address */ + pcd8544_send_colors(buf, disp_drv->hor_res * disp_drv->ver_res / 8); } else { @@ -142,11 +136,11 @@ void pcd8544_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t uint16_t bank; uint16_t cols_to_update = area->x2 - area->x1 + 1; - for (bank = bank_start ; bank <= bank_end ; bank++){ - pcd8544_send_cmd(disp_drv, 0x40 | bank); /* set Y address */ - pcd8544_send_cmd(disp_drv, 0x80 | area->x1); /* set X address */ + for (bank = bank_start ; bank <= bank_end ; bank++ ){ + pcd8544_send_cmd(0x40 | bank ); /* set Y address */ + pcd8544_send_cmd(0x80 | area->x1 ); /* set X address */ uint16_t offset = bank * disp_drv->hor_res + area->x1; - pcd8544_send_data(disp_drv, &buf[offset], cols_to_update); + pcd8544_send_data(&buf[offset], cols_to_update); } lv_disp_flush_ready(disp_drv); diff --git a/lvgl_tft/pcd8544.h b/lvgl_tft/pcd8544.h index de0dd4a..24fcc71 100644 --- a/lvgl_tft/pcd8544.h +++ b/lvgl_tft/pcd8544.h @@ -26,6 +26,10 @@ extern "C" { * DEFINES *********************/ +#define PCD8544_DC CONFIG_LV_DISP_PIN_DC +#define PCD8544_RST CONFIG_LV_DISP_PIN_RST +#define PCD8544_BCKL CONFIG_LV_DISP_PIN_BCKL + /********************** * TYPEDEFS **********************/ @@ -34,12 +38,12 @@ extern "C" { * GLOBAL PROTOTYPES **********************/ -void pcd8544_init(lv_disp_drv_t *drv); +void pcd8544_init(void); void pcd8544_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map); void pcd8544_rounder(lv_disp_drv_t * disp_drv, lv_area_t *area); void pcd8544_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 pcd8544_set_contrast(lv_disp_drv_t *drv, uint8_t contrast); +void pcd8544_set_contrast(uint8_t contrast); /********************** * MACROS diff --git a/lvgl_tft/ra8875.c b/lvgl_tft/ra8875.c index c394752..b4f8e2a 100644 --- a/lvgl_tft/ra8875.c +++ b/lvgl_tft/ra8875.c @@ -9,12 +9,16 @@ #include "ra8875.h" #include "disp_spi.h" #include "driver/gpio.h" +#include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" /********************* * DEFINES *********************/ +#define DEBUG false +#define TAG "RA8875" + #define DIV_ROUND_UP(n, d) (((n)+(d)-1)/(d)) #define SPI_CLOCK_SPEED_SLOW_HZ 1000000 @@ -24,45 +28,6 @@ #define RA8875_MODE_CMD_WRITE (0x80) #define RA8875_MODE_STATUS_READ (0xC0) -#define BYTES_PER_PIXEL (LV_COLOR_DEPTH / 8) - -#if defined (LV_HOR_RES_MAX) -#define HDWR_VAL (LV_HOR_RES_MAX/8 - 1) -#else - /* ToDo Remove magic number 256u */ -#define HDWR_VAL (256u/8u - 1u) -#endif - -#if defined (LV_VER_RES_MAX) -#define VDHR_VAL (LV_VER_RES_MAX - 1) -#else - /* ToDo Remove magic number 128u */ -#define VDHR_VAL (128u - 1u) -#endif - -#define VDIR_MASK (1 << 2) -#define HDIR_MASK (1 << 3) - -#ifndef CONFIG_LV_TFT_DISPLAY_CONTROLLER_RA8875 - // Use this settings if there is no Kconfig settings defined - #define SYSR_VAL (0x00) - #define DPCR_VAL (0x00) - #define PCSR_VAL (0x00) - #define HNDR_VAL (0x00) - #define HNDFTR_VAL (0x00) - #define HSTR_VAL (0x00) - #define HPW (0x00) - #define HPWR_VAL (0x00) - #define VNDR_VAL (0x00) - #define VSTR_VAL (0x00) - #define VPW (0x00) - #define VPWR_VAL (0x00) - #define CONFIG_LV_DISP_RA8875_PLLDIVM (0x00) - #define CONFIG_LV_DISP_RA8875_PLLDIVN (0x00) - #define CONFIG_LV_DISP_RA8875_PLLDIVK (0x00) - -#else - #if (LV_COLOR_DEPTH == 8) #define SYSR_VAL (0x00) #elif (LV_COLOR_DEPTH == 16) @@ -70,6 +35,13 @@ #else #error "Unsupported color depth (LV_COLOR_DEPTH)" #endif +#define BYTES_PER_PIXEL (LV_COLOR_DEPTH / 8) + +#define HDWR_VAL (LV_HOR_RES_MAX/8 - 1) +#define VDHR_VAL (LV_VER_RES_MAX - 1) + +#define VDIR_MASK (1 << 2) +#define HDIR_MASK (1 << 3) #if ( CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED || CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED ) #if CONFIG_LV_INVERT_DISPLAY @@ -120,7 +92,6 @@ #else #define VPWR_VAL (VPW) #endif -#endif // CONFIG_LV_TFT_DISPLAY_CONTROLLER_RA8875 /********************** * TYPEDEFS @@ -133,7 +104,7 @@ static void ra8875_configure_clocks(bool high_speed); static void ra8875_set_memory_write_cursor(unsigned int x, unsigned int y); static void ra8875_set_window(unsigned int xs, unsigned int xe, unsigned int ys, unsigned int ye); static void ra8875_send_buffer(uint8_t * data, size_t length, bool signal_flush); -static void ra8875_reset(void); + /********************** * STATIC VARIABLES **********************/ @@ -148,9 +119,6 @@ static void ra8875_reset(void); void ra8875_init(void) { -#ifndef CONFIG_LV_TFT_DISPLAY_CONTROLLER_RA8875 - assert(false); // This driver is not properly configured -#endif unsigned int i = 0; struct { @@ -178,9 +146,20 @@ void ra8875_init(void) }; #define INIT_CMDS_SIZE (sizeof(init_cmds)/sizeof(init_cmds[0])) - LV_LOG_INFO("Initializing RA8875..."); + ESP_LOGI(TAG, "Initializing RA8875..."); - ra8875_reset(); + // Initialize non-SPI GPIOs + +#if RA8875_USE_RST + gpio_pad_select_gpio(RA8875_RST); + gpio_set_direction(RA8875_RST, GPIO_MODE_OUTPUT); + + // 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); @@ -201,7 +180,7 @@ void ra8875_init(void) vTaskDelay(1); } if (i == 0) { - LV_LOG_WARN("WARNING: Memory clear timed out; RA8875 may be unresponsive."); + ESP_LOGW(TAG, "WARNING: Memory clear timed out; RA8875 may be unresponsive."); } // Enable the display @@ -210,7 +189,7 @@ void ra8875_init(void) void ra8875_enable_display(bool enable) { - LV_LOG_INFO("%s display.", enable ? "Enabling" : "Disabling"); + ESP_LOGI(TAG, "%s display.", enable ? "Enabling" : "Disabling"); uint8_t val = enable ? (0x80) : (0x00); ra8875_write_cmd(RA8875_REG_PWRR, val); // Power and Display Control Register (PWRR) } @@ -226,47 +205,35 @@ void ra8875_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * colo size_t linelen = (area->x2 - area->x1 + 1); uint8_t * buffer = (uint8_t*)color_map; - LV_LOG_INFO("flush: %d,%d at %d,%d", area->x1, area->x2, area->y1, area->y2 ); +#if DEBUG + ESP_LOGI(TAG, "flush: %d,%d at %d,%d", area->x1, area->x2, area->y1, area->y2 ); +#endif // Get lock disp_spi_acquire(); // Set window if needed if ((x1 != area->x1) || (x2 != area->x2)) { - LV_LOG_INFO("flush: set window (x1,x2): %d,%d -> %d,%d", x1, x2, area->x1, area->x2); - unsigned int ye = 0; - -#if LVGL_VERSION_MAJOR < 8 - ye = LV_VER_RES_MAX - 1; -#else - /* ToDo Get y end from driver information */ +#if DEBUG + ESP_LOGI(TAG, "flush: set window (x1,x2): %d,%d -> %d,%d", x1, x2, area->x1, area->x2); #endif - - ra8875_set_window(area->x1, area->x2, 0, ye); - + ra8875_set_window(area->x1, area->x2, 0, LV_VER_RES_MAX-1); x1 = area->x1; x2 = area->x2; } // Set cursor if needed if ((x != area->x1) || (y != area->y1)) { - LV_LOG_INFO("flush: set cursor (x,y): %d,%d -> %d,%d", x, y, area->x1, area->y1); +#if DEBUG + ESP_LOGI(TAG, "flush: set cursor (x,y): %d,%d -> %d,%d", x, y, area->x1, area->y1); +#endif ra8875_set_memory_write_cursor(area->x1, area->y1); x = area->x1; } // Update to future cursor location y = area->y2 + 1; - lv_coord_t ver_max = 0; - -#if LVGL_VERSION_MAJOR < 8 - ver_max = LV_VER_RES_MAX; -#else - /* ToDo Get vertical max from driver information */ - ver_max = lv_disp_get_ver_res((lv_disp_t *) drv); -#endif - - if (y >= ver_max) { + if (y >= LV_VER_RES_MAX) { y = 0; } @@ -284,21 +251,21 @@ void ra8875_sleep_in(void) ra8875_configure_clocks(false); ra8875_write_cmd(RA8875_REG_PWRR, 0x00); // Power and Display Control Register (PWRR) - vTaskDelay(DIV_ROUND_UP(20, portTICK_PERIOD_MS)); + vTaskDelay(DIV_ROUND_UP(20, portTICK_RATE_MS)); ra8875_write_cmd(RA8875_REG_PWRR, 0x02); // Power and Display Control Register (PWRR) } void ra8875_sleep_out(void) { ra8875_write_cmd(RA8875_REG_PWRR, 0x00); // Power and Display Control Register (PWRR) - vTaskDelay(DIV_ROUND_UP(20, portTICK_PERIOD_MS)); + vTaskDelay(DIV_ROUND_UP(20, portTICK_RATE_MS)); ra8875_configure_clocks(true); disp_spi_change_device_speed(-1); ra8875_write_cmd(RA8875_REG_PWRR, 0x80); // Power and Display Control Register (PWRR) - vTaskDelay(DIV_ROUND_UP(20, portTICK_PERIOD_MS)); + vTaskDelay(DIV_ROUND_UP(20, portTICK_RATE_MS)); } uint8_t ra8875_read_cmd(uint8_t cmd) @@ -331,7 +298,7 @@ void ra8875_configure_clocks(bool high_speed) vTaskDelay(1); ra8875_write_cmd(RA8875_REG_PCSR, PCSR_VAL); // Pixel Clock Setting Register (PCSR) - vTaskDelay(DIV_ROUND_UP(20, portTICK_PERIOD_MS)); + vTaskDelay(DIV_ROUND_UP(20, portTICK_RATE_MS)); } static void ra8875_set_window(unsigned int xs, unsigned int xe, unsigned int ys, unsigned int ye) @@ -365,13 +332,3 @@ static void ra8875_send_buffer(uint8_t * data, size_t length, bool signal_flush) | (RA8875_MODE_DATA_WRITE); // Data write mode disp_spi_transaction(data, length, flags, NULL, prefix, 0); } - -static void ra8875_reset(void) -{ -#if RA8875_USE_RST - gpio_set_level(RA8875_RST, 0); - vTaskDelay(DIV_ROUND_UP(100, portTICK_PERIOD_MS)); - gpio_set_level(RA8875_RST, 1); - vTaskDelay(DIV_ROUND_UP(100, portTICK_PERIOD_MS)); -#endif -} diff --git a/lvgl_tft/schmitt.c b/lvgl_tft/schmitt.c new file mode 100644 index 0000000..176947d --- /dev/null +++ b/lvgl_tft/schmitt.c @@ -0,0 +1,27 @@ +#include + +#include "schmitt.h" +#include "disp_spi.h" + +#include "esp_log.h" + +static const char* TAG = "SCHMITT_DIS"; + +void schmitt_init(void) +{ + disp_spi_acquire(); + // Do things + ESP_LOGI(TAG, "schmitt_init() called"); + disp_spi_release(); +} + +void schmitt_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map) +{ + disp_spi_acquire(); + // Do things + uint32_t size = lv_area_get_width(area) * lv_area_get_height(area); + disp_spi_send_colors(color_map, size * 4); + ESP_LOGI(TAG, "schmitt_flush() called"); + disp_spi_release(); + lv_disp_flush_ready(drv); +} \ No newline at end of file diff --git a/lvgl_tft/schmitt.h b/lvgl_tft/schmitt.h new file mode 100644 index 0000000..608f752 --- /dev/null +++ b/lvgl_tft/schmitt.h @@ -0,0 +1,20 @@ +#ifndef SCHMITT_H_ +#define SCHMITT_H_ + +#include + +#ifdef LV_LVGL_H_INCLUDE_SIMPLE +#include "lvgl.h" +#else +#include "lvgl/lvgl.h" +#endif +#include "../lvgl_helpers.h" + +#define LV_HOR_RES_MAX 64 +#define LV_VER_RES_MAX 64 + +void schmitt_init(void); + +void schmitt_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map); + +#endif /* SCHMITT_H_ */ \ No newline at end of file diff --git a/lvgl_tft/sh1107.c b/lvgl_tft/sh1107.c index 8c9874a..d7f6067 100644 --- a/lvgl_tft/sh1107.c +++ b/lvgl_tft/sh1107.c @@ -16,6 +16,7 @@ /********************* * DEFINES *********************/ + #define TAG "SH1107" /********************** * TYPEDEFS @@ -34,10 +35,6 @@ typedef struct { static void sh1107_send_cmd(uint8_t cmd); static void sh1107_send_data(void * data, uint16_t length); static void sh1107_send_color(void * data, uint16_t length); -static void sh1107_reset(void); - -static lv_coord_t get_display_ver_res(lv_disp_drv_t *disp_drv); -static lv_coord_t get_display_hor_res(lv_disp_drv_t *disp_drv); /********************** * STATIC VARIABLES @@ -94,21 +91,34 @@ void sh1107_init(void) {0, {0}, 0xff}, }; - sh1107_reset(); + //Initialize non-SPI GPIOs + gpio_pad_select_gpio(SH1107_DC); + gpio_set_direction(SH1107_DC, GPIO_MODE_OUTPUT); - //Send all the commands - uint16_t cmd = 0; - while (init_cmds[cmd].databytes!=0xff) { - sh1107_send_cmd(init_cmds[cmd].cmd); - sh1107_send_data(init_cmds[cmd].data, init_cmds[cmd].databytes&0x1F); - if (init_cmds[cmd].databytes & 0x80) { - vTaskDelay(pdMS_TO_TICKS(100)); - } - cmd++; - } +#if SH1107_USE_RST + gpio_pad_select_gpio(SH1107_RST); + gpio_set_direction(SH1107_RST, GPIO_MODE_OUTPUT); + + //Reset the display + gpio_set_level(SH1107_RST, 0); + 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; + while (init_cmds[cmd].databytes!=0xff) { + sh1107_send_cmd(init_cmds[cmd].cmd); + sh1107_send_data(init_cmds[cmd].data, init_cmds[cmd].databytes&0x1F); + if (init_cmds[cmd].databytes & 0x80) { + vTaskDelay(100 / portTICK_RATE_MS); + } + cmd++; + } } -void sh1107_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, +void sh1107_set_px_cb(struct _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) { /* buf_w will be ignored, the configured CONFIG_LV_DISPLAY_HEIGHT and _WIDTH, @@ -117,10 +127,10 @@ void sh1107_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, uint8_t bit_index = 0; #if defined CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE - byte_index = y + (( x>>3 ) * get_display_ver_res(disp_drv)); + byte_index = y + (( x>>3 ) * LV_VER_RES_MAX); bit_index = x & 0x7; #elif defined CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT - byte_index = x + (( y>>3 ) * get_display_hor_res(disp_drv)); + byte_index = x + (( y>>3 ) * LV_HOR_RES_MAX); bit_index = y & 0x7; #endif @@ -152,9 +162,9 @@ void sh1107_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * colo sh1107_send_cmd(0xB0 | i); // Set Page Start Address for Page Addressing Mode size = area->y2 - area->y1 + 1; #if defined CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE - ptr = color_map + i * get_display_ver_res(drv); + ptr = color_map + i * LV_VER_RES_MAX; #else - ptr = color_map + i * get_display_hor_res(drv); + ptr = color_map + i * LV_HOR_RES_MAX; #endif if(i != row2){ sh1107_send_data( (void *) ptr, size); @@ -165,21 +175,21 @@ void sh1107_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * colo } } -void sh1107_rounder(lv_disp_drv_t * disp_drv, lv_area_t *area) +void sh1107_rounder(struct _disp_drv_t * disp_drv, lv_area_t *area) { // workaround: always send complete size display buffer area->x1 = 0; area->y1 = 0; - area->x2 = get_display_hor_res(disp_drv) - 1; - area->y2 = get_display_ver_res(disp_drv) - 1; + area->x2 = LV_HOR_RES_MAX-1; + area->y2 = LV_VER_RES_MAX-1; } -void sh1107_sleep_in(void) +void sh1107_sleep_in() { sh1107_send_cmd(0xAE); } -void sh1107_sleep_out(void) +void sh1107_sleep_out() { sh1107_send_cmd(0xAF); } @@ -209,49 +219,3 @@ static void sh1107_send_color(void * data, uint16_t length) gpio_set_level(SH1107_DC, 1); /*Data mode*/ disp_spi_send_colors(data, length); } - -static lv_coord_t get_display_ver_res(lv_disp_drv_t *disp_drv) -{ - lv_coord_t val = 0; - -#if LVGL_VERSION_MAJOR < 8 -#if defined CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE - val = LV_VER_RES_MAX; -#endif -#else - /* ToDo Use display rotation API to get vertical size */ -#if defined CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE - val = lv_disp_get_ver_res((lv_disp_t *) disp_drv); -#endif -#endif - - return val; -} - -static lv_coord_t get_display_hor_res(lv_disp_drv_t *disp_drv) -{ - lv_coord_t val = 0; - -#if LVGL_VERSION_MAJOR < 8 -#if defined CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT - val = LV_HOR_RES_MAX; -#endif -#else - /* ToDo Use display rotation API to get horizontal size */ -#if defined CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT - val = lv_disp_get_hor_res((lv_disp_t *) disp_drv); -#endif -#endif - - return val; -} - -static void sh1107_reset(void) -{ -#if SH1107_USE_RST - gpio_set_level(SH1107_RST, 0); - vTaskDelay(pdMS_TO_TICKS(100)); - gpio_set_level(SH1107_RST, 1); - vTaskDelay(pdMS_TO_TICKS(100)); -#endif -} diff --git a/lvgl_tft/sh1107.h b/lvgl_tft/sh1107.h index 20beda3..ba77a61 100644 --- a/lvgl_tft/sh1107.h +++ b/lvgl_tft/sh1107.h @@ -39,8 +39,8 @@ extern "C" { void sh1107_init(void); void sh1107_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map); -void sh1107_rounder(lv_disp_drv_t * disp_drv, lv_area_t *area); -void sh1107_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, +void sh1107_rounder(struct _disp_drv_t * disp_drv, lv_area_t *area); +void sh1107_set_px_cb(struct _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 sh1107_sleep_in(void); void sh1107_sleep_out(void); diff --git a/lvgl_tft/ssd1306.c b/lvgl_tft/ssd1306.c index 802842c..c845eac 100644 --- a/lvgl_tft/ssd1306.c +++ b/lvgl_tft/ssd1306.c @@ -22,6 +22,8 @@ /********************* * DEFINES *********************/ +#define TAG "SSD1306" + #define OLED_I2C_PORT (CONFIG_LV_I2C_DISPLAY_PORT) // SLA (0x3C) + WRITE_MODE (0x00) = 0x78 (0b01111000) #define OLED_I2C_ADDRESS 0x3C @@ -104,7 +106,7 @@ void ssd1306_init(void) orientation_1 = 0xA0; orientation_2 = OLED_CMD_SET_COM_SCAN_MODE_NORMAL; #else - assert(false); // Invalid configuration of SSD1306 driver + #error "Unsupported orientation" #endif uint8_t display_mode = 0; diff --git a/lvgl_tft/st7735s.c b/lvgl_tft/st7735s.c index bd642aa..8be725b 100644 --- a/lvgl_tft/st7735s.c +++ b/lvgl_tft/st7735s.c @@ -9,6 +9,7 @@ #include "st7735s.h" #include "disp_spi.h" #include "driver/gpio.h" +#include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -19,6 +20,7 @@ /********************* * DEFINES *********************/ + #define TAG "ST7735S" #define AXP192_I2C_ADDRESS 0x34 /********************** @@ -39,14 +41,10 @@ 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 st7735s_reset(void); - -#ifdef CONFIG_LV_M5STICKC_HANDLE_AXP192 static void axp192_write_byte(uint8_t addr, uint8_t data); static void axp192_init(); static void axp192_sleep_in(); static void axp192_sleep_out(); -#endif /********************** * STATIC VARIABLES @@ -99,9 +97,22 @@ void st7735s_init(void) {0, {0}, 0xff} }; - st7735s_reset(); + //Initialize non-SPI GPIOs + gpio_pad_select_gpio(ST7735S_DC); + gpio_set_direction(ST7735S_DC, GPIO_MODE_OUTPUT); - LV_LOG_INFO("ST7735S initialization."); +#if ST7735S_USE_RST + gpio_pad_select_gpio(ST7735S_RST); + gpio_set_direction(ST7735S_RST, GPIO_MODE_OUTPUT); + + //Reset the display + gpio_set_level(ST7735S_RST, 0); + vTaskDelay(100 / portTICK_RATE_MS); + gpio_set_level(ST7735S_RST, 1); + vTaskDelay(100 / portTICK_RATE_MS); +#endif + + ESP_LOGI(TAG, "ST7735S initialization."); //Send all the commands uint16_t cmd = 0; @@ -109,7 +120,7 @@ void st7735s_init(void) st7735s_send_cmd(init_cmds[cmd].cmd); st7735s_send_data(init_cmds[cmd].data, init_cmds[cmd].databytes&0x1F); if (init_cmds[cmd].databytes & 0x80) { - vTaskDelay(pdMS_TO_TICKS(100)); + vTaskDelay(100 / portTICK_RATE_MS); } cmd++; } @@ -125,29 +136,29 @@ void st7735s_init(void) void st7735s_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map) { - uint8_t data[4] = {0}; + uint8_t data[4]; - /*Column addresses*/ - st7735s_send_cmd(0x2A); - data[0] = (area->x1 >> 8) & 0xFF; - data[1] = (area->x1 & 0xFF) + (st7735s_portrait_mode ? COLSTART : ROWSTART); - data[2] = (area->x2 >> 8) & 0xFF; - data[3] = (area->x2 & 0xFF) + (st7735s_portrait_mode ? COLSTART : ROWSTART); - st7735s_send_data(data, 4); + /*Column addresses*/ + st7735s_send_cmd(0x2A); + data[0] = (area->x1 >> 8) & 0xFF; + data[1] = (area->x1 & 0xFF) + (st7735s_portrait_mode ? COLSTART : ROWSTART); + data[2] = (area->x2 >> 8) & 0xFF; + data[3] = (area->x2 & 0xFF) + (st7735s_portrait_mode ? COLSTART : ROWSTART); + st7735s_send_data(data, 4); - /*Page addresses*/ - st7735s_send_cmd(0x2B); - data[0] = (area->y1 >> 8) & 0xFF; - data[1] = (area->y1 & 0xFF) + (st7735s_portrait_mode ? ROWSTART : COLSTART); - data[2] = (area->y2 >> 8) & 0xFF; - data[3] = (area->y2 & 0xFF) + (st7735s_portrait_mode ? ROWSTART : COLSTART); - st7735s_send_data(data, 4); + /*Page addresses*/ + st7735s_send_cmd(0x2B); + data[0] = (area->y1 >> 8) & 0xFF; + data[1] = (area->y1 & 0xFF) + (st7735s_portrait_mode ? ROWSTART : COLSTART); + data[2] = (area->y2 >> 8) & 0xFF; + data[3] = (area->y2 & 0xFF) + (st7735s_portrait_mode ? ROWSTART : COLSTART); + st7735s_send_data(data, 4); - /*Memory write*/ - st7735s_send_cmd(0x2C); + /*Memory write*/ + st7735s_send_cmd(0x2C); - uint32_t size = lv_area_get_width(area) * lv_area_get_height(area) * 2; - st7735s_send_color((void*)color_map, size); + uint32_t size = lv_area_get_width(area) * lv_area_get_height(area); + st7735s_send_color((void*)color_map, size * 2); } void st7735s_sleep_in() @@ -193,7 +204,11 @@ static void st7735s_send_color(void * data, uint16_t length) static void st7735s_set_orientation(uint8_t orientation) { - assert(orientation < 4); + const char *orientation_str[] = { + "PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED" + }; + + ESP_LOGD(TAG, "Display orientation: %s", orientation_str[orientation]); /* Portrait: 0xC8 = ST77XX_MADCTL_MX | ST77XX_MADCTL_MY | ST77XX_MADCTL_BGR @@ -202,58 +217,41 @@ static void st7735s_set_orientation(uint8_t orientation) */ uint8_t data[] = {0xC8, 0xC8, 0xA8, 0xA8}; -#if (LV_USE_LOG == 1) - const char *orientation_str[] = { - "PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED" - }; - - LV_LOG_INFO("Display orientation: %s", orientation_str[orientation]); - LV_LOG_INFO("0x36 command value: 0x%02X", data[orientation]); -#endif + ESP_LOGD(TAG, "0x36 command value: 0x%02X", data[orientation]); st7735s_send_cmd(ST7735_MADCTL); st7735s_send_data((void *) &data[orientation], 1); } -static void st7735s_reset(void) -{ -#if ST7735S_USE_RST - gpio_set_level(ST7735S_RST, 0); - vTaskDelay(pdMS_TO_TICKS(100)); - gpio_set_level(ST7735S_RST, 1); - vTaskDelay(pdMS_TO_TICKS(100)); -#endif -} - #ifdef CONFIG_LV_M5STICKC_HANDLE_AXP192 -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) { - LV_LOG_ERROR("AXP192 send failed. code: 0x%.2X", ret); + 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_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_init() + { + // information on how to init and use AXP192 ifor M5StickC taken from + // https://forum.m5stack.com/topic/1025/m5stickc-turn-off-screen-completely - axp192_write_byte(0x10, 0xFF); // OLED_VPP Enable - axp192_write_byte(0x28, 0xCC); // Enable LDO2&LDO3, LED&TFT 3.0V - axp192_sleep_out(); - LV_LOG_INFO("AXP192 initialized, power enabled for LDO2 and LDO3"); -} + 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"); + } -static void axp192_sleep_in() -{ - axp192_write_byte(0x12, 0x4b); -} + static void axp192_sleep_in() + { + axp192_write_byte(0x12, 0x4b); + } -static void axp192_sleep_out() -{ - axp192_write_byte(0x12, 0x4d); -} + static void axp192_sleep_out() + { + axp192_write_byte(0x12, 0x4d); + } #endif diff --git a/lvgl_tft/st7789.c b/lvgl_tft/st7789.c index c1fc87f..de7b35a 100644 --- a/lvgl_tft/st7789.c +++ b/lvgl_tft/st7789.c @@ -4,15 +4,21 @@ * Mostly taken from lbthomsen/esp-idf-littlevgl github. */ +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "sdkconfig.h" + +#include "esp_log.h" + #include "st7789.h" #include "disp_spi.h" -#include "display_port.h" +#include "driver/gpio.h" /********************* * DEFINES *********************/ - +#define TAG "st7789" /********************** * TYPEDEFS **********************/ @@ -27,20 +33,13 @@ typedef struct { /********************** * STATIC PROTOTYPES **********************/ -static void st7789_set_orientation(lv_disp_drv_t *drv, uint8_t orientation); -static void st7789_send_cmd(lv_disp_drv_t * drv, uint8_t cmd); -static void st7789_send_data(lv_disp_drv_t * drv, void *data, uint16_t length); -static void st7789_send_color(lv_disp_drv_t * drv, void *data, uint16_t length); -static void st7789_reset(lv_disp_drv_t * drv); +static void st7789_set_orientation(uint8_t orientation); + +static void st7789_send_color(void *data, size_t length); -static void setup_initial_offsets(lv_disp_drv_t * drv); -static lv_coord_t get_display_hor_res(lv_disp_drv_t * drv); -static lv_coord_t get_display_ver_res(lv_disp_drv_t * drv); /********************** * STATIC VARIABLES **********************/ -static uint16_t user_x_offset = 0u; -static uint16_t user_y_offset = 0u; /********************** * MACROS @@ -49,10 +48,8 @@ static uint16_t user_y_offset = 0u; /********************** * GLOBAL FUNCTIONS **********************/ -void st7789_init(lv_disp_drv_t *drv) +void st7789_init(void) { - setup_initial_offsets(drv); - lcd_init_cmd_t st7789_init_cmds[] = { {0xCF, {0x00, 0x83, 0X30}, 3}, {0xED, {0x64, 0x03, 0X12, 0X81}, 4}, @@ -88,28 +85,39 @@ void st7789_init(lv_disp_drv_t *drv) {0, {0}, 0xff}, }; - st7789_reset(drv); + //Initialize non-SPI GPIOs + gpio_pad_select_gpio(ST7789_DC); + gpio_set_direction(ST7789_DC, GPIO_MODE_OUTPUT); + +#if !defined(ST7789_SOFT_RST) + gpio_pad_select_gpio(ST7789_RST); + gpio_set_direction(ST7789_RST, GPIO_MODE_OUTPUT); +#endif + + //Reset the display +#if !defined(ST7789_SOFT_RST) + gpio_set_level(ST7789_RST, 0); + vTaskDelay(100 / portTICK_RATE_MS); + gpio_set_level(ST7789_RST, 1); + vTaskDelay(100 / portTICK_RATE_MS); +#else + st7789_send_cmd(ST7789_SWRESET); +#endif + + printf("ST7789 initialization.\n"); //Send all the commands uint16_t cmd = 0; while (st7789_init_cmds[cmd].databytes!=0xff) { - st7789_send_cmd(drv, st7789_init_cmds[cmd].cmd); - st7789_send_data(drv, st7789_init_cmds[cmd].data, st7789_init_cmds[cmd].databytes&0x1F); + st7789_send_cmd(st7789_init_cmds[cmd].cmd); + st7789_send_data(st7789_init_cmds[cmd].data, st7789_init_cmds[cmd].databytes&0x1F); if (st7789_init_cmds[cmd].databytes & 0x80) { - display_port_delay(drv, 100); + vTaskDelay(100 / portTICK_RATE_MS); } cmd++; } - /* NOTE: Setting rotation from lv_disp_drv_t instead of menuconfig */ - lv_disp_rot_t rotation; -#if (LVGL_VERSION_MAJOR >= 8) - rotation = lv_disp_get_rotation((lv_disp_t *) &drv); -#else - rotation = lv_disp_get_rotation((lv_disp_t *) drv); -#endif - - st7789_set_orientation(drv, rotation); + 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 @@ -123,219 +131,109 @@ void st7789_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * colo uint16_t offsetx2 = area->x2; uint16_t offsety1 = area->y1; uint16_t offsety2 = area->y2; - uint32_t size = lv_area_get_width(area) * lv_area_get_height(area); - /* On LVGLv7 we have to manually update the driver orientation, - * in LVGLv8 we use the driver update callback. */ -#if (LVGL_VERSION_MAJOR < 8) - static lv_disp_rot_t cached_rotation = LV_DISP_ROT_NONE; - lv_disp_rot_t rotation = lv_disp_get_rotation((lv_disp_t *) drv); - if (cached_rotation != rotation) { - st7789_set_orientation(drv, (uint8_t) rotation); - /* Update offset values */ - setup_initial_offsets(drv); - cached_rotation = rotation; - } +#if (CONFIG_LV_TFT_DISPLAY_OFFSETS) + offsetx1 += CONFIG_LV_TFT_DISPLAY_X_OFFSET; + offsetx2 += CONFIG_LV_TFT_DISPLAY_X_OFFSET; + offsety1 += CONFIG_LV_TFT_DISPLAY_Y_OFFSET; + 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 #endif - offsetx1 += st7789_x_offset(); - offsetx2 += st7789_x_offset(); - offsety1 += st7789_y_offset(); - offsety2 += st7789_y_offset(); - /*Column addresses*/ - st7789_send_cmd(drv, ST7789_CASET); + st7789_send_cmd(ST7789_CASET); data[0] = (offsetx1 >> 8) & 0xFF; data[1] = offsetx1 & 0xFF; data[2] = (offsetx2 >> 8) & 0xFF; data[3] = offsetx2 & 0xFF; - st7789_send_data(drv, data, 4); + st7789_send_data(data, 4); /*Page addresses*/ - st7789_send_cmd(drv, ST7789_RASET); + st7789_send_cmd(ST7789_RASET); data[0] = (offsety1 >> 8) & 0xFF; data[1] = offsety1 & 0xFF; data[2] = (offsety2 >> 8) & 0xFF; data[3] = offsety2 & 0xFF; - st7789_send_data(drv, data, 4); + st7789_send_data(data, 4); /*Memory write*/ - st7789_send_cmd(drv, ST7789_RAMWR); - st7789_send_color(drv, (void*) color_map, size * 2); -} + st7789_send_cmd(ST7789_RAMWR); -void st7789_set_x_offset(const uint16_t offset) -{ - user_x_offset = offset; -} + size_t size = (size_t)lv_area_get_width(area) * (size_t)lv_area_get_height(area); -void st7789_set_y_offset(const uint16_t offset) -{ - user_y_offset = offset; -} + st7789_send_color((void*)color_map, size * 2); -uint16_t st7789_x_offset(void) -{ - return user_x_offset; -} - -uint16_t st7789_y_offset(void) -{ - return user_y_offset; } /********************** * STATIC FUNCTIONS **********************/ -static void st7789_send_cmd(lv_disp_drv_t *drv, uint8_t cmd) +void st7789_send_cmd(uint8_t cmd) { disp_wait_for_pending_transactions(); - display_port_gpio_dc(drv, 0); + gpio_set_level(ST7789_DC, 0); disp_spi_send_data(&cmd, 1); } -static void st7789_send_data(lv_disp_drv_t *drv, void * data, uint16_t length) +void st7789_send_data(void * data, uint16_t length) { disp_wait_for_pending_transactions(); - display_port_gpio_dc(drv, 1); + gpio_set_level(ST7789_DC, 1); disp_spi_send_data(data, length); } -static void st7789_send_color(lv_disp_drv_t *drv, void * data, uint16_t length) +static void st7789_send_color(void * data, size_t length) { disp_wait_for_pending_transactions(); - display_port_gpio_dc(drv, 1); + gpio_set_level(ST7789_DC, 1); disp_spi_send_colors(data, length); } -/* Reset the display, if we don't have a reset pin we use software reset */ -static void st7789_reset(lv_disp_drv_t *drv) +static void st7789_set_orientation(uint8_t orientation) { -#if !defined(ST7789_SOFT_RST) - display_port_gpio_rst(drv, 0); - display_port_delay(drv, 100); - display_port_gpio_rst(drv, 1); - display_port_delay(drv, 100); -#else - st7789_send_cmd(drv, ST7789_SWRESET); - display_port_delay(drv, 5); -#endif -} + // ESP_ASSERT(orientation < 4); + + const char *orientation_str[] = { + "PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED" + }; + + ESP_LOGI(TAG, "Display orientation: %s", orientation_str[orientation]); -static void st7789_set_orientation(lv_disp_drv_t *drv, uint8_t orientation) -{ uint8_t data[] = { #if CONFIG_LV_PREDEFINED_DISPLAY_TTGO 0x60, 0xA0, 0x00, 0xC0 #else - 0xC0, 0x60, 0x00, 0xA0 + 0xC0, 0x00, 0x60, 0xA0 #endif }; - st7789_send_cmd(drv, ST7789_MADCTL); - st7789_send_data(drv, (void *) &data[orientation], 1); -} - -static void setup_initial_offsets(lv_disp_drv_t * drv) -{ - lv_disp_rot_t rotation; -#if (LVGL_VERSION_MAJOR >= 8) - rotation = lv_disp_get_rotation((lv_disp_t *) &drv); -#else - rotation = lv_disp_get_rotation((lv_disp_t *) drv); -#endif - -#if (CONFIG_LV_TFT_DISPLAY_OFFSETS) - st7789_set_x_offset(CONFIG_LV_TFT_DISPLAY_X_OFFSET); - st7789_set_y_offset(CONFIG_LV_TFT_DISPLAY_Y_OFFSET); -#else - if (240U == get_display_hor_res(drv) && 135U == get_display_ver_res(drv)) - { - if (LV_DISP_ROT_NONE == rotation || LV_DISP_ROT_180 == rotation) - { - st7789_set_x_offset(40); - st7789_set_y_offset(53); - } - else - { - st7789_set_x_offset(0); - st7789_set_y_offset(0); - } - } - else if (135U == get_display_hor_res(drv) && 240U == get_display_ver_res(drv)) - { - if (LV_DISP_ROT_90 == rotation || LV_DISP_ROT_270 == rotation) - { - st7789_set_x_offset(52); - st7789_set_y_offset(40); - } - else - { - st7789_set_x_offset(0); - st7789_set_y_offset(0); - } - } - else if (240U == get_display_hor_res(drv) && 240U == get_display_ver_res(drv)) - { - if (LV_DISP_ROT_NONE == rotation) - { - st7789_set_x_offset(80); - st7789_set_y_offset(0); - } - else if (LV_DISP_ROT_90 == rotation || LV_DISP_ROT_180 == rotation) - { - st7789_set_x_offset(0); - st7789_set_y_offset(0); - } - else if (LV_DISP_ROT_270 == rotation) - { - st7789_set_x_offset(0); - st7789_set_y_offset(80); - } - } -#endif -} - -/* Display update callback, we could update the orientation in here - * NOTE Available only for LVGL v8 */ -void st7789_update_cb(lv_disp_drv_t *drv) -{ - lv_disp_rot_t rotation; -#if (LVGL_VERSION_MAJOR >= 8) - rotation = lv_disp_get_rotation((lv_disp_t *) &drv); -#else - rotation = lv_disp_get_rotation((lv_disp_t *) drv); -#endif - - st7789_set_orientation(drv, (uint8_t) rotation); - setup_initial_offsets(drv); -} - -static lv_coord_t get_display_hor_res(lv_disp_drv_t * drv) -{ - lv_coord_t retval = 0; - -#if (LVGL_VERSION_MAJOR >= 8) - retval = drv->hor_res; -#else - (void) drv; - retval = LV_HOR_RES_MAX; -#endif - - return retval; -} - -static lv_coord_t get_display_ver_res(lv_disp_drv_t * drv) -{ - lv_coord_t retval = 0; - -#if (LVGL_VERSION_MAJOR >= 8) - retval = drv->ver_res; -#else - (void) drv; - retval = LV_VER_RES_MAX; -#endif - - return retval; + ESP_LOGI(TAG, "0x36 command value: 0x%02X", data[orientation]); + + st7789_send_cmd(ST7789_MADCTL); + st7789_send_data((void *) &data[orientation], 1); } diff --git a/lvgl_tft/st7789.h b/lvgl_tft/st7789.h index 82c3754..cacb31b 100644 --- a/lvgl_tft/st7789.h +++ b/lvgl_tft/st7789.h @@ -17,11 +17,22 @@ extern "C" #else #include "lvgl/lvgl.h" #endif +#include "../lvgl_helpers.h" -/* For SPI transfers */ -#include "lvgl_helpers.h" -/* For ST7789 particular configurations */ -#include "display_config.h" +#include "sdkconfig.h" + +#define ST7789_DC CONFIG_LV_DISP_PIN_DC +#define ST7789_RST CONFIG_LV_DISP_PIN_RST + +#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_INVERT_COLORS CONFIG_LV_INVERT_COLORS /* ST7789 commands */ #define ST7789_NOP 0x00 @@ -99,48 +110,11 @@ extern "C" #define ST7789_NVMSET 0xFC // NVM setting #define ST7789_PROMACT 0xFE // Program action -/** - * Initialize the ST7789 display controller with default configuration - * - * @param drv Pointer to lv_disp_drv_t being used - */ -void st7789_init(lv_disp_drv_t *drv); - -/** - * Send buffer content to display - * - * @param drv Pointer to lv_disp_drv_t being used - * @param area Pointer to area to be sent - * @param color_map Pointer to color map - */ +void st7789_init(void); void st7789_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map); -/** - * Set display buffer offset at x axis - */ -void st7789_set_x_offset(const uint16_t offset); - -/** - * Set display buffer offset at y axis - */ -void st7789_set_y_offset(const uint16_t offset); - -/** - * Get display buffer offset at x axis - */ -uint16_t st7789_x_offset(void); - -/** - * Get display buffer offset at y axis - */ -uint16_t st7789_y_offset(void); - -/** - * Display updated callback - * - * @param drv Pointer to lv_disp_drv_t being used - */ -void st7789_update_cb(lv_disp_drv_t *drv); +void st7789_send_cmd(uint8_t cmd); +void st7789_send_data(void *data, uint16_t length); #ifdef __cplusplus } /* extern "C" */ diff --git a/lvgl_tft/st7796s.c b/lvgl_tft/st7796s.c index 959d329..7de92ef 100644 --- a/lvgl_tft/st7796s.c +++ b/lvgl_tft/st7796s.c @@ -9,12 +9,14 @@ #include "st7796s.h" #include "disp_spi.h" #include "driver/gpio.h" +#include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" /********************* * DEFINES *********************/ +#define TAG "ST7796S" /********************** * TYPEDEFS @@ -36,7 +38,6 @@ static void st7796s_set_orientation(uint8_t orientation); static void st7796s_send_cmd(uint8_t cmd); static void st7796s_send_data(void *data, uint16_t length); static void st7796s_send_color(void *data, uint16_t length); -static void st7796s_reset(void); /********************** * STATIC VARIABLES @@ -80,24 +81,37 @@ void st7796s_init(void) {0, {0}, 0xff}, }; - st7796s_reset(); + //Initialize non-SPI GPIOs + gpio_pad_select_gpio(ST7796S_DC); + gpio_set_direction(ST7796S_DC, GPIO_MODE_OUTPUT); - LV_LOG_INFO("Initialization."); +#if ST7796S_USE_RST + gpio_pad_select_gpio(ST7796S_RST); + gpio_set_direction(ST7796S_RST, GPIO_MODE_OUTPUT); - //Send all the commands - uint16_t cmd = 0; - while (init_cmds[cmd].databytes != 0xff) - { - st7796s_send_cmd(init_cmds[cmd].cmd); - st7796s_send_data(init_cmds[cmd].data, init_cmds[cmd].databytes & 0x1F); - if (init_cmds[cmd].databytes & 0x80) - { - vTaskDelay(pdMS_TO_TICKS(100)); - } - cmd++; - } + //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 - st7796s_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION); + ESP_LOGI(TAG, "Initialization."); + + //Send all the commands + uint16_t cmd = 0; + while (init_cmds[cmd].databytes != 0xff) + { + st7796s_send_cmd(init_cmds[cmd].cmd); + st7796s_send_data(init_cmds[cmd].data, init_cmds[cmd].databytes & 0x1F); + if (init_cmds[cmd].databytes & 0x80) + { + vTaskDelay(100 / portTICK_RATE_MS); + } + cmd++; + } + + st7796s_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION); #if ST7796S_INVERT_COLORS == 1 st7796s_send_cmd(0x21); @@ -175,36 +189,25 @@ static void st7796s_send_color(void *data, uint16_t length) static void st7796s_set_orientation(uint8_t orientation) { - assert(orientation < 4); + // ESP_ASSERT(orientation < 4); -#if defined CONFIG_LV_PREDEFINED_DISPLAY_M5STACK - const uint8_t data[] = {0x68, 0x68, 0x08, 0x08}; -#elif defined(CONFIG_LV_PREDEFINED_DISPLAY_WROVER4) - const uint8_t data[] = {0x4C, 0x88, 0x28, 0xE8}; -#elif defined(CONFIG_LV_PREDEFINED_DISPLAY_WT32_SC01) - const uint8_t data[] = {0x48, 0x88, 0x28, 0xE8}; -#else - const uint8_t data[] = {0x48, 0x88, 0x28, 0xE8}; -#endif - -#if (LV_USE_LOG == 1) const char *orientation_str[] = { "PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED"}; - LV_LOG_INFO("Display orientation: %s", orientation_str[orientation]); - LV_LOG_INFO("0x36 command value: 0x%02X", data[orientation]); + ESP_LOGI(TAG, "Display orientation: %s", orientation_str[orientation]); + +#if defined CONFIG_LV_PREDEFINED_DISPLAY_M5STACK + uint8_t data[] = {0x68, 0x68, 0x08, 0x08}; +#elif defined(CONFIG_LV_PREDEFINED_DISPLAY_WROVER4) + uint8_t data[] = {0x4C, 0x88, 0x28, 0xE8}; +#elif defined(CONFIG_LV_PREDEFINED_DISPLAY_WT32_SC01) + uint8_t data[] = {0x48, 0x88, 0x28, 0xE8}; +#elif defined(CONFIG_LV_PREDEFINED_DISPLAY_NONE) + uint8_t data[] = {0x48, 0x88, 0x28, 0xE8}; #endif + ESP_LOGI(TAG, "0x36 command value: 0x%02X", data[orientation]); + st7796s_send_cmd(0x36); st7796s_send_data((void *)&data[orientation], 1); } - -static void st7796s_reset(void) -{ -#if ST7796S_USE_RST - gpio_set_level(ST7796S_RST, 0); - vTaskDelay(pdMS_TO_TICKS(100)); - gpio_set_level(ST7796S_RST, 1); - vTaskDelay(pdMS_TO_TICKS(100)); -#endif -} diff --git a/lvgl_tft/uc8151d.c b/lvgl_tft/uc8151d.c index 9ebb76e..d353225 100644 --- a/lvgl_tft/uc8151d.c +++ b/lvgl_tft/uc8151d.c @@ -29,37 +29,23 @@ #include #include #include +#include #include "disp_spi.h" #include "disp_driver.h" #include "uc8151d.h" +#define TAG "lv_uc8151d" + #define PIN_DC CONFIG_LV_DISP_PIN_DC #define PIN_DC_BIT ((1ULL << (uint8_t)(CONFIG_LV_DISP_PIN_DC))) - -#if defined CONFIG_LV_DISP_PIN_RST #define PIN_RST CONFIG_LV_DISP_PIN_RST #define PIN_RST_BIT ((1ULL << (uint8_t)(CONFIG_LV_DISP_PIN_RST))) -#endif - #define PIN_BUSY CONFIG_LV_DISP_PIN_BUSY #define PIN_BUSY_BIT ((1ULL << (uint8_t)(CONFIG_LV_DISP_PIN_BUSY))) #define EVT_BUSY (1UL << 0UL) - -#if defined (LV_HOR_RES_MAX) #define EPD_WIDTH LV_HOR_RES_MAX -#else - /* ToDo Fix, 256 is just a magic number */ -#define EPD_WIDTH 256u -#endif - -#if defined (LV_VER_RES_MAX) #define EPD_HEIGHT LV_VER_RES_MAX -#else - /* ToDo Fix, 128 is just a magic number */ -#define EPD_HEIGHT 128u -#endif - #define EPD_ROW_LEN (EPD_HEIGHT / 8u) #define BIT_SET(a, b) ((a) |= (1U << (b))) @@ -107,6 +93,26 @@ static void uc8151d_spi_send_data_byte(uint8_t data) disp_spi_send_data(&data, 1); } +static void uc8151d_spi_send_fb(uint8_t *data, size_t len) +{ + disp_wait_for_pending_transactions(); + gpio_set_level(PIN_DC, 1); // DC = 1 for data + disp_spi_send_colors(data, len); +} + +static void uc8151d_spi_send_seq(const uc8151d_seq_t *seq, size_t len) +{ + ESP_LOGD(TAG, "Writing cmd/data sequence, count %u", len); + + if (!seq || len < 1) return; + for (size_t cmd_idx = 0; cmd_idx < len; cmd_idx++) { + uc8151d_spi_send_cmd(seq[cmd_idx].cmd); + if (seq[cmd_idx].len > 0) { + uc8151d_spi_send_data((uint8_t *) seq[cmd_idx].data, seq[cmd_idx].len); + } + } +} + static esp_err_t uc8151d_wait_busy(uint32_t timeout_ms) { uint32_t wait_ticks = (timeout_ms == 0 ? portMAX_DELAY : pdMS_TO_TICKS(timeout_ms)); @@ -118,7 +124,7 @@ static esp_err_t uc8151d_wait_busy(uint32_t timeout_ms) return ((bits & EVT_BUSY) != 0) ? ESP_OK : ESP_ERR_TIMEOUT; } -static void uc8151d_sleep(void) +static void uc8151d_sleep() { // Set VCOM to 0xf7 uc8151d_spi_send_cmd(0x50); @@ -133,13 +139,14 @@ static void uc8151d_sleep(void) uc8151d_spi_send_data_byte(0xa5); } -static void uc8151d_reset(void); - -static void uc8151d_panel_init(void) +static void uc8151d_panel_init() { // Hardware reset for 3 times - not sure why but it's from official demo code for (uint8_t cnt = 0; cnt < 3; cnt++) { - uc8151d_reset(); + gpio_set_level(PIN_RST, 0); + vTaskDelay(pdMS_TO_TICKS(10)); // At least 10ms, leave 20ms for now just in case... + gpio_set_level(PIN_RST, 1); + vTaskDelay(pdMS_TO_TICKS(10)); } // Power up @@ -189,20 +196,19 @@ static void uc8151d_full_update(uint8_t *buf) void uc8151d_lv_fb_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map) { -#if LV_USE_LOG size_t len = ((area->x2 - area->x1 + 1) * (area->y2 - area->y1 + 1)) / 8; - LV_LOG_INFO("x1: 0x%x, x2: 0x%x, y1: 0x%x, y2: 0x%x", area->x1, area->x2, area->y1, area->y2); - LV_LOG_INFO("Writing LVGL fb with len: %u", len); -#endif + + ESP_LOGD(TAG, "x1: 0x%x, x2: 0x%x, y1: 0x%x, y2: 0x%x", area->x1, area->x2, area->y1, area->y2); + ESP_LOGD(TAG, "Writing LVGL fb with len: %u", len); uint8_t *buf = (uint8_t *) color_map; uc8151d_full_update(buf); lv_disp_flush_ready(drv); - LV_LOG_INFO("Ready"); + ESP_LOGD(TAG, "Ready"); } -void uc8151d_lv_set_fb_cb(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, +void uc8151d_lv_set_fb_cb(struct _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) { uint16_t byte_index = (x >> 3u) + (y * EPD_ROW_LEN); @@ -211,12 +217,12 @@ void uc8151d_lv_set_fb_cb(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_ if (color.full) { BIT_SET(buf[byte_index], 7 - bit_index); } else { - LV_LOG_INFO("Clear at x: %u, y: %u", x, y); + ESP_LOGD(TAG, "Clear at x: %u, y: %u", x, y); BIT_CLEAR(buf[byte_index], 7 - bit_index); } } -void uc8151d_lv_rounder_cb(lv_disp_drv_t *disp_drv, lv_area_t *area) +void uc8151d_lv_rounder_cb(struct _disp_drv_t *disp_drv, lv_area_t *area) { // Always send full framebuffer if it's not in partial mode area->x1 = 0; @@ -225,15 +231,25 @@ void uc8151d_lv_rounder_cb(lv_disp_drv_t *disp_drv, lv_area_t *area) area->y2 = EPD_HEIGHT - 1; } -void uc8151d_init(void) +void uc8151d_init() { // Initialise event group uc8151d_evts = xEventGroupCreate(); if (!uc8151d_evts) { - LV_LOG_ERROR("Failed when initialising event group!"); + ESP_LOGE(TAG, "Failed when initialising event group!"); return; } + // Setup output pins, output (PP) + gpio_config_t out_io_conf = { + .intr_type = GPIO_INTR_DISABLE, + .mode = GPIO_MODE_OUTPUT, + .pin_bit_mask = PIN_DC_BIT | PIN_RST_BIT, + .pull_down_en = 0, + .pull_up_en = 0, + }; + ESP_ERROR_CHECK(gpio_config(&out_io_conf)); + // Setup input pin, pull-up, input gpio_config_t in_io_conf = { .intr_type = GPIO_INTR_POSEDGE, @@ -246,18 +262,7 @@ void uc8151d_init(void) gpio_install_isr_service(0); gpio_isr_handler_add(PIN_BUSY, uc8151d_busy_intr, (void *) PIN_BUSY); - LV_LOG_INFO("IO init finished"); + ESP_LOGI(TAG, "IO init finished"); uc8151d_panel_init(); - LV_LOG_INFO("Panel initialised"); -} - -static void uc8151d_reset(void) -{ -#if defined CONFIG_LV_DISP_USE_RST - gpio_set_level(PIN_RST, 0); - // At least 10ms, leave 20ms for now just in case... - vTaskDelay(pdMS_TO_TICKS(20)); - gpio_set_level(PIN_RST, 1); - vTaskDelay(pdMS_TO_TICKS(10)); -#endif + ESP_LOGI(TAG, "Panel initialised"); } diff --git a/lvgl_tft/uc8151d.h b/lvgl_tft/uc8151d.h index 3a27f8f..e637f0e 100644 --- a/lvgl_tft/uc8151d.h +++ b/lvgl_tft/uc8151d.h @@ -29,11 +29,11 @@ #include -void uc8151d_init(void); -void uc8151d_lv_set_fb_cb(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, +void uc8151d_init(); +void uc8151d_lv_set_fb_cb(struct _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 uc8151d_lv_rounder_cb(lv_disp_drv_t *disp_drv, lv_area_t *area); +void uc8151d_lv_rounder_cb(struct _disp_drv_t *disp_drv, lv_area_t *area); void uc8151d_lv_fb_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map); #endif //LVGL_DEMO_UC8151D_H diff --git a/lvgl_touch/adcraw.c b/lvgl_touch/adcraw.c index 8e1bcfb..6170b4c 100644 --- a/lvgl_touch/adcraw.c +++ b/lvgl_touch/adcraw.c @@ -8,11 +8,11 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" -#include "esp_idf_version.h" #include #if CONFIG_LV_TOUCH_CONTROLLER_ADCRAW +#define TAG "ADCRAW" #define CALIBRATIONINSET 1 // range 0 <= CALIBRATIONINSET <= 40 #define SAMPLE_CALIBRATION_POINTS 4 // use this scale factor to avoid working in floating point numbers @@ -137,30 +137,21 @@ void adcraw_init(void) static void setup_axis(gpio_num_t plus, gpio_num_t minus, gpio_num_t measure, gpio_num_t ignore) { - // Set GPIOs: - // - Float "ignore" and "measure" -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) - esp_rom_gpio_pad_select_gpio(ignore); -#else - gpio_pad_select_gpio(ignore); -#endif - gpio_set_direction(ignore, GPIO_MODE_DISABLE); - gpio_set_pull_mode(ignore, GPIO_FLOATING); - -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) - esp_rom_gpio_pad_select_gpio(ignore); -#else - gpio_pad_select_gpio(measure); -#endif - gpio_set_direction(measure, GPIO_MODE_DISABLE); - gpio_set_pull_mode(measure, GPIO_FLOATING); - // - Set "plus" to 1, "minus" to 0 - gpio_config(&(gpio_config_t) { - .mode = GPIO_MODE_OUTPUT, - .pin_bit_mask = (1ULL << plus) | (1ULL << minus) - }); - gpio_set_level(plus, 1); - gpio_set_level(minus, 0); + // Set GPIOs: + // - Float "ignore" and "measure" + gpio_pad_select_gpio(ignore); + gpio_set_direction(ignore, GPIO_MODE_DISABLE); + gpio_set_pull_mode(ignore, GPIO_FLOATING); + gpio_pad_select_gpio(measure); + gpio_set_direction(measure, GPIO_MODE_DISABLE); + gpio_set_pull_mode(measure, GPIO_FLOATING); + // - Set "plus" to 1, "minus" to 0 + gpio_config(&(gpio_config_t) { + .mode = GPIO_MODE_OUTPUT, + .pin_bit_mask = (1ULL << plus) | (1ULL << minus) + }); + gpio_set_level(plus, 1); + gpio_set_level(minus, 0); } static void setup_adc(gpio_num_t measure) diff --git a/lvgl_touch/ft6x36.c b/lvgl_touch/ft6x36.c index 4bc5e1d..dae736c 100644 --- a/lvgl_touch/ft6x36.c +++ b/lvgl_touch/ft6x36.c @@ -1,162 +1,160 @@ -/* -* 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. -*/ - -#ifdef LV_LVGL_H_INCLUDE_SIMPLE -#include -#else -#include -#endif - -#include "ft6x36.h" -#include "lvgl_i2c/i2c_manager.h" - -#define TAG "FT6X36" -#define FT6X36_TOUCH_QUEUE_ELEMENTS 1 - -static ft6x36_status_t ft6x36_status; -/* Set during initialization */ -static uint8_t current_dev_addr; -/* -1 coordinates to designate it was never touched */ -static ft6x36_touch_t touch_inputs = { -1, -1, LV_INDEV_STATE_REL }; - -#if CONFIG_LV_FT6X36_COORDINATES_QUEUE -QueueHandle_t ft6x36_touch_queue_handle; -#endif - -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); -} - -/** - * @brief Read the FT6x36 gesture ID. Initialize first! - * @param dev_addr: I2C FT6x36 Slave address. - * @retval The gesture ID or 0x00 in case of failure - */ -uint8_t ft6x36_get_gesture_id() { - if (!ft6x36_status.inited) { - LV_LOG_ERROR("Init first!"); - return 0x00; - } - uint8_t data_buf; - esp_err_t ret; - if ((ret = ft6x06_i2c_read8(current_dev_addr, FT6X36_GEST_ID_REG, &data_buf) != ESP_OK)) - LV_LOG_ERROR("Error reading from device: %s", esp_err_to_name(ret)); - return data_buf; -} - -/** - * @brief Initialize for FT6x36 communication via I2C - * @param dev_addr: Device address on communication Bus (I2C slave address of FT6X36). - * @retval None - */ -void ft6x06_init(uint16_t dev_addr) { - - ft6x36_status.inited = true; - current_dev_addr = dev_addr; - uint8_t data_buf; - esp_err_t ret; - LV_LOG_INFO("Found touch panel controller"); - if ((ret = ft6x06_i2c_read8(dev_addr, FT6X36_PANEL_ID_REG, &data_buf) != ESP_OK)) - LV_LOG_ERROR("Error reading from device: %s", - esp_err_to_name(ret)); // Only show error the first time - LV_LOG_INFO("\tDevice ID: 0x%02x", data_buf); - - ft6x06_i2c_read8(dev_addr, FT6X36_CHIPSELECT_REG, &data_buf); - LV_LOG_INFO("\tChip ID: 0x%02x", data_buf); - - ft6x06_i2c_read8(dev_addr, FT6X36_DEV_MODE_REG, &data_buf); - LV_LOG_INFO("\tDevice mode: 0x%02x", data_buf); - - ft6x06_i2c_read8(dev_addr, FT6X36_FIRMWARE_ID_REG, &data_buf); - LV_LOG_INFO("\tFirmware ID: 0x%02x", data_buf); - - ft6x06_i2c_read8(dev_addr, FT6X36_RELEASECODE_REG, &data_buf); - LV_LOG_INFO("\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 ) - { - LV_LOG_ERROR("\tError creating touch input FreeRTOS queue" ); - return; - } - xQueueSend( ft6x36_touch_queue_handle, &touch_inputs, 0 ); -#endif -} - -/** - * @brief Get the touch screen X and Y positions values. Ignores multi touch - * @param drv: - * @param data: Store data here - * @retval Always false - */ -bool ft6x36_read(lv_indev_drv_t *drv, lv_indev_data_t *data) { - if (!ft6x36_status.inited) { - LV_LOG_ERROR("Init first!"); - return 0x00; - } - uint8_t data_buf[5]; // 1 byte status, 2 bytes X, 2 bytes Y - - 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) { - LV_LOG_ERROR("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; - 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); - -#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; -#endif -#if CONFIG_LV_FT6X36_INVERT_X - touch_inputs.last_x = LV_HOR_RES - touch_inputs.last_x; -#endif -#if CONFIG_LV_FT6X36_INVERT_Y - touch_inputs.last_y = LV_VER_RES - touch_inputs.last_y; -#endif - data->point.x = touch_inputs.last_x; - data->point.y = touch_inputs.last_y; - data->state = touch_inputs.current_state; - LV_LOG_INFO("X=%u Y=%u", data->point.x, data->point.y); - -#if CONFIG_LV_FT6X36_COORDINATES_QUEUE - xQueueOverwrite( ft6x36_touch_queue_handle, &touch_inputs ); -#endif - - return false; -} +/* +* 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 +#ifdef LV_LVGL_H_INCLUDE_SIMPLE +#include +#else +#include +#endif +#include "ft6x36.h" +#include "lvgl_i2c/i2c_manager.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 + +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); +} + +/** + * @brief Read the FT6x36 gesture ID. Initialize first! + * @param dev_addr: I2C FT6x36 Slave address. + * @retval The gesture ID or 0x00 in case of failure + */ +uint8_t ft6x36_get_gesture_id() { + if (!ft6x36_status.inited) { + ESP_LOGE(TAG, "Init first!"); + return 0x00; + } + uint8_t data_buf; + esp_err_t ret; + if ((ret = ft6x06_i2c_read8(current_dev_addr, FT6X36_GEST_ID_REG, &data_buf) != ESP_OK)) + ESP_LOGE(TAG, "Error reading from device: %s", esp_err_to_name(ret)); + return data_buf; +} + +/** + * @brief Initialize for FT6x36 communication via I2C + * @param dev_addr: Device address on communication Bus (I2C slave address of FT6X36). + * @retval None + */ +void ft6x06_init(uint16_t dev_addr) { + + 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 ); +#endif +} + +/** + * @brief Get the touch screen X and Y positions values. Ignores multi touch + * @param drv: + * @param data: Store data here + * @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 + + 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; + 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); + +#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; +#endif +#if CONFIG_LV_FT6X36_INVERT_X + touch_inputs.last_x = LV_HOR_RES - touch_inputs.last_x; +#endif +#if CONFIG_LV_FT6X36_INVERT_Y + touch_inputs.last_y = LV_VER_RES - touch_inputs.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 + + return false; +} diff --git a/lvgl_touch/gt911.c b/lvgl_touch/gt911.c index 112b9ac..03c3d9d 100644 --- a/lvgl_touch/gt911.c +++ b/lvgl_touch/gt911.c @@ -18,6 +18,7 @@ * SOFTWARE. */ +#include #ifdef LV_LVGL_H_INCLUDE_SIMPLE #include #else @@ -27,6 +28,8 @@ #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 @@ -50,9 +53,9 @@ void gt911_init(uint8_t dev_addr) { uint8_t data_buf; esp_err_t ret; - LV_LOG_INFO("Checking for GT911 Touch Controller"); + ESP_LOGI(TAG, "Checking for GT911 Touch Controller"); if ((ret = gt911_i2c_read(dev_addr, GT911_PRODUCT_ID1, &data_buf, 1) != ESP_OK)) { - LV_LOG_ERROR("Error reading from device: %s", + ESP_LOGE(TAG, "Error reading from device: %s", esp_err_to_name(ret)); // Only show error the first time return; } @@ -61,22 +64,22 @@ void gt911_init(uint8_t dev_addr) { 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); } - LV_LOG_INFO("\tProduct ID: %s", gt911_status.product_id); + ESP_LOGI(TAG, "\tProduct ID: %s", gt911_status.product_id); gt911_i2c_read(dev_addr, GT911_VENDOR_ID, &data_buf, 1); - LV_LOG_INFO("\tVendor ID: 0x%02x", data_buf); + 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); - LV_LOG_INFO("\tX Resolution: %d", gt911_status.max_x_coord); + 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); - LV_LOG_INFO("\tY Resolution: %d", gt911_status.max_y_coord); + ESP_LOGI(TAG, "\tY Resolution: %d", gt911_status.max_y_coord); gt911_status.inited = true; } } @@ -95,7 +98,7 @@ bool gt911_read(lv_indev_drv_t *drv, lv_indev_data_t *data) { uint8_t status_reg; gt911_i2c_read(gt911_status.i2c_dev_addr, GT911_STATUS_REG, &status_reg, 1); -// LV_LOG_INFO("\tstatus: 0x%02x", status_reg); +// 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 @@ -109,7 +112,7 @@ bool gt911_read(lv_indev_drv_t *drv, lv_indev_data_t *data) { } // gt911_i2c_read(gt911_status.i2c_dev_addr, GT911_TRACK_ID1, &data_buf, 1); -// LV_LOG_INFO("\ttrack_id: %d", data_buf); +// 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; @@ -135,7 +138,7 @@ bool gt911_read(lv_indev_drv_t *drv, lv_indev_data_t *data) { data->point.x = last_x; data->point.y = last_y; data->state = LV_INDEV_STATE_PR; - LV_LOG_INFO("X=%u Y=%u", data->point.x, data->point.y); - LV_LOG_INFO("X=%u Y=%u", data->point.x, data->point.y); + 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; } diff --git a/lvgl_touch/ra8875_touch.c b/lvgl_touch/ra8875_touch.c index b694dcd..3340e4f 100644 --- a/lvgl_touch/ra8875_touch.c +++ b/lvgl_touch/ra8875_touch.c @@ -5,6 +5,7 @@ /********************* * INCLUDES *********************/ +#include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -22,6 +23,7 @@ * DEFINES *********************/ #define DEBUG false +#define TAG "RA8875-Touch" #define DIV_ROUND_UP(n, d) (((n)+(d)-1)/(d)) @@ -81,7 +83,7 @@ void ra8875_touch_init(void) }; #define INIT_CMDS_SIZE (sizeof(init_cmds)/sizeof(init_cmds[0])) - LV_LOG_INFO("Initializing RA8875 Touch..."); + ESP_LOGI(TAG, "Initializing RA8875 Touch..."); // Send all the commands for (unsigned int i = 0; i < INIT_CMDS_SIZE; i++) { @@ -92,7 +94,7 @@ void ra8875_touch_init(void) void ra8875_touch_enable(bool enable) { - LV_LOG_INFO("%s touch.", enable ? "Enabling" : "Disabling"); + ESP_LOGI(TAG, "%s touch.", enable ? "Enabling" : "Disabling"); uint8_t val = enable ? (0x80 | TPCR0_VAL) : (TPCR0_VAL); ra8875_write_cmd(RA8875_REG_TPCR0, val); } @@ -120,7 +122,7 @@ bool ra8875_touch_read(lv_indev_drv_t * drv, lv_indev_data_t * data) y = (y << 2) | ((xy >> 2) & 0x03); #if DEBUG - LV_LOG_INFO("Touch Poll Raw: %d,%d", x, y); + ESP_LOGI(TAG, "Touch Poll Raw: %d,%d", x, y); #endif // Convert to display coordinates @@ -134,7 +136,7 @@ bool ra8875_touch_read(lv_indev_drv_t * drv, lv_indev_data_t * data) data->point.y = y; #if DEBUG - LV_LOG_INFO("Touch Poll - Event: %d; %d,%d", data->state, data->point.x, data->point.y); + ESP_LOGI(TAG, "Touch Poll - Event: %d; %d,%d", data->state, data->point.x, data->point.y); #endif return false; diff --git a/lvgl_touch/stmpe610.c b/lvgl_touch/stmpe610.c index 8693cfd..6c5ae60 100644 --- a/lvgl_touch/stmpe610.c +++ b/lvgl_touch/stmpe610.c @@ -7,6 +7,7 @@ *********************/ #include "stmpe610.h" #include "esp_system.h" +#include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" @@ -16,6 +17,8 @@ /********************* * DEFINES *********************/ +#define TAG "STMPE610" + /********************** * TYPEDEFS @@ -52,26 +55,26 @@ void stmpe610_init(void) uint8_t u8; uint16_t u16; - LV_LOG_INFO("Initialization."); + ESP_LOGI(TAG, "Initialization."); // Get the initial SPI configuration //u8 = read_8bit_reg(STMPE_SPI_CFG); - //LV_LOG_INFO("SPI_CFG = 0x%x", u8); + //ESP_LOGI(TAG, "SPI_CFG = 0x%x", u8); // Attempt a software reset write_8bit_reg(STMPE_SYS_CTRL1, STMPE_SYS_CTRL1_RESET); - vTaskDelay(pdMS_TO_TICKS(10)); + vTaskDelay(10 / portTICK_RATE_MS); // Reset the SPI configuration, making sure auto-increment is set u8 = read_8bit_reg(STMPE_SPI_CFG); write_8bit_reg(STMPE_SPI_CFG, u8 | STMPE_SPI_CFG_AA); u8 = read_8bit_reg(STMPE_SPI_CFG); - LV_LOG_INFO("SPI_CFG = 0x%x", u8); + ESP_LOGI(TAG, "SPI_CFG = 0x%x", u8); // Verify SPI communication u16 = read_16bit_reg(STMPE_CHIP_ID); if (u16 != 0x811) { - LV_LOG_ERROR("Incorrect version: 0x%x", u16); + ESP_LOGE(TAG, "Incorrect version: 0x%x", u16); } write_8bit_reg(STMPE_SYS_CTRL2, 0x00); // Disable clocks @@ -127,12 +130,12 @@ bool stmpe610_read(lv_indev_drv_t * drv, lv_indev_data_t * data) } if (c > 0) { - //LV_LOG_INFO("%d: %d %d %d", c, x, y, z); + //ESP_LOGI(TAG, "%d: %d %d %d", c, x, y, z); adjust_data(&x, &y); last_x = x; last_y = y; - //LV_LOG_INFO(" ==> %d %d", x, y); + //ESP_LOGI(TAG, " ==> %d %d", x, y); } z = read_8bit_reg(STMPE_INT_STA); // Clear interrupts @@ -141,7 +144,7 @@ bool stmpe610_read(lv_indev_drv_t * drv, lv_indev_data_t * data) // Clear the FIFO if we discover an overflow write_8bit_reg(STMPE_FIFO_STA, STMPE_FIFO_STA_RESET); write_8bit_reg(STMPE_FIFO_STA, 0); // unreset - LV_LOG_ERROR("Fifo overflow"); + ESP_LOGE(TAG, "Fifo overflow"); } } diff --git a/lv_port/tp_spi.c b/lvgl_touch/tp_spi.c similarity index 100% rename from lv_port/tp_spi.c rename to lvgl_touch/tp_spi.c diff --git a/lv_port/tp_spi.h b/lvgl_touch/tp_spi.h similarity index 100% rename from lv_port/tp_spi.h rename to lvgl_touch/tp_spi.h diff --git a/lvgl_touch/xpt2046.c b/lvgl_touch/xpt2046.c index 98a5804..93b4329 100644 --- a/lvgl_touch/xpt2046.c +++ b/lvgl_touch/xpt2046.c @@ -8,6 +8,7 @@ *********************/ #include "xpt2046.h" #include "esp_system.h" +#include "esp_log.h" #include "driver/gpio.h" #include "tp_spi.h" #include @@ -15,6 +16,8 @@ /********************* * DEFINES *********************/ +#define TAG "XPT2046" + #define CMD_X_READ 0b10010000 // NOTE: XPT2046 data sheet says this is actually Y #define CMD_Y_READ 0b11010000 // NOTE: XPT2046 data sheet says this is actually X #define CMD_Z1_READ 0b10110000 @@ -56,7 +59,7 @@ uint8_t avg_last; */ void xpt2046_init(void) { - LV_LOG_INFO("Initialization"); + ESP_LOGI(TAG, "XPT2046 Initialization"); #if XPT2046_TOUCH_IRQ || XPT2046_TOUCH_IRQ_PRESS gpio_config_t irq_config = { @@ -91,19 +94,19 @@ bool xpt2046_read(lv_indev_drv_t * drv, lv_indev_data_t * data) x = xpt2046_cmd(CMD_X_READ); y = xpt2046_cmd(CMD_Y_READ); - LV_LOG_INFO("P(%d,%d)", x, y); + ESP_LOGI(TAG, "P(%d,%d)", x, y); /*Normalize Data back to 12-bits*/ x = x >> 4; y = y >> 4; - LV_LOG_INFO("P_norm(%d,%d)", x, y); + ESP_LOGI(TAG, "P_norm(%d,%d)", x, y); xpt2046_corr(&x, &y); xpt2046_avg(&x, &y); last_x = x; last_y = y; - LV_LOG_INFO("x = %d, y = %d", x, y); + ESP_LOGI(TAG, "x = %d, y = %d", x, y); } else {