主要原理: 2440内部集成了LCD控制器,写程序时,2440从内存中读取显存到控制器。
流程:
1. 根据LCD手册,设置LCD控制器。
2. 分配显存,把地址、颜色格式、大小告诉控制器。
开始写代码:
1.开头引入头文件,
2.写出出入口框架,并修饰之,再加协议。
3.
static int lcd_init(void)
{
1.分配一个fb_info结构体
2.设置
4.硬件相关操作
3.注册
}
static struct fb_info *s3c_lcd;
static int lcd_init(void)
{
分配
s3c_lcd = framebuffer_alloc( 0,NULL);
2.设置,
2.1 固定参数
strcopy(s3c_lcd->fix.id, "mylcd"); //设置设备名字
s3c_lcd->fix.smem_len = 240*320*16; //要看LCD手册 240 * 320,RGB 6bit,一般选择565结构。
s3c_lcd->fix.type = FB_TYPE_PACKED_PIXELS //默认值0
s3c_lcd->fix.visual = FB_VISUAL_TRUECLOLR; //TFT屏是真彩色
s3c_lcd->fix..line_length = 240*2;
2.2 可变参数
s3c_lcd->var.xres = 240; //x轴上的分辨率
s3c_lcd->var.yres = 320; //y轴上的分辨率
s3c_lcd->var.xres_virtual = 320; //x轴上的虚拟分辨率
s3c_lcd->var.yres_virtual = 240; //y轴上的虚拟分辨率
s3c_lcd->var.bits_per_pixel = 16; //每个像素用多少位
/*RGB:5:6:5
s3c_lcd->var.red.offset = 11;
s3c_lcd->var.red.length = 5;
s3c_lcd->var.green.offset = 5;
s3c_lcd->var.blue.length = 6;
s3c_lcd->var.blue.offset = 0;
s3c_lcd->var.blue.length = 5;
s3c_lcd->var.activate = FB_ACTIVATE_NOW;
2.3 操作函数
先定义结构体
static struct fb_ops s3c_lcdfb_ops = {
.owner = THIS_MODULE,
.fb_fillrect = cfb_fillrect, //填充举行
.fb_copyarea = cfb_copyarea, //填充区域
.fb_imageblit = cfb_imageblit, //图像
}
s3c_lcd->fops = &s3c_lcdfb_ops;
2.4 其他设置
先闲置 s3c_lcd->screen_base
s3c_lcd->screen_base = ; //显存虚拟地址
s3c_lcd->screen_size = 320*240*16/8; //显存物理地址
3. 硬件设置
定义变量:
static volatile unsigned long *gpbcon;
static volatile unsigned long *gpbdat;
static volatile unsigned long *gpccon;
static volatile unsigned long *gpdcon;
static volatile unsigned long *gpgcon;
3.1 配置GPIO
gpbcon = ioremap(0x56000010,8);
gpbdat = gpbcon+1;
gpccon = ioremap(0x56000020 4);
gpdcon = ioremap(0x56000030, 4); //映射时都是以页为单位,所以写4还是1024没区别。
gpgcon = ioremap(0x56000060, 4);
*gpccon = 0xaaaaaaaa; 用于VD[7:0],LCDVF[2:0],VM,VFRAME,VLINE,VCLK,LEND
LCD本身的电源,LCD的背光电路,
配置好2440硬件之后,LCD控制器就会从设置好的内存中读出像素点,然后写入到显存中。
LCD控制器还没有那么只能,数据必须是连续的。内核分配显存显得尤其重要。
3.2 根据手册设置LCD控制器,发出正确信号。比如VCLK。
3.3 分配显存,并把地址告诉LCD控制器
s3c_lcd->screen_base = dma_alloc_writecombine(NULL, s3c_lcd->fix.smem_len, &s3c_lcd->fix.smem_start, GFP_KERNEL);
返回虚拟地址
s3c_lcd->fix.smem_start = ;
4. 注册
register_framebuffer(s3c_lcd);
}
调色板:
得到的八位数据并不是直接发给LED,而是在调色板(内存)存储真正的数据。八位数据为索引。