[置顶] fl2440的U-boot-2010.09移植(七)LCD的支持

一、LCD时序配置

     fl2440开发板的LCD是3.5寸屏型号是WXCAT35-TG3#001,这是一款320x240分辨率的TFT LCD屏,先来了解一下TFT LCD的时序如下:

[置顶] fl2440的U-boot-2010.09移植(七)LCD的支持_第1张图片

1 TFT LCD时序

1VSYNC信号来一个脉冲时,表示一帧的开始

2 VSPW表示VSYNC信号的脉冲宽度为(VSPW+1)个HSYNC信号周期,即(VSPW+1)行,这(VSPW+1)行的数据无效。

3VSYNC信号脉冲之后,还要经过(VBPD+1)个(HSYNC)信号周期,有效的行数据才出现。所以,在VSYNC信号有效之后,总共还要经过(VSPW+1+VBPD+1)个无效行,

4)随后连续发出(LINEVAL+1)行的有效数据

5)最后是(VFPD+1)个无效行,完整的一帧结束,紧接着就是下一帧的数据了(即下一个VSYNC信号)。

6HSYNC信号有效时,表示一行数据的开始

7 HSPW表示HSYNC信号的脉冲宽度为(HSPW+1)个VCLK信号周期,即(HSPW+1)个像素,这(HSPW+1)个像素的数据无效。

8HSYNC信号脉冲之后,还要经过(HBPD+1)个VCLK信号周期,有效的像素数据才会出现。所以,在HSYNC信号有效之后,总共还要经过(HSPW + 1 + HBPD + 1)个无效的像素,第一个有效像素才出现。

9)随后即连续发出(HOZVAL+1)个像素的有效数据。

10)最后是(HFPD+1)个无效的像素,完整的一行结束,紧接着就是下一行的数据了(即下一个HSYNC信号)。

TFT LCD的正常工作主要需要配置S3C2440的寄存器LCDCON1~LCDCON5

二、u-boot支持LCD的配置工作

首先要添加一个文件,driver/video/s3c2410_fb.c,其内容为:
/*
 * (C) Copyright 2006 by OpenMoko, Inc.
 * Author: Harald Welte <[email protected]>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */
#include <common.h>
 
#if defined(CONFIG_VIDEO_S3C2410)||defined(CONFIG_VIDEO_S3C2440)
 
#include <video_fb.h>
#include <asm/arch/s3c2410.h>

#include "videomodes.h"
/*
 * Export Graphic Device
 */
static GraphicDevice smi;
 
#define VIDEO_MEM_SIZE  0x200000        /* 240x320x16bit = 0x25800 bytes */
 
extern void board_video_init( GraphicDevice *pGD);
/*
 * Add by yanghao
 */
/*******************************************************************************
 *
 * Init video chip with common Linux graphic modes (lilo)
 */
void *video_hw_init (void)
{
    struct s3c24x0_lcd * const lcd = s3c24x0_get_base_lcd();
    GraphicDevice *pGD = (GraphicDevice *)&smi;
    int videomode;
    unsigned long t1, hsynch, vsynch;
    char *penv;
    int tmp, i, bits_per_pixel;
    struct ctfb_res_modes *res_mode;
    struct ctfb_res_modes var_mode;
//    unsigned char videoout;
 
    /* Search for video chip */
    printf("Video: ");
    tmp = 0;
 
         videomode = CONFIG_SYS_DEFAULT_VIDEO_MODE;
         /* get video mode via environment */
         if ((penv = getenv ("videomode")) != NULL) {
                 /* deceide if it is a string */
                 if (penv[0] <= '9') {
                         videomode = (int) simple_strtoul (penv, NULL, 16);
                         tmp = 1;
                 }
         } else {
                 tmp = 1;
         }
         if (tmp) {
                 /* parameter are vesa modes */
                 /* search params */
                 for (i = 0; i < VESA_MODES_COUNT; i++) {
                         if (vesa_modes[i].vesanr == videomode)
                                 break;
                 }
                 if (i == VESA_MODES_COUNT) {
                         printf ("no VESA Mode found, switching to mode 0x%x ", CONFIG_SYS_DEFAULT_VIDEO_MODE);
                         i = 0;
                }
                 res_mode =
                         (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].
                                                                  resindex];
                 bits_per_pixel = vesa_modes[i].bits_per_pixel;
         } else {
 
                res_mode = (struct ctfb_res_modes *) &var_mode;
                 bits_per_pixel = video_get_params (res_mode, penv);
         }
 
         /* calculate hsynch and vsynch freq (info only) */
         t1 = (res_mode->left_margin + res_mode->xres +
               res_mode->right_margin + res_mode->hsync_len) / 8;
         t1 *= 8;
         t1 *= res_mode->pixclock;
         t1 /= 1000;
         hsynch = 1000000000L / t1;
         t1 *=
                 (res_mode->upper_margin + res_mode->yres +
                  res_mode->lower_margin + res_mode->vsync_len);
         t1 /= 1000;
         vsynch = 1000000000L / t1;
 
         /* fill in Graphic device struct */
         sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
                  res_mode->yres, bits_per_pixel, (hsynch / 1000),
                  (vsynch / 1000));
         printf ("%s\n", pGD->modeIdent);
         pGD->winSizeX = res_mode->xres;
         pGD->winSizeY = res_mode->yres;
         pGD->plnSizeX = res_mode->xres;
         pGD->plnSizeY = res_mode->yres;
             
         switch (bits_per_pixel) {
         case 8:
                 pGD->gdfBytesPP = 1;
                 pGD->gdfIndex = GDF__8BIT_INDEX;
                 break;
         case 15:
                 pGD->gdfBytesPP = 2;
                 pGD->gdfIndex = GDF_15BIT_555RGB;
                 break;
         case 16:
                 pGD->gdfBytesPP = 2;
                 pGD->gdfIndex = GDF_16BIT_565RGB;
                 break;
         case 24:
                 pGD->gdfBytesPP = 3;
                 pGD->gdfIndex = GDF_24BIT_888RGB;
                 break;
         }
 
         /* statically configure settings */
        pGD->winSizeX = pGD->plnSizeX = 320;
         pGD->winSizeY = pGD->plnSizeY = 240;
         pGD->gdfBytesPP = 2;
         pGD->gdfIndex = GDF_16BIT_565RGB;
 
         pGD->frameAdrs = LCD_VIDEO_ADDR;
         pGD->memSize = VIDEO_MEM_SIZE;
 
         board_video_init(pGD);
 
         lcd->LCDSADDR1 = pGD->frameAdrs >> 1;
 
         /* This marks the end of the frame buffer. */
         lcd->LCDSADDR2 = (lcd->LCDSADDR1&0x1fffff) + (pGD->winSizeX+0) * pGD->winSizeY;
         lcd->LCDSADDR3 = (pGD->winSizeX & 0x7ff);
 
         /* Clear video memory */
         memset((void *)pGD->frameAdrs, 0, pGD->memSize);
 
         /* Enable  Display  */
         lcd->LCDCON1 |= 0x01;   /* ENVID = 1 */
 
         return ((void*)&smi);
 } 
 #endif /* CONFIG_VIDEO_S3C2410 */

修改driver/video/videomodes.h文件第25行左右为:

#ifndef CONFIG_SYS_DEFAULT_VIDEO_MODE
//#define CONFIG_SYS_DEFAULT_VIDEO_MODE 0x301


#define CONFIG_SYS_DEFAULT_VIDEO_MODE	0x211
#endif

紧接着修改driver/video/videomodes.h第81行左右为:

#define RES_MODE_1280x1024	5
#define RES_MODE_240x320        6	
#define RES_MODES_COUNT		7

#define VESA_MODES_COUNT 20

在driver/video/videomodes..c文件struct ctfb_vesa_modes vesa_modes定义中添加(第78行左右)本开发板LCD的相关配置:

        {0x211, RES_MODE_240x320, 16},

在driver/video/videomodes..c文件struct ctfb_res_modes res_mode_init定义中添加(第100行左右)本开发板LCD的相关配置:

 {320, 240, 158025, 58, 15, 3, 5, 8, 15, 0, FB_VMODE_NONINTERLACED},

