一.硬件基础
1.硬件框图

2.LCD控制浓ky"http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vc8YnI+CjwvcD4KPHA+ICAgIMHLveLTsrz+1+7Wsb3TtcSw7Leovs3Kx7+0ytay4aOs1NrV4sDvztLWu7vhvPK1pb3pydzPwkxDRLXE07K8/qGjvt/M5bXEztK74dTaz8LD5r3hus+zzNDyvbK94qGjPC9wPgo8cD48aW1nIHNyYz0="https://www.cppentry.com/upload_files/article/49/1_x7s8o__.jpg" alt="\">
a.REGBANK是LCD控制器的寄存器,含17个寄存器以及一块256*16的调色内存,用来设置各项参数。
b.LCDCDMA是LCD控制器专用的DMA信道。
c.TIMEGEN和LPC3600负责产生LCD屏所需要的控制时序。
d.VIDPRCS需要与LCDCDMA中的数组合成特定的格式,然后从VD[23:0]发送给LCD屏幕。
3.时序理解


二.驱动框架

三.改写驱动
1.程序代码
#include#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int s3c_lcdfb_setcolreg(unsigned int regno, unsigned int red, unsigned int green, unsigned int blue, unsigned int transp, struct fb_info *info); struct lcd_regs { unsigned long lcdcon1; unsigned long lcdcon2; unsigned long lcdcon3; unsigned long lcdcon4; unsigned long lcdcon5; unsigned long lcdsaddr1; unsigned long lcdsaddr2; unsigned long lcdsaddr3; unsigned long redlut; unsigned long greenlut; unsigned long bluelut; unsigned long reserved[9]; unsigned long dithmode; unsigned long tpal; unsigned long lcdintpnd; unsigned long lcdsrcpnd; unsigned long lcdintmsk; unsigned long lpcsel; }; static struct fb_ops s3c_lcdfb_ops = { .owner = THIS_MODULE, .fb_setcolreg = s3c_lcdfb_setcolreg, .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, }; static struct fb_info *s3c_lcd; 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; static volatile struct lcd_regs* lcd_regs; static u32 pseudo_palette[16]; /* from pxafb.c */ static inline unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf) { chan &= 0xffff; //清零高16位 chan >>= 16 - bf->length; //保留高8位置 return chan << bf->offset; //左移起始地址(得到的值就是颜色了) } static int s3c_lcdfb_setcolreg(unsigned int regno, unsigned int red, unsigned int green, unsigned int blue, unsigned int transp, struct fb_info *info) { unsigned int val; if (regno > 16) return 1; /* 用red,green,blue三原色构造出val */ val = chan_to_field(red, &info->var.red); val |= chan_to_field(green, &info->var.green); val |= chan_to_field(blue, &info->var.blue); //((u32 *)(info->pseudo_palette))[regno] = val; pseudo_palette[regno] = val; return 0; } /*入口函数*/ static int lcd_init(void) { /* 1. 分配一个fb_info */ s3c_lcd = framebuffer_alloc(0, NULL); /* 2. 设置 */ /* 2.1 设置固定的参数 */ strcpy(s3c_lcd->fix.id, "mylcd"); s3c_lcd->fix.smem_len = 320*240*32/8; /* MINI2440的LCD位宽是24,但是2440里会分配4字节即32位(浪费1字节) */ s3c_lcd->fix.type = FB_TYPE_PACKED_PIXELS; s3c_lcd->fix.visual = FB_VISUAL_TRUECOLOR; /* TFT */ s3c_lcd->fix.line_length = 240*4; /*一行240没个占4个字节*/ /* 2.2 设置可变的参数 */ 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_