From f7164ff22a9bc8f707544043c5adb907068c4aec Mon Sep 17 00:00:00 2001 From: C47D Date: Tue, 5 Oct 2021 00:03:02 -0500 Subject: [PATCH] ili9341: Update driver to use new port interface --- display_config.h | 7 ++ lvgl_tft/disp_driver.c | 2 +- lvgl_tft/ili9341.c | 234 ++++++++++++++++++++++------------------- lvgl_tft/ili9341.h | 14 +-- 4 files changed, 136 insertions(+), 121 deletions(-) diff --git a/display_config.h b/display_config.h index 37e6387..496c065 100644 --- a/display_config.h +++ b/display_config.h @@ -18,10 +18,17 @@ extern "C" { #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 + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/lvgl_tft/disp_driver.c b/lvgl_tft/disp_driver.c index 95569a8..eda9989 100644 --- a/lvgl_tft/disp_driver.c +++ b/lvgl_tft/disp_driver.c @@ -10,7 +10,7 @@ void *disp_driver_init(lv_disp_drv_t *drv) { #if defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341 - ili9341_init(); + ili9341_init(drv); #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481 ili9481_init(); #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488 diff --git a/lvgl_tft/ili9341.c b/lvgl_tft/ili9341.c index 00c0a42..e4b89b0 100644 --- a/lvgl_tft/ili9341.c +++ b/lvgl_tft/ili9341.c @@ -7,22 +7,25 @@ * INCLUDES *********************/ #include "ili9341.h" + #include "disp_spi.h" -#include "driver/gpio.h" -#include "esp_log.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" +#include "display_port.h" /********************* * DEFINES *********************/ - #define TAG "ILI9341" +#define TAG "ILI9341" +#define END_OF_CMD_MARKER 0xFFU + +#define MEMORY_ACCESS_CONTROL_REG 0x36U +#define SOFTWARE_RESET_REG 0x01U /********************** * 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]; @@ -32,12 +35,13 @@ typedef struct { /********************** * STATIC PROTOTYPES **********************/ -static void ili9341_set_orientation(uint8_t orientation); +static void ili9341_set_orientation(lv_disp_drv_t * drv, uint8_t orientation); -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_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_reset(lv_disp_drv_t * drv); /********************** * STATIC VARIABLES **********************/ @@ -50,150 +54,148 @@ static void ili9341_send_color(void * data, uint16_t length); * GLOBAL FUNCTIONS **********************/ -void ili9341_init(void) +void ili9341_init(lv_disp_drv_t * drv) { - 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}, - }; + 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}, + }; - //Initialize non-SPI GPIOs - gpio_pad_select_gpio(ILI9341_DC); - gpio_set_direction(ILI9341_DC, GPIO_MODE_OUTPUT); + ili9341_reset(drv); -#if ILI9341_USE_RST - gpio_pad_select_gpio(ILI9341_RST); - gpio_set_direction(ILI9341_RST, 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); + } - //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 + cmd++; + } - ESP_LOGI(TAG, "Initialization."); + ili9341_set_orientation(drv, ILI9341_INITIAL_ORIENTATION); - //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); +#if ILI9341_INVERT_COLORS == 1U + ili9341_send_cmd(drv, 0x21); #else - ili9341_send_cmd(0x20); + ili9341_send_cmd(drv, 0x20); #endif } void ili9341_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map) { - uint8_t data[4]; + uint8_t data[4] = {0}; + uint32_t size = lv_area_get_width(area) * lv_area_get_height(area); - /*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); + /*Column addresses*/ + data[0] = (area->x1 >> 8) & 0xFF; + data[1] = area->x1 & 0xFF; + data[2] = (area->x2 >> 8) & 0xFF; + data[3] = area->x2 & 0xFF; - /*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); + ili9341_send_cmd(drv, 0x2A); + ili9341_send_data(drv, data, 4); - /*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); + /* 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); } -void ili9341_sleep_in() +void ili9341_sleep_in(lv_disp_drv_t * drv) { - uint8_t data[] = {0x08}; - ili9341_send_cmd(0x10); - ili9341_send_data(&data, 1); + uint8_t data[] = {0x08}; + ili9341_send_cmd(drv, 0x10); + ili9341_send_data(drv, data, 1); } -void ili9341_sleep_out() +void ili9341_sleep_out(lv_disp_drv_t * drv) { - uint8_t data[] = {0x08}; - ili9341_send_cmd(0x11); - ili9341_send_data(&data, 1); + uint8_t data[] = {0x08}; + ili9341_send_cmd(drv, 0x11); + ili9341_send_data(drv, data, 1); } /********************** * STATIC FUNCTIONS **********************/ +static inline void set_cmd_mode(lv_disp_drv_t * drv) +{ + display_port_gpio_dc(drv, 0); +} -static void ili9341_send_cmd(uint8_t cmd) +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) { disp_wait_for_pending_transactions(); - gpio_set_level(ILI9341_DC, 0); /*Command mode*/ + set_cmd_mode(drv); disp_spi_send_data(&cmd, 1); } -static void ili9341_send_data(void * data, uint16_t length) +static void ili9341_send_data(lv_disp_drv_t *drv, void * data, uint16_t length) { disp_wait_for_pending_transactions(); - gpio_set_level(ILI9341_DC, 1); /*Data mode*/ + set_data_mode(drv); disp_spi_send_data(data, length); } -static void ili9341_send_color(void * data, uint16_t length) +static void ili9341_send_color(lv_disp_drv_t *drv, void * data, uint16_t length) { disp_wait_for_pending_transactions(); - gpio_set_level(ILI9341_DC, 1); /*Data mode*/ + set_data_mode(drv); disp_spi_send_colors(data, length); } -static void ili9341_set_orientation(uint8_t orientation) +static void ili9341_set_orientation(lv_disp_drv_t *drv, uint8_t orientation) { 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}; #elif defined (CONFIG_LV_PREDEFINED_DISPLAY_M5CORE2) @@ -204,8 +206,20 @@ static void ili9341_set_orientation(uint8_t orientation) const uint8_t data[] = {0x48, 0x88, 0x28, 0xE8}; #endif - ESP_LOGD(TAG, "0x36 command value: 0x%02X", data[orientation]); - - ili9341_send_cmd(0x36); - ili9341_send_data((void *) &data[orientation], 1); + ili9341_send_cmd(drv, MEMORY_ACCESS_CONTROL_REG); + ili9341_send_data(drv, (void *) &data[orientation], 1); +} + +/* 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 } diff --git a/lvgl_tft/ili9341.h b/lvgl_tft/ili9341.h index 62317e8..0f8c58b 100644 --- a/lvgl_tft/ili9341.h +++ b/lvgl_tft/ili9341.h @@ -13,23 +13,17 @@ extern "C" { /********************* * INCLUDES *********************/ -#include - #ifdef LV_LVGL_H_INCLUDE_SIMPLE #include "lvgl.h" #else #include "lvgl/lvgl.h" #endif -#include "sdkconfig.h" +#include "display_config.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 @@ -39,10 +33,10 @@ extern "C" { * GLOBAL PROTOTYPES **********************/ -void ili9341_init(void); +void ili9341_init(lv_disp_drv_t * drv); void ili9341_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map); -void ili9341_sleep_in(void); -void ili9341_sleep_out(void); +void ili9341_sleep_in(lv_disp_drv_t * drv); +void ili9341_sleep_out(lv_disp_drv_t *drv); /********************** * MACROS