韦东山视频之LCD驱动(Mini2440 X35)
来源:互联网 发布:地理空间数据云平台 编辑:程序博客网 时间:2024/05/01 16:43
测试平台: Mini2440 Sonic X35 Lcd Linux-2.6.29 u-boot 2008.10
实验思考:
说起这块屏幕,可真是费劲,LCD原理图跟别人的好多不一样,时序图也有很大的差别,LCD上vline 和vframe根本没有,只能通过pci和mck两个时钟进行设置;
还一个就是:不知道是uboot的原因还是友善官网提供的原理图有错 ,vden必须反转才能正常!!
源代码:
#include <linux/module.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/slab.h>#include <linux/delay.h>#include <linux/fb.h>#include <linux/init.h>#include <linux/dma-mapping.h>#include <linux/interrupt.h>#include <linux/workqueue.h>#include <linux/wait.h>#include <linux/platform_device.h>#include <linux/clk.h>#include <asm/io.h>#include <asm/uaccess.h>#include <asm/div64.h>#include <linux/types.h>#include <asm/mach/map.h>#include <mach/regs-lcd.h>#include <mach/regs-gpio.h>#include <mach/fb.h>struct lcd_regs{unsigned long lcdcon1; unsigned longlcdcon2;unsigned longlcdcon3;unsigned longlcdcon4;unsigned longlcdcon5;unsigned longlcdsaddr1;unsigned longlcdsaddr2;unsigned longlcdsaddr3;unsigned longredlut;unsigned longgreenlut;unsigned longbluelut; unsigned longreserved[9];unsigned longdithmode;unsigned longtpal;unsigned longlcdintpnd;unsigned longlcdsrcpnd;unsigned longlcdintmsk;unsigned longlpcsel;};static volatile struct lcd_regs *lcd_regs_base;static struct fb_info *fb_x35;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 u32 pseudo_palette[16];static inline unsigned int chan_to_field(unsigned int chan,struct fb_bitfield* bf){chan &= 0xffff;chan >>= 16 - bf->length;return chan << bf->offset;}//设置颜色static int x35_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;val = chan_to_field(red,&info->var.red);val |= chan_to_field(green, &info->var.green);val |= chan_to_field(blue,&info->var.blue);pseudo_palette[regno] = val;return 0;}static struct fb_ops mini_fb_ops = {.owner = THIS_MODULE,.fb_setcolreg = x35_setcolreg,.fb_fillrect = cfb_fillrect,.fb_copyarea = cfb_copyarea,.fb_imageblit = cfb_imageblit,};static int lcd_init(void){//1)分配一个fb_infofb_x35 = framebuffer_alloc(0, NULL);//2)填充fb_info结构// 1 设置固定参数// 2 设置可变参数// 3 设置操作函数// 4 其他的设置strcpy(fb_x35->fix.id, "mylcd");fb_x35->fix.smem_len = 240 * 320 * 32 / 8; // frambuffer的大小fb_x35->fix.type = FB_TYPE_PACKED_PIXELS;//扫描方式,以像素点扫描 非隔行扫描fb_x35->fix.visual = FB_VISUAL_TRUECOLOR; //色阶 真彩色fb_x35->fix.line_length = 240 * 4;fb_x35->var.xres = 240;fb_x35->var.yres = 320;fb_x35->var.xres_virtual = 240;fb_x35->var.yres_virtual = 320;fb_x35->var.bits_per_pixel = 32; //每个像素点占有的字节数//颜色放置的方式,这里是真彩色为 8:8:8,每种颜色占用8位fb_x35->var.red.offset = 16;fb_x35->var.red.length = 8;fb_x35->var.blue.offset = 8;fb_x35->var.blue.length = 8;fb_x35->var.green.offset = 0;fb_x35->var.green.length = 8;fb_x35->var.activate = FB_ACTIVATE_NOW; //设置颜色立即生效//设置操作函数fb_x35->fbops = &mini_fb_ops;fb_x35->pseudo_palette = pseudo_palette; //调色板fb_x35->screen_size = 240 * 320 * 32 / 8; //屏幕尺寸的大小//3)设置硬件,驱动lcd// 1 设置lcd引脚可用// 2 设置lcd控制器寄存器// 3 设置其他的gpbcon = ioremap(0x56000010, 8);gpbdat = gpbcon+1;gpccon = ioremap(0x5600020, 4);gpdcon = ioremap(0x5600030, 4);gpgcon = ioremap(0x5600060, 4);*gpccon = 0xaaaaaaaa;*gpdcon = 0xaaaaaaaa;*gpgcon |= (0x3 << (4 * 2)); //lcd_pwren lcd电源引脚lcd_regs_base = ioremap(0x4d000000, sizeof(struct lcd_regs));lcd_regs_base->lcdcon1 = (9 << 8) | (3 << 5) | (0xd << 1);lcd_regs_base->lcdcon2 = (8 << 24) | (319 << 14) | (4 << 6) | (9 << 0);lcd_regs_base->lcdcon3 = (15 << 19) | (239 << 8) | (16 << 0) ;lcd_regs_base->lcdcon4 = 5;lcd_regs_base->lcdcon5 = (0 << 12) | (0 << 10) | (1<<6) | (0 << 1) | (0 << 0) ;//vsync swap set error//分配显存,将显存地址告诉framebufferfb_x35->screen_base = dma_alloc_writecombine(NULL, fb_x35->fix.smem_len, &(fb_x35->fix.smem_start), GFP_KERNEL);//fb_x35->fix.smem_start = xxx; /* 显存的物理地址 */lcd_regs_base->lcdsaddr1 = (fb_x35->fix.smem_start >> 1) & (~(3 << 30)); //[31~0]=0b00xx xxxx ... 30误写成20lcd_regs_base->lcdsaddr2 = ((fb_x35->fix.smem_start + fb_x35->fix.smem_len) >> 1) & 0x1fffff;lcd_regs_base->lcdsaddr3 = (0 << 11) | ((240 * 32 / 16) << 0); //行的长度有错//启动lcdlcd_regs_base->lcdcon1 |= (1 << 0);lcd_regs_base->lcdcon5 |= (1 << 3);/* MINI2440的背光电路也是通过LCD_PWREN来控制的, 不需要单独的背光引脚 *///4)注册framebufferregister_framebuffer(fb_x35);return 0;}static void lcd_exit(void){//注销framebuffer结构//释放分配的frambuffer显存//关闭lcd控制器以及电源//取消映射地址//释放framebuffer结构unregister_framebuffer(fb_x35);lcd_regs_base->lcdcon1 &= ~(1 << 0);lcd_regs_base->lcdcon5 &= ~(1 << 3);dma_free_writecombine(NULL, fb_x35->fix.smem_len, fb_x35->screen_base, fb_x35->fix.smem_start);iounmap(lcd_regs_base);iounmap(gpccon);iounmap(gpdcon);iounmap(gpgcon);framebuffer_release(fb_x35);}module_init(lcd_init);module_exit(lcd_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("LCL");
如何测试:
1. make menuconfig去掉原来的驱动程序
-> Device Drivers
-> Graphics support
<M> S3C2410 LCD framebuffer support
2. make uImage
make modules
3. 使用新的uImage启动开发板:
4. 先将之前module下编译出来的几个文件拷到开发板上cfbcopyarea.ko cfbfillrect.ko cfbimgblt.ko(/drivers/video/*)
5.
insmod cfbcopyarea.ko
insmod cfbfillrect.ko
insmod cfbimgblt.ko
insmod lcd.ko
6.
echo hello > /dev/tty1 // 可以在LCD上看见hello
cat lcd.ko > /dev/fb0 // 花屏
当然也可以测试其他的,这里不进行描述。
注意:里面的图像调整其实还不是最关键的,关键是vden不翻转 就没有图像,我调试过好多次,幸亏论坛网友热心帮助,才点亮lcd。
- 韦东山视频之LCD驱动(Mini2440 X35)
- mini2440 X35 移植LCD驱动
- mini2440 X35上做韦东山LCD裸板程序
- 《韦东山视频第二期》——LCD驱动
- 韦东山视频实验之Nand驱动
- 韦东山视频实验之Nor驱动
- 基于ok6410的韦东山驱动视频简要分析--lcd驱动
- mini2440驱动分析之LCD
- mini2440驱动分析之LCD
- mini2440驱动分析之LCD
- mini2440驱动分析之LCD
- mini2440驱动分析之LCD
- mini2440驱动分析之LCD
- mini2440驱动分析之LCD
- mini2440驱动分析之LCD
- mini2440驱动分析之LCD
- mini2440驱动分析之LCD
- 韦东山视频实验之USB鼠标驱动
- 获取指定Cell
- linux modprobe命令参数及用法详解--linux加载模块命令
- snapshot原理
- 10.3.6 TCP传输连接建立
- 微软将免费发布C#和Visual Basic编译器
- 韦东山视频之LCD驱动(Mini2440 X35)
- myeclipse安装 配置Maven<转>
- java中的值传递和引用传递
- 【linux学习笔记】查找命令小结
- 设计驱动安装程序(一)
- C++ AMP的tiled_index线程编号属性笔记
- ubuntu下cacti(snmp网络管理软件)配置
- 正式开始做培训项目,会做一些系列教程放上来
- 设备驱动安装程序设计(二)