📄 auto.c
字号:
//----------------------------------------------------------------------------------------------------
// ID Code : Auto.c No.0002
// Update Note :
//
//----------------------------------------------------------------------------------------------------
#define __AUTO__
#include "Core\Header\Include.h"
//--------------------------------------------------
// Description : Auto clock, phase and H,V position
// Input Value : None
// Output Value : _ERROR_SUCCESS if succeed
//--------------------------------------------------
BYTE CAutoDoAutoConfig(void)
{
BYTE result, phasetemp, watchdogtemp;
CScalerRead(_WATCH_DOG_CTRL0_0C, 1, &watchdogtemp, _NON_AUTOINC);
CScalerSetByte(_WATCH_DOG_CTRL0_0C, 0x00);
// Save current phase
phasetemp = stModeUserData.Phase;
// Clear the HW auto status to prevent some un-expected event happened
CScalerSetByte(_AUTO_ADJ_CTRL1_7D, 0x00);
CMiscClearStatusRegister();
result = CAutoDoAutoPosition();
if(result == _ERROR_SUCCESS)
{
result = CAutoDoAutoClock();
if(result == _ERROR_SUCCESS)
{
result = CAutoDoAutoPhase();
if((result == _ERROR_SUCCESS) || (result == _ERROR_PHASE))
{
if(result == _ERROR_PHASE)
{
stModeUserData.Phase = phasetemp;
CAdjustPhase(stModeUserData.Phase);
}
result = CAutoDoAutoPosition();
if(result != _ERROR_SUCCESS)
{
stModeUserData.HPosition = stModeInfo.IHStartPos;
stModeUserData.VPosition = stModeInfo.IVStartPos;
CAdjustHPosition();
CAdjustVPosition();
}
}
else
{
// If auto phase is failed, load phase setting before auto config
stModeUserData.Phase = phasetemp;
CAdjustPhase(stModeUserData.Phase);
}
}
else
{
// If auto clock is failed, load default clock setting
stModeUserData.Clock = stModeInfo.IHTotal;
stModeUserData.HPosition = stModeInfo.IHStartPos;
stModeUserData.VPosition = stModeInfo.IVStartPos;
CAdjustAdcClock(stModeUserData.Clock);
CAdjustHPosition();
CAdjustVPosition();
}
}
else
{
stModeUserData.HPosition = stModeInfo.IHStartPos;
stModeUserData.VPosition = stModeInfo.IVStartPos;
CAdjustHPosition();
CAdjustVPosition();
}
if((result == _ERROR_SUCCESS) || (result == _ERROR_ABORT))
{
// Save auto result
CEepromSaveModeData(stModeInfo.ModeCurr);
CAdjustUpdateCenterData();
CEepromSaveCenterModeData(stModeInfo.ModeCurr);
}
CScalerSetByte(_WATCH_DOG_CTRL0_0C, watchdogtemp);
CMiscClearStatusRegister();
return result;
}
//--------------------------------------------------
// Description : Auto color ( white balance )
// Input Value : None
// Output Value : _ERROR_SUCCESS if succeed
//--------------------------------------------------
BYTE CAutoDoWhiteBalance(void)
{
BYTE result;
#if(_YPBPR_AUTO_TYPE==_NEW_TYPE)
if(_GET_INPUT_SOURCE() == _SOURCE_YPBPR)
result = CAutoTuneBalanceNew();
else
result = CAutoTuneBalance();
#else//_YPBPR_AUTO_TYPE==_ORIGINAL_TYPE
result = CAutoTuneBalance();
#endif
if(result == _ERROR_SUCCESS)
CEepromSaveAdcData();
else
{
if(_GET_INPUT_SOURCE() == _SOURCE_VGA)
CEepromLoadAdcDataDefault();
else
CEepromLoadYPbPrDataDefault();
}
if(bSourceVideo())
CEepromSaveSystemData();
return result;
}
//--------------------------------------------------
// Description : Wait auto measure process completed
// Input Value : None
// Output Value : Return result _ERROR_INPUT, _ERROR_SUCCESS
//--------------------------------------------------
BYTE CAutoWaitFinish(void)
{
BYTE timeoutcnt, ivsevent;
BYTE valuetemp;//tommy add 070608
CMiscClearStatusRegister();
// Auto timeout
#if 1
//{ add 070608
//tommy liao add for prevent (ADD PC_AUTOADJUST ITEM) ERROR
//tommy add for prevent execute funtion of (COsdMenuAutoAdjust) error
//warning!!!!!!!!!!!!,don't delete the below function
//warning!!!!!!!!!!!!,or if you change ,can cause serious error,can cause system error
CScalerRead(_AUTO_ADJ_CTRL0_7A, 1, &valuetemp, _AUTOINC);
valuetemp = (valuetemp&0x03);
if( valuetemp == 0x03 )
timeoutcnt = 150;
else
timeoutcnt = 50;
//warning!!!!!!!!!!!!,don't delete the up function
//} add 070608
#else
//tommy delete
//timeoutcnt = (CScalerGetBit(_AUTO_ADJ_CTRL0_7A, _BIT1 | _BIT0) == 0x03) ? 150 : 50;
#endif
// IVS timeout
ivsevent = 25;
do
{
CTimerDelayXms(1);
CScalerRead(_STATUS1_03, 1, pData, _NON_AUTOINC);
if(pData[0] & _EVENT_IVS)
{
CScalerSetByte(_STATUS1_03, 0x00);
ivsevent = 25;
}
else
{
ivsevent = ivsevent - 1;
}
if((ivsevent == 0) || (pData[0] & (_EVENT_UNDERFLOW | _EVENT_OVERFLOW)))
{
return _ERROR_INPUT;
}
// Power off while auto config--------
// CKeyCheckPowerKey(); cancel by weihao 940926
if(GET_POWERSWITCH())
return _ERROR_INPUT;
//------------------------------------
CScalerRead(_AUTO_ADJ_CTRL1_7D, 1, pData, _NON_AUTOINC);
}
while((pData[0] & 0x01) && (--timeoutcnt));
CScalerRead(_STATUS0_02, 1, pData, _NON_AUTOINC);
CScalerSetByte(_STATUS0_02, 0x00);
// Return non-zero value in Data[0] if :
// 1. IVS or IHS changed
// 2. Auto-Phase Tracking timeout
return ((pData[0] & 0x63) || (0 == timeoutcnt)) ? _ERROR_INPUT : _ERROR_SUCCESS;
}
//--------------------------------------------------
// Description : Wait for IVS process
// Input Value : ucTimes --> frames
// Output Value : Return underflow/overflow status
//--------------------------------------------------
BYTE CAutoWaitForIVS(BYTE ucTimes)
{
BYTE timeoutcnt;
timeoutcnt = 25;
CScalerSetByte(_STATUS1_03, 0x00);
do
{
CTimerDelayXms(1);
CScalerRead(_STATUS1_03, 1, pData, _NON_AUTOINC);
pData[0] &= (_EVENT_IVS | _EVENT_UNDERFLOW | _EVENT_OVERFLOW);
if(((pData[0] & _EVENT_IVS) == _EVENT_IVS) && (ucTimes != 0))
{
CScalerSetByte(_STATUS1_03, 0x00);
ucTimes--;
timeoutcnt = 25;
}
}
while((ucTimes != 0) && (--timeoutcnt) && ((pData[0] & (_EVENT_UNDERFLOW | _EVENT_OVERFLOW)) == 0));
return pData[0];
}
//--------------------------------------------------
// Description : Measure position H
// Input Value : ucNoiseMarginH --> Noise margin for H
// Output Value : Measure status
//--------------------------------------------------
BYTE CAutoMeasurePositionH(BYTE ucNoiseMarginH)
{
WORD lbound, rbound;
rbound = stModeUserData.Clock; // Totol Clock Number
lbound = (DWORD)rbound * stModeInfo.IHSyncPulseCount / stModeInfo.IHCount; // Clock number in HSYNC pulse
CScalerSetBit(_VGIP_HV_DELAY_1E, 0x0f, 0x50);
rbound = (rbound + _MEASURE_HDEALY) - 2;
rbound = rbound - 32;
lbound = (lbound + 20 + _MEASURE_HDEALY) < stModeInfo.IHStartPos ? (lbound + 20 + _MEASURE_HDEALY) : 0x0001;
lbound = (lbound > 32) ? (lbound - 32) : 0x0001;
ucNoiseMarginH &= 0xfc;
pData[0] = ((lbound >> 4) & 0x70) | (HIBYTE(rbound) & 0x0f);
pData[1] = (LOBYTE(lbound));
pData[2] = (LOBYTE(rbound));
CScalerWrite(_H_BOUNDARY_H_70, 3, pData, _AUTOINC);
pData[0] = ucNoiseMarginH;
pData[1] = ucNoiseMarginH;
pData[2] = ucNoiseMarginH;
pData[3] = 0x00;
pData[4] = 0x00;
pData[5] = 0x00;
pData[6] = 0x00;
pData[7] = 0x01;
CScalerWrite(_RED_NOISE_MARGIN_76, 8, pData, _AUTOINC);
pData[0] = CAutoWaitFinish();
if(pData[0] != _ERROR_SUCCESS)
return pData[0];
CScalerRead(_H_START_END_H_81, 3, &pData[8], _AUTOINC);
usHStartPos = (((WORD)(pData[8] & 0xf0 ) << 4) | (WORD)pData[9]) + 32;
usHEndPos = (((WORD)(pData[8] & 0x0f ) << 8) | (WORD)pData[10]) + 32;
return _ERROR_SUCCESS;
}
//--------------------------------------------------
// Description : Measure position V
// Input Value : ucNoiseMarginV --> Noise margin for V
// Output Value : Measure status
//--------------------------------------------------
BYTE CAutoMeasurePositionV(BYTE ucNoiseMarginV)
{
WORD lbound, rbound;
rbound = stModeUserData.Clock; // Totol Clock Number
lbound = (DWORD)rbound * stModeInfo.IHSyncPulseCount / stModeInfo.IHCount; // Clock number in HSYNC pulse
CScalerSetBit(_VGIP_HV_DELAY_1E, 0x0f, 0x50);
rbound = (rbound + _MEASURE_HDEALY) - 2;
rbound = rbound - 32;
lbound = (lbound + 20 + _MEASURE_HDEALY) < stModeInfo.IHStartPos ? (lbound + 20 + _MEASURE_HDEALY) : 0x0001;
lbound = (lbound > 32) ? (lbound - 32) : 0x0001;
ucNoiseMarginV &= 0xfc;
pData[0] = ((lbound >> 4) & 0x70) | (HIBYTE(rbound) & 0x0f);
pData[1] = (LOBYTE(lbound));
pData[2] = (LOBYTE(rbound));
pData[3] = (HIBYTE(stModeInfo.IVTotal - 1 + 3) & 0x0f);
pData[4] = (0x02);
pData[5] = (LOBYTE(stModeInfo.IVTotal - 1 + 3));
CScalerWrite(_H_BOUNDARY_H_70, 6, pData, _AUTOINC);
pData[0] = ucNoiseMarginV;
pData[1] = ucNoiseMarginV;
pData[2] = ucNoiseMarginV;
pData[3] = 0x00;
pData[4] = 0x00;
pData[5] = 0x00;
pData[6] = 0x00;
pData[7] = 0x01;
CScalerWrite(_RED_NOISE_MARGIN_76, 8, pData, _AUTOINC);
pData[0] = CAutoWaitFinish();
if(pData[0] != _ERROR_SUCCESS)
return pData[0];
CScalerRead(_V_START_END_H_7E, 3, &pData[8], _AUTOINC);
usVStartPos = (((WORD)(pData[8] & 0xf0 ) << 4) | (WORD)pData[9]) + 3;
usVEndPos = (((WORD)(pData[8] & 0x0f ) << 8) | (WORD)pData[10]) + 3;
// Check all black
if(usVEndPos == 0x0000)
return _ERROR_ABORT;
// Update auto-tracking window vertical range
pData[0] = (pData[8] & 0x7f);
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;
BYTE count, best;
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);
if(((DWORD)stModeInfo.IHFreq * stModeInfo.IHTotal / 1000) < 530){
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.
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;
if(((DWORD)stModeInfo.IHFreq * stModeInfo.IHTotal / 1000) < 530)
{
*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)
{
CScalerSetBit(_AUTO_ADJ_CTRL0_7A, ~(_BIT1 | _BIT0), ucColor & 0x03);
CScalerSetByte(_AUTO_ADJ_CTRL1_7D, 0x3b);
pData[0] = CAutoWaitFinish();
if(_ERROR_SUCCESS != pData[0])
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, phase;
WORD count, delta, stop;
DWORD maxval;
stModeUserData.Clock = stModeInfo.IHTotal;
stModeUserData.Clock &= 0xfffc;
CAdjustAdcClock(stModeUserData.Clock);
result = CAutoMeasurePositionV(_MIN_NOISE_MARGIN);
if(result != _ERROR_SUCCESS)
return result;
delta = (stModeInfo.IHTotal - stModeInfo.IHWidth * 8 / 10) / 2;
stop = 0;
count = 10;
do
{
// Measure Horizontal Start/End
//result = CAutoMeasurePositionH(_MIN_NOISE_MARGIN + 0x10);
result = CAutoMeasurePositionH(_MIN_NOISE_MARGIN + 0x30);
if(result != _ERROR_SUCCESS)
return result;
usHEndPos = usHEndPos + 1 - usHStartPos;
if(usHEndPos < stModeInfo.IHWidth)
{
if((stModeInfo.IHWidth - usHEndPos) >= (2 * delta))
{
stop = 1;
}
else
{
usHStartPos = (DWORD)(stModeInfo.IHWidth - usHEndPos) * (stModeUserData.Clock)
/ (DWORD)stModeInfo.IHWidth;
if(usHStartPos <= 2) break;
usHStartPos = (usHStartPos + 2) & 0xfffc;
//if((usHStartPos + stModeUserData.Clock - stModeInfo.IHTotal) > usDelta)
if((usHStartPos + stModeUserData.Clock) > (delta + stModeInfo.IHTotal))
{
stop = 1;
}
else
{
stModeUserData.Clock += usHStartPos;
}
}
}
else
{
if((usHEndPos - stModeInfo.IHWidth) >= (2 * delta))
{
stop = 1;
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -