⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s3c2410disp.cpp

📁 混泰CH7023,CH7024,CH7025视频解码芯片
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 2001. Samsung Electronics, co. ltd  All rights reserved.

Module Name:  

Abstract:

	This file implements the S3C2410 LCD function

rev:
	2002.4.4	: First S3C2410 version (kwangyoon LEE, kwangyoon@samsung.com)

	2002.1.31	: CE.NET port (kwangyoon LEE, kwangyoon@samsung.com)

Notes: 
--*/

#include "precomp.h"
#ifdef CLEARTYPE
#include <ctblt.h>
#endif
#include <aablt.h>

DWORD gdwLCDVirtualFrameBase;

/**********************************************************************************************************

	Description:	There are five places in this file modified from display driver 
					in SMDK2410	BSP for using Chrontel Chip, these modified places 
					have been marked with following:
					
					CHANGE(1)
					CHANGE(2)
					CHANGE(3)
					CHANGE(4)
					CHANGE(5) 

	Modified:		2007-5-15	By JUNFENG WANG

					2007-6-25	By JUNFENG WANG

***********************************************************************************************************/

//****************************************** CHANGE(1) BEGIN *********************************************//

I2C g_i2c(CH7025_ADDR);					//I2C object to operate IIC
UART g_uart;							//UART object to operate UART
CHIP_TYPE g_ChipType=CHIP_NUMBER;		//Chrontel Chip type flap variable

//Gate of IIC test:
//#define IIC_TEST_MODE

//CH7023/CH7024 timing define:	//clkdiv,	HA,		HFP,	FBP,	HW,		VA,		VFP,	VBP,	VW
TIMING CH7023_OUTPUT_TIMING  =  { 6,		320,	54,		40,		10,		240,	20,		20,		5}; //320x240

//CH7025 mode timing define:	//clkdiv,	HA,		HFP(HO),HBP,	HW,		VA,		VFP(VO),VBP,	VW
TIMING CH7025_OUTPUT_TIMING  = 	{ 6,		240,	9,		9,		7,		320,	3,		3,		5};// Local LCD screen 

//******************************************* CHANGE(1) END **********************************************//

INSTANTIATE_GPE_ZONES(0x3,"MGDI Driver","unused1","unused2")	// Start with errors and warnings

static	GPE		*gGPE = (GPE*)NULL;
static	ulong	gBitMasks[] = { 0xF800, 0x07E0, 0x001F };		// 565 MODE

static TCHAR gszBaseInstance[256] = _T("Drivers\\Display\\S3C2410\\CONFIG");

#define dim(x)                                  (sizeof(x) / sizeof(x[0]))

// This prototype avoids problems exporting from .lib
BOOL APIENTRY GPEEnableDriver(ULONG engineVersion, ULONG cj, DRVENABLEDATA *data,
							  PENGCALLBACKS  engineCallbacks);

// GWES will invoke this routine once prior to making any other calls into the driver.
// This routine needs to save its instance path information and return TRUE.  If it
// returns FALSE, GWES will abort the display initialization.
BOOL APIENTRY
DisplayInit(LPCTSTR pszInstance, DWORD dwNumMonitors)
{
	DWORD dwStatus;
	HKEY hkDisplay;
	BOOL fOk = FALSE;

    RETAILMSG(0, (_T("SALCD2: display instance '%s', num monitors %d\r\n"),
    	pszInstance != NULL ? pszInstance : _T("<NULL>"), dwNumMonitors));

    if(pszInstance != NULL) {
        _tcsncpy(gszBaseInstance, pszInstance, dim(gszBaseInstance));
    }

	// sanity check the path by making sure it exists
	dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, gszBaseInstance, 0, 0, &hkDisplay);
	if(dwStatus == ERROR_SUCCESS) {
		RegCloseKey(hkDisplay);
		fOk = TRUE;
	} else {
		RETAILMSG(0, (_T("SALCD2: DisplayInit: can't open '%s'\r\n"), gszBaseInstance));
	}

    return fOk;
}

BOOL APIENTRY DrvEnableDriver(ULONG engineVersion, ULONG cj, DRVENABLEDATA *data,
							  PENGCALLBACKS  engineCallbacks)
{
	BOOL fOk = FALSE;

	// make sure we know where our registry configuration is
	if(gszBaseInstance[0] != 0) {
		fOk = GPEEnableDriver(engineVersion, cj, data, engineCallbacks);
	}

	return fOk;
}

//
// Main entry point for a GPE-compliant driver
//

