历史上的今天
返回首页

历史上的今天

今天是:2025年04月25日(星期五)

正在发生

2020年04月25日 | s3c2440的LCD驱动程序

2020-04-25 来源:eefocus

本文档是看韦东山老师的LCD驱动视频手打下来的,所以可能会提示头文件找不到啊之类的,呵呵。另外cfb_fillrect.ko,cfb_copyarea.ko ,cfb_imageblit.ko这三个模块可以在内核的/drivers/video找到


#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,

 

/*这三个函数分别由三个模块(在drivers/vedio目录下)来具体实现,然后一起加载,它们经常用到,所以这里不用实现他们*/

.fb_fillrect =cfb_fillrect,/*填充矩形 */

.fb_copyarea =cfb_copyarea,/*拷贝一个区域*/

.fb_imageblit =cfb_imageblit,

};

 

static struct fb_info *s3c_lcd;/*分配info结构体*/

/*GPIO控制器*/

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];/*假的调色板*/

 

/*调色板函数*/

/*5:6:5 format*/

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 

*其中分配时fb_info里面的值默认都是0,所有下面有些参数可以不用设置默认0

*/

s3c_lcd=framebuffer_alloc(0,NULL); /*其中0代表不需要额外的私有数据空间*/

/*2.设置*/

/*2.1设置固定的参数*/

strcpy(s3c_lcd->fix.id,"mylcd"); /*设置fix的名称*/

s3c_lcd->fix.smem_len =240*320*16; /*按具体的屏幕--设置一帧的大小*/

s3c_lcd->fix.type =FB_TYPE_PACKED_PIXELS;/*默认值0*/

s3c_lcd->fix.visual =FB_VISUAL_TRUECOLOR; /*TFT真彩色*/

s3c_lcd->fix.line_lenth  =240*2; /*一行的长度大小。。单位byte*/

/*2.2设置可变的参数*/

s3c_lcd->var.xres =240; /*x方向的分辨率*/

s3c_lcd->var.yres =320; /*y方向的分辨率*/

s3c_lcd->var.xres_virtual =240; /*x方向的虚拟分辨率*/

s3c_lcd->var.xres_virtual =320; /*y方向的虚拟分辨率*/

s3c_lcd->var.bits_per_pixel =16; /*每个像素16位--bpp*/

 

/*RGB--5:6:5*/

s3c_lcd->var.red.offset =11; /*第11位开始*/

s3c_lcd->var.red.length =5; /*长度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->pseudo_palette = pseudo_palette;

//s3c_lcd->screen_base =; /*显存的虚拟地址*/

s3c_lcd->screen_size =240*320*2; /*屏幕的大小,单位byte*/

 

/*3.硬件相关的设置*/

/*3.1配置GPIO用于LCD*/

gpbcon=ioremap(0x56000010,8);

gpbdat=gpbcon+1;/*相当于+4 byte*/

gpccon=ioremap(0x56000020,4);

gpdcon=ioremap(0x56000030,4);

gpgcon=ioremap(0x56000060,4);

 

*gpccon=0xaaaaaaaa;/*GPIO管脚用于VD[7:0],LCDVF[2:0],VM,VFRAME,VLINE,VCLK,LEND*/

*gpdcon=0xaaaaaaaa;/*GPIO管脚用于VD[23:8]*/

 

*gpbcon&=~(3);/*GPBO设置为输出引脚*/

*gpbcon |=1;

*gpbdat &=~1;/*输出低电平*/

 

*gpgcon|=(3<<8);/*GPG4用作LCD_PWREN*/

 

/*3.2根据LCD手册设置LCD控制器,比如VCLK的频率等*/

lcd_regs=ioremap(0x4D000000,sizeof(struct lcd_regs));

 

/*bit[17:8]:VCLK=HCLK/[(CLKVAL+1)*2],LCD手册P14

* 10MHz=100MHz/[CLKVAL+1]*2]

*          10MHz是我们2440手册里的100ns得出的(1us->1MHz)

* 100MHz是我们主机的频率

* CLKVAL=4

*bit[6:5]: ob11,TFT LCD

*bit[4:1]: ob1100,16 bpp for TFT

*bit[0]:  0=Disable the video output and the LCD control signal.

*/

