346 lines
7.6 KiB
C
346 lines
7.6 KiB
C
|
|
#include "system/includes.h"
|
|
#include "typedef.h"
|
|
#include "asm/pap.h"
|
|
#include "app_config.h"
|
|
#include "lcd_drive.h"
|
|
#include "lcd_config.h"
|
|
|
|
|
|
#if TCFG_LCD_ILI9341_ENABLE
|
|
|
|
#if HORIZONTAL_SCREEN /*横屏*/
|
|
#define LCD_W 320
|
|
#define LCD_H 240
|
|
#else /*竖屏*/
|
|
#define LCD_W 240
|
|
#define LCD_H 320
|
|
#endif
|
|
|
|
static void ILI9341_SetRange(u16 xs, u16 xe, u16 ys, u16 ye)
|
|
{
|
|
/******UI每次发送数据都会调用开窗告诉屏幕要刷新那个区域***********/
|
|
set_lcd_ui_x_y(xs, xe, ys, ye);
|
|
}
|
|
|
|
static void ILI9341_SetRange_1(u16 xs, u16 xe, u16 ys, u16 ye)
|
|
{
|
|
WriteCOM(0x2A);
|
|
WriteDAT_8(ys >> 8);
|
|
WriteDAT_8(ys);
|
|
WriteDAT_8(ye >> 8);
|
|
WriteDAT_8(ye);
|
|
WriteCOM(0x2B);
|
|
WriteDAT_8(xs >> 8);
|
|
WriteDAT_8(xs);
|
|
WriteDAT_8(xe >> 8);
|
|
WriteDAT_8(xe);
|
|
}
|
|
|
|
static void ILI9341_io_init()
|
|
{
|
|
lcd_rs_pinstate(0);
|
|
lcd_cs_pinstate(1);
|
|
lcd_rst_pinstate(1);
|
|
}
|
|
|
|
|
|
void ILI9341_set_direction(u8 dir)
|
|
{
|
|
WriteCOM(0x36); //扫描方向控制
|
|
|
|
if (dir == ROTATE_DEGREE_0) { //正向
|
|
#if HORIZONTAL_SCREEN
|
|
WriteDAT_8(0xd8);
|
|
#else
|
|
WriteDAT_8(0x58);
|
|
#endif
|
|
} else if (dir == ROTATE_DEGREE_180) { //翻转180
|
|
#if HORIZONTAL_SCREEN
|
|
WriteDAT_8(0x18);
|
|
#else
|
|
WriteDAT_8(0x98);
|
|
#endif
|
|
}
|
|
ILI9341_SetRange(0, LCD_W - 1, 0, LCD_H - 1);
|
|
}
|
|
|
|
void ILI9341_clear_screen(u16 color)
|
|
{
|
|
lcd_interface_non_block_wait();
|
|
WriteCOM(0x2c);
|
|
u8 *buf = malloc(LCD_W * LCD_H * 2);
|
|
if (!buf) {
|
|
printf("no men in %s \n", __func__);
|
|
return;
|
|
}
|
|
for (u32 i = 0; i < LCD_W * LCD_H; i++) {
|
|
buf[2 * i] = (color >> 8) & 0xff;
|
|
buf[2 * i + 1] = color & 0xff;
|
|
}
|
|
WriteDAT_DMA(buf, LCD_W * LCD_H * 2);
|
|
free(buf);
|
|
}
|
|
|
|
void ILI9341_Fill(u8 *img, u16 len)
|
|
{
|
|
lcd_interface_non_block_wait();
|
|
WriteCOM(0x2c);
|
|
WriteDAT_DMA(img, len);
|
|
}
|
|
|
|
void ILI9341_Sleep_In_Mode(void)
|
|
{
|
|
WriteCOM(0x10); //Sleep in
|
|
lcd_delay(120); //Delay 120ms
|
|
}
|
|
|
|
void ILI9341_Sleep_Out_Mode(void)
|
|
{
|
|
WriteCOM(0x11); //Sleep out
|
|
lcd_delay(120); //Delay 120ms
|
|
}
|
|
|
|
void st7735_shown_image(u8 *buff, u16 x_addr, u16 y_addr, u16 width, u16 height)
|
|
{
|
|
lcd_interface_non_block_wait();
|
|
u32 i = 0;
|
|
ILI9341_set_xy_addr(x_addr, y_addr, width, height);
|
|
WriteDAT_DMA(buff, width * height * 2);
|
|
}
|
|
|
|
static void ILI9341_draw(u8 *map, u32 size)//获取Ui发送出来的数据
|
|
{
|
|
ui_send_data_ready(map, size);
|
|
}
|
|
|
|
static void ILI9341_draw_1(u8 *buf, u32 size, int width, int height)//获取camera发送出来的数据 //数据帧数以camera为基准
|
|
{
|
|
camera_send_data_ready(buf, size, width, height);
|
|
}
|
|
|
|
static void ILI9341_draw_2(int x, int y, int w, int h, char *img)//摄像头层任意位置修改数据
|
|
{
|
|
user_send_data_ready(x, y, w, h, img);
|
|
}
|
|
|
|
static void ILI9341_reset(void)
|
|
{
|
|
printf("lcd reset \n");
|
|
lcd_rst_pinstate(1);
|
|
lcd_rs_pinstate(1);
|
|
lcd_cs_pinstate(1);
|
|
lcd_rst_pinstate(1);
|
|
lcd_delay(60);
|
|
lcd_rst_pinstate(0);
|
|
lcd_delay(10);
|
|
lcd_rst_pinstate(1);
|
|
lcd_delay(100);
|
|
}
|
|
|
|
static void ILI9341_led_ctrl(u8 status)
|
|
{
|
|
lcd_bl_pinstate(status);
|
|
}
|
|
|
|
void ILI9341_clr(void)
|
|
{
|
|
ILI9341_clear_screen(0x00);
|
|
}
|
|
|
|
static void ILI9341_reg_cfg(void)
|
|
{
|
|
lcd_rst_pinstate(1);
|
|
lcd_delay(50);
|
|
lcd_rst_pinstate(0);
|
|
lcd_delay(20);
|
|
lcd_rst_pinstate(1);
|
|
lcd_delay(120);
|
|
|
|
WriteCOM(0x01);
|
|
WriteDAT_8(0x01);
|
|
WriteCOM(0x11);
|
|
WriteDAT_8(0x00);
|
|
lcd_delay(120);
|
|
lcd_delay(120);
|
|
|
|
/*********************************/
|
|
WriteCOM(0x35);//开TE
|
|
WriteDAT_8(0x00);
|
|
|
|
WriteCOM(0xb1);//调节屏幕自身刷新帧率 这个直接影响到一个TE周期的时间
|
|
WriteDAT_8(0x00);
|
|
WriteDAT_8(0x1f); //60fps
|
|
/*********************************/
|
|
|
|
WriteCOM(0xcf);
|
|
WriteDAT_8(0x00);
|
|
WriteDAT_8(0xaa);
|
|
WriteDAT_8(0xe0);
|
|
WriteCOM(0xed);
|
|
WriteDAT_8(0x67);
|
|
WriteDAT_8(0x03);
|
|
WriteDAT_8(0x12);
|
|
WriteDAT_8(0x81);
|
|
WriteCOM(0xe8);
|
|
WriteDAT_8(0x85);
|
|
WriteDAT_8(0x11);
|
|
WriteDAT_8(0x78);
|
|
WriteCOM(0xcb);
|
|
WriteDAT_8(0x39);
|
|
WriteDAT_8(0x2c);
|
|
WriteDAT_8(0x00);
|
|
WriteDAT_8(0x34);
|
|
WriteDAT_8(0x02);
|
|
WriteCOM(0xea);
|
|
WriteDAT_8(0x00);
|
|
WriteDAT_8(0x00);
|
|
|
|
WriteCOM(0xC0); //Power control
|
|
WriteDAT_8(0x21); //VRH[5:0]
|
|
|
|
WriteCOM(0xC1); //Power control
|
|
WriteDAT_8(0x11); //SAP[2:0];BT[3:0]
|
|
|
|
WriteCOM(0xC5); //VCM control
|
|
WriteDAT_8(0x24);
|
|
WriteDAT_8(0x3c);
|
|
|
|
WriteCOM(0xc7);
|
|
WriteDAT_8(0xb7);
|
|
|
|
WriteCOM(0x36);
|
|
WriteDAT_8(0x48);
|
|
|
|
WriteCOM(0x3a); // Memory Access Control
|
|
WriteDAT_8(0x55);
|
|
|
|
WriteCOM(0xf2); // Memory Access Control
|
|
WriteDAT_8(0x00);
|
|
|
|
WriteCOM(0x26);
|
|
WriteDAT_8(0x01);
|
|
|
|
WriteCOM(0xb7); // Display Function Control
|
|
WriteDAT_8(0x06);
|
|
|
|
WriteCOM(0xE0); //Set Gamma
|
|
WriteDAT_8(0x0f);
|
|
WriteDAT_8(0x1b);
|
|
WriteDAT_8(0x19);
|
|
WriteDAT_8(0x0c);
|
|
WriteDAT_8(0x0d);
|
|
WriteDAT_8(0x07);
|
|
WriteDAT_8(0x44);
|
|
WriteDAT_8(0xa9);
|
|
WriteDAT_8(0x2f);
|
|
WriteDAT_8(0x08);
|
|
WriteDAT_8(0x0d);
|
|
WriteDAT_8(0x03);
|
|
WriteDAT_8(0x10);
|
|
WriteDAT_8(0x0b);
|
|
WriteDAT_8(0x00);
|
|
|
|
WriteCOM(0XE1); //Set Gamma
|
|
WriteDAT_8(0x00);
|
|
WriteDAT_8(0x24);
|
|
WriteDAT_8(0x26);
|
|
WriteDAT_8(0x03);
|
|
WriteDAT_8(0x12);
|
|
WriteDAT_8(0x08);
|
|
WriteDAT_8(0x3c);
|
|
WriteDAT_8(0x56);
|
|
WriteDAT_8(0x50);
|
|
WriteDAT_8(0x07);
|
|
WriteDAT_8(0x12);
|
|
WriteDAT_8(0x0c);
|
|
WriteDAT_8(0x2f);
|
|
WriteDAT_8(0x34);
|
|
WriteDAT_8(0x0f);
|
|
|
|
WriteCOM(0X13); //
|
|
WriteDAT_8(0x00);
|
|
|
|
lcd_delay(150);
|
|
WriteCOM(0X29); //Set Gamma
|
|
lcd_delay(50);
|
|
|
|
}
|
|
|
|
static void ILI9341_lvgl_Fill(u16 xs, u16 xe, u16 ys, u16 ye, char *img)
|
|
{
|
|
lcd_interface_non_block_wait();
|
|
u32 len = 0;
|
|
len = (xe + 1 - xs) * (ye + 1 - ys) * 2;
|
|
WriteCOM(0x2A);
|
|
WriteDAT_8(xs >> 8);
|
|
WriteDAT_8(xs);
|
|
WriteDAT_8(xe >> 8);
|
|
WriteDAT_8(xe);
|
|
WriteCOM(0x2B);
|
|
WriteDAT_8(ys >> 8);
|
|
WriteDAT_8(ys);
|
|
WriteDAT_8(ye >> 8);
|
|
WriteDAT_8(ye);
|
|
WriteCOM(0x2c);
|
|
WriteDAT_DMA(img, len);
|
|
}
|
|
|
|
static void ILI9341_test(void)
|
|
{
|
|
lcd_bl_pinstate(lcd_bk_on);
|
|
while (1) {
|
|
os_time_dly(100);
|
|
ILI9341_clear_screen(RED);
|
|
printf("LCD_ILI9341_TSET_BLUE\n");
|
|
os_time_dly(100);
|
|
ILI9341_clear_screen(GREEN);
|
|
printf("LCD_ILI9341_TSET_GRED\n");
|
|
os_time_dly(100);
|
|
ILI9341_clear_screen(BLUE);
|
|
printf("LCD_ILI9341_TSET_BRRED\n");
|
|
os_time_dly(100);
|
|
ILI9341_clear_screen(YELLOW);
|
|
printf("LCD_ILI9341_TSET_YELLOW\n");
|
|
}
|
|
}
|
|
|
|
static int ILI9341_init(void)
|
|
{
|
|
ILI9341_io_init();
|
|
/* ILI9341_reset(); */
|
|
|
|
printf("LCD_ILI9341 config...\n");
|
|
ILI9341_reg_cfg();
|
|
ILI9341_set_direction(ROTATE_DEGREE_0);
|
|
init_TE(ILI9341_Fill);
|
|
lcd_bl_pinstate(lcd_bk_on);
|
|
/* ILI9341_test(); */
|
|
printf("LCD_ILI9341 config succes\n");
|
|
return 0;
|
|
}
|
|
|
|
// *INDENT-OFF*
|
|
REGISTER_LCD_DEV(LCD_ILI9341) = {
|
|
.name = "ili9341",
|
|
.lcd_width = LCD_W,
|
|
.lcd_height = LCD_H,
|
|
.color_format = LCD_COLOR_RGB565,
|
|
.column_addr_align = 1,
|
|
.row_addr_align = 1,
|
|
.LCD_Init = ILI9341_init,
|
|
.SetDrawArea = ILI9341_SetRange,
|
|
.LCD_Draw = ILI9341_draw,
|
|
.LCD_Draw_1 = ILI9341_draw_1,
|
|
.LCD_Draw_2 = ILI9341_draw_2,
|
|
.LCD_DrawToDev = ILI9341_Fill,//应用层直接到设备接口层,需要做好缓冲区共用互斥,慎用!
|
|
.LCD_Lvgl_Full = ILI9341_lvgl_Fill,//LVGL发送数据接口
|
|
.LCD_ClearScreen = ILI9341_clear_screen,
|
|
.Reset = ILI9341_reset,
|
|
.BackLightCtrl = ILI9341_led_ctrl,
|
|
};
|
|
// *INDENT-ON*
|
|
|
|
#endif
|
|
|