目标:在5.0BSP中加入对800x480分辨率的支持。在 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\S2410LCD\s2410disp.cpp
4. …\WINCE420\PLATFORM\SMDK2410\FILES\config.bib
5. …\ WINCE420\PLATFORM\SMDK2410\FILES\platform.reg
注:蓝色字体为加入或修改的http://hi.baidu.com/luv_resplendent/blog/item/39ad08ecf3dd912263d09f23.html
1. s2440.h
http://hi.baidu.com/mikenoodle/blog/item/a9d1a30fcdd187eaab6457d4.html
// Make sure this matches entry in config.bib
// These buffs are now offset via a constant
#define DMA_BUFFER_BASE 0xAC000000
#define DMA_PHYSICAL_BASE 0x30000000 // S3C2440X01
#define AUDIO_DMA_BUFFER_BASE (DMA_BUFFER_BASE + 0x00002000)
#define AUDIO_DMA_BUFFER_PHYS (DMA_PHYSICAL_BASE + 0x00002000)
#define SDI_DMA_BUFFER_BASE (DMA_BUFFER_BASE + 0x00028000)
#define SDI_DMA_BUFFER_PHYS (DMA_PHYSICAL_BASE + 0x00028000)
#define FRAMEBUF_BASE (DMA_BUFFER_BASE + 0x00100000)
#define FRAMEBUF_DMA_BASE (DMA_PHYSICAL_BASE + 0x00100000)
// Define LCD type of S3C2400X01
#define STN8BPP 1
#define TFT16BPP 2
#define LCDTYPE TFT16BPP // define LCD type as upper definition.
#define TFT240_320 1
#define TFT640_480 4
#define TFT480_272 8
#define TFT800_480 16 //这里要定义一个宏
//#define LCD_TYPE TFT480_272
//#define LCD_TYPE TFT240_320
//#define LCD_TYPE TFT640_480
#define LCD_TYPE TFT800_480
#if (LCD_TYPE == TFT640_480)
#define LCD_XSIZE_TFT (640)
#define LCD_YSIZE_TFT (480)
#elif (LCD_TYPE == TFT240_320)
#define LCD_XSIZE_TFT (240)
#define LCD_YSIZE_TFT (320)
#elif (LCD_TYPE == TFT480_272)
#define LCD_XSIZE_TFT (480)
#define LCD_YSIZE_TFT (272)
#elif (LCD_TYPE == TFT800_480)
#define LCD_XSIZE_TFT (800)
#define LCD_YSIZE_TFT (480)
#endif
#if (LCD_TYPE == TFT640_480)
#define SCR_XSIZE_TFT (LCD_XSIZE_TFT*2)
#define SCR_YSIZE_TFT (LCD_YSIZE_TFT*2)
#elif (LCD_TYPE == TFT240_320)
#define SCR_XSIZE_TFT (640) //for virtual screen
#define SCR_YSIZE_TFT (480)
#elif (LCD_TYPE == TFT480_272)
#define SCR_XSIZE_TFT (LCD_XSIZE_TFT) //for virtual screen
#define SCR_YSIZE_TFT (LCD_YSIZE_TFT)
#elif (LCD_TYPE == TFT800_480)
#define SCR_XSIZE_TFT (LCD_XSIZE_TFT*2) //for virtual screen
#define SCR_YSIZE_TFT (LCD_YSIZE_TFT*2)
#endif
#if (LCD_TYPE == TFT640_480)
#define HOZVAL_TFT (LCD_XSIZE_TFT-1)
#define LINEVAL_TFT (LCD_YSIZE_TFT-1)
#elif (LCD_TYPE == TFT240_320)
#define HOZVAL_TFT (LCD_XSIZE_TFT-1)
#define LINEVAL_TFT (LCD_YSIZE_TFT-1)
#elif (LCD_TYPE == TFT480_272)
#define HOZVAL_TFT (LCD_XSIZE_TFT-1)
#define LINEVAL_TFT (LCD_YSIZE_TFT-1)
#elif (LCD_TYPE == TFT800_480)
#define HOZVAL_TFT (LCD_XSIZE_TFT-1)
#define LINEVAL_TFT (LCD_YSIZE_TFT-1)
#endif
...这里省略了部分代码
#elif (LCD_TYPE == TFT800_480)
#define MVAL (13)
#define MVAL_USED (0) //wujiarui
#define VBPD ((3)&0xff)
#define VFPD ((43-1)&0xff)
#define VSPW ((4-1) &0x3f)
#define HBPD ((48)&0x7f)
#define HFPD ((16)&0xff)
#define HSPW ((128)&0xff)
#endif
#define CLKVAL_TFT (6)
2. config.bib
CAMERA 8c088000 00140000 RESERVED
; DISPLAY 8c100000 00100000 RESERVED
; DISPLAY 8c1d0000 00030000 RESERVED
DISPLAY 8c100000 00100000 RESERVED ;注意,这的要和reg和s3c2440disp.cpp中的一致
3. platform.reg
[HKEY_LOCAL_MACHINE\Drivers\Display\S3C2440\CONFIG]
"DisplayDll"="s3c2440disp.dll"
"LCDVirtualFrameBase"=dword:ac100000
"LCDPhysicalFrameBase"=dword:30100000
4. s3c2440disp.cpp
#include "precomp.h"
#ifdef CLEARTYPE
#include <ctblt.h>
#endif
#include <aablt.h>
#define TFT800_480 16
#define TFT240_320 1
#define TFT640_480 4
#define LCD_TYPE TFT800_480
#if (LCD_TYPE == TFT640_480)
WORD TempBuffer[641][480];
#elif (LCD_TYPE == TFT240_320)
WORD TempBuffer[241][320];
#elif (LCD_TYPE == TFT800_480)
WORD TempBuffer[801][320];
#endif
#if (LCD_TYPE == TFT640_480)
m_nScreenWidth = 640;
m_nScreenHeight = 480;
#elif (LCD_TYPE == TFT240_320)
m_nScreenWidth = 240;
m_nScreenHeight = 320;
#elif (LCD_TYPE == TFT800_480)
m_nScreenWidth = 800;
m_nScreenHeight = 480;
RETAILMSG(1,(TEXT("Display mode 800*480.\r\n")));
#endif
}
#elif (LCD_TYPE == TFT240_320)
m_VirtualFrameBuffer = (DWORD)VirtualAlloc(0, (0x30000), 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, (0x30000), PAGE_READWRITE | PAGE_NOCACHE))
{
RETAILMSG(0, (TEXT("m_VirtualFrameBuffer is not mapped\n\r")));
VirtualFree((PVOID)m_VirtualFrameBuffer, 0, MEM_RELEASE);
return;
}
#elif (LCD_TYPE == TFT800_480)
m_VirtualFrameBuffer = (DWORD)VirtualAlloc(0, (0x100000), 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, (0x100000), PAGE_READWRITE | PAGE_NOCACHE))
{
RETAILMSG(0, (TEXT("m_VirtualFrameBuffer is not mapped\n\r")));
VirtualFree((PVOID)m_VirtualFrameBuffer, 0, MEM_RELEASE);
return;
}
#endif
#elif (LCD_TYPE == TFT240_320)
for (index = 0; index < 320*240; index++)
{
if(index < 3200)
{
ptr[index] = 0xf800;
}
else if(index < 6400)
{
ptr[index] = 0x07e0;
}
else if(index < 9600)
{
ptr[index] = 0x001f;
}
else
{
ptr[index] = 0xffff;
}
}
#elif (LCD_TYPE == TFT800_480)
for (index = 0; index < 800*480; index++)
{
if(index < 800*120)
{
ptr[index] = 0xf800;
}
else if(index < 800*120*2)
{
ptr[index] = 0x07e0;
}
else if(index < 800*120*3)
{
ptr[index] = 0x001f;
}
else
{
ptr[index] = 0xffff;
}
}
#endif
5. cfw.c
修改
static void InitDisplay()
为
static void InitDisplay()
{
int i, j;
volatile IOPreg *s2440IOP;
volatile LCDreg *s2440LCD;
s2440IOP = (IOPreg *)IOP_BASE;
s2440LCD = (LCDreg *)LCD_BASE;
// LCD port initialize.
s2440IOP->rGPCUP = 0xFFFFFFFF;
s2440IOP->rGPCCON = 0xAAAAAAAA; //GPC0 ouput
s2440IOP->rGPDUP = 0xFFFFFFFF;
s2440IOP->rGPDCON = 0xAAAAAAAA;
s2440IOP->rGPGUP=s2440IOP->rGPGUP&(~(1<<4))|(1<<4); // Pull-up disable
s2440IOP->rGPGCON=s2440IOP->rGPGCON&(~(3<<8))|(3<<8); //GPG4=LCD_PWREN
s2440LCD->rLCDCON1 = (1 << 8) | /* VCLK = HCLK / ((CLKVAL + 1) * 2) -> About 7 Mhz */ // ;;; SHL
(MVAL_USED << 7) | /* 0 : Each Frame */
(3 << 5) | /* TFT LCD Pannel */
(12 << 1) | /* 16bpp Mode */
(0 << 0) ; /* Disable LCD Output */
s2440LCD->rLCDCON2 = (VBPD << 24) | /* VBPD : 1 */
(LINEVAL_TFT << 14) | /* Virtical Size : 320 - 1 */
(VFPD << 6) | /* VFPD : 2 */
(VSPW << 0) ; /* VSPW : 1 */
s2440LCD->rLCDCON3 = (HBPD << 19) | /* HBPD : 6 */
(HOZVAL_TFT << 8) | /* HOZVAL_TFT : 240 - 1 */
(HFPD << 0) ; /* HFPD : 2 */
s2440LCD->rLCDCON4 = (MVAL << 8) | /* MVAL : 13 */
(HSPW << 0) ; /* HSPW : 4 */
s2440LCD->rLCDCON5 = (0 << 12) | /* BPP24BL : LSB valid */
(1 << 11) | /* FRM565 MODE : 5:6:5 Format */
(0 << 10) | /* INVVCLK : VCLK Falling Edge */
(1 << 9) | /* INVVLINE : Inverted Polarity */
(1 << 8) | /* INVVFRAME : Inverted Polarity */
(0 << 7) | /* INVVD : Normal */
(0 << 6) | /* INVVDEN : Normal */
(0 << 5) | /* INVPWREN : Normal */
(0 << 4) | /* INVENDLINE : Normal */
(1 << 3) | /* PWREN : Disable PWREN */
(0 << 2) | /* ENLEND : Disable LEND signal */
(0 << 1) | /* BSWP : Swap Disable */
(1 << 0) ; /* HWSWP : Swap Enable */
s2440LCD->rLCDSADDR1 = ((FRAMEBUF_DMA_BASE >> 22) << 21) |
((M5D(FRAMEBUF_DMA_BASE >> 1)) << 0);
s2440LCD->rLCDSADDR2 = M5D((FRAMEBUF_DMA_BASE + (LCD_XSIZE_TFT * LCD_YSIZE_TFT * 2)) >> 1);
s2440LCD->rLCDSADDR3 = (((LCD_XSIZE_TFT - LCD_XSIZE_TFT) / 1) << 11) | (LCD_XSIZE_TFT / 1);
s2440LCD->rTCONSEL &= ~(0x7); // ;;; SHL
s2440LCD->rLCDINTMSK |= (3);
s2440LCD->rTPAL = 0x0;
//s2440LCD->rLCDCON1 &= 0xfffe;
s2440LCD->rLCDCON1 |= 0x1;
RETAILMSG(1,(TEXT("LCD OUTPUT MODE 800*480.\r\n")));
}
做上述改动后就支持800x480的分辨率了
在使用时发现5V/1A的电源功率不足,导致程序工作不正常
后改用5V/6A的电源就好了