07ad6bf43e
Added support for ILI9225 display controller. Currently no support for hardware rotation is implemented and only the default portrait resolution 176x220 is supported.
249 lines
8.9 KiB
C
249 lines
8.9 KiB
C
/**
|
|
* @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);
|
|
}
|