measure.c
来自「显示屏驱动源代码」· C语言 代码 · 共 1,866 行 · 第 1/3 页
C
1,866 行
return _PcMode;
}
WORD ConvertBasedOnInput(WORD dat)
{
DWORD dtmp;
if( IsBypassmode() ) return dat; // HHY 2.01
dtmp = PCMDATA[PcMode].PPF*100000L/dat; // from PPF-based to IPF-based
dtmp = PCMDATA[PcMode].IPF*100000L/dtmp; // NewHPN = OldHPN * (IPF/PPF)
return (WORD)dtmp;
}
//=============================================================================
// Search ADC Clock with measuring Phase
//=============================================================================
#ifdef AUTO_TUNE_CLOCK
WORD AutoTuneClock(void)
{
WORD low, high; // Test value range of plldiv
WORD i;
// BYTE phase, phasepeak, j;
WORD num, width;
#ifdef DEBUG_PC
dPrintf("\r\n---Tune-Coarse Mode=%d", (WORD)PcMode);
#endif
//------ Set Test Range, Divide Range more detail
low = 10;
high = ConvertBasedOnInput( GetHPN() );
SetMeasureWindowH(low, high); //
low = 1;
high = GetVPN() - 1;
SetMeasureWindowV(low, high); //
low = PCMDATA[PcMode].low;
high = PCMDATA[PcMode].high;
#ifdef DEBUG_PC
dPrintf("\r\n===>>>>Get Divider Number=0x%4x to 0x%4x", (WORD)low, (WORD)high);
#endif
MeasureAndWait(3);
width = GetHend() - GetHstart() + 1;
SetCoarse( low );
MeasureAndWait(3);
low = GetHend() - GetHstart() + 1;
SetCoarse( high );
MeasureAndWait(3);
high = GetHend() - GetHstart() + 1;
if(( low > width ) || ( width > high ) ) return 0; // cannot adjustable in setting range...
for(i=PCMDATA[PcMode].low; i <= PCMDATA[PcMode].high; i+=4 ) { // increment by 4
SetCoarse(i);
MeasureAndWait(3);
width = GetHend() - GetHstart() + 1;
if ( width >= PCMDATA[PcMode].HAN ) return (i);
}
return num;
}
#endif
#ifdef AUTOTUNEPHASE
//-----------------------------------------------------------------------------
// Final Set ADC [PLL div], [Phase]
//-----------------------------------------------------------------------------
void AutoTunePhase(void)
{
BYTE i, j, peak_j;
dPuts("\r\n-------------Tune-Fine");
if( IsDTVInput() ) return;
j = GetPhaseCurrent() - 8; //- 0x20;
RGBPeak=0;
for(i=0; i<9; i++, j+=0x02) {
j=j%0x1f;
SetPhase(j); // if NO_INPUT stop
if( !GetPhaseRGB() ) return; //
if(RGBPeak < PhaseRGB) {
RGBPeak = PhaseRGB;
peak_j = j;
dPuts("--peak");
}
else {
dPuts(" ");
}
}
SetPhase(peak_j);
}
#endif
//-----------------------------------------------------------------------------
// Measure VPN, HPN
// Calculate IVF, IHF
//-----------------------------------------------------------------------------
WORD GetHpnVpn(BYTE en)
{
WORD vpn, hpn, sync; //hsync, vsync;
BYTE SyncPol;
en = DebugLevel;
if( !en && DebugLevel ) DebugLevel = 0;
#ifdef DEBUG_PC
dPuts("\r\n------ GetHpnVpn()");
#endif
//----- Measurement Command -------------
if( !MeasureAndWait(3) ) { // field any...
#ifdef DEBUG_PC
dPrintf(" Error at GetHpnVpn ");
#endif
DebugLevel = en;
return 0;
}
//----- Get VPN -------------------------
vpn = GetVPN(); // VPN = V Period Num
sync = GetVSYNCPulse();
// in case of 8816 sync is same to vpn so I cannot use below....
// Polarity check
if( sync > (vpn/3) ) {
InvertVSYNCPolarity();
MeasureAndWait(3);
sync = GetVSYNCPulse();
#ifdef DEBUG_PC
dPrintf(" --->New VSYNC:%04x(%d)", sync, sync);
#endif
}
#ifdef DEBUG_PC
dPrintf("\r\n VPN:%04x(%d) VSYNC:%04x(%d)", vpn, vpn, sync, sync);
dPrintf("\r\n IHF:%08lx(%ld)", IHF, IHF);
#endif
//----- Get HPN ---------------------
hpn = GetHPN(); // HPN = H Period Num
sync = GetHSYNCPulse(); // H sync Pulse Width = HSYNC interval
#ifdef DEBUG_PC
dPrintf("\r\n HPN:%04x(%d) HSYNC:%04x(%d)", hpn, hpn, sync, sync);
dPrintf("\r\n PPF:%08lx(%ld)", GetPPF(), GetPPF() );
#endif
if( sync >= (hpn/3) ) {
SyncPol = ReadDecoder(0x40); // INVERT SYNC POLARITY
if ( SyncPol & 0x04 ) // b'2 is HSYNC POL
SyncPol &= 0xfb;
else SyncPol |= 0x04;
WriteDecoder(0x40, SyncPol);
MeasureAndWait(3);
sync = GetHSYNCPulse(); // H sync Pulse Width = HSYNC interval
hpn = GetHPN(); // HPN = H Period Num
}
//----- Get New HPN -------------
IHF = (GetPPF()+hpn/2) / hpn; // IHF = PPF / HPN
//----- Get New VPN -------------
vpn = GetVPN();
IVF = (WORD)((IHF+vpn/2)/vpn); // IVF = IHF / VPN
#ifdef DEBUG_PC
dPrintf("\r\nIHF(New):%08lx(%ld)", IHF, IHF);
dPrintf("\r\nHPN(New):%04x(%d) HSYNC(New):%04x(%d)", hpn, hpn, sync, sync);
dPrintf("\r\nVPN(New):%04x(%d)", vpn, vpn);
dPrintf("\r\nIVF(New):%04x(%d)", IVF, IVF);
dPuts("\r\n-------");
#endif
DebugLevel = en;
return vpn;
}
//=============================================================================
// Return V active Start
//=============================================================================
WORD GetVerticalActiveArea(void)
{
WORD vstart, vstart1, vend;
char off=0;
dPuts("\r\n----- Get V Active Area");
//----- if current mode is DTV, use default value----------------
//#ifdef SUPPORT_DTV
if( IsDTVInput() ) {
#ifdef DEBUG_DTV
dPrintf(" ---> Use fixed data Vstart=%d VAN=%d", PCMDATA[PcMode].Vstart, PCMDATA[PcMode].VAN);
#endif
SetVactiveStart( PCMDATA[PcMode].Vstart );
switch (PcMode) {
case EE_YPbPr_480I: off = 4; break;
case EE_YPbPr_1080I: off = 2; break;
case EE_RGB_1080I: off = 4; break;
default: off = 0; break;
}
SetVactiveLen( PCMDATA[PcMode].VAN+off+20 );
return PCMDATA[PcMode].Vstart;
}
//#endif
//======================== Get the Bottom End ========================
vend = GetVend();
if( vend >= GetVPN() ) {
#ifdef DEBUG_PC
dPrintf("\r\nToo big vend [%04x]", vend);
#endif
vend = GetVPN()-1;
}
vstart = vend - PCMDATA[PcMode].VAN + 1;
vstart1 = GetVstart();
// vstart = GetVstart();
#ifdef DEBUG_PC
dPrintf("\r\nFind Vend --- %04x %04x", vstart, vend);
#endif
//================================================= HHY 2.00
if( PcMode >= EE_1152_60 && PcMode <=EE_1152_75 ) {
if( vstart1 > vstart && vstart1 <= vstart+3 ) {
vstart = vstart1;
vend = vstart + PCMDATA[PcMode].VAN - 1;
#ifdef DEBUG_PC
dPuts(" -------> Use Vstart");
#endif
}
}
//=================================================
#ifdef DEBUG_PC
dPrintf("\r\nAuto Measure Vstart=%04x(%d) Vend=%04x(%d)", vstart, vstart, vend, vend);
#endif
if( (vstart > PCMDATA[PcMode].Vstart + 30) || ((int)vstart < ((int)PCMDATA[PcMode].Vstart - 30) ) ) {
#ifdef DEBUG_PC
ePrintf(" ==> Out Of Range V Active");
#endif
vstart = GetVactiveStartEE(PcMode);
vend = vstart + PCMDATA[PcMode].VAN - 1;
}
//----- Compensation mode by mode -------------------------------
#ifdef VGA
if( PcMode>=EE_VGA_60 || PcMode<=EE_VGA_85 ) {
vstart -= 5;
dPrintf("\r\n ----------- VGA Bypass !!!");
}
#endif
if( PcMode==EE_SP2 ) vstart = PCMDATA[EE_SP2].Vstart; // HHY 1.62 640x350
//----- set the register values ( Vstart, VAN ) -----------------
SetVactiveStart(vstart);
SetVactiveLen(PCMDATA[PcMode].VAN); // with VAN
#ifdef DEBUG_PC
ePrintf("\r\n@@@@@ Vstart=%04x[%d] Vend=%04x[%d]", vstart, vstart, vend, vend);
#endif
return vstart;
}
//=============================================================================
//
//=============================================================================
BYTE GetHorizontalActiveArea(void)
{
WORD hstart, hend;
dPuts("\r\n----- Get H Active Area ");
#ifdef SUPPORT_DTV
if( IsDTVInput() ) {
hstart = PCMDATA[PcMode].Hstart;
hend = hstart + PCMDATA[PcMode].HAN + 1;
#ifdef DEBUG_PC
dPrintf(" ---> Use fixed data Hstart=%d HAN=%d Hend=%d", hstart, PCMDATA[PcMode].HAN, hend);
#endif
SetHactiveStart( hstart );
SetHactiveEnd( hend+3 ); // with HAN, Hstart
return TRUE;
}
#endif
//======================== Get the Right End ========================
hstart = GetHstart();
hend = hstart + PCMDATA[PcMode].HAN + hstart;
#ifdef DEBUG_PC
dPrintf("\r\nAuto Measure Hstart=%04x(%d) Hend=%04x(%d)", hstart, hstart, hend, hend);
#endif
if( (hstart > PCMDATA[PcMode].Hstart + 100) || ((int)hstart < (int)PCMDATA[PcMode].Hstart - 100) ) {
#ifdef DEBUG_PC
ePuts(" ==> Out Of Range H Active");
#endif
hstart = GetHactiveStartEE(PcMode);
hend = hstart + PCMDATA[PcMode].HAN + 1;
SetHactiveStart(hstart); // with Hstart
SetHactiveEnd( hend ); // with HAN, Hstart
return TRUE;
}
//----- Compensation mode by mode -------------------------------
if( PcMode < EE_XGA_60 ) hend++;
if( !IsBypassmode() ) {
hstart -= 3;
hend -= 3;
}
#ifdef XGA
if( PcMode>=EE_1152_60 ) {
hstart+=3;
hend+=3;
}
#endif
#ifdef SXGA
if( PcMode>=EE_1152_60 && PcMode<=EE_1152_75 ) {
hstart+=2;
hend+=2;
}
#endif
//----- set the register values ( Hstart, Hend ) ----------------
SetHactiveStart(hstart); // with Hstart
SetHactiveEnd( hend ); // with HAN, Hstart
#ifdef DEBUG_PC
ePrintf("\r\n@@@@@ Hstart=%04x[%d] Hend=%04x[%d]", hstart, hstart, hend, hend);
#endif
return TRUE;
}
//-----------------------------------------------------------------------------
// Calcurate and Save VOback(0xb9) & PVP(0xb7,0xbb)
// - Refer to additional document
//-----------------------------------------------------------------------------
void SetVValueForPanel(WORD VIstart)
{
WORD PVR, VAN, VScale, VIsync;
BYTE VOsync, VOback;
VIstart = VIstart;
VIsync = VIstart; // active pulse width
PVR = GetPVR();
VAN = PCMDATA[PcMode].VAN;
VOsync = ReadTW88(0xb8);
// dtmp = VIstart + 3 - VIsync - 1;
// dtmp = VIstart + 3;
// dtmp = (dtmp * PVR * 10) / VAN; // +5 means round-up.
VScale = ReadTW88(0x63) & 0x0c;
VScale <<= 6;
VScale += ReadTW88(0x62); // read VScale
// VIsync--;
VIsync <<= 8; // multiply by 256
// VIsync += 128;
VIsync /= VScale; // divide by scale, calculate
VOback = VIsync - VOsync - 1;
#ifdef DEBUG_PC
dPrintf("\r\n************************");
dPrintf("\r\nVScale=%d VIsync=%d PVR=%d VAN=%d ", (WORD)VScale, (WORD)VIsync, (WORD)PVR, (WORD)VAN);
dPrintf("\r\nVIstart=%d VIsync=%d PVR=%d VAN=%d ", (WORD)VIstart, (WORD)VIsync, (WORD)PVR, (WORD)VAN);
dPrintf("VOsync=%d", (WORD)VOsync);
dPrintf("==> VOback=%02bx(%bd)", VOback, VOback);
dPrintf("\r\n************************");
#endif // DEBUG_PC
/*
//----- Compensation mode by mode -------------------------------
#ifdef XGA
if ( PcMode==EE_DOS ) VOback -= 2; // HHY 3.00
else if( PcMode==EE_SP1 ) VOback -= 2; // HHY 3.00
#endif
#if defined VGA || defined WVGA
if ( PcMode==EE_DOS ) VOback += 1;
else if( (PcMode>=EE_SVGA_56) && (PcMode<=EE_SVGA_85) ) VOback += 1;
#endif
*/
//-----------------------------------------------------------
#ifdef WQVGA
SetVBackPorch(PanelData.VBackporch);
SetPVP(PanelData.VPeriod);
#else
SetVBackPorch( (BYTE)VOback );
SetPVP(VOsync + VOback + PVR + 10);
#endif
}
//-----------------------------------------------------------------------------
// Calcurate [Panel H. Cycle] = PHP(Panel H Period)
//-----------------------------------------------------------------------------
#ifndef AUTOCALC_PC
BYTE SetHValueForPanel(void)
{
WORD sum=0;
WORD php;
sum = ReadTW88(0xb3) + ReadTW88(0xb4) + GetPHR(); // sum = AA+AB+AC,AD = From Hsync to Active region
MeasureAndWait(3);
php = (DWORD)(GetHPN()) * PCMDATA[PcMode].VAN / GetPVR(); // PHP = HPN * (VAN/PVR)
#ifdef DEBUG_PC
dPrintf("\r\nHPN:%04x(%d)", GetHPN(), GetHPN());
dPrintf("\r\nVAN:%04x(%d)", PCMDATA[PcMode].VAN, PCMDATA[PcMode].VAN);
dPrintf("\r\nPVR:%04x(%d)", GetPVR(), GetPVR());
dPrintf("\r\nPanel H. Cycle:%04x(%d), aa+ab+ac:%04x(%d)", php, php, sum, sum);
#endif
if( php <= sum ) {
ePuts("--not enough");
#ifdef DEBUG_PC
return FALSE;
#endif
}
//=================================
#ifdef SXGA
switch( PcMode ) {
case EE_RGB_576I: case EE_YPbPr_576I: php = 0x70f; break;
case EE_RGB_720P: case EE_YPbPr_720P: php = 0x623; break;
case EE_RGB_1080I: case EE_YPbPr_1080I: php = 0x618; break;
case EE_RGB_1080I50A: case EE_YPbPr_1080I50A: php -= 6; break;
}
#endif
//=================================
//------ Set PHP ----------
SetPHP(php);
return TRUE;
}
#else
BYTE SetHValueForPanel(void)
{
return TRUE;
}
#endif
//-----------------------------------------------------------------------------
// VAN = V Active Number
// HAN = H active Number
//-----------------------------------------------------------------------------
BYTE GetActiveRegion(void)
{
WORD vstart;
DWORD pres, scale;
DWORD ppf;
WORD period, sync;
//----- Set Measurement Wondow Size -----
SetMeasureWindowV(1, 0x400);
MeasureAndWait(3);
// Set H window
if( (PCMDATA[PcMode].VAN != GetPVR()) || !Flag4Bypass ) { // --- Change hpulse & hpn ---
period = ConvertBasedOnInput( GetHPN() );
sync = ConvertBasedOnInput( GetHSYNCPulse() );
}
else {
period = GetCoarse();
sync = GetHSYNCPulse();
}
SetMeasureWindowH(sync, period);
// Set V window
period = GetVPN();
sync = GetVSYNCPulse();
SetMeasureWindowV(1, period);
//----- Do Measurement ---------------------------
MeasureAndWait(3);
//----- Get VAN = Vertical Active Area -----------
vstart = GetVerticalActiveArea(); // Measure Input Vstart, Vactive
SetMeasureWindowV(1, period); // HHY 1.61 for stable h sync region
//----- Calculate Y-scale Factor, and save -------
#if (defined WIDE_SCREEN)
Set4WideScreen(GetWideModeEE());
#else
{ //NORNAL SCREEN
pres = (DWORD)PVR_;
scale = (PCMDATA[PcMode].VAN * 0x10000L) / pres;
#ifdef DEBUG_PC
dPrintf("\r\n VAN=%04x PVR=%04x", PCMDATA[PcMode].VAN, pres);
dPrintf("\r\nYscaleFactor:%04x(%d)", scale, scale);
#endif
#ifndef WXGA
if( scale==0x10000 && Flag4Bypass ) { // Bypass
BypassZoom();
}
else
#endif
{
Clear_bypass();
YScale2(scale); // save V Scale Up Factor
}
} // WIDE
#endif
vstart = GetVactiveStart();
SetVValueForPanel(vstart); // with VAN, Vstart
//----- Calcurate Panel H. Cycle(A9,AD) ----------
ppf = GetPPF();
/****/
#if 0 // Hans
#ifdef DEBUG_PC
while( !SetHValueForPanel() ) { // we need to use higher PPF
ppf += 2700000;
if( ppf > MAX_PPF ) {
ePuts("\r\n\n--------------Too big IPF\r\n");
return FALSE;
}
ChangeInternPLL(ppf); // internal PLL
#ifdef DEBUG_PC
dPrintf("--> Increased PPF:%8ld", ppf);
#endif
delay(10);
}
#endif
#endif
/****/
//----- Get HAN = Horizontal Active Area ---------
GetHorizontalActiveArea();
if( (PCMDATA[PcMode].VAN != GetPVR()) || !Flag4Bypass) { // non-bypass
pres = (DWORD)GetPHR();
scale = (PCMDATA[PcMode].HAN * 0x10000L ) / pres; // 256*han/phr
#ifdef DEBUG_PC
dPrintf("\r\nXscaleFactor:%04x(%d)", scale, scale);
#endif
//#if (defined SXGA) || (defined WXGA) || (defined WSGA)
if( PCMDATA[PcMode].HAN > 1024 ) {//1100
scale = (PCMDATA[PcMode].HAN * 0x80L ) / 1024 + 1; // (HAN/1024)*256
XscaleD(scale);
#ifdef DEBUG_PC
dPrintf("\r\nXscaleFactorD:%04x(%d)", scale, scale);
#endif
scale = (1024 * 0x10000L ) / 1280; // (1024/PHR)*256
XscaleU(scale);
#ifdef DEBUG_PC
dPrintf("\r\nXscaleFactorU:%04x(%d)", scale, scale);
#endif
}
else
//#endif
{
#ifdef WIDE_SCREEN
if(WideScreenMode == WIDESCREEN_WIDE)
#endif // WIDE_SCREEN
XScale2(scale);
}
}
SavePCDataEE(PcMode);
return TRUE;
}
/*===========================================================================*/
/* Display The Result for Debugging */
/*===========================================================================*/
void DisplayResultAndSetActiveRange(void)
{
BYTE cRang;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?