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.h2. …/WINCE420/PLATFORM/SMDK2410/KERNEL/HAL/cfw.c3. …/WINCE420/PLATFORM/SMDK2410/DRIVERS/DISPLAY/S3C2410LCD/s3c2410disp.cpp4. …/WINCE420/PLATFORM/SMDK2410/FILES/config.bib5. …/ 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 ********} 红色部分为修改后的内容: 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 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 8c 060000 001a 0000 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. 完!