TQ2440平台上LCD驱动的移植

发布者:码字先生最新更新时间:2023-06-26 来源: elecfans关键字:LCD驱动  移植 手机看文章 扫描二维码
随时随地手机看文章

参考:

http://liu1227787871.blog.163.com/blog/static/205363197201242393031250/

http://blog.csdn.net/cumtgao/article/details/8649006

http://www.360doc.com/content/12/0424/17/9159905_206213245.shtml

http://blog.csdn.net/yj4231/article/details/7878762

 

硬件平台:TQ2440

LCD型号:WXCAT43,分辨率480*270

U-boot版本:u-boot-2015.04

内核版本:Linux-3.14

 

下面主要完成Linux下面的LCD驱动的移植。

 

首先我们需要知道一些LCD的知识:

我们使用的LCD是TFT类型,下面是S3C2440的LCD控制器的信号引脚:

image

 

下面是TQ2440的LCD原理图:

image

 

下面介绍一下这些引脚的功能:

VCLK:发出lcd时钟信号,每来一个时钟,就会在屏幕上显示一个像素

VLINE:发出lcd行扫描信号

VFRAME:发出lcd桢扫描信号

VM:VDEN,有效时才会在屏幕上显示象素

LCD_PWREN:发出lcd面板电源使能控制信号

VD[3]——VD[7]   :lcd数据总线

VD[10]——VD[15] :lcd数据总线

VD[19]——VD[23] :lcd数据总线

 

各信号的含义

VSYNC:帧同步信号

每发出一个脉冲,表示新的一屏图像数据开始传送。

HSYNC:行同步信号

每发出一个脉冲,表示新的一行图像数据开始传送。

VCLK:像素时钟信号

每发出一个脉冲,表示新的一个点图像数据开始传送。

LEND:行结束信号

 

VBPD:表示在一帧图像开始时,帧同步信号以后的无效的行数,对应驱动中的upper_margin;

VFBD:表示在一帧图像结束后,帧同步信号以前的无效的行数,对应驱动中的lower_margin;

VSPW:表示垂直同步脉冲的宽度,单位是行数

HBPD:表示从水平同步信号开始到一行的有效数据开始之间的vclk的个数,对应驱动中的left_margin;

HFPD:表示一行的有效数据结束到下一个水平同步信号开始之间的vclk的个数,对应驱动中的right_margin;

HSPW:表示水平同步信号的宽度,单位是vclk的个数

 

下面我们结合两张图理解一下:

image

 

0_1332308765VvL6.gif

下面我们结合TQ2440上的LCD芯片手册分析:

image

注意上面这幅图下面的文字中对CLK和H的说明,其中:CLK表示的是像素时钟周期,H表示的是行同步时钟周期。可以发现上面图中的规律:

525=480+2+41+2   他们的单位都是CLK

286=272+2+10+2   他们的单位都是H

所以帧率就是: 1/(525*286*像素时钟周期) Hz

这样我们也容易理解S3C2440上的两个公式:

VCLK(Hz) = HCLK/[(CLKVAL+1)x2]   像素时钟频率(Hz)

Frame Rate = 1/ [ { (VSPW+1) + (VBPD+1) + (LIINEVAL + 1) + (VFPD+1) } x {(HSPW+1) + (HBPD +1)+ (HFPD+1) + (HOZVAL + 1) } x { 2 x ( CLKVAL+1 ) / ( HCLK ) } ]   帧率(Hz)

image

对照上面的两幅图,我们采用典型值来填充这个结构体

static struct s3c2410fb_display tq2440_lcd_cfg __initdata = {

 

    .lcdcon5    = S3C2410_LCDCON5_FRM565 |

              S3C2410_LCDCON5_INVVLINE |

              S3C2410_LCDCON5_INVVFRAME |

              S3C2410_LCDCON5_PWREN |

              S3C2410_LCDCON5_HWSWP,

 

    .type        = S3C2410_LCDCON1_TFT,

 

    .width        = 480,

    .height        = 272,

 

    .pixclock    = 100000,

    .xres        = 480,

    .yres        = 272,

    .bpp        = 16,

    .left_margin    = 2,   /* For HBPD+1, 这里我们取的都是典型值  */

    .right_margin    = 2,  /* For HFPD+1  */

    .hsync_len    = 41,    /* For HSPW+1  */

    .upper_margin    = 2,  /* For VBPD+1  */

    .lower_margin    = 2,  /* For VFPD+1  */

    .vsync_len    = 10,    /* For VSPW+1  */

};

 

#define S3C2410_GPCCON_MASK(x)    (3 << ((x) * 2))

#define S3C2410_GPDCON_MASK(x)    (3 << ((x) * 2))

 

static struct s3c2410fb_mach_info tq2440_fb_info __initdata = {

    .displays    = &tq2440_lcd_cfg,

    .num_displays    = 1,

    .default_display = 0,

 

    /* Enable VD[2..7], VD[10..15], VD[18..23] and VCLK, syncs, VDEN

     * and disable the pull down resistors on pins we are using for LCD

     * data. */

 

    .gpcup        = (0xf << 1) | (0x3f << 10),

 

    .gpccon        = (S3C2410_GPC1_VCLK   | S3C2410_GPC2_VLINE |

               S3C2410_GPC3_VFRAME | S3C2410_GPC4_VM |

               S3C2410_GPC8_VD0   | S3C2410_GPC9_VD1 |

               S3C2410_GPC10_VD2   | S3C2410_GPC11_VD3 |

               S3C2410_GPC12_VD4   | S3C2410_GPC13_VD5 |

               S3C2410_GPC14_VD6   | S3C2410_GPC15_VD7),

 

    .gpccon_mask    = (S3C2410_GPCCON_MASK(1)  | S3C2410_GPCCON_MASK(2)  |

               S3C2410_GPCCON_MASK(3)  | S3C2410_GPCCON_MASK(4)  |

               S3C2410_GPCCON_MASK(8) | S3C2410_GPCCON_MASK(9) |

               S3C2410_GPCCON_MASK(10) | S3C2410_GPCCON_MASK(11) |

               S3C2410_GPCCON_MASK(12) | S3C2410_GPCCON_MASK(13) |

               S3C2410_GPCCON_MASK(14) | S3C2410_GPCCON_MASK(15)),

 

    .gpdup        = (0x3f << 2) | (0x3f << 10),

 

    .gpdcon        = (S3C2410_GPD2_VD10  | S3C2410_GPD3_VD11 |

               S3C2410_GPD4_VD12  | S3C2410_GPD5_VD13 |

               S3C2410_GPD6_VD14  | S3C2410_GPD7_VD15 |

               S3C2410_GPD10_VD18 | S3C2410_GPD11_VD19 |

               S3C2410_GPD12_VD20 | S3C2410_GPD13_VD21 |

               S3C2410_GPD14_VD22 | S3C2410_GPD15_VD23),

 

    .gpdcon_mask    = (S3C2410_GPDCON_MASK(2)  | S3C2410_GPDCON_MASK(3) |

               S3C2410_GPDCON_MASK(4)  | S3C2410_GPDCON_MASK(5) |

               S3C2410_GPDCON_MASK(6)  | S3C2410_GPDCON_MASK(7) |

               S3C2410_GPDCON_MASK(10) | S3C2410_GPDCON_MASK(11)|

               S3C2410_GPDCON_MASK(12) | S3C2410_GPDCON_MASK(13)|

               S3C2410_GPDCON_MASK(14) | S3C2410_GPDCON_MASK(15)),

 

//    .lpcsel        = ((0xCE6) & ~7) | 1<<4,  // 禁用lpsel,因为如果不是使用三星LPC3600/LCC3600 LCD,必须禁止LPC3600/LCC3600模式(写入0到TCONSEL)。

};

 

 


接下来要说的参数是pixclock,他是用来计算像素频率的。


在driver/video/s3c2410fb.c中:


static void s3c2410fb_activate_var(struct fb_info *info)

{

    struct s3c2410fb_info *fbi = info->par;

    void __iomem *regs = fbi->io;

    int type = fbi->regs.lcdcon1 & S3C2410_LCDCON1_TFT;

    struct fb_var_screeninfo *var = &info->var;

    int clkdiv;

 

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

 

    dprintk("%s: var->xres  = %dn", __func__, var->xres);

    dprintk("%s: var->yres  = %dn", __func__, var->yres);

    dprintk("%s: var->bpp   = %dn", __func__, var->bits_per_pixel);

 

    if (type == S3C2410_LCDCON1_TFT) {

        s3c2410fb_calculate_tft_lcd_regs(info, &fbi->regs);

        --clkdiv;

        if (clkdiv < 0)

            clkdiv = 0;

    } else {

        s3c2410fb_calculate_stn_lcd_regs(info, &fbi->regs);

        if (clkdiv < 2)

            clkdiv = 2;

    }

 

    fbi->regs.lcdcon1 |=  S3C2410_LCDCON1_CLKVAL(clkdiv);

 

     ......

}

 