紧接着修改driver/video/Makefile文件,在41行后添加:

COBJS-$(CONFIG_VIDEO_S3C2440) += videomodes.o
COBJS-$(CONFIG_VIDEO_S3C2440) += s3c2410_fb.o

最后,修改文件board/fl2440/fl2440.c,在文件最后添加:

/*
 * Add by yanghao
 */
#if defined(CONFIG_VIDEO_S3C2440)
#define MVAL                   (13)
#define MVAL_USED              (0)
#define INVVDEN                (1)
#define BSWP                   (0)
#define HWSWP                  (1)
//TFT 240320
#define LCD_XSIZE_TFT_240320   (320)
#define LCD_YSIZE_TFT_240320   (240)
//TFT 240320
#define HOZVAL_TFT_240320      (LCD_XSIZE_TFT_240320-1)
#define LINEVAL_TFT_240320     (LCD_YSIZE_TFT_240320-1)
//Timing parameter for WXCAT35-TG#001
#define VBPD_240320            (3)
#define VFPD_240320            (5)
#define VSPW_240320            (15)
#define HBPD_240320            (58)
#define HFPD_240320            (15)
#define HSPW_240320_WXCAT35    (8)//adjust the horizontal displacement of the screen


#define CLKVAL_TFT_240320      (7)
//FCLK = 405MHZ, HCLK = 101.25MHZ, VCLK=4602272HZ
void board_video_init(GraphicDevice *pGD)
{
    struct s3c24x0_lcd * const lcd = s3c24x0_get_base_lcd();
   /*Configuration for fl2440*/
    lcd->LCDCON1 = (CLKVAL_TFT_240320 <<8)|(MVAL_USED <<7)|(3<<5)|(12<<1)|0;
   lcd->LCDCON2 = (VBPD_240320<<24)|(LINEVAL_TFT_240320<<14)|(VFPD_240320<<6)|(VSPW_240320);
   lcd->LCDCON3 = (HBPD_240320<<19)|(HOZVAL_TFT_240320<<8)|(HFPD_240320);
   lcd->LCDCON4 = (MVAL<<8)|(HSPW_240320_WXCAT35);
   lcd->LCDCON5 = (1<<11)|(1<<9)|(1<<8)|(1<<3)|(BSWP<<1)|(HWSWP);
   lcd->LPCSEL = 0x00000000;
}
#endif /*CONFIG_VIDEO_S3C2440*/

最后还需要在开发板配置文件中添加LCD屏支持的宏定义,修改文件include/configs/fl2440.h文件,在文件中添加:

#include <video_fb.h> //头文件定义处添加
/*****************add by yanghao support LCD文件末尾处添加********************/
/*LCD support*/
#define CONFIG_VIDEO_S3C2440     1
#define CONFIG_VIDEO_LOGO        1
#define CONFIG_VIDEO_BMP_LOGO           1
#define VIDEO_FB_16BPP_WORD_SWAP       1
#define CONFIG_CMD_BMP                  1
//#define CONFIG_LCD               1
#define CONFIG_VIDEO               1
#define CONFIG_CFB_CONSOLE       1
#define CFG_CONSOLE_INFO_QUIET        //support display of console information at boot

#define LCD_VIDEO_ADDR          0x33b00000

/*for PC-keyboard*/
#define VIDEO_KBD_INIT_FCT      0
/*for PC-keyboard*/

#define VIDEO_TSTC_FCT          serial_tstc
#define VIDEO_GETC_FCT          serial_getc

#define CONFIG_SERIAL_MULTI     1
/*LCD support*/


重新上电后,uboot的输出就都显示在LCD上了,我们的输入还是选择的串口输入,输入信息也都显示在LCD屏之上效果图如下:

[置顶] fl2440的U-boot-2010.09移植(七)LCD的支持_第2张图片

我把uboot的原始显示图片给替换掉了,故显示如上,图片上有些个人信息被我抹掉了。

你可能感兴趣的:(c,struct,video,null,search,2010)