调试OTM4001A液晶驱动的一点心得 .

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

这几天调试一块以OTM4001A作驱动芯片的LCM模组,调试完毕后,终于有结果OK了。之前对这块一直用的不太透彻,恰好趁这次摸清楚了。需要注意的几点记录如下:

(1)关于信号类型的片选。在很多LCD芯片规格书上都有关于信号片选的描述,如

M2/M1/M0,典型如下:

如上图,上面的三个M接口脚是有连接线直接连到主板接口上的,至于是高还是低,可以由主板硬件限定死,另一方面也可以由LCM模组自身做工来限制。具体到我的工作内容上,主板上IM0是不接的,IM2接地,基本上就由IM1来决定是16位是18位,用一个电阻来控制。目前我是用的18位接口,多属于DBI B类型。

关于DBI接口,18位数据线连接和16位连接线要作下说明,针对16位寄存器(8位寄存器不存在这个问题)。

A,18位

可以看出:18位的数据线传输16位的寄存器参数和命令时,DB0和DB9是跳过去的。这就决定了在写寄存器控制命令时要注意移位(假设32位系统上,怎么样将16位寄存器数

据分离,然后放到18位数据线上发送出去),这个在后面会有程序说明。18位的数据传输就是RGB666了,此处不作说明。

B,16位

可以看出:16位的数据线,硬件上是直接对应上的,所以写控制命令和参数时,不存在上述移位的问题。16位的数据就是RGB565,这个也不做说明。

从上可以看出,不管是16位还是18位,传输命令的总是那几根线。在硬件接线上注意具体要求。

(2)关于写寄存器的说明。

主芯片自带的读写语句分别是:写寄存器地址SendCtrlComnd(),写寄存器参数SendDataComnd()。两者的形参后来我验证了,应该是32位。硬件采用18位,传输18位数据。那么需要对数据线对应的位进行适当的处理,以在写寄存器命令时跳过DB0和DB9:

#define

SendCtrlComndWrapped(value) SendCtrlComnd(((value<<1)&0x1fe)|(((value<<2)& 0x3fc00)))

#define

SendDataComndWrapped(value) SendDataComnd(((value<<1)&0x1fe)|(((value<<2) &0x3fc00)))

说明:((value<<1)&0x1fe)保证跳过DB0后传输采用的DB8到DB1,恰好在位置上对应。((value<<2)&0x3fc00)保证跳过DB0跟DB9两个位,取得DB17到DB10的数据,从这里可以看出,该寄存器参数类型是32位的,否则无法跟0x3fc00相与。

另外,跳过DB0和DB9还有另一种写法:

#define SendCtrlComndWrapped(value) SendCtrlComnd(((value&0xFF00)<<2) | ((value&0x00FF)<<1) )

#define SendDataComndWrapped(value) SendDataComnd(((value&0xFF00)<<2) | ((value&0x00FF)<<1) )

另补充:以上写控制命令和命令参数都是16位的,所以在18位数据线和16位数据线上要考虑时序。如果控制命令和参数都是8位的,则不需考虑这个过程,也即直接用:

#define SendCtrlComndWrapped(value) SendCtrlComnd(value&0xff)

#define SendDataComndWrapped(value) SendDataComnd(value&0xff)

(3)关于配新屏的过程。

大部分的LCM模组只需要处理好四个函数就可以了。初始化,进入睡眠,唤醒睡眠,写GRAM。都是通过一系列寄存器语句来实现的,比如对于OTM4001A,典型的语句是:

SendCtrlComndWrapped(0x0200);SendDataComndWrapped(0x0000);

其它典型的要补充的是:初始化时要在写GRAM前设置RAM ADDR参数、起始终结的水平垂直位置、Display ON、Write Start;唤醒和睡眠都是有特定的sleep寄存器来控制的,唤醒后可以再把初始化执行一次就可以了。

(4)关于RGB565向RGB666转化

写GRAM的本质就是向不同地址写入对应的点阵颜色的数据,而每个颜色点的格式可能有16位或者18位。如果是单点16位的点阵格式,采用在地址自加的同时,执行WriteHwDataAddrWrapped( color );如果是18位的格式,除了在配置时要改成18位和RGB666格式外,在循环写入颜色数据时需要一个转换:

UINT16 color; //16位颜色值存储单元

UINT32 rgb666; //18位颜色值存储单元

UINT32 panelX, panelY;

UINT16 x0, y0, x1, y1;

x0 = (UINT16)rc.left;

y0 = (UINT16)rc.top;

x1 = (UINT16)rc.right-1;

y1 = (UINT16)rc.bottom-1; //起始终结坐标

for (panelY = y0; panelY <= y1; panelY++)

{

for (panelX = x0; panelX <= x1; panelX++)

{

color = pFB[pixelIndex++];

rColor = ((color & 0xF800) >> 10);

gColor = ((color & 0x07E0) >> 5);

bColor = ((color & 0x001F) << 1);

rgb666 = ((rColor << 12) | (gColor << 6) | (bColor)); //RGB565转成RGB666

WriteHwDataAddrWrapped( rgb666 );

}

}

(5)关于图像倾斜。如果一个图像出现一个对角线,整体倾斜,那么可以考虑是多写了数据或是少些了数据。我的改动方法是一定要注意矩形窗口坐标是0到WIDTH-1,和0到HEIGHT-1。如果没有减去1,则会出现此问题。

(6)关于读芯片的ID号

很多芯片的ID都是0X0000寄存器的值,不需要发读出命令。所以只要在读数据前把寄存器的地址0X0000写进去,就可以读到正确的ID。6516提供的命令如下:

VOID LCDReadDataCommand(void )

{

UIN T32 data;

LCD_OUTREG32(PARALLEL[s_pLCDParams->m_ifIndex].CON TROL, 0x0000);//写索引地址0X0000 data = LCD_INREG32(PARALLEL[s_pLCDPar ams->m_ifIndex].DATA);

SHIPMSG(2,(L"Read lcd id is : 0x%x /r /n",data));

}

直接把该函数放到初始化开始就可以了。

实际调试R61509V的代码时,读得的ID号是0x2d412。而芯片规格书上的0XB509,不一致。后来想了一下,由于是18位的接口,对于命令来说,读和写都要跳过第零位和第九位。所以把0x2d412处理一下后就是0XB509。

(7)关于TE(tearing effect)现象

相关文档
最新文档