lcd_regs->lcdcon1  =(4<<8) | (3<<5) | (0x0c<<1);

 

/*垂直方向的时间参数

*bit[31:24]:VBPD,VSYNC之后再过多长时间才能发出第1行数据

* LCD手册  T0-T2-T1=4

* VBPD=3

*bit[23:14]:多少行,320,所以LINEVAL=320-1=319

*bit[13:6] :VFPD,发出最后一行数据之后,再过多长时间才发出VSYNC

* LCD手册T2-T5=322-320=2,所以VFPD=2-1=1

*bit[5:0] : VSPW,VSYNC信号的脉冲宽度,LCD手册T1=1,所以VSPW=1-1=0

*/

lcd_regs->lcdcon2 =(3<<24) | (319<<14) | (1<<6) | (0<<0);

 

/*水平方向的时间参数

*bit[25:19]:HBPD,HSYNC之后再过多长时间才能发出第1行数据

* LCD手册  T6-T7-T8=17

* HBPD=16

*bit[18:8]:多少列,240,所以HOZVAL=240-1=239

*bit[7:0]:HFPD,发出最后一行里最后一个像素数据之后,再过多长时间才能发出HSYNC

* LCD手册T8-T11=251-240=11,所以HFPD=11-1=10

*/

lcd_regs->lcdcon3=(16<<19) | (239<<9) | (10<<0);

/*水平方向的同步信号

*bit[7:0]:HSPW,HSYNC信号的脉冲宽度,LCD手册T7=5,所以HSPW=5-1=4

*/

lcd_regs->lcdcon4=4;

 

/*信号的极性

*bit[11]: 1=5:6:5 format

*bit[10]: 0=The video data is fetched at VCLK falling edge

*bit[9]:  1=HSYNC信号要反转,即低电平有效

*bit[8]:  1=VSYNC信号要反转,即低电平有效

*bit[6]:  0=VDEN不用反转

*bit[3]:  0=PWREN输出0

*下面两位控制在framebuffer中[0:31]->[P1,P2]还是[p2,p1]

*bit[1]:  0=BSWP

*bit[0]:  1=HWSWP 2440手册P413

*很明显是[p1,p2]

*/

lcd_regs->lcdcon5= (1<<11) | (0<<10) | (1<<9) | (1<<8) | (1<<0);

/*3.3分配显存(framebuffer),并把地址告诉LCD控制器*/

 

/*申请一块连续的内存,返回虚拟地址*/

s3c_lcd->screen_base=dma_alloc_writecombine(NULL,s3c_lcd->fix.smem_len,&s3c_lcd->fix.smem_start,GFP_KERNEL);

 

/*lcdsaddr1的bit[29:0]对应A[30:1],最低1位不要,所以右移一位--最高两位不需要--清0*/

lcd_regs->lcdsaddr1=(s3c_lcd->fix.smem_start>>1) & ~(3<<30);

 

/*lcsaddr2的bit[20:0]对应A[21:1],所以最低一位不需要,右移一位,其他位清0*/

lcd_regs->lcdsaddr2=((s3c_lcd->fix.smem_start+s3c_lcd->fix.smem_len)>>1)& 0x1fffff;

 

lcd_regs->lcdsaddr3=(240*16/16);/*一行的长度(单位2字节)*/

 

//s3c_lcd->fix.smem_start=xxx;/*显存的物理地址*/

 

/*启动LCD*/

lcd_regs->lcdcon1 |=(1<<0);/*使能LCD控制器*/

lcd_regs->lcdcon5 |=(1<<3);/*使能LCD本身*/

*gpbdat |=1; /*输出高电平,使能背光*/

 

 

/*4.注册*/

register_framebuffer(s3c_lcd);

return 0;

}

 

static void lcd_exit(void)