GPE *GetGPE(void)
{
	if (!gGPE)
	{
		gGPE = new S3C2410DISP();
	}

	return gGPE;
}

WORD	TempBuffer[241][320];

S3C2410DISP::S3C2410DISP (void)
{
	RETAILMSG(0, (TEXT("++S3C2410DISP::S3C2410DISP\r\n")));

//****************************************** CHANGE(2) BEGIN *********************************************//
	
	g_ChipType=FindChrontelChip();
	switch(g_ChipType)
	{
	case CHIP_CH7023:
		RETAILMSG(1,(_T("Find CH7023 Chip on Board!!!\r\n")));
		Set2410LCDReg(&CH7023_OUTPUT_TIMING);
		m_nScreenWidth = CH7023_OUTPUT_TIMING.ha;
		m_nScreenHeight = CH7023_OUTPUT_TIMING.va;
		RETAILMSG(1,(_T("m_nScreenWidth=%d,m_nScreenHeight=%d\r\n"),m_nScreenWidth,m_nScreenHeight));
		break;
	case CHIP_CH7025:
		RETAILMSG(1,(_T("Find CH7025 Chip on Board!!!\r\n")));
		Set2410LCDReg(&CH7025_OUTPUT_TIMING);
		m_nScreenWidth = CH7025_OUTPUT_TIMING.ha;
		m_nScreenHeight = CH7025_OUTPUT_TIMING.va;
		RETAILMSG(1,(_T("m_nScreenWidth=%d,m_nScreenHeight=%d\r\n"),m_nScreenWidth,m_nScreenHeight));
		break;
	default:
		RETAILMSG(1,(_T("No chip connect,only choose mode for Ch7025...\n")));
		m_nScreenWidth = 240;
		m_nScreenHeight = 320;
		RETAILMSG(1,(_T("m_nScreenWidth=%d,m_nScreenHeight=%d\r\n"),m_nScreenWidth,m_nScreenHeight));
		break;
	}
//******************************************* CHANGE(2) END **********************************************//
	
	// setup up display mode related constants
	m_colorDepth = 16;
	m_cbScanLineLength = m_nScreenWidth * 2;
	m_FrameBufferSize = m_nScreenHeight * m_cbScanLineLength;
	
	// memory map register access window, frame buffer, and program LCD controller
	InitializeHardware();

#ifdef ROTATE
	m_iRotate = 0;
	SetRotateParms();
#endif //ROTATE	

	// setup ModeInfo structure
	m_ModeInfo.modeId = 0;
	m_ModeInfo.width = m_nScreenWidth;
	m_ModeInfo.height = m_nScreenHeight;
	m_ModeInfo.Bpp = m_colorDepth;
	m_ModeInfo.format = gpe16Bpp;
	m_ModeInfo.frequency = 60;	// ?
	m_pMode = &m_ModeInfo;
	
	// allocate primary display surface
#ifdef 	ROTATE
	m_pPrimarySurface = new GPESurfRotate(m_nScreenWidthSave, m_nScreenHeightSave, (void*)(m_VirtualFrameBuffer), m_cbScanLineLength, m_ModeInfo.format);
#else
	m_pPrimarySurface = new GPESurf(m_nScreenWidth, m_nScreenHeight, (void*)(m_VirtualFrameBuffer), m_cbScanLineLength, m_ModeInfo.format);	
#endif //!ROTATE
	memset ((void*)m_pPrimarySurface->Buffer(), 0x0, m_FrameBufferSize);

	// init cursor related vars
	m_CursorVisible = FALSE;
	m_CursorDisabled = TRUE;
	m_CursorForcedOff = FALSE;
	memset (&m_CursorRect, 0x0, sizeof(m_CursorRect));
	m_CursorBackingStore = NULL;
	m_CursorXorShape = NULL;
	m_CursorAndShape = NULL;

#ifdef CLEARTYPE
	HKEY  hKey;
	DWORD dwValue;
	ULONG ulGamma = DEFAULT_CT_GAMMA;	
	
	if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_LOCAL_MACHINE,szGamma,0, NULL,0,0,0,&hKey,&dwValue))
	{
	    if (dwValue == REG_OPENED_EXISTING_KEY)
	    {
		DWORD dwType = REG_DWORD;
		DWORD dwSize = sizeof(LONG);
		if (ERROR_SUCCESS == RegQueryValueEx(hKey,szGammaValue,0,&dwType,(BYTE *)&dwValue,&dwSize))
		{
		    ulGamma = dwValue;
		}
	    } 
	    else if (dwValue == REG_CREATED_NEW_KEY )
	    {
		RegSetValueEx(hKey,szGammaValue,0,REG_DWORD,(BYTE *)&ulGamma,sizeof(DWORD));
	    }
	    RegCloseKey(hKey);
	}

	SetClearTypeBltGamma(ulGamma);
	SetClearTypeBltMasks(gBitMasks[0], gBitMasks[1], gBitMasks[2]);