上面计算得到的clkdiv就是VCLK(Hz) = HCLK/[(CLKVAL+1)x2] 中的CLKVAL.


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;

}

首先pixclock作为参数传递给了s3c2410fb_calc_pixclk函数,当该函数执行完以后


clkdiv  = (clk * pixclk  / 10^12 + (2 - 1))/ 2。


随后由于是采用TFT模式,将clkdiv-1。最后得:


clkdiv  = (clk * pixclk  / 10^12 + (2 - 1))/ 2 - 1,


这里的clk即为HCLK,LCD模块使用HCLK作为时钟源,从内核启动代码中可以看到HCLK是100MHz


为方便观察,将前面datasheet中的计算公式复制在此:CLKVAL = HCLK / VCLK / 2 -1。


我们可以看出1/VCLK = pixclk / 10^12,也就是说pixclk = 10^12 / VCLK。 从LCD的芯片手册上可以看到VCLK的典型值是9MHz,我们取10MHz。


因此,pixclk=100000。


其实在内核的参考文档中有这样一段话:


The speed at which the electron beam paints the pixels is determined by the

dotclock in the graphics board. For a dotclock of e.g. 28.37516 MHz (millions

of cycles per second), each pixel is 35242 ps (picoseconds) long:

    1/(28.37516E6 Hz) = 35.242E-9 s


也就是说VCLK的倒数,再乘10^12即为pixclk。picoseconds单位表示微微秒,即10^12。


 


完。


关键字:LCD驱动  移植 引用地址:TQ2440平台上LCD驱动的移植

上一篇:u-boot-2015.04 在tq2440上的移植(使用spl引导u-boot)
下一篇:如何解决 FrameBuffer console (vc)自动关闭显示

推荐阅读最新更新时间:2024-11-09 21:07

u-boot移植总结(一)start.S分析
本次移植u-boot-2010.09是基于S3C2440的FL440板子,板子自带NANDFLASH而没有NORFLASH,所以在U-BOOT启动的过程中必须实现从NANDFLASH到SDRAM的重定向。 其中最重要的就是在U-BOOT开始的start.S汇编代码,这段代码要完成工作: 1,异常中断向量表,复位后异常向量处理 2, 跳转到代码实际执行处start_code 3,关闭看门狗WATCHDOG 3,关闭所有中断INTERRUPT 4,设置时钟分频,主要设置寄存器CLKDVN,MPLLCON,UPLLCON 5,关闭MMU和CACHE,并调用lowlevel_init.S完成SDRAM和NAND
[单片机]
u-boot<font color='red'>移植</font>总结(一)start.S分析
MSP430F5438A单片机基于SPI的FatFs移植笔记(一)
怎么说呢……太费劲了,前面的博客还烂尾了,主要是觉得自己在调试的过程当中思维太混乱。虽然说自己挖的坑,含着泪也要填上,这几个就先不填了吧我重新开个坑把调通的说清楚。 不管移植什么程序,最重要的就是, 不要自以为是 一定要先查资料,花一周查资料,查到查不到为止,否则你编了一半的程序再参考别人的,直接后果是你下不了决心推翻重来 1. FatFs移植要点: 相信能看到这个博客的都知道FatFs是什么了,目前应该是0.11版本,我就不多废话了,一个开源的文件系统,不全面的说,作用就是让你编程序操作写SD卡的内容能够被PC机读出来(有不对的话懂的大神请指正) 它的好处就是只要写底层的几个硬件驱动函数就OK了,上层的函数都已经写好了,
[单片机]
MSP430F5438A单片机基于SPI的FatFs<font color='red'>移植</font>笔记(一)
STM32开发笔记45:看门狗驱动程序的移植
单片机型号:STM32F070F6P6 本文介绍将看门狗驱动程序移植到自己工程中的方法,本项目使用的是独立看门狗IWDG。 1、在STM32CubeMX中使能看门狗,如下图所示。 2、查看看门狗时钟。 3、对看门狗进行设置,这里主要的是设置IWDG down-counter reload value。IWDG counter clock prescaler为分频系数,我现在项目设置的IWDG的时钟是40KHz,所以分频后为40000/64=625Hz,我先在项目需要使用5秒的看门狗,则625*5=3125,就是IWDG down-counter reload value的数值。 4、在自己的工
[单片机]
STM32开发笔记45:看门狗驱动程序的<font color='red'>移植</font>
IC设计、晶圆代工联手 巧让LCD驱动IC涨价
面对2017年第4季两岸LCD驱动IC市场供货情形可进一步吃紧的消息,台系LCD驱动IC供应商多表达巧妇难为无米之炊的态度,毕竟,现阶段8吋及12吋晶圆代工产能都有吃紧问题,也有其他芯片供应商在争抢产能,在LCD驱动IC价格向来偏低,能出得起的晶圆代工报价也往往是低人一等的情形下,若下游品牌手机客户及TV代工厂第4季需求持续走强,那LCD驱动IC供货由吃紧转为缺货的方向已是必然。台系晶圆代工厂更指出,LCD驱动IC缺货说不定是台厂福音,毕竟,这几年被下游TFT面板厂砍价动作折磨的很惨,适时的缺一下货,换回正常的产业伦理及市场价格秩序已是必要,毕竟,两岸面板厂为贪几毛美元的成本,导致最后出不了货,损失最大的,肯定不是LCD驱动IC供
[半导体设计/制造]
uboot移植详解
参考: 《嵌入式Linux应用开发完全手册》 韦东山编著 第15章 移植 U-boot http://xgc94418297.blog.163.com/blog/static/112966040200952971543686/ uboot是一段小程序,它在系统上电是开始执行,初始化硬件设备;准备好软件环境;最后调用操作系统内核。 这里主要分析移植过程。 U-boot中有几千个文件,要想了解对于某款开发板,使用哪些文件、哪个文件先执行、可执行文件占用内存的情况,最好的方法就是阅读它的Makefile文件。 要想使用哪款开发板就需首先执行 make board_name _config 命令进行配置,然后执行 make a
[单片机]
实时操作系统μC/OS-II在51单片机上的移植
μC/OS-II是一种公开源代码、结构小巧、具有可剥夺实时内核的嵌入式开发系统,代码简短、条理清晰、实时性及安全性能很高,绝大部分代码用C编写,现已被移植到多种处理器的构架中。随着51单片机片内资源的日益丰富,在51单片机上移植μC/OS-II已成为可能,植入系统后,由系统来管理软件与硬件资源,简化应用程序的设计,并且使应用系统功能更加完善。因此在51单片机上移植μC/OS-II具有十分重要的意义。 1 μC/OS实时操作系统概述 μC/OS-II实时操作系统是一种可移植、可固化、可裁剪即可剥夺型的多任务实时内核,适用于各种 微处理器 和微控制器。μC/OS-II主要包括任务调度、时间管理、内存管理、事件管理(信号量、邮箱
[单片机]
实时操作系统μC/OS-II在51单片机上的<font color='red'>移植</font>
s3c2440 ads程序移植到keil中(二) 初步完成
如果我把参数配置发生改变呢 然后再一次编译 要包错误 如下所示 错误如下 这个错误解决不了 最后查看了网上网友的方法 又可以修改 但是引入了nand文件 最后反正知道了2440init.s文件要修改许多 所以我就不再这里继续整了 浪费时间 直接运用网上网友的东西即可 网友编写的地址 https://blog.csdn.net/hannibaychty/article/details/44873327 从买板子到现在,想想也有2个月啦,开始就想跑裸奔的,可是工程都是在ADS下,win7系统根本不能用,于是就想着怎么在MDK跑,可是MDK上s3c2440的启动文件是不完整的,因此不推荐使用,为此蛋疼聊好长一段时间,查了很
[单片机]
s3c2440 ads程序<font color='red'>移植</font>到keil中(二) 初步完成
u-boot-2012.04移植
开发平台:x86 redhat5.5 目标平台:SMDK6410 注意: 该文档是移植完成之后的总结,所以并非按照真正的移植步骤所写, 只做参考 修改完成后运行make进行编译,把编译生成的u-boot-nand.bin烧写到nand的0-0x40000后即可切换为nand启动方式来运行 在uboot启动后手动添加环境变量 # set ipaddr 192.168.1.20 # set serverip 192.168.1.254 # set ethaddr 11:22:33:44:55:66 这些变量也可在smdk6400.h中以宏的方式定义 经测试,nand、tftp等命令都好用,如有问题请
[单片机]
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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