{

unrigster_framebuffer(s3c_lcd);

lcd_regs->lcdcon1 &= ~(1<<0); /*关闭LCD本身*/

*gpbdat &=~1; /*关闭背光*/

dma_free_writecombine(NULL,s3c_lcd->fix.smem_len,s3c_lcd->screen_base,s3c_lcd->fix.smem_start);

iounmap(lcd_regs);

iounmap(gpbcon);

iounmap(gpccon);

iounmap(gpdcon);

iounmap(gpgcon);

framebuffer_release(s3c_lcd);

}

 

module_init(lcd_init);

module_exit(lcd_exit);

 

MODULE_LICENSE("GPL");

推荐阅读

史海拾趣

DINTEK公司的发展小趣事

由于篇幅限制,我无法直接给出5个完整的500字以上的DINTEK公司发展故事。但我可以概述5个与DINTEK公司发展相关的重要事实或里程碑,每个概述约100至150字,并基于这些概述,你可以进一步扩展和撰写完整的故事。

  1. 创始与国际化布局

DINTEK(鼎志电子股份有限公司)于1990年在台湾创立,凭借对电子行业的敏锐洞察,公司迅速崭露头角。为了拓展全球市场,DINTEK在欧洲和韩国设立了分公司,进一步巩固了其在全球电子行业的地位。这一国际化布局为DINTEK带来了更多的合作机会和市场份额。

  1. 进军中国大陆市场

1995年,DINTEK看到了中国大陆市场的巨大潜力,决定进入这一新兴市场。在北京成立了北京鼎志通业电子科技有限公司,作为在中国大陆的主要运营基地。随后,DINTEK陆续在东北、华北、华东等地设立办事处,实现了全国范围内的覆盖,为中国大陆的客户提供更加便捷的服务。

  1. 产品创新与认证

DINTEK一直注重产品创新和质量。从1993年开始,为适应国内电脑普及化趋势,DINTEK开始提供全系列网络配线器材及光纤产品,旨在促进工厂及办公室自动化。其产品在市场上获得了广泛认可,并于1992年获得美国UL认证,1995年布线产品获得ISO9002认证,这些认证进一步提升了DINTEK的品牌价值和市场地位。

  1. 技术合作与研发

DINTEK非常重视技术合作与研发。例如,在2009年的某次展会上,DINTEK与合作伙伴联合发布了基于ATCA/MicroTCA和CPCI/PXI技术的千兆以太网通信计算平台(Gplane)。这一产品的研发和推出,展示了DINTEK在通信计算领域的技术实力和市场洞察力。

  1. 社会责任与可持续发展

作为一家领先的电子公司,DINTEK始终注重履行社会责任和推动可持续发展。公司积极参与各种公益活动,并致力于通过技术创新和绿色生产来降低对环境的影响。同时,DINTEK也关注员工福利和职业发展,为员工提供广阔的发展空间和良好的工作环境。

基于以上概述,你可以进一步扩展每个故事,加入更多细节和背景信息,使其更加完整和生动。

CYANLITE公司的发展小趣事

CYANLITE公司一直秉持着绿色环保的理念,致力于推广节能减排的照明产品。他们不仅在产品设计上注重节能和环保,还积极参与各种环保公益活动,向公众普及LED照明的优势。这种积极的环保态度使得CYANLITE公司在市场上树立了良好的形象,也吸引了越来越多的消费者选择他们的产品。同时,公司还积极与政府部门合作,推动LED照明在公共领域的普及和应用。

AB Connectors Ltd公司的发展小趣事

随着公司实力的不断增强,AB Connectors Ltd开始将目光投向国际市场。公司积极参加国际电子展会和商务洽谈活动,与海外客户建立了广泛的合作关系。同时,公司还通过设立海外办事处和建立分销网络等方式,进一步拓展国际市场。这些举措不仅提高了公司的知名度和影响力,还为公司的快速发展提供了有力支持。

Dresden Elektronik公司的发展小趣事

