s3c2440的LCD驱动程序

发布者:创意梦者最新更新时间:2020-04-25 来源: eefocus关键字:s3c2440  LCD  驱动程序 手机看文章 扫描二维码
随时随地手机看文章

本文档是看韦东山老师的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");

关键字:s3c2440  LCD  驱动程序 引用地址:s3c2440的LCD驱动程序

上一篇:ARM9 mini2451裸机学习——NAND flash驱动学习 2
下一篇:《韦东山视频第二期》——LCD驱动

推荐阅读最新更新时间:2024-11-17 08:19

RTEMS在S3C2440上的移植-(1)
学习RTEMS这款RTOS到入门实在是不容易,且这款系统性能等各方面都可以与VxWorks媲美,弃之可惜故而又想把学过的只是捡起来。以前由于课题的需要,曾经在PC104上移植过这款系统。但是由于官方支持力度较大,提供了可以使用的交叉编译工具链,因此在x86系列的硬件平台上移植RTEMS相对比较方便。由于没有自己成功搭建开发环境的经验,因此虽然搞过一年多的RTEMS,但还是不算入门。目前,手头工作相对轻轻,因此想捡起一些以前学过的知识,再次学习使用这款实时操作系统。这次经过反复的权衡,考虑在已经购买的TQ2440开发板上移植曾经学习使用过的RTEMS。等这次成功在TQ2440开发板上移植后,后面还将在STM32F407上进行移植。因
[单片机]
S3C2440 2440init.s分析第二篇(二)
S3C2440 2440init.s分析第二篇(二) ;***************************************************************************** ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ;终说见到艳阳天了!!!!!!!!!! ; 跳到C语言的main函数处了. ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ;
[单片机]
s3c2440裸板_时钟系统及定时器
若Fout = 200MHz则, Fout = 2 *m * Fin / (p * 2 ^ s) = 2 * (92 + 8) * 12MHz / (3 * 2 ^ 2) = 200MHz m = 100, MDIV = 92 p = 3, PDIV = 2 s = 2, SDIV = 2 #define S3C2440_MPLL_200MHZ ((0x5c 12) | (0x01 4) | (0x02)) CLKDIVN = 0x03; // FCLK:HCLK:PCLK=4:2:1, HDIVN=1,PDIVN=1 /* * * * * * * * * * * * *
[单片机]
<font color='red'>s3c2440</font>裸板_时钟系统及定时器
IMX257 混杂设备miscdevice驱动程序
在Linux驱动中把无法归类的五花八门的设备定义为混杂设备(用miscdevice结构体表述)。miscdevice共享一个主设备号MISC_MAJOR(即10),但次设备号不同。 所有的miscdevice设备形成了一个链表,对设备访问时内核根据次设备号查找对应的miscdevice设备,然后调用其file_operations结构中注册的文件操作接口进行操作。 在内核中用struct miscdevice表示miscdevice设备,然后调用其file_operations结构中注册的文件操作接口进行操作。miscdevice的API实现在drivers/char/misc.c中。 一、混杂设备介绍 1. miscdevi
[单片机]
IMX257 混杂设备miscdevice<font color='red'>驱动程序</font>
STM8L152的LCD模块原理及驱动
STM8L182内部集成了一个高达320个像素LCD的驱动模块。框图如下: 1. 配置LCD的时钟源、分频比、占空比、偏移电压、启用LCD端口复用功能、清晰度,并使能LCD功能。 void LCD_Config(void) { /* Enable RTC CLK */ CLK_PeripheralClockConfig(CLK_Peripheral_RTC, ENABLE); /* Enable RTC CLK */ CLK_PeripheralClockConfig(CLK_Peripheral_LCD, ENABLE); /* Choice CLK Source, HSI_Freq =
[单片机]
STM8L152的<font color='red'>LCD</font>模块原理及驱动
PIC单片机+LCD12864显示汉字程序
#include pic.h #define RS RD2 #define CS2 RD1 #define CS1 RD0 #define E RD4 #define RW RD3 #define BUSY RC7 const unsigned char tab2 ={ /*-- 文字: 福 --*/ /*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/ 0x08,0x08,0x89,0xCE,0x28,0x18,0x02,0x7A,0x4A,0x4A,0x4A,0x4A,0x4A,0x7A,0x02,0x00, 0x02,0x01,0x00,0xFF,0x01,0x02,0xF
[单片机]
PIC单片机+<font color='red'>LCD</font>12864显示汉字程序
安富利发布赛灵思视频套件和LCD面板套件
安富利公司旗下安富利电子元件部 (Avnet Electronics Marketing) 宣布推出赛灵思Xilinx® Spartan®-3A DSP 1800A视频套件和NEC 6.5英寸LCD面板套件。这两种套件为视频监控、机器视觉、视频处理和嵌入式LCD面板接口应用提供了初期预研、原型验证和设计开发的解决方案。 安富利的赛灵思Spartan®-3A DSP 1800A视频套件是一个完整的综合平台,包括新的NEC 6.5英寸LCD面板套件、Avnet PS-Video EXP模块和Spartan-3A DSP入门套件。它支持多种视频输入和输出格式,通过Spartan-3A DSP FPGA的灵活性,为设计人员考察视频应用设计提
[嵌入式]
探讨半导体照明热分析、可靠性及创新设计
  元件及系统的散热与可靠性是半导体照明的两大重要议题,在奥地利工业重镇林茨举行的EuroSimE2011国际学术会议期间,国际专家围绕这两大议题,进行了学术报告与交流,解答了诸如如何使用如碳纳米管进行散热?如何使用仿真准确预测8W替代型灯泡及3W led阵列的散热情况?如何突破LED芯片仿真的局限进行整个灯具系统的可靠性仿真等问题。会上,2个欧洲大型、跨国半导体照明研究项目SE2A (汽车电子元件开发、汽车SSL头灯)与CSSL(替代型球泡灯)的项目主管,对这两个项目的概况,管理方法与进度进行了汇报。   半导体照明热分析以及创新设计   关于半导体照明的热力分析以及散热设计,其中,来自香港科技大学的张凯介绍了如何使用压电材
[电源管理]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved