linux2.6.32.2 mini2440平台移植-- LCD 显示驱动 ( W35屏 )

发布者:古通闲人最新更新时间:2022-10-17 来源: csdn关键字:linux2  6  mini2440  LCD  显示驱动 手机看文章 扫描二维码
随时随地手机看文章

1.4.1 LCD 驱动基础知识


Linux-2.6.32.2 内核已经支持 S3C2440 的 LCD 控制器驱动,但在此我们先介绍一下关于 2440 LCD 控制器以及驱动相关的 LCD 的一些基础知识。


注意:在此我们只讨论 TFT LCD,也就是真彩屏。


LCD  驱动中最关键的就是时钟频率(Clock  frequency)的设置,时钟频率设置不对,LCD 的显示就会闪,或者根本没有显示。一般 LCD 的  Datasheet 上会写有一个推荐的频率,比如 mini2440 所用的统宝 3.5"LCD,在它的数据手册第 13 页,有这样一个表格:可以看到,这里推荐的时钟频率是 6.39MHz,近似于 6.4MHz,范围,是 5M-6.85MHz。


S3C2440 之 LCD 控制器与此相关的设置为 CLKVAL,通过设置它,就可以在 LCD 接口的 VCLK 引脚上产生 LCD 所需要的时钟频率,那么 CLKVAL 和 VCLK 有何种关系呢?在 2440 英文手册(411页  )中,有这样一段描述:


The  rate  of  VCLK  signal  depends  on  the  CLKVAL  field  in  the  LCDCON1  register.  Table  15-3  defines  the


relationship of VCLK and CLKVAL. The minimum value of CLKVAL is 0


接下来,手册中提供了它们的数学关系公式:


VCLK(Hz) = HCLK/[(CLKVAL+1)x2]


因此可以得出:


VCLK = HCLK / ((CLKVAL+1)*2)


那么  HCLK 是多少呢?


我们的开发板运行于400Mhz,这个可以在  bootloader 的源代码头文件中看到


FCLK:HCLK:PCLK  =  1:4:8,因此得出  HCLK=100Mhz,再根据上述公式得出


CLKVAL 应为:


CLKVAL=HCLK/(VCLK*2) -1


VCLK :LCD屏幕所需的频率


CLKVAL = 100000000 / (6400000 * 2) - 1 = 6.8


选择最接近的整数值 7,并把它写入 LCDCON1:17-8(注意:我们实际使用的数值是 8),由此产生的 VCLK 频率实测为 5.63Mhz 左右,它也是在 5-6.85Mhz 之间的数值。


1.4.2  新内核中的 pixclock 参数


在以前较老的 Linux 内核中,对于 LCD 寄存器的设置都是这样直接填写 CLKVAL 的,但 Linux-2.6.32.2 内核却不再使用这样简单直观的方式,而是通过一个称为"pixclock"的参数进行调节,它的计算变的复杂和难以理解,我们不清楚 Linux 内核中关于 2440 部分的移植为何改变成这样的方式,这有可能是为了和  X86  体系中的设置保持一致的风格,下面我们根据实际的代码进行一些推导和说明,但推导结果和我们的实际设置是并不一致的,会有一些误差。


提示:我们实际提供的  pixclock 参数并不是按照以下的方式推导计算出的,而是先确定好 CLKVAL 的数值,再反复尝试、猜测得到的。


在 Framebuffer 驱动(linux-2.6.32.2/ drivers/video/s3c2410fb.c)中有这样一个函数:


clkdiv = DIV_ROUND_UP(s3c2410fb_calc_pixclk(fbi, var->pixclock), 2);


这里的 clkdiv 就是我们上面提到的 CLKVAL,而 DIV_ROUND_UP 是一个宏定义,它位于 include/linux/kernel.h 文件中:


#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))


这其实是一个数学概念:向上取整。下面是关于"向上取整"的一段说明:


以下信息来自:


http://www.vckbase.com/document/viewdoc/?id=743


1.  问题


A,B 都是整数并且  A>1, B>1


求┌A/B┐即 A/B 的上取整。


当  A/B  整除,往上取整返回值  为  A/B。


当  不整除,返回值是  int(A/B) + 1


这个算法的一个应用:如果你有一个动态增长的缓冲区,增长的步长是  B,


某一次缓冲区申请的大小是  A,这个时候,就可以用这个算法,计算出缓冲区的一个合


适大小了,正好可以容纳 A,并且不会过于得多,多余部分不会比 B 多。


2.  方法


int( (A+B-1)/B )


3. HUNTON  的证明


上取整用 UP 表示


由于 A>1、B>1,且 A、B 都是整数,所以可以设 A=NB+M


其中 N 为非负整数,M 为 0 到 B-1 的数,则


A/B = N + M/B


(A+B-1)/B = N + 1 + (M - 1)/B;


当 M 为 0 时,


UP(A/B) = N,


int((A+B-1)/B) = N + int(1 - 1/B) = N


当 M 为 1 到 B-1 的数时,0 <= M-1 <= B-2


UP(A/B) = N + 1,


int((A+B-1)/B) = N + 1 + int((M-1)/B) = N + 1


所以对 A>1、B>1 的整数 A、B 都有:


UP(A/B) = int((A+B-1)/B)


对于除数为"2"的本算法而言,我们可以简单的理解为"(n/2)+0.5"所对应的整数值,因此这里不可能避免的就出现了误差,也就是说n的数值是有一定范围的,这里的n就是 "s3c2410fb_calc_pixclk(fbi, var->pixclock)",因此上面的公式可以改写为:clkdiv= s3c2410fb_calc_pixclk(fbi, var->pixclock)/2 + 0.5


而      s3c2410fb_calc_pixclk(fbi, var->pixclock)   


这个函数在linux-2.6.32.2/ drivers/video/s3c2410fb.c 中是这样定义的:


/* s3c2410fb_calc_pixclk()


*


* calculate divisor for clk->pixclk


*/


static unsigned int s3c2410fb_calc_pixclk(struct s3c2410fb_info *fbi,


unsigned long pixclk)


{


unsigned long clk = fbi->clk_rate;


unsigned long long div;


/* pixclk is in picoseconds, our clock is in Hz


*


* Hz -> picoseconds is / 10^-12


*/


;这里计算出本函数的结果


div = (unsigned long long)clk * pixclk;


div >>= 12;                                        /* div / 2^12 */


do_div(div, 625 * 625UL * 625); /* div / 5^12 */


dprintk("pixclk %ld, divisor is %ldn", pixclk, (long)div);


return div;


}


因此得出:


clkdiv=clk*pixclk/(10^12)/2 + 0.5


根据实际打印结果验证,此处的 clk 其实就是 HCLK。


而根据 static void s3c2410fb_activate_var(struct fb_info *info)函数中的描述,会得出这样一个关系:


CLKVAL=clkdiv-1


再结合从 2440 芯片手册得到的公式 CLKVAL=HCLK/(VCLK*2)  -1,因此可以得出大致这样的结果("大致"可以理解为一定的误差范围):


Pixclk=(HCLK-VLCK)x10^12/HCLK*VCLK


以我们所用的统宝屏为例:


HCLK=100Mhz=100,000,000Hz


VLCK=6.4Mhz=6400,000Hz


因此计算出:pixclk =146250,单位是 ps(picoseconds),这和我们实际设置的数值 170000是有一定误差的。另外在Linux内核文档中,还有另外一种计算   pixclock的方式,见 linux/Documentation/fb/framebuffer.txt。


1.4.3  在内核中添加各种 LCD 类型的支持


打开  arch/arm/mach-s3c2440/mach-mini2440.c,先删除之前的  LCD 设备平台代码,如下:


/* LCD driver info */


static struct s3c2410fb_display mini2440_lcd_cfg __initdata = {


    .lcdcon5    = S3C2410_LCDCON5_FRM565 |


              S3C2410_LCDCON5_INVVLINE |


              S3C2410_LCDCON5_INVVFRAME |


              S3C2410_LCDCON5_PWREN |


              S3C2410_LCDCON5_HWSWP,


    .type       = S3C2410_LCDCON1_TFT,


    .width      = 240,


    .height     = 320,


    .pixclock   = 166667, /* HCLK 60 MHz, divisor 10 */


    .xres       = 240,


    .yres       = 320,


    .bpp        = 16,


    .left_margin    = 20,


    .right_margin   = 8,


    .hsync_len  = 4,


    .upper_margin   = 8,


    .lower_margin   = 7,


    .vsync_len  = 4,


};


static struct s3c2410fb_mach_info mini2440_fb_info __initdata = {


    .displays   = &mini2440_lcd_cfg,


    .num_displays   = 1,


    .default_display = 0,


#if 0


    /* currently setup by downloader */


    .gpccon     = 0xaa940659,


    .gpccon_mask    = 0xffffffff,


    .gpcup      = 0x0000ffff,


    .gpcup_mask = 0xffffffff,


    .gpdcon     = 0xaa84aaa0,


    .gpdcon_mask    = 0xffffffff,


    .gpdup      = 0x0000faff,


    .gpdup_mask = 0xffffffff,


#endif


    .lpcsel     = ((0xCE6) & ~7) | 1<<4,


};


再把友善之臂已经移植好的代码加入,如下  //这里有多种屏幕的配置,我用的是w35屏


#if defined(CONFIG_FB_S3C2410_N240320)


#define LCD_WIDTH 240


#define LCD_HEIGHT 320


#define LCD_PIXCLOCK 100000


#define LCD_RIGHT_MARGIN 36


#define LCD_LEFT_MARGIN 19


#define LCD_HSYNC_LEN 5


#define LCD_UPPER_MARGIN 1


#define LCD_LOWER_MARGIN 5


#define LCD_VSYNC_LEN 1


#elif defined(CONFIG_FB_S3C2410_N480272)


#define LCD_WIDTH 480


#define LCD_HEIGHT 272


#define LCD_PIXCLOCK 100000


#define LCD_RIGHT_MARGIN 36


#define LCD_LEFT_MARGIN 19


#define LCD_HSYNC_LEN 5


#define LCD_UPPER_MARGIN 1


#define LCD_LOWER_MARGIN 5


#define LCD_VSYNC_LEN 1


#elif defined(CONFIG_FB_S3C2410_W320240)       //这里是W35屏的配置


#define LCD_WIDTH      320


#define LCD_HEIGHT     240


#define LCD_PIXCLOCK   70000


#define LCD_RIGHT_MARGIN       68


#define LCD_LEFT_MARGIN        66


#define LCD_HSYNC_LEN          4


#define LCD_UPPER_MARGIN       4


#define LCD_LOWER_MARGIN       4


#define LCD_VSYNC_LEN          9


#define LCD_CON5 (S3C2410_LCDCON5_FRM565 |S3C2410_LCDCON5_INVVDEN | S3C2410_LCDCON5_INVVFRAME | S3C2410_LCDCON5_INVVLINE| S3C2410_LCDCON5_INVVCLK | S3C2410_LCDCON5_HWSWP) 


#elif defined(CONFIG_FB_S3C2410_TFT640480)


#define LCD_WIDTH 640


#define LCD_HEIGHT 480


#define LCD_PIXCLOCK 40000


#define LCD_RIGHT_MARGIN 67


#define LCD_LEFT_MARGIN 40


#define LCD_HSYNC_LEN 31


#define LCD_UPPER_MARGIN 5


#define LCD_LOWER_MARGIN 25


#define LCD_VSYNC_LEN 1


#elif defined(CONFIG_FB_S3C2410_T240320)


#define LCD_WIDTH 240


#define LCD_HEIGHT 320


#define LCD_PIXCLOCK 170000


#define LCD_RIGHT_MARGIN 25


#define LCD_LEFT_MARGIN 0


#define LCD_HSYNC_LEN 4


#define LCD_UPPER_MARGIN 1


#define LCD_LOWER_MARGIN 4


#define LCD_VSYNC_LEN 1


#define LCD_CON5 (S3C2410_LCDCON5_FRM565 | S3C2410_LCDCON5_INVVDEN | S3C2410_LCDCON5_INVVFRAME | S3C2410_LCDCON5_INVVLINE | S3C2410_LCDCON5_INVVCLK | S3C2410_LCDCON5_HWSWP )


#elif defined(CONFIG_FB_S3C2410_X240320)


#define LCD_WIDTH 240


#define LCD_HEIGHT 320


#define LCD_PIXCLOCK 170000


#define LCD_RIGHT_MARGIN 25


#define LCD_LEFT_MARGIN 0


#define LCD_HSYNC_LEN 4


#define LCD_UPPER_MARGIN 0


#define LCD_LOWER_MARGIN 4


#define LCD_VSYNC_LEN 9


#define LCD_CON5 (S3C2410_LCDCON5_FRM565 | S3C2410_LCDCON5_INVVDEN |


S3C2410_LCDCON5_INVVFRAME | S3C2410_LCDCON5_INVVLINE |


S3C2410_LCDCON5_INVVCLK | S3C2410_LCDCON5_HWSWP )



#elif defined(CONFIG_FB_S3C2410_TFT800480)


#define LCD_WIDTH 800


#define LCD_HEIGHT 480


#define LCD_PIXCLOCK 40000


#define LCD_RIGHT_MARGIN 67


#define LCD_LEFT_MARGIN 40


#define LCD_HSYNC_LEN 31


#define LCD_UPPER_MARGIN 25


#define LCD_LOWER_MARGIN 5


#define LCD_VSYNC_LEN 1


#elif defined(CONFIG_FB_S3C2410_VGA1024768)


#define LCD_WIDTH 1024


#define LCD_HEIGHT 768


#define LCD_PIXCLOCK 80000


#define LCD_RIGHT_MARGIN 15


#define LCD_LEFT_MARGIN 199


#define LCD_HSYNC_LEN 15


#define LCD_UPPER_MARGIN 1


#define LCD_LOWER_MARGIN 1


#define LCD_VSYNC_LEN 1


#define LCD_CON5 (S3C2410_LCDCON5_FRM565 | S3C2410_LCDCON5_HWSWP)


#endif



#if defined (LCD_WIDTH)


static struct s3c2410fb_display mini2440_lcd_cfg __initdata = {


#if !defined (LCD_CON5)


        .lcdcon5        = S3C2410_LCDCON5_FRM565 |


                          S3C2410_LCDCON5_INVVLINE |


                          S3C2410_LCDCON5_INVVFRAME |


                          S3C2410_LCDCON5_PWREN |


                          S3C2410_LCDCON5_HWSWP,


#else


        .lcdcon5        = LCD_CON5,


#endif


 


        .type           = S3C2410_LCDCON1_TFT,


      .width          = LCD_WIDTH,


        .height         = LCD_HEIGHT,


 


        .pixclock       = LCD_PIXCLOCK,

[1] [2]
关键字:linux2  6  mini2440  LCD  显示驱动 引用地址:linux2.6.32.2 mini2440平台移植-- LCD 显示驱动 ( W35屏 )

上一篇:mini2440简单的lcd显示驱动程序
下一篇:linux 2.6.32.2 mini2440平台移植--触摸屏驱动移植

推荐阅读最新更新时间:2024-11-08 04:09

一加6迎来系统更新:新增自拍背景虚化
    今年5月份,一加6发布,搭载高通骁龙845,最高配备8GB内存,成为一加最新的年度旗舰。   一加6相比以往,参数上升级较大的就是相机,其后置为2000万+1600万像素双摄像头,其中1600万像素传感器为索尼IMX519,拥有双核对焦,进光量比F/2.0增加34%的F/1.7光圈,前置相机为1600万像素镜头,支持AI人像美拍。 近日,一加向一加6推送了较大的系统更新,更新包大小为212MB。   除了一些系统优化以外,能够看出新增了前置人像模式,让自拍也能背景虚化,以及后置人像模式增加光斑的预览效果。   另外,在系统中新增双卡4G网络开关、提升铃声音量、勿扰模式定时自动开关设置、状态栏支持显示电量百分比、连接蓝牙耳
[手机便携]
基于STM32物联网开发板(4)--LCD
1.概述 屏幕尺寸为1.3寸,分辨率240*240,颜色格式RGB565,驱动IC:ST7789VW; 超大可视角度:大于160°(显示屏中可视角度最大的一种屏幕); 宽电压供电(3V~5V),兼容3.3V和5V电平逻辑,无需电平转换芯片; 采用7线制SPI接口; 工作温度范围为工业级(-20℃~60℃); 军工级工艺标准,长期稳定工作; 硬件接口: 引脚 说明 LEDK PB0背光 CS PA4片选 SCL PA5时钟 SDA PA7主机输出 RES PB1复位脚(电平复位) D/C PC4数据命令选择脚 2.通讯协议 ST7789VW是一款用于262K彩色图形型TFT-LCD的单片
[单片机]
基于STM<font color='red'>32</font>物联网开发板(4)--<font color='red'>LCD</font><font color='red'>屏</font>
基于MSP432P410R的HC-SR04超声波程序
代码 //HCSR04.h配置 #ifndef _HCSR04_H #define _HCSR04_H #include main.h void HCSR04Init(void); float Distance(void); #endif //HCSR04.c配置 #include HCSR04.h #include main.h const Timer_A_UpModeConfig upConfig = { TIMER_A_CLOCKSOURCE_SMCLK, // SMCLK Clock Source TIMER_A_CLOCKSOURCE_DIVIDER_3
[单片机]
Q2 MPU聚焦:AMD状况好转市场占有率高于预期,英特尔份额微降但仍是主流
根据iSuppli公司的调查,跟原来的预期相比,AMD第二季度在微处理器市场的占有率的增长远远超过英特尔公司。据这家市场研究公司透露,AMD公司在第一季度占整个微处理器销售收入的13.4%,而第二季度增长了2.5%;相比之下,英特尔公司在第二季度遭遇了2%的销售收入占有率的下降,但就整体而言,英特尔仍然以78.8%的占有率独占鳌头。 iSuppli在7月时估计英特尔和AMD的增长都是0.5%,实际情况远远超过预期。AMD公司第二季度的增长结束了该公司销售下滑的周期。据iSuppli透露,AMD的市场占有率从2006年第三季度的16.8锐减为2007年第一季度的10.9%,缩小了近6%。 目前,在微处理器市场中的情况由严重的价格
[焦点新闻]
STM32F4 定义ucosii到CCM
STM32F4说是有192KRAM 但是很是很坑。192k分为两部分128k普通RAM和64K CCM RAM,CCM只能内核调用,外设无法使用。本来想着192KRAM挺好,结果仔细看悲剧了。但是也不能浪费,可以尝试使用它,把UCOS内核数据放到CCM。网上搜索到一个FreeRTOS的照着他的自己弄了弄。 1.勾选IARM2 确认使用CCM 此时编译程序后打开.map文件会发现使用了CCM但是没有数据定义到这块RAM。同时发现IRAM1内部关于UCOS的存储。 2.打开.sct文件添加如下图代码--UCOS_ii_IARM自己写的,把刚刚在IRAM1中看到的 os_core.o 和os_cpu_c.o文件
[单片机]
STM<font color='red'>32</font>F4 定义ucosii到CCM
TMS320C62x HPI引导过程的实现
作者Email: cai_yang@etang.com 摘要:TMS320C62x和TMS320C67x DSPs提供了几种不同的启动模式,不同的启动模式决定了DSP复位后的初始化以及代码装载方式。本文就TMS320C62x DSP的HPI启动模式进行详细的说明。 关键词:TMS320C62x DSP HPI 启动模式 1 绪言 在TMS320C62x系列DSP中,主机口HPI是一个16位宽度的并行端口。主机(也称上位机)掌管该接口的主控权,通过它可以直接访问CPU的存储器空间。另外,主机还可以直接访问TMS320C62x片内的存储映射的外围设备。 HPI与CPU存储空间的互连是通过DMA控制器实
[嵌入式]
【STM32Cube_02】获取并安装STM32CubeMX
本文中涉及到的安装包可以在官网下载到,速度比较慢,为了方便大家,我已上传到百度网盘,资源列表如下: 1.安装Java环境(JRE) 因为STM32CubeMX是采用Java语言编写的,所以需要先在电脑上安装Java运行环境(JRE,Java runtime Environment),安装JRE时建议选择Java 8或者以后的版本。 安装JRE有两种方式: 单独的安装Jre; 直接安装开发者套件JDK,其中就包括了JRE,这样以后还能用于开发Java。 这里我选择第二种,安装JDK8不是本文的重点,具体请参考我的Java系列文章或者网上自行搜索。 2.获取STM32CubeMX STM32CubeMX可以访问STM32
[单片机]
【STM<font color='red'>32</font>Cube_02】获取并安装STM<font color='red'>32</font>CubeMX
stm32之DMA研究
在做实验之前,首先必须明白什么是DMA,DMA的作用又体现在哪里。 DMA,即直接内存存储,在一些数据的传输中,采用DMA方式,从而将CPU解放出来。让CPU有足够的时间处理其他的事情。 stm32使用DMA的相关操作: 1、DMA的配置 要配置的有DMA传输通道选择,传输的成员和方向、普通模式还是循环模式等等。 void DMA_Configuration(void) { DMA_InitTypeDef DMA_InitStructure; //DMA设置: //设置DMA源:内存地址&串口数据寄存器地址 //方向:内存-- 外设 //每次传输位:8bit //传输大小DMA_BufferSize=SEN
[单片机]
热门资源推荐
热门放大器推荐
  •  zip文件2024 DigiKey 创意大赛
  •  zip文件智联音响
  •  zip文件usb_host_device_code
  •  rar文件声源定位
  • 系统发生错误

    系统发生错误

    您可以选择 [ 重试 ] [ 返回 ] 或者 [ 回到首页 ]

    [ 错误信息 ]

    页面错误!请稍后再试~

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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