日期:2015.09.30

一、总篇说明

    本篇主要分为三个方面去讲:
        1,总结以往所遇到的问题点,并且深入去分析和解决这些问题点。
        2,LCD驱动层的基本要点和相关知识。
        3,更深层次的追问。
二、开始
    1,问题1:LCD画面一直在跳屏
       答:一般LCD驱动调试过程中经常会遇到跳屏、闪屏的现像,这个和像素时钟速率有关,如果用的是Video模式的话还会与垂直同步、水平同步等6个参数的大小设置有关系。要知道像素时钟速率在CMD和VDO这两种模式下各自的算法,再在这个算法的基础上作细分的高度。
       尤其是水平同步等6个参数的大小设置,这个一般在LCD屏的规格书上能找到它们的典型值。 在做完以上的这些工作之后,如果问题还是没有得到解决,那么就要去看看它的init部分的代码,是否已正确无误。还有就是要看看是否和所用的是CMD或VDO模式有关,如果LCD屏的模组本身并没有带ROM的话,那么它就用不了CMD模式,只能用VDO模式。
    2,问题2:LCD开机第一帧画面花屏/闪屏
        答:出现这种问题是很正常的,原因是在刚开机的时候,LCD背光已经先点亮了,而后LCD的数据才开始打上来。自然,我们会看到那一瞬间的花屏。要解决这一问题也很简单,就是让背光晚一点再点亮即可,用delay_ms()的办法就好。具体方法如下:
        1,在 mediatek/kernel/drivers/leds/leds_drv.c 文件中,找到 static void mt65xx_leds_shutdown(struct platform_device *pdev){……}
        在这函数下有个 case MT65XX_LED_MODE_GPIO: 在这下加个 mdelay(300);
        2,在 mediatek/platform/common/kernel/drivers/video/mtkfb.c    --------> mtkfb_ioctl(){} -------->case MTKFB_POWERON:
        ---------> 在 mt65xx_leds_brightness_set(MT65XX_LED_TYPE_LCD,127);之前加  mdelay(300);
        3,在 mediatek/platform/mt6572/kernel/drivers/leds/leds.c   -------->mt_mt65xx_led_set_cust(){} -------->case MT65XX_LED_MODE_GPIO:
        --------> 在 if(strcmp(cust->name,"lcd-backlight") == 0)里的 return brightness_set_gpio_bl(cust->data, level);之前加 mdelay(300);
        4,在 mediatek/platform/mt6572/lk/mt_leds.c  --------> mt65xx_led_set_cust(){}  --------> case MT65XX_LED_MODE_GPIO:
-------> 添加 mdelay(300);//chenjun add
-------> return brightness_set_gpio(cust->data, level);
        至于开机闪屏,这个在mt6572平台上有一个补丁是专门修复这个问题的,打上这个path就OK了。(遗憾的是我当时没有去看看它这个path内部所实现的原理~)
    3,问题3:如何做多款不同IC的屏兼容
        答:在做MTK平台上的项目开发中,我们常常会在同一项目中用到多款LCD屏,这时候我们就需要用到兼容多款LCD屏的知识了。
        如果单单只在软件上做多款LCD屏的兼容的话,以读取LCD屏的ID作区分的办法就足够了。那么具体的操作是该如何做的呢?
            例:以做信利屏(IC是Hx8357-d)和盛世创业屏(IC是ili9488)的兼容为例子作说明。
            1,在 mediatek/config/gioneely72_cwet_kk(project name)/ProjectConfig.mk  的三个和LCD屏相关的三个地方,写上你所要兼容的LCD屏的驱动名字,并以空格格开。
                CUSTOM_LK_LCM = hx8357d_hvga_dsi_cmd_truly_mt6572 ili9488_dsi_cmd_6572_hvga
                CUSTOM_KERNEL_LCM = hx8357d_hvga_dsi_cmd_truly_mt6572 ili9488_dsi_cmd_6572_hvga
                CUSTOM_UBOOT_LCM = hx8357d_hvga_dsi_cmd_truly_mt6572 ili9488_dsi_cmd_6572_hvga
            2,首先,从信利屏的规格书或FAE得到读取ID的方法,最后会从D0h这个寄存器中读出的ID值为 0x99。
                viod Read_Id()

{

/**必須加入**/

LCDSPI_InitCMD(0xB9);

LCDSPI_InitDAT(0xFF);

LCDSPI_InitDAT(0x83);

LCDSPI_InitDAT(0x57);

/**開始讀**/

LCDSPI_InitCMD(0xFE);

LCDSPI_InitDAT(0xD0);// GETICID: IC ID Read Command Data (D0h)

LCDSPI_InitCMD(0xFF);

//LCDSPI_ReadDAT(); //Dummy

LCDSPI_ReadDAT(); //0x99 作為ID使用

}  但这个和我们MTK平台是不一样的,需要我们用MTK平台的方式去实现。

                在 hx8357d_hvga_dsi_cmd_truly_mt6572.c 这个驱动文件上做以下工作:
                LCM_DRIVER hx8357d_hvga_dsi_cmd_truly_mt6572_drv = 
                {
.......
.compare_id    = lcm_compare_id,//添加
};
然后去实现 lcm_compare_id 这个函数:
#define HX8357D_ID 0x99
                static unsigned int lcm_compare_id(void)
{
unsigned int id = 0, id2 = 0;
unsigned char buffer[2];
unsigned int data_array[16];
SET_RESET_PIN(1);
MDELAY(10);
SET_RESET_PIN(0);
MDELAY(10);
SET_RESET_PIN(1);
MDELAY(15);
//*************Enable CMD2 Page1  *******************//
data_array[0]=0x00043902;
data_array[1]=0x5783FFb9;
dsi_set_cmdq(data_array,2, 1);
#if 0
data_array[0]=0x00023902;
data_array[1]=0x0000D0FE;
dsi_set_cmdq(data_array,2, 1);
data_array[0]=0x00013902;
data_array[1]=0x000000FF;
dsi_set_cmdq(data_array,2, 1);
#endif
data_array[0]=0x00023700;//set return byte number
dsi_set_cmdq(data_array,1, 1);
//----------------------------
read_reg_v2(0xD0, buffer, 2);
id = buffer[0]; //we only need ID
id2= buffer[1]; //we test buffer 1
//----------------------------
HX8357_ID = id;
HX8357_ID = id2;//
#if defined(BUILD_LK)
printf("%s, %d\n", __func__, HX8357_ID);
#elif defined(BUILD_UBOOT)
printf("%s, %d\n", __func__, HX8357_ID);
#else
printk("======================lcd_truly_v2_id1 = %d======================\n", id);
printk("======================lcd_truly_v2_id2 = %d======================\n", id2);
#endif
return (HX8357D_ID == id)?1:0;
}
                
                3,从盛世创业的FAE中得知,要读屏的ID号很简单,连读4次D3h 这个寄存器时就会返回一个0x88的ID值。
                在  ili9488_dsi_cmd_6572_hvga.c 文件上作以下的操作:
                
                #define GTLCDID 0x88
                LCM_DRIVER hx8357d_hvga_dsi_cmd_truly_mt6572_drv = 
                {
.......
.compare_id    = lcm_compare_id,//添加
};
然后去实现 lcm_compare_id 这个函数:
                static unsigned int lcm_compare_id(void)
{
int i;
unsigned int id = 0, id2 = 0;
unsigned char buffer[4];
unsigned int data_array[16];
SET_RESET_PIN(1);  //NOTE:should reset LCM firstly
MDELAY(10);
SET_RESET_PIN(0);
MDELAY(10);
SET_RESET_PIN(1);
MDELAY(15);
data_array[0] = 0x00023700;
dsi_set_cmdq(data_array, 1, 1);
//*************Enable CMD2 Page1  *******************//
for(i=0;i<4;i++) {
read_reg_v2(0xD3, buffer, 2);
}
id = buffer[0]; //we only need ID
id2= buffer[1]; //we test buffer 1
GTLCD_ID = id;
GTLCD_ID2 = id2;
#if defined(BUILD_LK)
printf("======================lcd_gtlcd_id1: = %d=====================\n", GTLCD_ID);
#elif defined(BUILD_UBOOT)
printf("======================lcd_gtlcd_id1: = %d=====================\n", GTLCD_ID);
#else
printk("================lcd_gtlcd_id1: %s, %x================\n", __func__, GTLCD_ID);
printk("================lcd_gtlcd_id2: %s, %x================\n", __func__, GTLCD_ID2);
#endif
return (GTLCDID == id)?1:0;
}
提问:那么,是先读那一个屏的ID先呢?
答: 其实是按它们在 mt65xx_lcm_list.c 里边的位置排序来加载的。
        4, 问题4:如何做多款相同IC的屏兼容 ?
           
可能的方法如下:
        1, 可以在FPC中预留几个PIN,将GPIO与这些PIN相连。 不同的LCD给PIN分配不同的高低电平组合。以此识别。

        2, 可以在FPC中预留一个PIN, 将ADC与此PIN相连。 通过读取此PIN上的电压值不同来识别。总之,就是要想办法去正确的加载上它们相应的初始化。

《LCD总结篇(中级)》相关推荐

  1. ComeFuture英伽学院——2020年 全国大学生英语竞赛【C类初赛真题解析】(持续更新)

    视频:ComeFuture英伽学院--2019年 全国大学生英语竞赛[C类初赛真题解析]大小作文--详细解析 课件:[课件]2019年大学生英语竞赛C类初赛.pdf 视频:2020年全国大学生英语竞赛 ...

  2. ComeFuture英伽学院——2019年 全国大学生英语竞赛【C类初赛真题解析】大小作文——详细解析

    视频:ComeFuture英伽学院--2019年 全国大学生英语竞赛[C类初赛真题解析]大小作文--详细解析 课件:[课件]2019年大学生英语竞赛C类初赛.pdf 视频:2020年全国大学生英语竞赛 ...

  3. 信息学奥赛真题解析(玩具谜题)

    玩具谜题(2016年信息学奥赛提高组真题) 题目描述 小南有一套可爱的玩具小人, 它们各有不同的职业.有一天, 这些玩具小人把小南的眼镜藏了起来.小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的 ...

  4. 信息学奥赛之初赛 第1轮 讲解(01-08课)

    信息学奥赛之初赛讲解 01 计算机概述 系统基本结构 信息学奥赛之初赛讲解 01 计算机概述 系统基本结构_哔哩哔哩_bilibili 信息学奥赛之初赛讲解 02 软件系统 计算机语言 进制转换 信息 ...

  5. 信息学奥赛一本通习题答案(五)

    最近在给小学生做C++的入门培训,用的教程是信息学奥赛一本通,刷题网址 http://ybt.ssoier.cn:8088/index.php 现将部分习题的答案放在博客上,希望能给其他有需要的人带来 ...

  6. 信息学奥赛一本通习题答案(三)

    最近在给小学生做C++的入门培训,用的教程是信息学奥赛一本通,刷题网址 http://ybt.ssoier.cn:8088/index.php 现将部分习题的答案放在博客上,希望能给其他有需要的人带来 ...

  7. 信息学奥赛一本通 提高篇 第六部分 数学基础 相关的真题

    第1章   快速幂 1875:[13NOIP提高组]转圈游戏 信息学奥赛一本通(C++版)在线评测系统 第2 章  素数 第 3 章  约数 第 4 章  同余问题 第 5 章  矩阵乘法 第 6 章 ...

  8. 信息学奥赛一本通题目代码(非题库)

    为了完善自己学c++,很多人都去读相关文献,就比如<信息学奥赛一本通>,可又对题目无从下手,从今天开始,我将把书上的题目一 一的解析下来,可以做参考,如果有错,可以告诉我,将在下次解析里重 ...

  9. 信息学奥赛一本通(C++版) 刷题 记录

    总目录详见:https://blog.csdn.net/mrcrack/article/details/86501716 信息学奥赛一本通(C++版) 刷题 记录 http://ybt.ssoier. ...

  10. 最近公共祖先三种算法详解 + 模板题 建议新手收藏 例题: 信息学奥赛一本通 祖孙询问 距离

    首先什么是最近公共祖先?? 如图:红色节点的祖先为红色的1, 2, 3. 绿色节点的祖先为绿色的1, 2, 3, 4. 他们的最近公共祖先即他们最先相交的地方,如在上图中黄色的点就是他们的最近公共祖先 ...

最新文章

  1. 程序员被知乎优化!瞄准bat大厂再次求职!结果让人意外!
  2. 关于大型网站技术演进的思考(一)--存储的瓶颈(上)
  3. 中国python之父是谁-Python之父:谈Python
  4. Create React App使用
  5. ansible自动化部署(一)
  6. 华为8x计算机横屏怎么设置,荣耀8x怎么设置横屏显示 两种操作方法详细介绍
  7. 微信小程序知识点GET
  8. CUBRID学习笔记 22 插入数据
  9. JS判断正则表达式验证规则
  10. Dynamics CRM2016 新功能之Solution enhancements
  11. mysql性能优化的最佳20条经验_MySQL性能优化的最佳20+条经验
  12. mysql创建多个联合索引吗_高性能索引油画策略(二):多个索引是独立建立索引还是建联合索引?...
  13. eviews建立时间序列模型_模型建立——时间序列 eviews协整检验(EG两步法(Engle-Granger))...
  14. Servlet容器和Tomcat容器区别
  15. U盘文件夹变成.exe文件的解决方法
  16. 使用backdrop-filter部分场景的替代效果
  17. 2D/3D视图变换、canvas画布
  18. 【数据结构】图邻接矩阵的创建完整代码
  19. overflow(溢出)属性的5个值
  20. Python破解百度翻译反爬机制---自制翻译器

热门文章

  1. 【综述 寿命预测】基于机器学习的设备剩余寿命预测方法综述
  2. js IP地址正则校验
  3. python生成关键词
  4. setHeader的参数种类
  5. linux常用命令 cp命令的使用和介绍
  6. 实时获取当前的时区和时间的方法
  7. 对持续集成、 持续交付、持续部署和持续发布的介绍
  8. 时间、延迟及延缓操作
  9. 解放前端工程师——手把手教你开发自己的自定义列表和自定义表单系列之二接口
  10. 极限论总极难学真因:人有抵制思想混乱学说本能