#endif //CLEARTYPE	

//****************************************** CHANGE(3) BEGIN *********************************************//

//Test IIC read and write ( EPPROM and CHIP)
#ifdef IIC_TEST_MODE
	for(int i=0;i<26;i++)
		g_uart.SendByte('A'+i);
	g_uart.GetKey();
	RETAILMSG(1,(_T("Now to test the I2C read and write...\n\rChoices:\r\n")));
	RETAILMSG(1,(_T("r(R):read 8 byte from 0x00 to 0x07...\r\n")));
	RETAILMSG(1,(_T("w(W):write 8 byte from 0x00 to 0x07 with index...\r\n")));
	RETAILMSG(1,(_T("m(M):change the slave address...\r\n")));
	RETAILMSG(1,(_T("q(Q):quit..\r\n")));
	UCHAR cValue,fQuit;
	int j,k;
	fQuit=0;
	while(1)
	{
	if(fQuit)
		break;
	RETAILMSG(1,(_T("Please press the key as you want to do...\r\n")));
	switch(g_uart.GetKey())
	{
	case 'q':
	case 'Q':
		fQuit=1;
		break;
	case 'r':
	case 'R':
		for(j=0;j<8;j++)
		{
			g_i2c.GetReg((UCHAR)j,&cValue);
			RETAILMSG(1,(_T("READ:reg[0x%.2x]=0x%.2x\r\n"),j,cValue));
		}
		break;
	case 'w':
	case 'W':
		for(k=0;k<8;k++)
		{
			g_i2c.SetReg((UCHAR)k,(UCHAR*)&k);
			RETAILMSG(1,(_T("WRITE:reg[0x%.2x]=0x%.2x\r\n"),k,k));
		}
		break;
	case 'm':
	case 'M':
		RETAILMSG(1,(_T("Please select one slave address:\r\n")));
		RETAILMSG(1,(_T("a(A):0xA0   b(B):0xEC\r\n")));
		switch(g_uart.GetKey())
		{
		case 'a':
		case 'A':
			g_i2c.SetChipAddr((UCHAR)0xA0);
			break;

		case 'b':
		case 'B':
			g_i2c.SetChipAddr((UCHAR)0xEC);
			break;

		default:
			RETAILMSG(1,(_T("you input is invalid,nothing has been done!\r\n")));
			break;
		}
		break;
	default:
		RETAILMSG(1,(_T("invalid! please input again...\r\n")));
		break;
	}
	}
	RETAILMSG(1,(_T("test end...\r\n")));
#endif
	//I2C test end

	//Now to initialize the chrontel chip
	RETAILMSG(1,(_T("\r\nNow to initialize the Chrontel Chip...\n\n")));
	InitChrontelChip(g_ChipType);

//******************************************* CHANGE(3) END **********************************************//

	RETAILMSG(0, (TEXT("--S3C2410DISP::S3C2410DISP\r\n")));
}

//****************************************** CHANGE(4) BEGIN *********************************************//

