diff --git a/lvgl_helpers.c b/lvgl_helpers.c index a8946f5..b382fb4 100644 --- a/lvgl_helpers.c +++ b/lvgl_helpers.c @@ -6,8 +6,11 @@ /********************* * INCLUDES *********************/ -#include "sdkconfig.h" #include "lvgl_helpers.h" + +#include "sdkconfig.h" + +#include "driver/spi_common.h" #include "esp_log.h" #include "esp_idf_version.h" @@ -47,6 +50,13 @@ */ 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 **********************/ @@ -68,25 +78,20 @@ void lvgl_interface_init(void) ESP_LOGI(TAG, "Display hor size: %d, ver size: %d", LV_HOR_RES_MAX, LV_VER_RES_MAX); #endif - ESP_LOGI(TAG, "Display buffer size: %d", lvgl_get_display_buffer_size()); - -#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X) - ESP_LOGI(TAG, "Initializing SPI master for FT81X"); - 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, SPI_DMA_CH1, - DISP_SPI_IO2, DISP_SPI_IO3); + ESP_LOGI(TAG, "Display buffer size: %d", display_buffer_size); - disp_spi_add_device(TFT_SPI_HOST); - -#if defined (CONFIG_LV_TOUCH_CONTROLLER_FT81X) - touch_driver_init(); + /* SPI DMA Channel selection + * SPI_DMA_CH1 is only defined for ESP32, so let the driver choose which + * channel to use, and use the proven channel 1 on esp32 targets */ + int dma_channel = 3; +#if defined (CONFIG_IDF_TARGET_ESP32) + dma_channel = 1; #endif +#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X) + init_ft81x(dma_channel); return; #endif @@ -95,19 +100,19 @@ void lvgl_interface_init(void) ESP_LOGI(TAG, "Initializing SPI master"); int miso = DISP_SPI_MISO; - size_t display_buffer_size = lvgl_get_display_buffer_size(); 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 - lvgl_spi_driver_init(TFT_SPI_HOST, - miso, DISP_SPI_MOSI, DISP_SPI_CLK, - spi_max_transfer_size, SPI_DMA_CH1, - DISP_SPI_IO2, DISP_SPI_IO3); + lvgl_spi_driver_init(TFT_SPI_HOST, 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); + + /* Add device for touch driver */ #if defined (SHARED_SPI_BUS) tp_spi_add_device(TOUCH_SPI_HOST); touch_driver_init(); @@ -122,26 +127,28 @@ void lvgl_interface_init(void) /* 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"); - lvgl_spi_driver_init(TOUCH_SPI_HOST, - TP_SPI_MISO, TP_SPI_MOSI, TP_SPI_CLK, - DMA_DEFAULT_TRANSFER_SIZE, SPI_DMA_CH2, - GPIO_NOT_USED, GPIO_NOT_USED); +#if defined (CONFIG_IDF_TARGET_ESP32) + dma_channel = 2; +#endif - tp_spi_add_device(TOUCH_SPI_HOST); + 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); - 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 + 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 #else #endif } @@ -254,7 +261,7 @@ size_t lvgl_get_display_buffer_size(void) * We could use the ESP_IDF_VERSION_VAL macro available in the "esp_idf_version.h" * header available since ESP-IDF v4. */ -bool lvgl_spi_driver_init(spi_host_device_t host, +bool lvgl_spi_driver_init(int host, int miso_pin, int mosi_pin, int sclk_pin, int max_transfer_sz, int dma_channel, @@ -286,12 +293,9 @@ bool lvgl_spi_driver_init(spi_host_device_t host, }; ESP_LOGI(TAG, "Initializing SPI bus..."); - #if defined (CONFIG_IDF_TARGET_ESP32C3) - dma_channel = SPI_DMA_CH_AUTO; - #endif #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 0) - esp_err_t ret = spi_bus_initialize(host, &buscfg, (spi_dma_chan_t)dma_channel); + esp_err_t ret = spi_bus_initialize((spi_host_device_t) host, &buscfg, (spi_dma_chan_t)dma_channel); #else esp_err_t ret = spi_bus_initialize(host, &buscfg, dma_channel); #endif @@ -324,3 +328,20 @@ static int calculate_spi_max_transfer_size(const int display_buffer_size) 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 ca73431..6031036 100644 --- a/lvgl_helpers.h +++ b/lvgl_helpers.h @@ -14,8 +14,6 @@ extern "C" { *********************/ #include -#include "driver/spi_common.h" - #include "lvgl_spi_conf.h" #include "lvgl_tft/disp_driver.h" #include "lvgl_tft/esp_lcd_backlight.h" @@ -39,7 +37,7 @@ void lvgl_i2c_locking(void* leader); void lvgl_interface_init(void); /* Initialize SPI master */ -bool lvgl_spi_driver_init(spi_host_device_t host, int miso_pin, int mosi_pin, int sclk_pin, +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 */ diff --git a/lvgl_spi_conf.h b/lvgl_spi_conf.h index c7e1672..9b6d0ae 100644 --- a/lvgl_spi_conf.h +++ b/lvgl_spi_conf.h @@ -6,6 +6,8 @@ #ifndef LVGL_SPI_CONF_H #define LVGL_SPI_CONF_H +#include + #ifdef __cplusplus extern "C" { #endif @@ -73,11 +75,15 @@ extern "C" { #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 */ diff --git a/lvgl_tft/GC9A01.c b/lvgl_tft/GC9A01.c index b571818..83e24e4 100644 --- a/lvgl_tft/GC9A01.c +++ b/lvgl_tft/GC9A01.c @@ -36,6 +36,7 @@ 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 @@ -110,20 +111,7 @@ void GC9A01_init(void) }; - //Initialize non-SPI GPIOs - gpio_pad_select_gpio(GC9A01_DC); - gpio_set_direction(GC9A01_DC, GPIO_MODE_OUTPUT); - -#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 + GC9A01_reset(); LV_LOG_INFO("Initialization."); @@ -241,3 +229,14 @@ static void GC9A01_set_orientation(uint8_t 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(100 / portTICK_RATE_MS); + gpio_set_level(GC9A01_RST, 1); + vTaskDelay(100 / portTICK_RATE_MS); +#endif +} diff --git a/lvgl_tft/hx8357.c b/lvgl_tft/hx8357.c index a22287b..d7faf42 100644 --- a/lvgl_tft/hx8357.c +++ b/lvgl_tft/hx8357.c @@ -49,7 +49,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,44 +156,31 @@ static uint8_t displayType = HX8357D; void hx8357_init(void) { - //Initialize non-SPI GPIOs - gpio_pad_select_gpio(HX8357_DC); - gpio_set_direction(HX8357_DC, GPIO_MODE_OUTPUT); + hx8357_reset(); -#if HX8357_USE_RST - gpio_pad_select_gpio(HX8357_RST); - gpio_set_direction(HX8357_RST, GPIO_MODE_OUTPUT); + LV_LOG_INFO("Initialization."); - //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 + //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) + } + } - LV_LOG_INFO("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); + hx8357_set_rotation(1); #if HX8357_INVERT_COLORS hx8357_send_cmd(HX8357_INVON); @@ -286,3 +273,13 @@ 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(10 / portTICK_RATE_MS); + gpio_set_level(HX8357_RST, 1); + vTaskDelay(120 / portTICK_RATE_MS); +#endif +} diff --git a/lvgl_tft/il3820.c b/lvgl_tft/il3820.c index 31fea55..5179b27 100644 --- a/lvgl_tft/il3820.c +++ b/lvgl_tft/il3820.c @@ -100,6 +100,7 @@ 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) @@ -195,26 +196,7 @@ void il3820_init(void) { uint8_t tmp[3] = {0}; - /* 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); + il3820_reset(); /* Busy wait for the BUSY signal to go low */ il3820_waitbusy(IL3820_WAIT); @@ -416,3 +398,17 @@ 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(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); +} diff --git a/lvgl_tft/ili9481.c b/lvgl_tft/ili9481.c index 565182d..d4b1a93 100644 --- a/lvgl_tft/ili9481.c +++ b/lvgl_tft/ili9481.c @@ -35,6 +35,7 @@ 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 @@ -70,27 +71,10 @@ void ili9481_init(void) {0, {0}, 0xff}, }; - //Initialize non-SPI GPIOs - gpio_pad_select_gpio(ILI9481_DC); - gpio_set_direction(ILI9481_DC, GPIO_MODE_OUTPUT); - -#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 + ili9481_reset(); LV_LOG_INFO("Initialization."); - // Exit sleep - ili9481_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) { @@ -108,7 +92,8 @@ 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) { - uint32_t size = lv_area_get_width(area) * lv_area_get_height(area); + /* 3 is number of bytes in lv_color_t */ + uint32_t size = lv_area_get_width(area) * lv_area_get_height(area) * 3; lv_color16_t *buffer_16bit = (lv_color16_t *) color_map; uint8_t *mybuf; @@ -159,7 +144,9 @@ 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 * 3); + ili9481_send_color((void *) mybuf, size); + + /* FIXME: Can we free the memory even when it's being transferred? */ heap_caps_free(mybuf); } @@ -203,3 +190,17 @@ static void ili9481_set_orientation(uint8_t orientation) 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(100 / portTICK_RATE_MS); + gpio_set_level(ILI9481_RST, 1); + vTaskDelay(100 / portTICK_RATE_MS); +#else + // Exit sleep, software reset + ili9481_send_cmd(0x01); + vTaskDelay(100 / portTICK_RATE_MS); +#endif +} diff --git a/lvgl_tft/ili9486.c b/lvgl_tft/ili9486.c index 2283e54..f7b08a7 100644 --- a/lvgl_tft/ili9486.c +++ b/lvgl_tft/ili9486.c @@ -35,7 +35,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,77 +50,62 @@ static void ili9486_send_color(void * data, uint16_t length); 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}, + }; - //Initialize non-SPI GPIOs - gpio_pad_select_gpio(ILI9486_DC); - gpio_set_direction(ILI9486_DC, GPIO_MODE_OUTPUT); + ili9486_reset(); -#if ILI9486_USE_RST - gpio_pad_select_gpio(ILI9486_RST); - gpio_set_direction(ILI9486_RST, GPIO_MODE_OUTPUT); + LV_LOG_INFO("ILI9486 Initialization."); - //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 - - LV_LOG_INFO("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++; - } + //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}; - uint32_t size = 0; + 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; - /*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); - - size = lv_area_get_width(area) * lv_area_get_height(area); - - ili9486_send_color((void*) color_map, size * 2); + /*Memory write*/ + ili9486_send_cmd(0x2C); + ili9486_send_color((void*) color_map, size); } /********************** @@ -128,30 +113,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) @@ -179,3 +164,13 @@ static void ili9486_set_orientation(uint8_t 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(100 / portTICK_RATE_MS); + gpio_set_level(ILI9486_RST, 1); + vTaskDelay(100 / portTICK_RATE_MS); +#endif +} diff --git a/lvgl_tft/jd79653a.c b/lvgl_tft/jd79653a.c index a9e5590..55737f9 100644 --- a/lvgl_tft/jd79653a.c +++ b/lvgl_tft/jd79653a.c @@ -417,8 +417,11 @@ 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 uint8_t *buf = (uint8_t *) color_map; diff --git a/lvgl_tft/ra8875.c b/lvgl_tft/ra8875.c index 97f0d1e..7404da5 100644 --- a/lvgl_tft/ra8875.c +++ b/lvgl_tft/ra8875.c @@ -133,7 +133,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 **********************/ @@ -180,18 +180,7 @@ void ra8875_init(void) LV_LOG_INFO("Initializing RA8875..."); - // 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 + ra8875_reset(); // Initalize RA8875 clocks (SPI must be decelerated before initializing clocks) disp_spi_change_device_speed(SPI_CLOCK_SPEED_SLOW_HZ); @@ -376,3 +365,13 @@ 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_RATE_MS)); + gpio_set_level(RA8875_RST, 1); + vTaskDelay(DIV_ROUND_UP(100, portTICK_RATE_MS)); +#endif +} diff --git a/lvgl_tft/sh1107.c b/lvgl_tft/sh1107.c index 84ab65c..76e9044 100644 --- a/lvgl_tft/sh1107.c +++ b/lvgl_tft/sh1107.c @@ -34,6 +34,7 @@ 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); @@ -93,31 +94,18 @@ void sh1107_init(void) {0, {0}, 0xff}, }; - //Initialize non-SPI GPIOs - gpio_pad_select_gpio(SH1107_DC); - gpio_set_direction(SH1107_DC, GPIO_MODE_OUTPUT); + sh1107_reset(); -#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++; - } + //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, @@ -257,3 +245,13 @@ static lv_coord_t get_display_hor_res(lv_disp_drv_t *disp_drv) return val; } + +static void sh1107_reset(void) +{ +#if SH1107_USE_RST + gpio_set_level(SH1107_RST, 0); + vTaskDelay(100 / portTICK_RATE_MS); + gpio_set_level(SH1107_RST, 1); + vTaskDelay(100 / portTICK_RATE_MS); +#endif +} diff --git a/lvgl_tft/st7735s.c b/lvgl_tft/st7735s.c index c2786a1..83835c6 100644 --- a/lvgl_tft/st7735s.c +++ b/lvgl_tft/st7735s.c @@ -39,6 +39,7 @@ 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); @@ -98,20 +99,7 @@ void st7735s_init(void) {0, {0}, 0xff} }; - //Initialize non-SPI GPIOs - gpio_pad_select_gpio(ST7735S_DC); - gpio_set_direction(ST7735S_DC, GPIO_MODE_OUTPUT); - -#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 + st7735s_reset(); LV_LOG_INFO("ST7735S initialization."); @@ -137,29 +125,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]; + uint8_t data[4] = {0}; - /*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); - st7735s_send_color((void*)color_map, size * 2); + uint32_t size = lv_area_get_width(area) * lv_area_get_height(area) * 2; + st7735s_send_color((void*)color_map, size); } void st7735s_sleep_in() @@ -227,6 +215,16 @@ static void st7735s_set_orientation(uint8_t orientation) st7735s_send_data((void *) &data[orientation], 1); } +static void st7735s_reset(void) +{ +#if ST7735S_USE_RST + gpio_set_level(ST7735S_RST, 0); + vTaskDelay(100 / portTICK_RATE_MS); + gpio_set_level(ST7735S_RST, 1); + vTaskDelay(100 / portTICK_RATE_MS); +#endif +} + #ifdef CONFIG_LV_M5STICKC_HANDLE_AXP192 static void axp192_write_byte(uint8_t addr, uint8_t data) diff --git a/lvgl_tft/st7796s.c b/lvgl_tft/st7796s.c index 75e9bd2..90e0d8c 100644 --- a/lvgl_tft/st7796s.c +++ b/lvgl_tft/st7796s.c @@ -36,6 +36,7 @@ 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 @@ -79,37 +80,24 @@ void st7796s_init(void) {0, {0}, 0xff}, }; - //Initialize non-SPI GPIOs - gpio_pad_select_gpio(ST7796S_DC); - gpio_set_direction(ST7796S_DC, GPIO_MODE_OUTPUT); + st7796s_reset(); -#if ST7796S_USE_RST - gpio_pad_select_gpio(ST7796S_RST); - gpio_set_direction(ST7796S_RST, GPIO_MODE_OUTPUT); + LV_LOG_INFO("Initialization."); - //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 + //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++; + } - LV_LOG_INFO("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); + st7796s_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION); #if ST7796S_INVERT_COLORS == 1 st7796s_send_cmd(0x21); @@ -210,3 +198,13 @@ static void st7796s_set_orientation(uint8_t 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(100 / portTICK_RATE_MS); + gpio_set_level(ST7796S_RST, 1); + vTaskDelay(100 / portTICK_RATE_MS); +#endif +} diff --git a/lvgl_tft/uc8151d.c b/lvgl_tft/uc8151d.c index 472fc3d..9ebb76e 100644 --- a/lvgl_tft/uc8151d.c +++ b/lvgl_tft/uc8151d.c @@ -189,8 +189,11 @@ 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 uint8_t *buf = (uint8_t *) color_map; uc8151d_full_update(buf); diff --git a/lvgl_touch/adcraw.c b/lvgl_touch/adcraw.c index c8da1b0..d26596e 100644 --- a/lvgl_touch/adcraw.c +++ b/lvgl_touch/adcraw.c @@ -136,21 +136,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" - 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); + // 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)