LCD显示原理:
在JZ2440上,想要让LCD显示,需要几个部分1、LCD硬件 2、开发板上的LCD控制器 3、SDRAM内存存放数据FramBuffer 4、可能还需要一个调色板(实际上是一块内存,里面数据可以组成各种颜色)
显示原理:在开发板上操作LCD控制器,使得开发板向SDRAM内存里去除数据发送通过LCD数据引脚发送到LCD屏上。
具体硬件操作步骤:
1、LCD引脚的连接,根据LCD原理图配置引脚
2、根据LCD控制器手册设置LCD控制器
3、分配显存,并把地址告诉LCD控制器
需要调色板的情况:LCD数据线少,比如16位数据线无法显示完全部的颜色组成,只能当做一个索引作用,指向调色板上正真的地址颜色空间
LCD液晶屏显示原理:
可以想象一下LCD后面有一个电子枪,电子枪的作用就是将从FramBuffer内存里获取到的颜色,一个一个的打到LCD屏幕上,怎么打?顺序为:
以液晶屏左上角开始,从左往右开始,一个一个颜色点打上去,打到后面没有地方的时候,又开始换行又从左往右打;就比如你打开一个记事本按住某个字符符号不懂,
它会不断的在记事本上输出字母,当到边界是开始换行输出。直到输出完为止。当然LCD液晶屏上空间有限,打的速率非常快的,是你感觉是图像是突然就出现到你
前面来一样。
------------------------------------------------------------------------------------------------------------------------------------
LCD驱动程序的框架
满足字符设备驱动程序的框架
1、应用程序通过open、read、write等函数进入内核进而调用dri_open、dri_read、dir_write等函数,通过设备好找到LCD驱动的注册id,进而
进入到到驱动函数的File_operation结构体函数,对硬件进行操作,主要框架如图所示。
LCD驱动程序
假设
app: open("/dev/fb0", ...) 主设备号: 29, 次设备号: 0--------------------------------------------------------------kernel: fb_open int fbidx = iminor(inode); struct fb_info *info = = registered_fb[0];app: read()
---------------------------------------------------------------kernel: fb_read int fbidx = iminor(inode); struct fb_info *info = registered_fb[fbidx]; if (info->fbops->fb_read) return info->fbops->fb_read(info, buf, count, ppos); src = (u32 __iomem *) (info->screen_base + p); dst = buffer; *dst++ = fb_readl(src++); copy_to_user(buf, buffer, c)问1. registered_fb在哪里被设置?
答1. register_framebuffer怎么写LCD驱动程序?
1. 分配一个fb_info结构体: framebuffer_alloc2. 设置3. 注册: register_framebuffer4. 硬件相关的操作----------------------------------------------------------------------------------------------------------------
对LCD初始化:主入口函数要做的事情
1. 分配一个fb_info结构体: framebuffer_alloc
struct fb_info {
........
struct fb_var_screeninfo var; /* Current var 可变参数*/
struct fb_fix_screeninfo fix; /* Current fix 固定参数*/........
}
/* 1. 分配一个fb_info */
s3c_lcd = framebuffer_alloc(0, NULL);2. 设置
/* 2. 设置 */
/* 2.1 设置固定的参数 Current fix*/struct fb_fix_screeninfo {
char id[16]; /* identification string eg "TT Builtin" */ unsigned long smem_start; /* Start of frame buffer mem */ /* (physical address) */ __u32 smem_len; /* Length of frame buffer mem */ __u32 type; /* see FB_TYPE_* */ __u32 type_aux; /* Interleave for interleaved Planes */ __u32 visual; /* see FB_VISUAL_* */ __u16 xpanstep; /* zero if no hardware panning */ __u16 ypanstep; /* zero if no hardware panning */ __u16 ywrapstep; /* zero if no hardware ywrap */ __u32 line_length; /* length of a line in bytes */ unsigned long mmio_start; /* Start of Memory Mapped I/O */ /* (physical address) */ __u32 mmio_len; /* Length of Memory Mapped I/O */ __u32 accel; /* Indicate to driver which */ /* specific chip/card we have */ __u16 reserved[3]; /* Reserved for future compatibility */};strcpy(s3c_lcd->fix.id, "mylcd");
s3c_lcd->fix.smem_len = 240*320*16/8; s3c_lcd->fix.type = FB_TYPE_PACKED_PIXELS; s3c_lcd->fix.visual = FB_VISUAL_TRUECOLOR; /* TFT */ s3c_lcd->fix.line_length = 240*2; /* 2.2 设置可变的参数Current var */
struct fb_var_screeninfo {
__u32 xres; /* visible resolution */ __u32 yres; __u32 xres_virtual; /* virtual resolution */ __u32 yres_virtual; __u32 xoffset; /* offset from virtual to visible */ __u32 yoffset; /* resolution */__u32 bits_per_pixel; /* guess what */
__u32 grayscale; /* != 0 Graylevels instead of colors */struct fb_bitfield red; /* bitfield in fb mem if true color, */
struct fb_bitfield green; /* else only length is significant */ struct fb_bitfield blue; struct fb_bitfield transp; /* transparency */__u32 nonstd; /* != 0 Non standard pixel format */
__u32 activate; /* see FB_ACTIVATE_* */
__u32 height; /* height of picture in mm */
__u32 width; /* width of picture in mm */__u32 accel_flags; /* (OBSOLETE) see fb_info.flags */
/* Timing: All values in pixclocks, except pixclock (of course) */
__u32 pixclock; /* pixel clock in ps (pico seconds) */ __u32 left_margin; /* time from sync to picture */ __u32 right_margin; /* time from picture to sync */ __u32 upper_margin; /* time from sync to picture */ __u32 lower_margin; __u32 hsync_len; /* length of horizontal sync */ __u32 vsync_len; /* length of vertical sync */ __u32 sync; /* see FB_SYNC_* */ __u32 vmode; /* see FB_VMODE_* */ __u32 rotate; /* angle we rotate counter clockwise */ __u32 reserved[5]; /* Reserved for future compatibility */};s3c_lcd->var.xres = 240;
s3c_lcd->var.yres = 320; s3c_lcd->var.xres_virtual = 240; s3c_lcd->var.yres_virtual = 320; s3c_lcd->var.bits_per_pixel = 16;
/* RGB:565 */
s3c_lcd->var.red.offset = 11; s3c_lcd->var.red.length = 5; s3c_lcd->var.green.offset = 5; s3c_lcd->var.green.length = 6;s3c_lcd->var.blue.offset = 0;
s3c_lcd->var.blue.length = 5;s3c_lcd->var.activate = FB_ACTIVATE_NOW;
/* 2.3 设置操作函数 */s3c_lcd->fbops = &s3c_lcdfb_ops;
/* 2.4 其他的设置 */s3c_lcd->screen_size = 240*324*16/8;
3. 硬件相关的操作
/* 3.1 配置GPIO用于LCD */ /* 3.2 根据LCD手册设置LCD控制器, 比如VCLK的频率等 */ /* 3.3 分配显存(framebuffer), 并把地址告诉LCD控制器 */
4. 注册: register_framebuffer
/* 4. 注册 */
register_framebuffer(s3c_lcd);
剩余的对s3c_lcdfb_ops的配置以及硬件配置查看LCD驱动(二)