//Define 4 member functions: Get2410LCDReg(), Set2410LCDReg(), DelayNS() and CleanBuffer():
void S3C2410DISP::Get2410LCDReg(PTIMING tm)
{
	switch(g_ChipType)
	{
	case CHIP_CH7023:
		*tm=CH7023_OUTPUT_TIMING;
		break;
	case CHIP_CH7025:
		*tm=CH7025_OUTPUT_TIMING;
		break;
	default:
		break;
	}
}
void S3C2410DISP::Set2410LCDReg(PTIMING tm)
{
//	Check parameter:
	RETAILMSG(1,(_T("\nCheck timing------\nclkdiv=%d\ntm.ha=%d\rtm.va=%d\ntm.hfp=%d\rtm.vfp=%d\ntm.hw=%d\rtm.vw=%d\ntm.hbp=%d\rtm.vbp=%d\r\n"),
						tm->clkdiv,tm->ha,tm->va,tm->hfp,tm->vfp,tm->hw,tm->vw,tm->hbp,tm->vbp));

	RETAILMSG(1,(_T("Set2410LCDReg invoked\n\r")));
	volatile S3C2410_IOPreg *s2410IOP = (volatile S3C2410_IOPreg *)IOP_BASE; //defined in s2410.h
    volatile S3C2410_LCDreg *s2410LCD = (volatile S3C2410_LCDreg *)LCD_BASE; //defined in s2410.h  

	//turn off the LCD controller
	s2410LCD->rLCDCON1 &= 0xFFFFFFFE;

    // Assume that the LCD port not initialized,so setup LCD port ...
    s2410IOP->rGPCUP  = 0xFFFFFFFF;
    s2410IOP->rGPCCON = 0xAAAAAAAA;
    s2410IOP->rGPDUP  = 0xFFFFFFFF;
    s2410IOP->rGPDCON = 0xAAAAAAAA;
    s2410IOP->rGPGCON &= ~(3 << 8);                 /* Set LCD_PWREN as output                          */
    s2410IOP->rGPGCON |=  (1 << 8);
									
	//initialize...
    s2410LCD->rLCDCON1 &= 0xFFFFFFFE;
	//reset the start buffer address 
	s2410LCD->rLCDSADDR1=0x00000000;
	s2410LCD->rLCDSADDR2=0x00000000;
	s2410LCD->rLCDSADDR3=0x00000000;

	//set:
	// assume LCD control not initialized,so set LCD controller registers
	s2410LCD->rLCDCON1= (tm->clkdiv     << 8) |
						(0				<< 7) |
						(3				<< 5) |
						(12				<< 1) |
						(0				<< 0) ; 
    // TFT LCD panel,16bpp TFT,ENVID=off
	s2410LCD->rLCDCON2= ((tm->vbp-1)	<<24) |
						((tm->va-1)		<<14) |
						((tm->vfp-1)	<< 6) |
						((tm->vw-1)		<< 0) ;

	s2410LCD->rLCDCON3= ((tm->hbp-1)	<<19) |
						((tm->ha-1)		<< 8) |
						((tm->hfp-1)	<< 0) ;

	s2410LCD->rLCDCON4= (13				<< 8) |
						((tm->hw-1)		<< 0) ;

	s2410LCD->rLCDCON5= (1				<<11) |
						(0				<< 9) |
						(0				<< 8) |
						(0				<< 3) |
						(1				<< 0) ;	//FRM5:6:5,HSYNC and VSYNC are inverted

	s2410LCD->rLCDSADDR1=((FRAMEBUF_DMA_BASE>>22)<<21)|M5D(FRAMEBUF_DMA_BASE>>1);
	s2410LCD->rLCDSADDR2=M5D( (FRAMEBUF_DMA_BASE+((tm->ha)*(tm->va)*2))>>1 );
	s2410LCD->rLCDSADDR3=(0<<11)|(tm->ha);
	s2410LCD->rLCDINTMSK|=(3); // MASK LCD Sub Interrupt
	s2410LCD->rLPCSEL&=(~7); // Disable LPC3600
	s2410LCD->rTPAL=0; // Disable Temp Palette

	DelayNS(5000);

	s2410LCD->rTPAL = 0x0;

	s2410LCD->rLCDCON1 |= 1; // Enable lcd ouput
}

void S3C2410DISP::CleanBuffer(LPVOID buf)
{
	memset(buf,0,FRAMEBUF_SIZE);
}

void  S3C2410DISP::DelayNS(unsigned int  dly)
{  
	unsigned int i;

   	for(; dly>0; dly--) 
       for(i=0; i<50000; i++);
}

//******************************************* CHANGE(4) END **********************************************//

void S3C2410DISP::InitializeHardware (void)
{
	WORD *ptr;
	DWORD index;
	HKEY hkDisplay = NULL;
	DWORD dwLCDPhysicalFrameBase;
	DWORD dwStatus, dwType, dwSize;

	RETAILMSG(0, (_T("++S3C2410DISP::InitializeHardware\r\n")));

	// open the registry key and read our configuration
	dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, gszBaseInstance, 0, 0, &hkDisplay);
	dwType = REG_DWORD;

	if(dwStatus == ERROR_SUCCESS && dwType == REG_DWORD) {
		dwSize = sizeof(DWORD);
		dwStatus = RegQueryValueEx(hkDisplay, _T("LCDVirtualFrameBase"), NULL, &dwType, 
			(LPBYTE) &gdwLCDVirtualFrameBase, &dwSize);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -