您的位置:首页 > 其它

lcd fb参数如何计算

2018-02-01 14:31 411 查看
Linux内核的amba lcd控制器使用clcd_panel结构体表示一个LCD屏的硬件参数:/* include/linux/fb.h */

struct fb_videomode {

     const char *name;     /* optional */

     u32 refresh;          /* optional */

     u32 xres;

     u32 yres;

     u32 pixclock;

     u32 left_margin;

     u32 right_margin;

     u32 upper_margin;

     u32 lower_margin;

     u32 hsync_len;

     u32 vsync_len;

     u32 sync;

     u32 vmode;

     u32 flag;

};

/* include/linux/amba/clcd.h */

struct clcd_panel {

     struct fb_videomode     mode;

     signed short          width;     /* width in mm */

     signed short          height;     /* height in mm */

     u32                       tim2;

     u32                       tim3;

     u32                        cntl;

     unsigned int             bpp:8,

                                   fixedtimings:1,

                                   grayscale:1;

     unsigned int           connector;

};

先看一个例子:http://lxr.linux.no/linux+v2.6.37.4/arch/arm/mach-lpc32xx/phy3250.c

fb_videomode各个参数的意义

Linux对LCD的抽象如下图所示:



下面研究一下fb_videomode各个成员的意义:

名称
在数据手册中的简称
中文名
意义
备注
name
No
名字
液晶屏名字(可选)
No
refresh
No
刷新频率
刷新频率(内核中很多例子都赋值为60)
No
xres
No
行宽
每行的像素个数
No
yres
No
屏幕高度
屏幕的行数
No
pixclock
No
像素时钟
每个像素时钟周期的长度,单位是皮秒(10的负12次方分之1秒)
No
left_margin
HBP  (Horizontal
Back Porch)
水平后沿
在每行或每列的象素数据开始输出时要插入的象
素时钟周期数
No
right_margin
HFP (Horizontal
Front Porch )
水平前沿
在每行或每列的象素结束到LCD 行时钟输出脉冲
之间的象素时钟数
No
upper_margin
VBP (Vertical
Back Porch)
垂直后沿
在垂直同步周期之后帧开头时的无效行数
No
lower_margin
VFP (Vertical
Front Porch)
垂直前沿
本帧数据输出结束到下一帧垂直同步周期开始之
前的无效行数
No
hsync_len
HPW  (HSYNC plus width)
行同步脉宽
单位:像素时钟周期
也有手册简称为HWH(HSYNC width)
vsync_len
VPW (VSYNC width)
垂直同步脉宽
单位:显示一行的时间th
也有手册简称为VWH(VSYNC width)
sync
No 
同步极性设置
可以根据需要设置FB_SYNC_HOR_HIGH_ACT(水平同步高电平有效)和FB_SYNC_VERT_HIGH_ACT(垂直同步高电平有效)
No
vmode
No
No
在内核中的大多数示例都直接置为FB_VMODE_NONINTERLACED。interlaced的意思是交错[隔行]扫描,电视中使用2:1的交错率,
即每帧分两场,垂直扫描两次,一场扫描奇数行,另一场扫描偶数行。很显然LCD目前不是这种模式。
No
flag
No
No
目前没有看到用法
No
说明:

(1)Linux对LCD的抽象是以图像为中心的,而LCD手册则以同步信号为中心,所以内核中的left_margin是指在每一行之前(前面自然对应左边)的空闲周期数,而它对应LCD数据手册中的水平后沿(HBP  Horizontal Back Porch),是指在行同步信号之后的空闲周期。参照物不同而已,但是说的是同一个东西。

(2)水平同步信号有时也成为行同步型号,垂直同步信号有人称为场同步信号。

(3)对于LCD的frambuffer抽象模型请参考内核中的文档:Documention/fb/frambuffer.txt。

(4)fb_videomode各个成员的用处是我自己参照内核代码中的include/linux/amba/clcd.h中的clcdfb_decode()函数总结的,不保证护绝对正确。

clcd_panel各个成员的意义

clcd_panel是ARM的AMBA LCD控制器专有的数据结构,定义在include/linux/amba/clcd.h中。

ARM的AMBA LCD控制器数据手册在这里:http://infocenter.arm.com/help/topic/com.arm.doc.ddi0121d/DDI0121.pdf

width和height的单位是mm,应该是指屏幕的物理尺寸。但是在drivers/video/amba-clcd.c中只是简单的赋给fb.var.width/height,内核中大多数例子直接赋为-1。

从include/linux/amba/clcd.h中的clcdfb_decode()函数和drivers/video/amba-clcd.c中的clcdfb_set_par()函数可以看出 tim2是时钟和信号极性寄存器,tim3是行末控制寄存器,用来控制每行输出结束后是否输出一个脉冲。tim3一般不用理,使用默认值。tim2一般要根据LCD数据手册用下面几个宏赋值:

#define TIM2_CLKSEL          (1 << 5)      选择LCD的时钟源,0选择片内时钟,1选择外部引脚接入的时钟。一般用默认值即可

#define TIM2_IVS          (1 << 11)          反转垂直同步 信号的极性。0:高电平有效,低电平无效。1:相反

#define TIM2_IHS          (1 << 12)          反转水平同步 信号的极性。0:高电平有效,低电平无效。1:相反

#define TIM2_IPC          (1 << 13)          来选择象素数据是在显示屏时钟的上升沿还是下降沿被驱动到LCD 数据线。0:上升沿。1:下降沿。

#define TIM2_IOE          (1 << 14)          这个位选择输出使能信号的有效极性。0:高电平有效,低电平无效。1:相反

#define TIM2_BCD          (1 << 26)         将该位设为 1,令 PCD 的分频无效。主要用于 TFT 显示屏。这个位通常不设置,使用默认值0.

clcd_panel的cntl成员实际上是要写入AMBA LCD控制器的控制寄存器,根据具体硬件使用下面的宏填充:

#define CNTL_LCDEN          (1 << 0)                  LCD 使能控制位。0:禁止。1:使能。

#define CNTL_LCDBPP1          (0 << 1)               bit[1-3]定义色深。bpp:bits per pixel,每个像素的比特数。000 = 1 bpp.

#define CNTL_LCDBPP2          (1 << 1)               001 = 2 bpp.

#define CNTL_LCDBPP4          (2 << 1)               010 = 4 bpp.

#define CNTL_LCDBPP8          (3 << 1)               011 = 8 bpp.

#define CNTL_LCDBPP16          (4 << 1)             100 = 16 bpp 

#define CNTL_LCDBPP16_565     (6 << 1)           110 = 16 bpp, 5:6:5 mode

#define CNTL_LCDBPP24          (5 << 1)             101 = 24 bpp (TFT panel only).

#define CNTL_LCDBW          (1 << 4)                  STN LCD 单色/彩色选择 。1:彩色,0:单色

#define CNTL_LCDTFT          (1 << 5)                 LCD 显示屏 TFT 类型选择。0: STN 显示屏,使用灰度定标器。1: TFT 显示屏,不使用灰度定标器

#define CNTL_LCDMONO8          (1 << 6)            这个位决定单色 STN LCD 是使用 4 位并行接口还是 8 位并行接口。0:4位接口。

#define CNTL_LCDDUAL          (1 << 7)               STN  单 LCD 显示屏或双 LCD 显示屏选择 。0=单屏

#define CNTL_BGR          (1 << 8)                      色彩模式选择,0=RGB:正常输出,1=BGR:红色和蓝色交换位置

#define CNTL_BEBO          (1 << 9)                    控制内存中字节的存储顺序: 0=小端字节顺序,1=大端字节顺序

#define CNTL_BEPO          (1 << 10)                    设定象素排序的方式,0=采用小端象素排序,1=采用大端象素排序

#define CNTL_LCDPWR          (1 << 11)               LCD 电源使能。1=LCD 显示屏通电且 LCDV[23:0]信号使能

#define CNTL_LCDVCOMP(x)     ((x) << 12)          LCD 纵向比较中断.00=垂直同步脉冲有效,01=垂直后沿开始,10=有效视频图像开始,11=垂直前沿开始

#define CNTL_LDMAFIFOTIME     (1 << 15)          DMA FIFO请求延时

#define CNTL_WATERMARK          (1 << 16)        LCD DMA FIFO 水位线.0:当 DMA  FIFO 包含 4 个或 4 个以上空单元时产生一个 LCD DMA 请求  .1:8个。

一般要初始化 CNTL_LCDBPP16_565、 CNTL_LCDTFT、CNTL_BGR、CNTL_LCDVCOMP(x) 。CNTL_LCDEN和CNTL_LCDPWR会被驱动自动置位。

CNTL_LCDVCOMP(x)一般初始化为CNTL_LCDVCOMP(1).

clcd_panel的bpp成员是传递给frambuffer子系统的。感觉这个地方有点重复,cntl中本来就已经有了这个信息。

bpp一般是16 或者24.

clcd_panel的其它成员没看到具体用法。

如何从LCD数据手册中计算参数

下面主要以16BPP的TFT屏作为例子。有的LCD会给出参数列表,比如下图,可以很清楚的在红框中找到需要的参数,取“type”典型值即可。但是有的LCD并没有直接给出这样的列表,设置某些参数没有给出,这需要通过时序图来确定。



下面以天马的3.5寸TFT液晶屏 TM035KDH03为例进行讲解。

参数计算:



可以看到LCD时钟是28M,所以pixclock=1000000/28

行同步脉冲宽度是一个时钟周期,所以,hsync_len=1

场同步脉冲的宽度是一个行周期,所以vsync_len = 1



上图是一帧图像的显示时序图。的上图显示,up_margin = 13-1=12,, yres= 240,

 整个场周期为263,所以lower_margin= 263-13-240 = 10

同时看到,列同步信号高电平有效,行同步信号也是高电平有效。



上图是一行的时序图。

可以看到,left_margin = 69, xres = 320, right_margin = 408 -320 - 70 = 18

数据在上升沿有效,输出使能是高电平有效。

总计一下上面的参数,得到如下结果:

static struct clcd_panel conn_lcd_panel = {

     .mode          = {

          .name          = "QVGA TM035KDH03",

          .refresh     = 60,

          .xres          = 240,

          .yres          = 320,

          .pixclock     = 35714,

          .left_margin     = 69,

          .right_margin     = 18,

          .upper_margin     = 12,

          .lower_margin     = 10,

          .hsync_len     = 1,

          .vsync_len     = 1,

          .sync          = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,

          .vmode          = FB_VMODE_NONINTERLACED,

     },

     .width          = -1,

     .height          = -1,

     .tim2          = 0,

     .cntl          = ( CNTL_LCDTFT | CNTL_LCDVCOMP(1) | CNTL_LCDBPP16_565),

     .bpp          = 16,

};

计算

HFP: Horizon front porch

  HBP: Horizon back porch

    VFP: Vertical front porch

    VBP: Vertical back porch

  HDP: Horizon display period

    VDP:  Vertical display period

 

HTP = HSYNC + HDP + HFP + HBP

VTR = VSYNC + VDP + VFP + VBP

f dot _ clk = pixel clock

f dot _ clk = f v * VTR * HTP

f v = vertical frequency  (这个是频率,平时见到的很多时候是60HZ)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: