tw88.c

来自「显示屏驱动源代码」· C语言 代码 · 共 2,093 行 · 第 1/4 页

C
2,093
字号
	   
	WriteDecoder( TW88_YUSCALEFINE, (BYTE)(scale));

	scale >>= 8;
	WriteDecoder( TW88_YUSCALELO, (BYTE)(scale));

	scale >>= 8;
	scale <<= 2;
	val = ReadDecoder(TW88_XYSCALEHI) & 0xf3;
	val |= (BYTE)scale;
	WriteDecoder( TW88_XYSCALEHI, val );
}

// PLL = 108MHz *FPLL / 2^17
// FPLL = PLL * 2^17 / 108MHz
void ChangeInternPLL(DWORD _PPF)
{
	BYTE	ppf, CURR, VCO, POST, i;
	DWORD	FPLL;

	#ifdef DEBUG_PC
	dPrintf("\r\n++ ChangeInternPLL ++_PPF:%08lx(%ld) ", _PPF, _PPF);
	#endif

	ppf = _PPF/1000000;

	//----- Frequency Range --------------------
	if     ( ppf < 27 )  { VCO=0; CURR=0; POST=0; }		// step = 0.5MHz
	else if( ppf < 54 )  { VCO=1; CURR=0; POST=1; }		// step = 1.0MHz
	else if( ppf < 108 ) { VCO=2; CURR=0; POST=2; }		// step = 1.0MHz
	else                 { VCO=3; CURR=0; POST=2; }		// step = 1.0MHz

	//----- Get FBDN
	FPLL = (_PPF/100000L)*2427L;

	i = POST;
	for(; i>0; i-- )
		FPLL *= 2;

	FPLL = FPLL / 20L;

	//----- Setting Registers : below is different with 8806
	WriteDecoder( TW88_FPLL0, (FPLL>>16));
	WriteDecoder( TW88_FPLL1, (BYTE)(FPLL>>8));
	WriteDecoder( TW88_FPLL2, (BYTE)FPLL );

	WriteDecoder( TW88_PLL_DIV, (VCO<<4) | (POST<<6) |CURR );
}

/**
#if defined(SUPPORT_PC) || defined(SUPPORT_DTV)
WORD GetYScale(void)
{
	WORD scale;
	BYTE val;

	scale = ReadDecoder(TW88_YUSCALELO);
	val = ReadDecoder(TW88_XYSCALEHI);
	val = (val >> 2) & 0x03;
	scale = scale + val*0x100;

	return scale;
}
#endif // SUPPORT_PC || SUPPORT_DTV
**/

//=============================================================================
//	                             Panel related..
//=============================================================================
/***
#if (defined SERIAL) || (defined WIDE_SCREEN)
void SetPVR(WORD pvr)
{
	BYTE buf;

	// TW8804 write LSByte first
	buf = ReadDecoder(0xbb) & 0x0f;
	buf = buf | ( (pvr>>4) & 0xf0 );
	WriteDecoder( 0xbb, buf );

	WriteDecoder( 0xba, (BYTE)pvr );
}

void SetPHR(WORD phr)
{
	BYTE buf;

	// TW8804 write LSByte first
	buf = ReadDecoder(0xb6) & 0x0f;
	buf = buf | ( (phr>>4) & 0xf0 );
	WriteDecoder( 0xb6, buf );

	WriteDecoder( 0xb5, (BYTE)phr );
}
#endif // SERIAL || WIDE_SCREEN
***/

#if defined( SUPPORT_PC ) || defined( SUPPORT_DTV ) || defined( DEBUG_SETPANEL)
//----- Panel V Resolution
WORD GetPVR(void)
{
/*	WORD	pvr;
	BYTE	val;
	
	val = ReadDecoder(0xbb);
	pvr = (val & 0x70) << 4;		// pppp xxxx -> pppp 0000 0000
	pvr |= ReadDecoder(0xba);

	return pvr;*/
	return PVR_;
}

//----- Panel H Resolution
WORD GetPHR(void)
{
/*	WORD	phr;
	BYTE	val;

	val = ReadDecoder(0xb6);
	phr = (val & 0x70) << 4;		// pppp xxxx -> pppp 0000 0000
	phr |= ReadDecoder(0xb5);

	return phr;*/
	return PHR_;
}

WORD GetHPN(void)
{
	WORD buf;

	ClearEnDet();			// HHY 05.29.03 protect changing during read out

	WriteDecoder(0x5b, 0x50);	// HSYNC period and VSYNC period

	buf = ReadDecoder(0x58);	// from MSB
	buf = buf << 8;
	buf = buf | ReadDecoder(0x57);

	SetEnDet();				// HHY 05.29.03 release protection

	return buf;


}
/*
WORD GetHPN(void)
{
	WORD buf, sum;
	BYTE i;

	//Get HPN 
	WriteDecoder(0x5b, 0x50);	// HSYNC period and VSYNC period

	//HPN

	for(i=0, sum=0; i<5; i++) {		// HHY 1.45 take average 
		buf = (WORD)ReadDecoder(0x58) << 8;// from MSB
		buf |= ReadDecoder(0x57);
		sum += buf;
	}

	buf = (sum+5)/5;

	return buf;
}
*/
WORD GetVPN(void)
{
	WORD buf;

	WriteDecoder(0x5b, 0x50);	// HSYNC period and VSYNC period

	buf = (WORD)ReadDecoder(0x5a);
	buf = buf << 8;
	buf = buf | ReadDecoder(0x59);
	return buf;
}

/*
WORD GetPVP(void)
{
	WORD pvp;

	pvp = ReadDecoder(0xbb);					// pvp = Panel Vsync Period
	pvp = (pvp & 0x0f) << 8;				//
	pvp |= ReadDecoder(0xb7);					//

	return pvp;
}
*/

BYTE GetVBackPorch(void)
{
	return ReadDecoder(0xb9);
}

#endif // SUPPORT_PC

#if defined SUPPORT_PC || defined SUPPORT_DTV
void SetVBackPorch(BYTE val)
{
	#ifdef DEBUG_PC
	dPrintf("\r\n === SetVBackPorch(%d)", (WORD)val);
	#endif
	WriteDecoder(0xb9, val);
}

void SetPVP(WORD period )
{
	BYTE val;

	// TW8804 write LSByte first
	val = ReadDecoder(0xbb);
	val = val & 0xf0;
	val = val | (BYTE)(period>>8);
	WriteDecoder(0xbb, val);
	WriteDecoder(0xb7, (BYTE)period);	// A4, A8 = Panel Vsync Period
}

void SetPHP(WORD php)
{
	BYTE val;

#ifdef DEBUG
       dPrintf("\r\n SetPHP : %04x----------", (WORD)php); // test only
#endif
	// TW8804 write LSByte first
	val = ReadDecoder(0xb6);
	val &= 0xf0;				//0xf8; cut D
	val |= (BYTE)(php>>8);
	WriteDecoder(0xb6, val);
	WriteDecoder(0xb2, php);		// A9, AD = Panel Hsync Cycle
}

#endif //#if defined SUPPORT_PC || defined SUPPORT_DTV

/*WORD GetPHP(void)
{
	WORD php;

	php = ((WORD)ReadDecoder(0xb6) & 0x0f) << 8;
	php += ReadDecoder(0xb2);

	return php;
}

*/


//#if (defined SERIAL) || (defined WIDE_SCREEN)
/*#if (defined WIDE_SCREEN)
WORD GetVactive(void)  // Input V active length
{
	WORD actv;

	actv =   ReadDecoder(CROP_HI) & 0x30;
	actv <<= 4;
	actv |=  ReadDecoder(VACTIVE_LO);

	return actv;
}
#endif // WIDE_SCREEN


WORD GetHCounter1(BYTE field )
{
	WORD counter;

	MeasureAndWait(field);

	WriteDecoder(0x5b, 0xc0);
	counter = (WORD)ReadDecoder(0x58) << 8;
	counter += ReadDecoder(0x57);

	return counter;
}

void SetHInitial(BYTE field, WORD counter)
{
	BYTE val;
	
	if( field==0 ) {	// odd
		val = ReadDecoder( 0xc2 );
		val = ( val & 0xf0 ) |  ( ( counter>>8 ) & 0x0f );
		WriteDecoder(0xc2, val);
		WriteDecoder(0xc0, (BYTE)counter);
	}
	
	else {				// even
		val = ReadDecoder( 0xc2 );
		val = ( val & 0x0f ) |  ( ( counter>>4 ) & 0xf0 );
		WriteDecoder(0xc2, val);
		WriteDecoder(0xc1, (BYTE)counter);
	}
}
*/
//=============================================================================
//
//=============================================================================
//
/*
void TuneLineBuffer(BYTE field)
{
	WORD php, hcounter;
	int initial=0;
	BYTE freerun;

	extern IDATA BYTE  PcMode;


	#if defined (DEBUG_PC) || defined (DEBUG_DECODER)
	dPrintf("\r\n----- TuneLineBuffer:%d -----", (WORD)field);
	#endif

	#ifdef SUPPORT_PC
	if( IsBypassmode() ) return;
	#endif

	//#ifdef SUPPORT_DTV
	//if( IsDTVInput() ) return;
	//#endif

	// disable free run
	freerun = IsFreeRun();
	PanelFreeRun(0);

	php = GetPHP();

	initial = 0;
	SetHInitial(field, initial);

	hcounter = GetHCounter1(field);
	#if defined (DEBUG_PC) || defined (DEBUG_DECODER)
	dPrintf("\r\nInitial=%4x  Hcounter=%4x  PHP=%4x (%2d%%)", initial, hcounter, php, (WORD)((DWORD)hcounter*100/php) );
	#endif
	
	if( (hcounter < ((DWORD)php*78/100)) || (hcounter > ((DWORD)php*82/100)) ) {
		
		initial = php*4/5 - hcounter + initial;
		if( initial>=0 ) {
			SetHInitial(field, initial/2);
			dPuts(" + ");
		}
		else {
			SetHInitial(field, 0x1000 + initial/2);
			dPuts(" - ");
		}
		
//		WriteDecoder(0xb1, ReadDecoder(0xb1)&0x08);
//		WriteDecoder(0xb0, 0xff);
//		WriteDecoder(0xb1, 0xff);
		
	}
	

	PanelFreeRun(freerun);
}
*/

//=============================================================================
//
//=============================================================================
/*
WORD GetAveHCVWRS(BYTE field)
{
	WORD hcounter, ave=0;
	BYTE i;


	#ifdef DEBUG_TW88
	dPuts("\r\n------ Get Average of HCVWRS ------");
	#endif

	for(i=0; i<5; i++) {
	
		hcounter = GetHCounter1(field);

		#ifdef DEBUG_TW88
		dPrintf("\r\n[%2d] HCVWRS=%4d", i, hcounter);
		#endif
		if( i==0 )
			ave = hcounter;
		else
			ave = ( ave + hcounter ) / 2;
	}
	#ifdef DEBUG_TW88
	dPrintf("\r\n----------- Average:%d -------------", ave);
	#endif

	return ave;
}
*/


#if 0 //SERIAL
void TestHCVWRS(BYTE field, WORD initial)
{
	WORD /*php,*/ hcounter, min=0, max=0;
	BYTE i;


	#ifdef DEBUG_TW88
	dPuts("\r\n------ Get HCVWRS ------");
	#endif

//	php = GetPHP();
	
	SetHInitial(field, initial);

	for(i=0; i<30; i++) {
	
		hcounter = GetHCounter1(field);
		dPrintf("\r\n[%2d] HInitial:%d  HCVWRS=%4d  PHP=%4d", i, initial, hcounter, GetPHP());
		dPrintf(" : %d%% of PHP ", hcounter*10/(GetPHP()/10));
		if( i==0 )
			min = hcounter;
		if( min > hcounter )
			min = hcounter;
		if( max < hcounter )
			max = hcounter;
	}
	dPrintf("\r\n------ Min:%d     Max:%d  ---(Field:%d)--", min, max, field);
}
#endif // SERIAL

//#endif

/***
WORD GetHPN1(void)
{
	WORD buf;
	BYTE val;

	//Get HPN 
	WriteDecoder(0x5b, 0x50);	// HSYNC period and VSYNC period

	//HPN

	val = ReadDecoder(0x58);	// from MSB
	buf = (WORD)val << 8;
	val = ReadDecoder(0x57);
	buf |= val;

	return buf;
}
***/

/****
#if (defined SERIAL) || (defined WIDE_SCREEN)
WORD CalcVBackPorch4DecoderInput( void )
{
	WORD		back_porch, vsud;
	DWORD		realv;

	vsud = GetVSUD();
	back_porch = ( ReadDecoder(VDELAY_LO) - ReadDecoder( 0xbd ) + 2 ) * 0x100L ;	
											// input vdelay - diff_in_out_vsync + 2 
	back_porch += (vsud-1);					// for getting rounded up result
	back_porch /=  vsud ;					// convert to value based on output
	back_porch -= ReadDecoder( 0xb8 );			// - Pandel Vertical Pulse Width

	realv =  ( GetVactive() * (DWORD)0x100 / vsud - GetPVR() ) / 2 ;
											// because of overscan.
	Printf("\r\n(CalcVBack...) min back proch:0x%x  add:0x%lx", back_porch, realv);
	back_porch +=  realv;

	SetVBackPorch( (BYTE) back_porch );
	return back_porch;
}
#endif // SERIAL || WIDE_SCREEN
****/

/******
WORD GetVSUD(void)
{
	WORD		vsud;
	BYTE        scale;

	scale = ReadDecoder( TW88_XYSCALEHI );
	vsud = (WORD)(scale & 0x0c) << 8;
	vsud |= ReadDecoder( TW88_YUSCALELO );

	#ifdef DEBUG_TW88
	dPrintf("\r\n(GetVSDU) :0x%x", vsud);
	#endif
	return vsud;
}
******/

/////////////////////////////////////////////////////////////////////////////
// Mapping( int fromValue, CRegInfo fromRange,
//                                           int * toValue, CRegInfo toRange )
// Purpose: Map a value in certain range to a value in another range
// Input:   int fromValue - value to be mapped from
//          CRegInfo fromRange - range of value mapping from
//          CRegInfo toRange   - range of value mapping to
// Output:  int * toValue - mapped value
// Return:  Fail if error in parameter, else Success
// Comment: No range checking is performed here. Assume parameters are in
//          valid ranges.
//          The mapping function does not assume default is always the mid
//          point of the whole range. It only assumes default values of the
//          two ranges correspond to each other.
//          
//          The mapping formula is:
//
//            For fromRange.Min() <= fromValue <= fromRange.Default():
//
//				(fromValue -fromRange.Min())* (toRange.Default() - toRange.Min())
//				-------------------------------------------------------------------- + toRange.Min()
//					fromRange.Default() - fromRange.Min()
//
//			  For fromRange.Default() < fromValue <= fromRange.Max():
//
//				(fromValue - fromRange.Default()) * (toRange.Max() - toRange.Default())
//				--------------------------------------------------------------------- + toRange.Default()
//		             fromRange.Max() - fromRange.Default()
////
////////////////////////////////////////////////////////////////////////////
BYTE Mapping1( int fromValue, CODE_P struct RegisterInfo *fromRange,
                                 int * toValue, CODE_P struct RegisterInfo *toRange ){

	// calculate intermediate values
	int a;

⌨️ 快捷键说明

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