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 + -
显示快捷键?