Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for ILI9225 display controller #172

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ 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_ILI9225)
list(APPEND SOURCES "lvgl_tft/ili9225.c")
else()
message(WARNING "LVGL ESP32 drivers: Display controller not defined.")
endif()
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ swap of RGB565 color on the LVGL configuration menuconfig (it's not handled auto
| HX8357B/HX8357D | TFT | SPI | 16: RGB565 | Yes |
| ST7789 | TFT | SPI | 16: RGB565 | Yes |
| ST7735S | TFT | SPI | 16: RGB565 | Yes |
| ILI9225 | TFT | SPI | 16: RGB565 | Yes |
| FT81x | TFT | Single, Dual, Quad SPI | 16: RGB565 | No |
| GC9A01 | TFT | SPI | 16: RGB565 | Yes |
| RA8875 | TFT | SPI | 16: RGB565 | Yes |
Expand Down
4 changes: 4 additions & 0 deletions lvgl_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,11 @@ bool lvgl_spi_driver_init(int host,
int dma_channel,
int quadwp_pin, int quadhd_pin)
{
#ifdef SPI_HOST_MAX
assert((0 <= host) && (SPI_HOST_MAX > host));
#else
assert(0 <= host);
#endif
const char *spi_names[] = {
"SPI1_HOST", "SPI2_HOST", "SPI3_HOST"
};
Expand Down
2 changes: 2 additions & 0 deletions lvgl_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ extern "C" {
#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_ILI9225
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
#else
#error "No display controller selected"
#endif
Expand Down
9 changes: 9 additions & 0 deletions lvgl_tft/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,11 @@ menu "LVGL TFT Display controller"
bool
help
PCD8544 display controller (Nokia 3110/5110)

config LV_TFT_DISPLAY_CONTROLLER_ILI9225
bool
help
ILI9225 display controller.
# Display controller communication protocol
#
# This symbols define the communication protocol used by the
Expand Down Expand Up @@ -349,6 +354,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_ILI9225
bool "ILI9225"
select LV_TFT_DISPLAY_CONTROLLER_ILI9225
select LV_TFT_DISPLAY_PROTOCOL_SPI
endchoice

config CUSTOM_DISPLAY_BUFFER_SIZE
Expand Down
4 changes: 4 additions & 0 deletions lvgl_tft/disp_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ void *disp_driver_init(void)
ili9163c_init();
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_PCD8544
pcd8544_init();
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9225
ili9225_init();
#endif

// We still use menuconfig for these settings
Expand Down Expand Up @@ -111,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_ILI9225
ili9225_flush(drv, area, color_map);
#endif
}

Expand Down
2 changes: 2 additions & 0 deletions lvgl_tft/disp_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_ILI9225
#include "ili9225.h"
#endif

/*********************
Expand Down
248 changes: 248 additions & 0 deletions lvgl_tft/ili9225.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
/**
* @file ili9225.c
*
*/

/*********************
* INCLUDES
*********************/
#include "ili9225.h"
#include "disp_spi.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

/*********************
* DEFINES
*********************/
#define TAG "ILI9225"
#define ILI9225_DRIVER_OUTPUT_CTRL 0x01 // Driver Output Control
#define ILI9225_LCD_AC_DRIVING_CTRL 0x02 // LCD AC Driving Control
#define ILI9225_ENTRY_MODE 0x03 // Entry Mode
#define ILI9225_DISP_CTRL1 0x07 // Display Control 1
#define ILI9225_BLANK_PERIOD_CTRL1 0x08 // Blank Period Control
#define ILI9225_FRAME_CYCLE_CTRL 0x0B // Frame Cycle Control
#define ILI9225_INTERFACE_CTRL 0x0C // Interface Control
#define ILI9225_OSC_CTRL 0x0F // Osc Control
#define ILI9225_POWER_CTRL1 0x10 // Power Control 1
#define ILI9225_POWER_CTRL2 0x11 // Power Control 2
#define ILI9225_POWER_CTRL3 0x12 // Power Control 3
#define ILI9225_POWER_CTRL4 0x13 // Power Control 4
#define ILI9225_POWER_CTRL5 0x14 // Power Control 5
#define ILI9225_VCI_RECYCLING 0x15 // VCI Recycling
#define ILI9225_RAM_ADDR_SET1 0x20 // Horizontal GRAM Address Set
#define ILI9225_RAM_ADDR_SET2 0x21 // Vertical GRAM Address Set
#define ILI9225_GRAM_DATA_REG 0x22 // GRAM Data Register
#define ILI9225_GATE_SCAN_CTRL 0x30 // Gate Scan Control Register
#define ILI9225_VERTICAL_SCROLL_CTRL1 0x31 // Vertical Scroll Control 1 Register
#define ILI9225_VERTICAL_SCROLL_CTRL2 0x32 // Vertical Scroll Control 2 Register
#define ILI9225_VERTICAL_SCROLL_CTRL3 0x33 // Vertical Scroll Control 3 Register
#define ILI9225_PARTIAL_DRIVING_POS1 0x34 // Partial Driving Position 1 Register
#define ILI9225_PARTIAL_DRIVING_POS2 0x35 // Partial Driving Position 2 Register
#define ILI9225_HORIZONTAL_WINDOW_ADDR1 0x36 // Horizontal Address Start Position
#define ILI9225_HORIZONTAL_WINDOW_ADDR2 0x37 // Horizontal Address End Position
#define ILI9225_VERTICAL_WINDOW_ADDR1 0x38 // Vertical Address Start Position
#define ILI9225_VERTICAL_WINDOW_ADDR2 0x39 // Vertical Address End Position
#define ILI9225_GAMMA_CTRL1 0x50 // Gamma Control 1
#define ILI9225_GAMMA_CTRL2 0x51 // Gamma Control 2
#define ILI9225_GAMMA_CTRL3 0x52 // Gamma Control 3
#define ILI9225_GAMMA_CTRL4 0x53 // Gamma Control 4
#define ILI9225_GAMMA_CTRL5 0x54 // Gamma Control 5
#define ILI9225_GAMMA_CTRL6 0x55 // Gamma Control 6
#define ILI9225_GAMMA_CTRL7 0x56 // Gamma Control 7
#define ILI9225_GAMMA_CTRL8 0x57 // Gamma Control 8
#define ILI9225_GAMMA_CTRL9 0x58 // Gamma Control 9
#define ILI9225_GAMMA_CTRL10 0x59 // Gamma Control 10

/**********************
* 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];
uint8_t databytes; //No of data in data; bit 7 = delay after set; 0xFF = end of cmds.
} lcd_init_cmd_t;

/**********************
* STATIC PROTOTYPES
**********************/
static void ili9225_send_cmd(uint8_t cmd);
static void ili9225_send_cmds(void *data, uint16_t length);
static void ili9225_send_data(void *data, uint16_t length);
static void ili9225_send_color(void *data, uint16_t length);
static void ili9225_set_window(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);

/**********************
* STATIC VARIABLES
**********************/

/**********************
* MACROS
**********************/

/**********************
* GLOBAL FUNCTIONS
**********************/

void ili9225_init(void)
{
lcd_init_cmd_t ili_init_cmds[] = {
{ILI9225_POWER_CTRL1, {0x00, 0x00}, 2}, // Set SAP,DSTB,STB
{ILI9225_POWER_CTRL2, {0x00, 0x00}, 2}, // Set APON,PON,AON,VCI1EN,VC
{ILI9225_POWER_CTRL3, {0x00, 0x00}, 2}, // Set BT,DC1,DC2,DC3
{ILI9225_POWER_CTRL4, {0x00, 0x00}, 2}, // Set GVDD
{ILI9225_POWER_CTRL5, {0x00, 0x00}, 2 | 0x80}, // Set VCOMH/VCOML voltage, 40ms delay

{ILI9225_POWER_CTRL2, {0x00, 0x18}, 0x00}, // Set APON,PON,AON,VCI1EN,VC
{ILI9225_POWER_CTRL3, {0x61, 0x21}, 0x00}, // Set BT,DC1,DC2,DC3
{ILI9225_POWER_CTRL4, {0x00, 0x6F}, 0x00}, // Set GVDD 007F 0088
{ILI9225_POWER_CTRL5, {0x49, 0x5F}, 0x00}, // Set VCOMH/VCOML voltage
{ILI9225_POWER_CTRL1, {0x08, 0x00}, 2 | 0x80}, // Set SAP,DSTB,STB, 10ms delay

{ILI9225_POWER_CTRL2, {0x10, 0x3B}, 2 | 0x80}, // Set APON,PON,AON,VCI1EN,VC, 50ms delay

{ILI9225_DRIVER_OUTPUT_CTRL, {0x01, 0x1C}, 2},
{ILI9225_LCD_AC_DRIVING_CTRL, {0x01, 0x00}, 2},
{ILI9225_ENTRY_MODE, {0x10, 0x30}, 2},
{ILI9225_DISP_CTRL1, {0x00, 0x00}, 2},
{ILI9225_BLANK_PERIOD_CTRL1, {0x08, 0x08}, 2},
{ILI9225_FRAME_CYCLE_CTRL, {0x11, 0x00}, 2},
{ILI9225_INTERFACE_CTRL, {0x00, 0x00}, 2},
{ILI9225_OSC_CTRL, {0x0D, 0x01}, 2},
{ILI9225_VCI_RECYCLING, {0x00, 0x20}, 2},
{ILI9225_RAM_ADDR_SET1, {0x00, 0x00}, 2},
{ILI9225_RAM_ADDR_SET2, {0x00, 0x00}, 2},

{ILI9225_GATE_SCAN_CTRL, {0x00, 0x00}, 2},

{ILI9225_GAMMA_CTRL1, {0x00, 0x00}, 2},
{ILI9225_GAMMA_CTRL2, {0x08, 0x08}, 2},
{ILI9225_GAMMA_CTRL3, {0x08, 0x0A}, 2},
{ILI9225_GAMMA_CTRL4, {0x00, 0x0A}, 2},
{ILI9225_GAMMA_CTRL5, {0x0A, 0x08}, 2},
{ILI9225_GAMMA_CTRL6, {0x08, 0x08}, 2},
{ILI9225_GAMMA_CTRL7, {0x00, 0x00}, 2},
{ILI9225_GAMMA_CTRL8, {0x0A, 0x00}, 2},
{ILI9225_GAMMA_CTRL9, {0x07, 0x10}, 2},
{ILI9225_GAMMA_CTRL10, {0x07, 0x10}, 2},

{ILI9225_DISP_CTRL1, {0x00, 0x12}, 2 | 0x80},
{ILI9225_DISP_CTRL1, {0x00, 0x17}, 2},
{0xFF, {0x00}, 0xFF}};

//Initialize non-SPI GPIOs
gpio_pad_select_gpio(ILI9225_DC);
gpio_set_direction(ILI9225_DC, GPIO_MODE_OUTPUT);

#if ILI9225_USE_RST
gpio_pad_select_gpio(ILI9225_RST);
gpio_set_direction(ILI9225_RST, GPIO_MODE_OUTPUT);

//Reset the display
gpio_set_level(ILI9225_RST, 1);
vTaskDelay(10 / portTICK_RATE_MS);
gpio_set_level(ILI9225_RST, 0);
vTaskDelay(10 / portTICK_RATE_MS);
gpio_set_level(ILI9225_RST, 1);
vTaskDelay(150 / portTICK_RATE_MS);
#endif

ESP_LOGI(TAG, "Initialization.");

//Send all the commands
uint16_t cmd = 0;
while (ili_init_cmds[cmd].databytes != 0xFF)
{
ili9225_send_cmd(ili_init_cmds[cmd].cmd);
ili9225_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++;
}
}

void ili9225_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map)
{
uint16_t x1 = area->x1;
uint16_t x2 = area->x2;

uint16_t y1 = area->y1;
uint16_t y2 = area->y2;

ili9225_set_window(x1, y1, x2, y2);

uint8_t data[2];
ili9225_send_cmd(ILI9225_RAM_ADDR_SET1);
data[0] = (x1 >> 8) & 0xFF;
data[1] = x1 & 0xFF;
ili9225_send_data(data, 2);

ili9225_send_cmd(ILI9225_RAM_ADDR_SET2);
data[0] = (y1 >> 8) & 0xFF;
data[1] = y1 & 0xFF;
ili9225_send_data(data, 2);

ili9225_send_cmd(ILI9225_GRAM_DATA_REG);

uint32_t size = lv_area_get_width(area) * lv_area_get_height(area);
ili9225_send_color((void *)color_map, size * 2);
}

/**********************
* STATIC FUNCTIONS
**********************/
static void ili9225_send_cmd(uint8_t cmd)
{
disp_wait_for_pending_transactions();
uint8_t data[2];
data[0] = 0x00;
data[1] = cmd;

gpio_set_level(ILI9225_DC, 0); /*Command mode*/
disp_spi_send_data(data, 2);
}

static void ili9225_send_data(void *data, uint16_t length)
{
disp_wait_for_pending_transactions();
gpio_set_level(ILI9225_DC, 1); /*Data mode*/
disp_spi_send_data(data, length);
}

static void ili9225_send_color(void *data, uint16_t length)
{
disp_wait_for_pending_transactions();
gpio_set_level(ILI9225_DC, 1); /*Data mode*/
disp_spi_send_colors(data, length);
}

static void ili9225_set_window(uint16_t h1, uint16_t v1, uint16_t h2, uint16_t v2)
{
uint8_t data[2];

ili9225_send_cmd(ILI9225_HORIZONTAL_WINDOW_ADDR1); // HEA
data[0] = (h2 >> 8) & 0xFF;
data[1] = h2 & 0xFF;
ili9225_send_data(data, 2);

ili9225_send_cmd(ILI9225_HORIZONTAL_WINDOW_ADDR2); // HSA
data[0] = (h1 >> 8) & 0xFF;
data[1] = h1 & 0xFF;
ili9225_send_data(data, 2);

ili9225_send_cmd(ILI9225_VERTICAL_WINDOW_ADDR1); // VEA
data[0] = (v2 >> 8) & 0xFF;
data[1] = v2 & 0xFF;
ili9225_send_data(data, 2);

ili9225_send_cmd(ILI9225_VERTICAL_WINDOW_ADDR2); // VSA
data[0] = (v1 >> 8) & 0xFF;
data[1] = v1 & 0xFF;
ili9225_send_data(data, 2);
}
54 changes: 54 additions & 0 deletions lvgl_tft/ili9225.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* @file lv_templ.h
*
*/

#ifndef ILI9225_H
#define ILI9225_H

#ifdef __cplusplus
extern "C" {
#endif

/*********************
* INCLUDES
*********************/
#include <stdbool.h>

#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif

#include "sdkconfig.h"

/*********************
* DEFINES
*********************/
#define ILI9225_DC CONFIG_LV_DISP_PIN_DC
#define ILI9225_USE_RST CONFIG_LV_DISP_USE_RST
#define ILI9225_RST CONFIG_LV_DISP_PIN_RST
#define ILI9225_INVERT_COLORS CONFIG_LV_INVERT_COLORS

/**********************
* TYPEDEFS
**********************/

/**********************
* GLOBAL PROTOTYPES
**********************/

void ili9225_init(void);
void ili9225_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);

/**********************
* MACROS
**********************/


#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /*ILI9225_H*/