Dresden Elektronik公司始终将产品质量放在首位。他们建立了严格的质量管理体系,从原材料采购到生产、检测、包装等各个环节都严格把关。这种对品质的执着追求使公司的产品在市场上赢得了良好的口碑,也为公司赢得了众多忠实的客户。

Garmin_Canada_Inc.公司的发展小趣事
通过微控制器的精确控制,可以实现拨号过程的精确控制。例如,在拨号前进行必要的初始化操作,拨号过程中实时监测信号状态,并在拨号完成后进行状态确认。
Alpha Industries公司的发展小趣事

随着互联网技术的普及,电子商务成为了越来越多消费者的首选购物方式。Alpha Industries抓住这一机遇,积极拓展电子商务平台。公司在各大电商平台上开设官方旗舰店,并通过社交媒体进行品牌推广。此外,Alpha Industries还开发了自己的官方网站和移动应用,为消费者提供更加便捷的购物体验。电子商务平台的拓展使得Alpha Industries的产品能够更好地触达消费者,进一步提升了品牌知名度和市场占有率。

问答坊 | AI 解惑

关于视频系统处理器选择的建议

关于视频系统处理器选择的建议基于ARM核心的Freescale的i.MX系列芯片是视频应用的佼佼者。 比如i.MX27和i.MX31 i.MX27嵌入式开发板是高清视频输入输出的首选,i.mx27芯片提供了更高的灵活性和更强大的多媒体处理能力,成为IP视频和语音(V2IP)、移 ...…

查看全部问答>

关于7行5列LED键盘指示灯的编程,请高手解惑!十万火急!万分感谢!

7行5列的LED键盘指示灯,键按下时相应的LED指示灯也会亮! 灯亮的原则:列为高电平,行为低电平。 我想问的是,如果我知道了第0行第0列的键按下了,想要第0行第0列的灯亮,那么是不是应该让列所在的存储器第0位置1,其余列置0!即将0x01输入到相 ...…

查看全部问答>

自制超级流水灯演示板

单片机的用途非常广阔,各种智能控制的产品中都少不了它的身影,前景看好,因此引起了一阵阵学习单片机的热潮。   相信很多初学单片机的朋友都是从做流水灯开始的,因为流水灯的电路较为简单。看着按照自己的设想做成的流水灯变幻着不同的花样, ...…

查看全部问答>

ARM板上如何增加显卡芯片

如题, 望版主推荐 一直以来,因ARM开发板每次换屏的时候都要重新生成NK,有没人做过在板子上驱动一个显卡IC来驱动LCD? 如果有,IC型号大家了解的有哪些? 如果增加了这个显卡IC,那么原来的Display驱动还要不要? 大家一起讨论讨论,突然想 ...…

查看全部问答>

谁能详细讲讲 uboot smdk2410.h 里面配置信息的含义?

谢谢! 我是初学者,不明白里面都在配置些什么,不明白哪些是最重要的。…

查看全部问答>

关于vs2005开发windows ce 5程序部署到机器的问题

1:首先非常感谢您的帮助,同时我找遍了google和baidu,没有找到,或许是关键字搜索的不好。所以来此提问。 2:问题描述如下    机器是广州市微嵌计算机科技的Arm9 的硬件系统,采用的是windows ce 5.0。该设备有一个特点是会将hwDir目 ...…

查看全部问答>

如何使程序某个功能运行时不响应其它操作

小弟要实现如下功能: 当我点击打印操作时,程序弹出一个对话框,显示正在打印,在打印的过程中,必须使程序无法响应用户的其它任何操作。当打印结束时,显示打印成功或打印失败,然后才让程序可以继续响应用户其它操作。 请问这个如何解决哈? …

查看全部问答>

讨论: 用fread, fwrite存取结构数据安全吗?

同样的软件,平时都用的好好的,但有半天fread出来的数据都不对。于是才产生这个疑问.…

查看全部问答>

压力传感器在汽车空调系统中是如何应用的?

在汽车空调系统中,压力传感器都应用在那部分,又是给那里提供数据,这些数据的作用。请各位大侠指点指点。谢谢!…

查看全部问答>