MTK怎样移植LCD 驱动
时间:10-02
整理:3721RD
点击:
以我在公司项目移植ILI9327DS为例:
移植时,我拿到的文档包括厂商提供的代码仅提供Init代码和一个datasheet文档。mtk写代码时最重要的一点就是进行宏控制。
1.定义宏 LCD_ILI9327DS_ACTIVE
定义位置可以lcd.c ,lcd_sw.h或者按照定义模块。在在客户定制里边定义(在这个位置定义需要new)
#define LCD_ILI9327DS_ACTIVE
客户定制:
COMTOM_OPTION += LCD_ILI9327DS_ACTIVE
2。在lcd.c加入ILI9327DS的相关函数
重点是Init ,这个部分参考厂商代码。
3。 查看datasheet里边会有进入或者退出休眠模式的说明。
Enter_sleep_mode(10h) Exit_sleep_mode (11h)
函数书写void LCD_Enter_Sleep_ILI9327DS(void)
{
说明:关于LCD_CtrlWrite_ILI9327DS的书写需要知道,总线的工作方式和液晶的工作方式这里都是采用了8位传输。
#define LCD_CtrlWtire_ILI9327DS(_data){\
SET_LCD_CMD_PARAMETER(0,LCD_CMD,(_data & 0xFF));\
LCD_SEND_DMA_CMD(1);\
}
void LCD_Exit_Sleep_ILI9327DS(void)
{
4.块写函数BlockWrite书写。
往屏输出数据的函数。我们在LCM上看到的各种缤纷图像,都是通过这个函数来实现的。在这个函数里面我们要设置LCD屏幕显示的一些位置参数,并把它写道相应的寄存器里面。
看datasheet时,提供两个命令2ah和2bh,分为是Set_column_address和Set_page_address.他们分别有四个参数。
上图解释(startx&0x100)>>8;
void LCD_Block_Write_ILI9327DS(kal_uint16 startx,kal_uint16 starty,kal_uint16 endx,kal_uint16 endy)
{
while (LCD_IS_RUNNING);//LCD_ISRUNING由lcd状态寄存器和 lcd运行状态位决定
{
unsigned int i,j,tmp1,tmp2;
if(endx> ( LCD_WIDTH -1 ) )
endx= (LCD_WIDTH -1);
if(endy > ( LCD_HEIGHT - 1 ))
endy = ( LCD_HEIGHT - 1 );
SET_LCD_CMD_PARAMETER(0,LCD_CMD,0x2A);
SET_LCD_CMD_PARAMETER(1,LCD_DATA,((startx&0x100)>>8));
SET_LCD_CMD_PARAMETER(2,LCD_DATA,(startx&0x0FF));
SET_LCD_CMD_PARAMETER(3,LCD_DATA,((endx&0x100)>>8));
SET_LCD_CMD_PARAMETER(4,LCD_DATA,(endx&0x0FF));
SET_LCD_CMD_PARAMETER(5,LCD_CMD,0x2B);
SET_LCD_CMD_PARAMETER(6,LCD_DATA,((starty&0x100)>>8));
SET_LCD_CMD_PARAMETER(7,LCD_DATA,(starty&0x0FF));
SET_LCD_CMD_PARAMETER(8,LCD_DATA,((endy&0x100)>>8));
SET_LCD_CMD_PARAMETER(9,LCD_DATA,(endy&0x0FF));
//Write_memory_start;
SET_LCD_CMD_PARAMETER(10,LCD_CMD,0x2c);
SET_LCD_ROI_CTRL_NUMBER_OF_CMD(11);
}
ENABLE_LCD_TRANSFER_COMPLETE_INT;
ENABLE_LCD_ROI_CTRL_CMD_FIRST;
while (LCD_IS_RUNNING) {};
START_LCD_TRANSFER;
}
//
LCD_Funcs LCD_func_ILI9327DS = {
LCD_Init_ILI9327DS,
LCD_PWRON_ILI9327DS,
LCD_SetContrast_ILI9327DS,
LCD_ON_ILI9327DS,
LCD_BlockWrite_ILI9327DS,
LCD_Size_ILI9327DS,
LCD_EnterSleep_ILI9327DS,
LCD_ExitSleep_ILI9327DS,
LCD_Partial_On_ILI9327DS,
LCD_Partial_Off_ILI9327DS,
LCD_Partial_line_ILI9327DS,
/*Engineering mode*/
LCD_GetPARM_ILI9327DS,
LCD_SetBias_ILI9327DS,
LCD_Contrast_ILI9327DS,
LCD_LineRate_ILI9327DS,
LCD_Temp_Compensate_ILI9327DS
#ifdef LCM_ROTATE_SUPPORT
,LCD_Set_Scan_Direction_ILI9327DS
#endif
#ifdef LQT_SUPPORT/*Do not remove LQT code segment*/
,LCD_gamma_test
,LCD_flicker_test
#endif
,0 // NULL function for SetFrmMarker Function.
,LCD_IOCTRL_ILI9327DS
};
上述是ILI9327DS需要的成员函数,里边多数为不做操作的。
5。搞定后就是Lcd _id了。datasheet给我们的命令式EFh,它有六个属性第四位和第五位是lcd_id为0x9327;
有两种方法一种直接送值,另外一种是自适应的方法。编写方法读取reg.
void read_lcd_device_code(void)
{
///自适应
void read_lcd_device_code(void)
{
new之后慢慢调试出现的错误。
2010-7-27
结束//
来南京第四周了,各方面依然过得还行。和我一块住的丽姐和魏大哥,操飞以及他老婆都是非常好相处的人。每天丽姐都为我们住的屋子打扫一下啊,使得我们住的非常舒心。
移植时,我拿到的文档包括厂商提供的代码仅提供Init代码和一个datasheet文档。mtk写代码时最重要的一点就是进行宏控制。
1.定义宏 LCD_ILI9327DS_ACTIVE
定义位置可以lcd.c ,lcd_sw.h或者按照定义模块。在在客户定制里边定义(在这个位置定义需要new)
#define LCD_ILI9327DS_ACTIVE
客户定制:
COMTOM_OPTION += LCD_ILI9327DS_ACTIVE
2。在lcd.c加入ILI9327DS的相关函数
重点是Init ,这个部分参考厂商代码。
3。 查看datasheet里边会有进入或者退出休眠模式的说明。
Enter_sleep_mode(10h) Exit_sleep_mode (11h)
函数书写void LCD_Enter_Sleep_ILI9327DS(void)
{
LCD_CtrlWrite_ILI9327DS(0x10);//这个函数在lcd_sw.h中定义}
说明:关于LCD_CtrlWrite_ILI9327DS的书写需要知道,总线的工作方式和液晶的工作方式这里都是采用了8位传输。
#define LCD_CtrlWtire_ILI9327DS(_data){\
SET_LCD_CMD_PARAMETER(0,LCD_CMD,(_data & 0xFF));\
LCD_SEND_DMA_CMD(1);\
}
void LCD_Exit_Sleep_ILI9327DS(void)
{
//可以采用两用方法一种是采用datasheet 中的退出命令另一种就是重新初始化一遍}
//1
LCD_CtrlWtire_ILI9327DS(0x11);
// LCD_Init_ILI9327DS(0,0);
4.块写函数BlockWrite书写。
往屏输出数据的函数。我们在LCM上看到的各种缤纷图像,都是通过这个函数来实现的。在这个函数里面我们要设置LCD屏幕显示的一些位置参数,并把它写道相应的寄存器里面。
看datasheet时,提供两个命令2ah和2bh,分为是Set_column_address和Set_page_address.他们分别有四个参数。
上图解释(startx&0x100)>>8;
void LCD_Block_Write_ILI9327DS(kal_uint16 startx,kal_uint16 starty,kal_uint16 endx,kal_uint16 endy)
{
while (LCD_IS_RUNNING);//LCD_ISRUNING由lcd状态寄存器和 lcd运行状态位决定
{
unsigned int i,j,tmp1,tmp2;
if(endx> ( LCD_WIDTH -1 ) )
endx= (LCD_WIDTH -1);
if(endy > ( LCD_HEIGHT - 1 ))
endy = ( LCD_HEIGHT - 1 );
SET_LCD_CMD_PARAMETER(0,LCD_CMD,0x2A);
SET_LCD_CMD_PARAMETER(1,LCD_DATA,((startx&0x100)>>8));
SET_LCD_CMD_PARAMETER(2,LCD_DATA,(startx&0x0FF));
SET_LCD_CMD_PARAMETER(3,LCD_DATA,((endx&0x100)>>8));
SET_LCD_CMD_PARAMETER(4,LCD_DATA,(endx&0x0FF));
SET_LCD_CMD_PARAMETER(5,LCD_CMD,0x2B);
SET_LCD_CMD_PARAMETER(6,LCD_DATA,((starty&0x100)>>8));
SET_LCD_CMD_PARAMETER(7,LCD_DATA,(starty&0x0FF));
SET_LCD_CMD_PARAMETER(8,LCD_DATA,((endy&0x100)>>8));
SET_LCD_CMD_PARAMETER(9,LCD_DATA,(endy&0x0FF));
//Write_memory_start;
SET_LCD_CMD_PARAMETER(10,LCD_CMD,0x2c);
SET_LCD_ROI_CTRL_NUMBER_OF_CMD(11);
}
ENABLE_LCD_TRANSFER_COMPLETE_INT;
ENABLE_LCD_ROI_CTRL_CMD_FIRST;
while (LCD_IS_RUNNING) {};
START_LCD_TRANSFER;
}
//
LCD_Funcs LCD_func_ILI9327DS = {
LCD_Init_ILI9327DS,
LCD_PWRON_ILI9327DS,
LCD_SetContrast_ILI9327DS,
LCD_ON_ILI9327DS,
LCD_BlockWrite_ILI9327DS,
LCD_Size_ILI9327DS,
LCD_EnterSleep_ILI9327DS,
LCD_ExitSleep_ILI9327DS,
LCD_Partial_On_ILI9327DS,
LCD_Partial_Off_ILI9327DS,
LCD_Partial_line_ILI9327DS,
/*Engineering mode*/
LCD_GetPARM_ILI9327DS,
LCD_SetBias_ILI9327DS,
LCD_Contrast_ILI9327DS,
LCD_LineRate_ILI9327DS,
LCD_Temp_Compensate_ILI9327DS
#ifdef LCM_ROTATE_SUPPORT
,LCD_Set_Scan_Direction_ILI9327DS
#endif
#ifdef LQT_SUPPORT/*Do not remove LQT code segment*/
,LCD_gamma_test
,LCD_flicker_test
#endif
,0 // NULL function for SetFrmMarker Function.
,LCD_IOCTRL_ILI9327DS
};
上述是ILI9327DS需要的成员函数,里边多数为不做操作的。
5。搞定后就是Lcd _id了。datasheet给我们的命令式EFh,它有六个属性第四位和第五位是lcd_id为0x9327;
有两种方法一种直接送值,另外一种是自适应的方法。编写方法读取reg.
void read_lcd_device_code(void)
{
unsigned short value=0;
#ifdef LCD_ILI9327DS_ACTIVE}
value =0x9325;
#endif
switch(value)
{
#ifdef LCD_ILI9327DS_ACTIVE
case 0x9327:
MainLCD =& LCD_func_ILI9327DS;
break;
#endif
}
///自适应
void read_lcd_device_code(void)
{
unsigned value=0,value1=0;
#ifdef LCD_ILI9327DS_ACTIVE}
LCD_CtrlWrite_ILI9327DS(0xef);//读取lcd ID/
value1 = (*(volatile kal_uint8 *)MAIN_LCD_DATA_ADDR);
value1 = (*(volatile kal_uint8 *)MAIN_LCD_DATA_ADDR);
value1 = (*(volatile kal_uint8 *)MAIN_LCD_DATA_ADDR);
value = (*(volatile kal_uint8 *)MAIN_LCD_DATA_ADDR) <<8;
value |= (*(volatile kal_uint8 *)MAIN_LCD_DATA_ADDR);
value1 = (*(volatile kal_uint8 *)MAIN_LCD_DATA_ADDR);
#endif
switch(value)
{
#ifdef LCD_ILI9327DS_ACTIVE
case 0x9327:
MainLCD =& LCD_func_ILI9327DS;
break;
#endif
}
new之后慢慢调试出现的错误。
2010-7-27
结束//
来南京第四周了,各方面依然过得还行。和我一块住的丽姐和魏大哥,操飞以及他老婆都是非常好相处的人。每天丽姐都为我们住的屋子打扫一下啊,使得我们住的非常舒心。