WinCE LCD驱动编程分析

    本文以1024*768分辨率的TFT_16BPP真彩LCD为例,说明在WIN CE 4.2中驱动程序的修改事项,目标板的微处理器是S3C2410A。
该LCD的时序图如下图所示:

Note:LCD时序的参数和时钟相位因不同LCD而异,请参考相应LCD的datasheet.
在WIN CE 4.2中修改LCD驱动程序有五个相关文件,分别是:
1.    …/WINCE420/PLATFORM/SMDK2410/INC/s2410.h
2.    …/WINCE420/PLATFORM/SMDK2410/KERNEL/HAL/cfw.c
3.    …/WINCE420/PLATFORM/SMDK2410/DRIVERS/DISPLAY/S3C2410LCD/s3c2410disp.cpp
4.    …/WINCE420/PLATFORM/SMDK2410/FILES/config.bib
5.    …/ WINCE420/PLATFORM/SMDK2410/FILES/platform.reg

1.  s2410.h
…/WINCE420/PLATFORM/SMDK2410/INC/s2410.h
主要有LCD控制器的寄存器定义、LCD控制器的工作时序定义、分辨率的定义等等。红色部分为修改后的内容:
#define LCDTYPE TFT16BPP #define LCD_TYPE TFTxxx_xxx #define SCR_XSIZE_TFT (1280) #define SCR_YSIZE_TFT (960) #define LCD_XSIZE_TFT (1024) #define LCD_YSIZE_TFT (768) #define VBPD ((2-1)&0xff) #define VFPD ((2-1)&0xff) #define VSPW ((2-1) &0x3f) #define HBPD ((16-1)&0x7f) #define HFPD ((200-1)&0xff) #define HSPW ((16-1)&0xff) #define CLKVAL_TFT (1) //这个值的定义在LCD初始化函数中并不用到,而是直接用数值表示。

2.  cfw.c
…/WINCE420/PLATFORM/SMDK2410/KERNEL/HAL/cfw.c
红色部分为修改后的内容:
static void InitDisplay() { ******** s2410LCD->rLCDCON1=(1<<8)|(MVAL_USED<<7)|(3<<5)|(12<<1)|0; // CLKVAL_TFT = 1 , HCLK = 100MHz -> VCLK = 25MHz //TFT LCD panel //16 bpp for TFT s2410LCD->rLCDCON2=(VBPD<<24)|(LINEVAL_TFT<<14)|(VFPD<<6)|(VSPW); s2410LCD->rLCDCON3=(HBPD<<19)|(HOZVAL_TFT<<8)|(HFPD); s2410LCD->rLCDCON4=(MVAL<<8)|(HSPW); s2410LCD->rLCDCON5= (1<<11)|(0<<10)|(0<<9)|(0<<8)|(0<<7)|(0<<6)|(0<<3)|(0<<1)|(1<<0); //5:6:5 Format //The video data is fetched at VCLK falling edge //VLINE/HSYNC pulse polarity-Normal //VFRAME/VSYNC pulse polarity-Normal //VD (video data) pulse polarity-Normal //VDEN signal polarity-Normal //Disable PWREN signal //Byte swap Disable //Half-Word swap Enable ******** }

3.  s3c2410disp.cpp
…/WINCE420/PLATFORM/SMDK2410/DRIVERS/DISPLAY/S3C2410LCD/s3c2410disp.cpp
红色部分为修改后的内容:
WORD    TempBuffer[1025][768];
S3C2410DISP::S3C2410DISP (void)
{
      ********
      m_nScreenWidth = 1024;
      m_nScreenHeight = 768;
      *********
}
      到此修改工作基本完成,但还要一个问题:1024*768分辨率占用的显示缓冲区大小是:1024*768*2 = 1536 K Bytes,因此要确认所分配的内存空间够不够,是在config.bib文件中定义的。如果以前定义的足够大,后面的步骤可以省略了。

4.  config.bib
…/WINCE420/PLATFORM/SMDK2410/FILES/config.bib
      #define NKNAME NK
      #define NKSTART        8C200000
      #define NKLEN              01D00000
      #define RAMSTART      8E000000
      #define RAMLEN          01F00000
      $(NKNAME)              $(NKSTART)        $(NKLEN)            RAMIMAGE
      RAM                        $(RAMSTART)      $(RAMLEN)        RAM
      AUD_DMA                  8c002000            00002000            RESERVED
      DRV_GLB                  8c010000            00010000            RESERVED
      DBGSER_DMA            8c022000            00002000            RESERVED
      SER_DMA                  8c024000            00002000            RESERVED
      IR_DMA                    8c026000            00002000            RESERVED
      SD_DMA                    8c028000            00008000            RESERVED
      EDBG                        8c030000            00020000            RESERVED
      CPXIPCHAIN              8c050000            00008000            RESERVED
      SLEEP_BUFF              8c058000            00004000            RESERVED
      DISPLAY                    8c100000            00100000            RESERVED
      DISPLAY项就是显示缓冲区的内存空间定义, 8c100000是开始地址, 00100000是大小。可以看出原先只定义了1M Bytes的内存空间给LCD显示缓冲区;而1024*768需要1536 K Bytes的内存空间,因此需要修改这里的定义。但是一旦修改到config.bib文件的内容,将会涉及到很多地方的修改工作,过程比较繁琐。所幸的是我的目标板DISPLAY前面还有0x8C100000-(0x8C058000+0x00004000) = 656K Bytes未分配的内存空间,因此做如下修改:
      AUD_DMA                8c002000            00002000            RESERVED
      DRV_GLB                  8c010000            00010000            RESERVED
      DBGSER_DMA          8c022000            00002000              RESERVED
      SER_DMA                8c024000            00002000              RESERVED
      IR_DMA                    8c026000            00002000              RESERVED
      SD_DMA                  8c028000            00008000            RESERVED
      EDBG                        8c030000            00020000            RESERVED
      CPXIPCHAIN            8c050000            00008000            RESERVED
      SLEEP_BUFF            8c058000            00004000            RESERVED
      ;DISPLAY                  8c100000            00100000            RESERVED
        DISPLAY                  8c060000            001a0000            RESERVED

5.  在(4)中修改了DISPLAY显示缓冲区的开始地址,因此要在“s2410.h”中做相应的修改:
…/WINCE420/PLATFORM/SMDK2410/INC/s2410.h
#define DMA_BUFFER_BASE                    0xAC000000
#define DMA_PHYSICAL_BASE                0x30000000
//#define FRAMEBUF_BASE                      (DMA_BUFFER_BASE + 0x00100000)
//#define FRAMEBUF_DMA_BASE            (DMA_PHYSICAL_BASE + 0x00100000)
#define FRAMEBUF_BASE                        (DMA_BUFFER_BASE + 0x00060000)
#define FRAMEBUF_DMA_BASE              (DMA_PHYSICAL_BASE + 0x00060000)

6.  在(4)中修改了DISPLAY显示缓冲区的大小, 因此要在“s3c2410disp.cpp”中做相应的修改:
…/WINCE420/PLATFORM/SMDK2410/DRIVERS/DISPLAY/S3C2410LCD/s3c2410disp.cpp
红色部分为修改后的内容:
void S3C2410DISP::InitializeHardware (void) { ********* m_VirtualFrameBuffer = (DWORD)VirtualAlloc(0, (0x1A0000), MEM_RESERVE, PAGE_NOACCESS); if (m_VirtualFrameBuffer == NULL) { RETAILMSG(0,(TEXT("m_VirtualFrameBuffer is not allocated/n/r"))); return; } else if (!VirtualCopy((PVOID)m_VirtualFrameBuffer, (PVOID)gdwLCDVirtualFrameBase, (0x1A0000), PAGE_READWRITE | PAGE_NOCACHE)) { RETAILMSG(0, (TEXT("m_VirtualFrameBuffer is not mapped/n/r"))); VirtualFree((PVOID)m_VirtualFrameBuffer, 0, MEM_RELEASE); return; } ********* }

7.  在(4)中修改了DISPLAY显示缓冲区的开始地址,还要对注册表文件“platform.reg”做相应的修改:
…/ WINCE420/PLATFORM/SMDK2410/FILES/platform.reg
[HKEY_LOCAL_MACHINE/Drivers/Display/S3C2410/CONFIG]
"DisplayDll"="s3c2410disp.dll"
;"LCDVirtualFrameBase"=dword:ac100000
;"LCDPhysicalFrameBase"=dword:30100000
"LCDVirtualFrameBase"=dword:ac060000
"LCDPhysicalFrameBase"=dword:30060000

 

你可能感兴趣的:(编程,c,video,buffer,WinCE,Signal)