📄 auto.c
字号:
pData[1] = pData[9];
pData[2] = pData[10];
CScalerWrite(_V_BOUNDARY_H_73, 3, pData, _AUTOINC);
return _ERROR_SUCCESS;
}
//--------------------------------------------------
// Description : Auto phase search function
// Input Value :
// Output Value :
//--------------------------------------------------
DWORD CAutoPhaseSearch(BYTE ucSelColor, BYTE ucSelStep, BYTE ucSelStepNum, BYTE ucSelStepStart, BYTE *ucPhaseResult)
{
DWORD maxsum = 0;
BYTE count=0, best=0;
// Read difference threshold
CScalerRead(_DIFF_THRESHOLD_79, 1, &count, _NON_AUTOINC);
// Set difference threshold for Phase Search
if(count == 0)
{
count = 0xA0;
CScalerSetByte(_DIFF_THRESHOLD_79, count);
}
best = CAutoMeasurePositionV(_MIN_NOISE_MARGIN);
if(_ERROR_SUCCESS != best)
{
return best;
}
best = CAutoMeasurePositionH(_MIN_NOISE_MARGIN);
if(_ERROR_SUCCESS != best)
{
return best;
}
best = 0;
((WORD *)pData)[4] = g_usHStartPos - 1; // Hsync Lbound
((WORD *)pData)[5] = g_usHEndPos + 1; // Hsync Rbound
((WORD *)pData)[6] = g_usVStartPos - 1; // Vsync Lbound
((WORD *)pData)[7] = g_usVEndPos; // Vsync Rbound
pData[0] = ((pData[8] << 4) & 0x70) | (pData[10] & 0x0f);
pData[1] = pData[9];
pData[2] = pData[11];
pData[3] = ((pData[12] << 4) & 0x70) | (pData[14] & 0x0f);
pData[4] = pData[13];
pData[5] = pData[15];
CScalerWrite(_H_BOUNDARY_H_70, 6, pData, _AUTOINC);
CScalerSetByte(_AUTO_ADJ_CTRL1_7D, 0x00);
CScalerSetBit(_AUTO_ADJ_CTRL0_7A, ~(_BIT1 | _BIT0), ucSelColor & 0x03);
// Issac : Because H/W auto phase search may cause underflow at start and stop,
// frame-sync watch-dog must be disabled.
//CAdjustDisableWatchDog(_WD_ALL);
// V011 Patch Note (6) : Fix the Auto-Phase error in low frequency mode.
if(((DWORD)stModeInfo.IHFreq * stModeInfo.IHTotal / 1000) < 1000)
{
ucSelStep += 1;
ucSelStepStart *= 2;
CScalerPageSelect(_PAGE1);
if (ucSelStepStart >= 64) CScalerSetBit(_P1_MIX_B0, ~_BIT1, _BIT1);
}
CScalerSetByte(_HW_AUTO_PHASE_CTRL0_7B, (ucSelStep & 0x07) | (((ucSelStepNum - 1) & 0x1f) << 3));
CScalerSetByte(_HW_AUTO_PHASE_CTRL1_7C, 0x00 | (ucSelStepStart & 0x3f));
ucSelStep = (0x01 << ucSelStep);
ucSelColor = ucSelStepStart + (ucSelStepNum) * ucSelStep;
count = ucSelStepStart;
maxsum = 0;
best = 0;
// Issac : Using Wait_For_Event(EVENT_IVS) instead of Wait_For_IVS().
// Because H/W auto phase search may cause underflow at start and stop.
// Wait_For_Event() will not check underflow/overflow.
if(CScalerGetBit(_AUTO_ADJ_CTRL0_7A, _BIT1 | _BIT0) == 0x03)
{
CScalerSetBit(_AUTO_ADJ_CTRL0_7A, ~(_BIT4 | _BIT1 | _BIT0), _BIT4);
}
else
{
CScalerSetBit(_AUTO_ADJ_CTRL0_7A, ~_BIT4, _BIT4);
}
CScalerSetByte(_AUTO_ADJ_CTRL1_7D, 0x7b);
CAutoWaitForIVS(1);
do
{
if(CAutoWaitForIVS(((CScalerGetBit(_AUTO_ADJ_CTRL0_7A, _BIT1 | _BIT0) == 0x03) ? 3 : 1)) & (_EVENT_UNDERFLOW | _EVENT_OVERFLOW))
{
CScalerSetByte(_AUTO_ADJ_CTRL1_7D, 0x00);
CScalerPageSelect(_PAGE1);
CScalerSetBit(_P1_MIX_B0, ~_BIT1, 0x00);
return 0xffffffff;
}
CScalerRead(_AUTO_PHASE_3_84, 3, pData, _AUTOINC);
pData[3] = 0;
if(((DWORD *)pData)[0] > maxsum)
{
maxsum = ((DWORD *)pData)[0];
best = count;
}
count += ucSelStep;
}
while(count < ucSelColor);
CScalerSetByte(_AUTO_ADJ_CTRL1_7D, 0x00);
CScalerPageSelect(_PAGE1);
CScalerSetBit(_P1_MIX_B0, ~_BIT1, 0x00);
CTimerWaitForEvent(_EVENT_IVS);
pData[0] = CAutoWaitFinish();
if(pData[0] != _ERROR_SUCCESS)
{
return 0xffffffff;
}
// V011 Patch Note (6) : Fix the Auto-Phase error in low frequency mode.
if(((DWORD)stModeInfo.IHFreq * stModeInfo.IHTotal / 1000) < 1000)
{
*ucPhaseResult = best / 2;
}
else
{
*ucPhaseResult = best;
}
return maxsum;
}
//--------------------------------------------------
// Description : Get phase SOD information
// Input Value : ucColor --> Color we measure
// Output Value : Measure status
//--------------------------------------------------
BYTE CAutoReadPhaseInfo(BYTE ucColor)
{
CScalerSetByte(_AUTO_ADJ_CTRL1_7D, 0x00);
CScalerSetBit(_AUTO_ADJ_CTRL0_7A, ~(_BIT1 | _BIT0), ucColor & 0x03);
CScalerSetByte(_AUTO_ADJ_CTRL1_7D, 0x3b);
pData[0] = CAutoWaitFinish();
if(_ERROR_SUCCESS != pData[0])
{
CScalerSetByte(_AUTO_ADJ_CTRL1_7D, 0x00);
return pData[0];
}
CScalerRead(_AUTO_PHASE_3_84, 4, pData, _AUTOINC);
return _ERROR_SUCCESS;
}
//--------------------------------------------------
// Description : Auto clock process
// Input Value : None
// Output Value : Measure status
//--------------------------------------------------
BYTE CAutoDoAutoClock(void)
{
BYTE result=0, phase=0;
WORD count=0, delta=0, stop=0;
DWORD maxval=0;
maxval = CAutoPhaseSearch(_COLOR_SELECT, _HWAUTO_STEP_8, HWAUTOSTEPNUM(8), HWAUTOSTEPSTART(0), &result);
if((maxval != 0xffffffffL) && (maxval != 0))
{
CAdjustPhase(stModeUserData.Phase);
}
result = CAutoMeasurePositionH(_MIN_NOISE_MARGIN);
if(result != _ERROR_SUCCESS)
{
return result;
}
g_usHEndPos = g_usHEndPos + 1 - g_usHStartPos;
if(g_usHEndPos < ((DWORD)stModeInfo.IHWidth * _AUTO_CLOCK_RANGE / 100))
{
return _ERROR_ABORT;
}
stModeUserData.Clock = stModeInfo.IHTotal;
stModeUserData.Clock &= 0xfffc;
#if(_NEW_ADC == _FALSE)
CAdjustAdcClock(stModeUserData.Clock, 1);
CAdjustAdcClock(stModeUserData.Clock, 2);
#else
CAdjustAdcClock(stModeUserData.Clock);
#endif
result = CAutoMeasurePositionV(_MIN_NOISE_MARGIN);
if(result != _ERROR_SUCCESS)
{
return result;
}
delta = (stModeInfo.IHTotal - stModeInfo.IHWidth * 8 / 10) / 2;
stop = 0;
count = 10;
do
{
/*
// Power off while auto config--------
CKeyCheckPowerKey();
if(GET_POWERSWITCH())
return _ERROR_INPUT;
//------------------------------------
*/
// Measure Horizontal Start/End
result = CAutoMeasurePositionH(_MIN_NOISE_MARGIN + 0x10);
if(result != _ERROR_SUCCESS)
{
return result;
}
g_usHEndPos = g_usHEndPos + 1 - g_usHStartPos;
if(g_usHEndPos < stModeInfo.IHWidth)
{
if((stModeInfo.IHWidth - g_usHEndPos) >= (2 * delta))
{
stop = 1;
}
else
{
g_usHStartPos = (DWORD)(stModeInfo.IHWidth - g_usHEndPos) * (stModeUserData.Clock)
/ (DWORD)stModeInfo.IHWidth;
if(g_usHStartPos <= 2)
{
break;
}
g_usHStartPos = (g_usHStartPos + 2) & 0xfffc;
if((g_usHStartPos + stModeUserData.Clock) > (delta + stModeInfo.IHTotal))
{
stop = 1;
}
else
{
stModeUserData.Clock += g_usHStartPos;
}
}
}
else
{
if((g_usHEndPos - stModeInfo.IHWidth) >= (2 * delta))
{
stop = 1;
}
else
{
g_usHStartPos = (DWORD)(g_usHEndPos - stModeInfo.IHWidth) * (stModeUserData.Clock)
/ (DWORD)stModeInfo.IHWidth;
if(g_usHStartPos <= 2)
{
break;
}
g_usHStartPos = (g_usHStartPos + 2) & 0xfffc;
if((g_usHStartPos + stModeInfo.IHTotal) > (delta + stModeUserData.Clock))
{
stop = 1;
}
else
{
stModeUserData.Clock -= g_usHStartPos;
}
}
}
if(stop)
{
break;
}
#if(_NEW_ADC == _FALSE)
CAdjustAdcClock(stModeUserData.Clock, 1);
CAdjustAdcClock(stModeUserData.Clock, 2);
#else
CAdjustAdcClock(stModeUserData.Clock);
#endif
}
while(--count);
if((count == 0) || (stop == 1))
{
return _ERROR_ABORT;
}
// Prevent from 1/2-line moire and smear effect.
if((g_usHEndPos >= stModeInfo.IHWidth && (stModeUserData.Clock - stModeInfo.IHTotal) == 4)
|| (g_usHEndPos < stModeInfo.IHWidth && (stModeInfo.IHTotal - stModeUserData.Clock) == 4))
{
stModeUserData.Clock = stModeInfo.IHTotal;
#if(_NEW_ADC == _FALSE)
CAdjustAdcClock(stModeUserData.Clock, 1);
CAdjustAdcClock(stModeUserData.Clock, 2);
#else
CAdjustAdcClock(stModeUserData.Clock);
#endif
result = CAutoMeasurePositionH(_MIN_NOISE_MARGIN + 0x10);
if(result != _ERROR_SUCCESS)
{
return result;
}
g_usHEndPos = g_usHEndPos + 1 - g_usHStartPos;
}
#if(_AUTO_CLOCK_PRECISION < 4)
// Save 4N clock
stop = stModeUserData.Clock;
stModeUserData.Clock += (stModeInfo.IHWidth >= g_usHEndPos) ? 4 : 2;
#if(_NEW_ADC == _FALSE)
CAdjustAdcClock(stModeUserData.Clock, 1);
CAdjustAdcClock(stModeUserData.Clock, 2);
#else
CAdjustAdcClock(stModeUserData.Clock);
#endif
// Set threshold for Clock Search
CScalerSetByte(_DIFF_THRESHOLD_79, 0x18);
count = stop;
maxval = 0;
delta = 6; // Initial value must be (N * AUTO_CLOCK_STEP)
do
{
result = CAutoMeasurePositionH(_MIN_NOISE_MARGIN + 0x10);
if(result != _ERROR_SUCCESS)
{
return result;
}
g_usHEndPos = g_usHEndPos + 1 - g_usHStartPos;
if(g_usHEndPos > (stModeInfo.IHWidth + 2))
{
((DWORD *)pData)[0] = 0;
}
else
{
((DWORD *)pData)[0] = CAutoPhaseSearch(_COLOR_SELECT, _HWAUTO_STEP_8, HWAUTOSTEPNUM(8), HWAUTOSTEPSTART(0), &phase);
if (0xffffffffL == ((DWORD *)pData)[0])
{
return _ERROR_INPUT;
}
}
if(maxval < ((DWORD *)pData)[0])
{
maxval = ((DWORD *)pData)[0];
count = stModeUserData.Clock;
}
if(delta == 0x00)
{
// Check if default clock is the best when clock searching range is larger than default.
if(stModeUserData.Clock > stModeInfo.IHTotal)
{
stModeUserData.Clock = stModeInfo.IHTotal;
#if(_NEW_ADC == _FALSE)
CAdjustAdcClock(stModeUserData.Clock, 1);
CAdjustAdcClock(stModeUserData.Clock, 2);
#else
CAdjustAdcClock(stModeUserData.Clock);
#endif
continue;
}
break;
}
delta -= _AUTO_CLOCK_PRECISION;
stModeUserData.Clock -= _AUTO_CLOCK_PRECISION;
#if(_NEW_ADC == _FALSE)
CAdjustAdcClock(stModeUserData.Clock, 1);
CAdjustAdcClock(stModeUserData.Clock, 2);
#else
CAdjustAdcClock(stModeUserData.Clock);
#endif
}
while(_TRUE);
maxval = maxval / 3;
stModeUserData.Clock = (maxval > ((DWORD)stModeInfo.IHWidth << 10)) ? count : stop;
#if(_NEW_ADC == _FALSE)
CAdjustAdcClock(stModeUserData.Clock, 1);
CAdjustAdcClock(stModeUserData.Clock, 2);
#else
CAdjustAdcClock(stModeUserData.Clock);
#endif
#endif
return _ERROR_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -