上次说到,小企鹅终于可以显示了,但是现在这个世道,现在这个中国,山寨横行,没有最便宜的,只有更便宜的,今天用ILI9320的人,或许就是昨天用S6D0110,或许还是明天用和谐8347的人,不好意思是HX8347,这个可恶的输入法。因此,俺们的驱动就不能只支持ILI9320,不然客户就用别人的芯片去了。当然,客户也可以直接改cbp-fb.c或者cbp-fb.h, 可是客户是很忙的,说不定今天晚上还要去兜风呢!而且客户也不想知道,我们ASIC老大们也不想让他知道俺们的DMA和其他模块是怎么玩的,所以把故意把文档写的那么晦涩,连我们这些本公司开发人员都看不懂。客户可能改了还可能会出新的bug,还得麻烦俺们。
因此对于LCD,就定义一个结构来描述它算了,为了不要太复杂,就定义了这些参数:
typedef struct LCD_INFO
{
int16 BankNo; /*Physical LCD/IF Bank Number*/
int16 FreezeStatus; /*Lcd Freeze State*/
void (*FreezeCallback)(void *pInfo); /*Callback function when lcd in freezed state*/
int LcdOnState; /*Lcd is on or sleep*/
SemaphoreT *SemaphoreCbP; /*Lcd Device Seamphore*/
SemaphoreT *FrameBufferSemaphoreCbP; /*Lcd Device Seamphore*/
LcdBankAddressT Address; /*Bank Cmd and Data Address*/
LcdDMAControlT DMAControl; /*DMA Information*/
struct LCD_CONTROLLER
{
LcdBankParamT BankParam; /*Bank Timing*/
HwdLcdInfoT LcdInfo; /*Lcd information about vendor,size,framebuffer,etc*/
void (*InitDev)(struct LCD_INFO *Info);
void (*SetWindow)(struct LCD_INFO *pInfo,uint16 x, uint16 y, uint16 dx, uint16 dy);
oid (*UpdateRect)(struct LCD_INFO *pInfo,uint8* Bmp, uint16 x, uint16 y, uint16 dx, uint16 dy);
oid (*UpdateAll)(struct LCD_INFO *pInfo,uint8* Bmp, uint16 x, uint16 y, uint16 dx, uint16 dy);
oid (*SetContrast)(struct LCD_INFO *pInfo,uint8 Leve);
oid (*LcdOn)(struct LCD_INFO *pInfo,bool OpCode);
}*pController;
}LcdInfoT;
其实看起来还是挺复杂的,其中的LCD_CONTROLLER定义是相对于具体的LCD控制器的,其实就算有了S3C2410那样的带控制器的CPU,也是可以用这个结构的。LCD_CONTROLLER的 HwdLcdInfoT LcdInfo里面则主要定义了一些和LCD的参数有关的东东,比如分辨率,颜色深度之类的玩意儿。LCD_CONTROLLER还定义了几个操作,就是UpdateRect之类的东东。
剩下的其他成员主要定义了一些防止竞态访问的Semaphore,各种状态控制,还有一个就是关于我们的DMA的参数。
这样对于客户就简单了,就算他今天晚上除了去兜风还要泡吧也没关系了,因为他只需要负责其中的LCD_CONTROLLER结构就OK了,比如如下的ILI9320定义:
LcdControllerInfoT gILI9320_16BitBus_16BPP=
{
{
LCDIF_READ_WAIT(0x1)|LCDIF_READ_HIGH(1),/*Read Timing*/
LCDIF_WRITE_WAIT(0x2)|LCDIF_WRITE_HIGH(2),/*Write Timing*/
LCDIF_MODE_CONVMODE(LCD_CONV_NONE)|LCDIF_MODE_DATAWIDTH(LCD_BUS_WIDTH_16Bit)
},
{
"ILI", /*Vendor*/
"9320", /*Model*/
240, /*Width*/
320, /*Height*/
FB_16BPP, /*Frame buffer BPP*/
NULL /*Frame buffer Address*/
},
/*****Operations********/
ILI9320Init, /*InitDev*/
ILI9320WindowSet, /*Set Window address*/
ILI9320UpdateRect, /*UpdateRect*/
ILI9320UpdateAll, /*UpdateAll*/
ILI9320SetContrast, /*Set Contrast*/
ILI9320LcdOn /*LCD on/off*/
};
Operations以前的东西看起来很长,其实第一对大括号就是配置一下LCD Bridge应该以什么样的时序与LCD Controller接口,其中的第三行表示是颜色变换和外部总线宽度等等。
第二个大括号就更简单了,有厂商名字,控制器型号,宽度,长宽和颜色深度,FrameBuffer地址是个Legacy,现在由驱动程序申请,因此在这里就是NULL了,当然也可以设上,不过设了也是白设!
剩下就是Operations了,看名字就知道是干啥的,这个东西在俺们的平台上都是有用的,比如Update Rect之类的东东,但是在Linux Frame Buffer上就没用了,因为Frame Buffer驱动都是在内存中操作,有CFB支持,这些设置硬件的操作就不需要了。而且Update在Linux里面都是定时刷新的,也不需要专门的Update函数了。
因此俺的客户就只需要实现 ILI9320Init,ILI9320SetContrast,ILI9320LcdOn,如果不需要调亮度和关闭LCD的话,他就只剩下ILI9320Init一个函数需要写了,听起来好像还是有点麻烦,其实每个LCM厂商都会给初始化参数的,如下:
Cmd(0x1234);
Data(0x4321);
这样的东东。
你只要按部就班的填完就OK了。请问该去兜风了吗,我的劳力士呢?原来在水里,离兜风时间还有三个小时呢!
阅读(1663) | 评论(0) | 转发(0) |