2012年4月26日 星期四
研究所委托的3.5寸LCD在mini6410上的点亮阶段性完成。
出现的问题有:
1、初始化问题,此款LCD非标准品,系统上电需要对LCD进行初始化方可点亮,初始化依旧是传统的SPI模式,使用的方式为在LCD驱动程序中加入SPI初始化程序,SPI初始化程序采用GPIO口模拟SPI总线的方式完成,程序模板来自于BMDT(覃qin玉)稍作了修改。
2、屏幕抖动问题,进入系统后出现图像不停的跳动,示波器观察后发现是因为HSYNC信号不规整(其实其他的时钟信号也不是很好比如VCLK、VSYNC,不知道什么原因),存在加大抖动造成的,用导电体接触后就稍显改善。通过在HSYNC端加PF级滤波电容,抖动现象消失,图像显示稳定。
3、目前是使用16bitRGB接口,显示正常、当设置为24bit时,图像异常,出现两个视窗,不知道是什么原因。
4、图像有上下错位问题,大概左边的1/6图像同右边的5/6图像有大概一两行的错位,目前原因不明。
现将3.5LCD驱动编写和添加过程记录如下,以备日后查阅
硬件平台:MINI6410、3.5LCD IC为LG4572.
软件平台:linux2.6.36+android2.3.4
驱动程序:s3cfb_forBOE3.5.c (母版为s3cfb.c)
第一步 修改/driver/video/samsung/下的Kconfig和makefile文件
在Kconfig文件的choice
depends on FB_S3C_EXT
prompt "Select LCD Type"
default FB_S3C_EXT_TFT480272下加入
config FB_S3C_BOE_TFT480800
boolean "BOE 3.5 inch 480x800 TFT LCD"
select TOUCHSCREEN_IF
help
BOE 3.5 inch 480x800 TFT LCD也就是添加3.5LCD在config中的配置选项。
在makefile文件中原先的s3cfb_forBOE3.5.o修改为obj-$(CONFIG_FB_S3C_EXT) += s3cfb_forBOE3.5.o (因为添加了初始化的程序,以及保持程序的独立性,所以没有和原先的s3cfb进行兼容设定)
第二步 修改s3c_mini6410.c文件的LCD配置选项
#elif defined(CONFIG_FB_S3C_BOE_TFT480800)//当在config菜单下选择了3.5的配置项,Autoconf.h (linux-2.6.36-android\include\generated) 下会自动产生CONFIG_FB_S3C_BOE_TFT480800=1
#define S3CFB_LCD_TYPE "BOE3.5"
#define S3CFB_VBP (5) /* back porch */
#define S3CFB_VFP (5) /* front porch */
#define S3CFB_VSW (2) /* vsync width */
#define S3CFB_HBP (10) /* back porch */
#define S3CFB_HFP (10) /* front porch */
#define S3CFB_HSW (1) /* hsync width */
#define S3CFB_HRES 480 /* horizon pixel x resolition */
#define S3CFB_VRES 800 /* line cnt y resolution */
#define S3CFB_CLKVAL 5 //VCLK=133MHZ/(S3CFB_CLKVAL+1)
#define S3CFB_VIDCON1 (S3C_VIDCON1_IHSYNC_INVERT | S3C_VIDCON1_IVSYNC_INVERT|S3C_VIDCON1_IVDEN_NORMAL)//HSYNC、VSYNC、VDEN极性设置,在6410中,NORMAL是指HSYNC、VSYNC低电平有效,VDEN高电平有效,对应LCD中的设置(在初始化中将这三个极性全部设定为高电平有效),需要将HSYNC、VSYNC极性反转,VDEN极性保持不变。
第三步 s3cfb_forBOE3.5.c文件的编写
将LCD驱动程序与LG4572初始化程序分开分析
首先分析初始化程序 比较经典的GPIO模拟简单串行总线的模板
#define CS_H writel(readl(S3C64XX_GPQDAT)|(1<<1), S3C64XX_GPQDAT) //宏定义各种命令,方便以后使用
#define CS_L writel(readl(S3C64XX_GPQDAT)&~(1<<1),S3C64XX_GPQDAT)
#define RST_H writel(readl(S3C64XX_GPEDAT)|(1<<4), S3C64XX_GPEDAT)
#define RST_L writel(readl(S3C64XX_GPEDAT)&~(1<<4),S3C64XX_GPEDAT)
#define SDI_H writel(readl(S3C64XX_GPQDAT)|(1<<6), S3C64XX_GPQDAT)
#define SDI_L writel(readl(S3C64XX_GPQDAT)&~(1<<6),S3C64XX_GPQDAT)
#define SCLK_H writel(readl(S3C64XX_GPEDAT)|(1<<1), S3C64XX_GPEDAT)
#define SCLK_L writel(readl(S3C64XX_GPEDAT)&~(1<<1),S3C64XX_GPEDAT)
static void comm_out(unsigned int comm)
{
unsigned int temp1,temp2,i,j,ID;
// RS_L;
ID=0x74;//这里根据IC spec对覃玉的代码进行了修改
CS_L;
//temp1=((comm<<10)|0x0a)&0xffff;
temp1=comm;
temp2=ID<<24|temp1<<16;
//SCLK_L;
//SDI_L;
//SCLK_H;
for(i=0;i<16;i++)
{
SCLK_L;
if(temp2 & (1<<(31-i)) )
SDI_H;
else
SDI_L;
SCLK_H;
}
CS_H;
}
static void data_out(unsigned int data)
{
unsigned int temp1,temp2,i,j,ID;
// RS_H;
ID=0x76;
CS_L;
temp1=data;
temp2=ID<<24|temp1<<16;
//SCLK_L;
//SDI_H;
//SCLK_H;
for(i=0;i<16;i++)
{
SCLK_L;
if(temp2 & (1<<(31-i)) )
SDI_H;
else
SDI_L;
SCLK_H;
}
CS_H;
}
void LG4572_Power_ON(void)
{
int old_gpecon;
int old_gpeup;
int old_gpqcon;
int old_gpqup;
old_gpecon=readl(S3C64XX_GPECON);
old_gpeup=readl(S3C64XX_GPEPUD);
old_gpqcon=readl(S3C64XX_GPQCON);
old_gpqup=readl(S3C64XX_GPQPUD);
writel(readl(S3C64XX_GPECON)&0xfff0ff0f,S3C64XX_GPECON);//将相应的GPIO口设置为输出模式。
writel(readl(S3C64XX_GPECON)|0x00010010,S3C64XX_GPECON);
writel(readl(S3C64XX_GPEPUD)&0xfffffcf3,S3C64XX_GPEPUD);
writel(readl(S3C64XX_GPEPUD)|0x00000208,S3C64XX_GPEPUD);
writel(readl(S3C64XX_GPQCON)&0xffff0ff0,S3C64XX_GPQCON);
writel(readl(S3C64XX_GPQCON)|0x00001004,S3C64XX_GPQCON);
writel(readl(S3C64XX_GPQPUD)&0xffff0ff0,S3C64XX_GPQPUD);
writel(readl(S3C64XX_GPQPUD)|0x00002008,S3C64XX_GPQPUD);
CS_H;
SDI_H;
SCLK_H;
CS_L;
/