📄 auto.c
字号:
if(_ERROR_SUCCESS != result) return result;
// Set threshold 0x80 for Phase Search
CScalerSetByte(_DIFF_THRESHOLD_79, 0x80);
maxsum = CAutoPhaseSearch(_COLOR_SELECT, _HWAUTO_STEP_8, HWAUTOSTEPNUM(8), HWAUTOSTEPSTART(0), &result);
if(maxsum == 0xffffffffL) return _ERROR_INPUT;
if(maxsum == 0) return _ERROR_ABORT;
if(maxsum < ((LWORD)stModeInfo.IVHeight * 1024 * 3 / 2))
{
// Decrease threshold to 0x40 for Phase Search
CScalerSetByte(_DIFF_THRESHOLD_79, 0x40);
maxsum = CAutoPhaseSearch(_COLOR_SELECT, _HWAUTO_STEP_8, HWAUTOSTEPNUM(8), HWAUTOSTEPSTART(0), &result);
if(maxsum == 0xffffffffL) return _ERROR_INPUT;
if(maxsum == 0) return _ERROR_ABORT;
if(maxsum < ((LWORD)stModeInfo.IVHeight * 1024 * 3 / 2))
return _ERROR_PHASE;
}
maxsum = CAutoPhaseSearch(_COLOR_SELECT, _HWAUTO_STEP_2, HWAUTOSTEPNUM(8), HWAUTOSTEPSTART((result - 8) & 0x3f), &result);
if(maxsum == 0xffffffffL) return _ERROR_INPUT;
if(maxsum == 0) return _ERROR_ABORT;
// Search phase by weighting SOD
phase = (result - 3) & 0x3f;
CAdjustPhase(phase);
if(_ERROR_SUCCESS != CAutoReadPhaseInfo(_COLOR_SELECT)) return _ERROR_INPUT;
temp0 = ((LWORD *)pData)[0];
phase = (phase + 1) & 0x3f;
CAdjustPhase(phase);
if(_ERROR_SUCCESS != CAutoReadPhaseInfo(_COLOR_SELECT)) return _ERROR_INPUT;
temp1 = ((LWORD *)pData)[0];
result = (result + 3) & 0x3f;
maxsum = 0;
do
{
phase = (phase + 1) & 0x3f;
CAdjustPhase(phase);
if(_ERROR_SUCCESS != CAutoReadPhaseInfo(_COLOR_SELECT)) return _ERROR_INPUT;
temp2 = ((LWORD *)pData)[0];
((LWORD *)pData)[0] = temp2 + temp1 + temp0
- ((temp1 > temp0 ? temp1 - temp0 : temp0 - temp1) / 2)
- ((temp1 > temp2 ? temp1 - temp2 : temp2 - temp1) / 2);
if(((LWORD *)pData)[0] > maxsum)
{
maxsum = ((LWORD *)pData)[0];
best = (phase - 1) & 0x3f;
}
temp0 = temp1;
temp1 = temp2;
}
while(phase != result);
stModeUserData.Phase = best;
CAdjustPhase(stModeUserData.Phase);
CScalerSetByte(_DIFF_THRESHOLD_79, 0x40);
return _ERROR_SUCCESS;
}
//--------------------------------------------------
// Description : Auto position process
// Input Value : None
// Output Value : Measure status
//--------------------------------------------------
BYTE CAutoDoAutoPosition(void)
{
BYTE result;
SWORD dtemp, ctemp, atemp;
result = CAutoMeasurePositionV(_MIN_NOISE_MARGIN);
if(_ERROR_SUCCESS != result) return result;
result = CAutoMeasurePositionH(_MIN_NOISE_MARGIN);
if(_ERROR_SUCCESS != result) return result;
/////////////////////////////////
// Calculate Vertical Position //
/////////////////////////////////
CScalerRead(_IPV_ACT_STA_H_0D, 2, pData, _AUTOINC);
ctemp = (((WORD)(pData[0] & 0x07)) << 8) | pData[1];
CScalerRead(_IVS_DELAY_11, 1, pData, _AUTOINC);
CScalerRead(_VGIP_HV_DELAY_13, 1, &pData[1], _AUTOINC);
dtemp = (((WORD)(pData[1] & _BIT1)) << 8) | pData[0];
dtemp = usVStartPos - dtemp;
atemp = abs(usVEndPos - usVStartPos + 1 - stModeInfo.IVHeight) / 2;
while(_TRUE)
{
if(abs(stModeUserData.VPosition + (ctemp - dtemp) - stModeInfo.IVStartPos + atemp) <= ucVStartBias)
{
#if(_V_POSITION_DIRECTION == _LAST_LINE_METHOD_0)
stModeUserData.VPosition += ctemp - dtemp + atemp;
#endif
#if(_V_POSITION_DIRECTION == _LAST_LINE_METHOD_1)
stModeUserData.VPosition -= ctemp - dtemp + atemp;
#endif
break;
}
else
{
stModeUserData.VPosition = stModeInfo.IVStartPos;
break;
}
}
CAdjustVPosition();
///////////////////////////////////
// Calculate Horizontal Position //
///////////////////////////////////
CScalerRead(_IPH_ACT_STA_H_09, 2, pData, _AUTOINC);
ctemp = (((WORD)(pData[0] & 0x07)) << 8) | pData[1];
CScalerRead(_IHS_DELAY_12, 2, pData, _AUTOINC);
dtemp = (((WORD)(pData[1] & _BIT0)) << 8) | pData[0];
dtemp = usHStartPos - dtemp - 2;
while(_TRUE)
{
if(abs(stModeUserData.HPosition + (ctemp - dtemp) - stModeInfo.IHStartPos) <= ucHStartBias)
{
stModeUserData.HPosition += ctemp - dtemp;
break;
}
else
{
stModeUserData.HPosition = stModeInfo.IHStartPos;
break;
}
}
CAdjustHPosition();
return _ERROR_SUCCESS;
}
//--------------------------------------------------
// Description : Tune ADC gain and offset
// Input Value : None
// Output Value : Measure status
//--------------------------------------------------
BYTE CAutoTuneBalance(void)
{
BYTE rev, result0, result1, color, count;
rev = CAutoMeasurePositionV(_MIN_NOISE_MARGIN);
if(rev != _ERROR_SUCCESS) return rev;
rev = CAutoMeasurePositionH(_MIN_NOISE_MARGIN);
if(rev != _ERROR_SUCCESS) return rev;
color = _BLUE;
while(_TRUE)
{
count = 0x30;
do
{
rev = CAutoTuneAdcGain(color, &result0);
if(rev == _ERROR_ABORT) return rev;
if(rev == _ERROR_FINISH) break;
rev = CAutoTuneAdcOffset(color, &result1);
if(rev == _ERROR_ABORT) return rev;
if(result0 == _WHITEBALANCE_MAX_LEVEL)
break;
}
while(--count);
if(color == _BLUE)
color = _GREEN;
else if(color == _GREEN)
color = _RED;
else
break;
}
return _ERROR_SUCCESS;
}
//--------------------------------------------------
// Description : Get max or min color value
// Input Value : Measure information
// Output Value : Measure status
//--------------------------------------------------
BYTE CAutoMeasureColor(BYTE ucColor, BYTE ucPar, BYTE *pMargin)
{
CScalerSetBit(_AUTO_ADJ_CTRL0_7A, ~(_BIT2 | _BIT1 | _BIT0), (ucColor == 3) ? ucColor : ( 2 - ucColor));
if(ucPar == _MEASURE_COLORS_MIN)
{
pData[0] = 0x12;
pData[1] = 0x80;
pData[2] = 0x00;
pData[3] = 0x00;
pData[4] = (usVStartPos > 9) ? 9 : (usVStartPos - 1);
pData[5] = pData[4] + 1;
}
else
{
pData[0] = ((usHStartPos >> 4) & 0x70) | (HIBYTE(usHEndPos) & 0x0f);
pData[1] = (LOBYTE(usHStartPos));
pData[2] = (LOBYTE(usHEndPos));
pData[3] = ((usVStartPos >> 4) & 0x70) | (HIBYTE(usVEndPos) & 0x0f);
pData[4] = (LOBYTE(usVStartPos));
pData[5] = (LOBYTE(usVEndPos));
}
CScalerWrite(_H_BOUNDARY_H_70, 6, pData, _AUTOINC);
CScalerSetByte(_AUTO_ADJ_CTRL1_7D, 0x01 | ((ucPar & 0x01) << 5));
pData[0] = CAutoWaitFinish();
if(pData[0] != _ERROR_SUCCESS) return pData[0];
CScalerRead(_AUTO_PHASE_0_87, 1, pMargin, _AUTOINC);
if(ucPar == _MEASURE_COLORS_MIN)
*pMargin ^= 0xff;
return _ERROR_SUCCESS;
}
//--------------------------------------------------
// Description : Adjust ADC gain
// Input Value : Adjusting setting
// Output Value : Measure status
//--------------------------------------------------
BYTE CAutoTuneAdcGain(BYTE ucColor, BYTE *pMargin)
{
BYTE temp;
if(CAutoMeasureColor(ucColor, _MEASURE_COLORS_MAX, pMargin) != _ERROR_SUCCESS)
return _ERROR_ABORT;
if(*pMargin > _WHITEBALANCE_MAX_LEVEL)
{
temp = *pMargin - _WHITEBALANCE_MAX_LEVEL;
// Non-zero return value of Change_ADC_Gain() means ADC gain reaches maximum.
if(CAutoChangeAdcGain(ucColor, temp, 0)) // Increase Gain; Decrease Contrast
{
if(CAutoChangeAdcOffset(ucColor, 4, 0)) // Increase Offset; Decrease Brightness
return _ERROR_FINISH;
}
}
else if(*pMargin < _WHITEBALANCE_MAX_LEVEL)
{
temp = _WHITEBALANCE_MAX_LEVEL - *pMargin;
// Non-zero return value of Change_ADC_Gain() means ADC gain reaches minimum.
if(CAutoChangeAdcGain(ucColor, temp, 1)) // Decrease Gain; Increase Contrast
{
if(CAutoChangeAdcOffset(ucColor, 4, 1)) // Decrease Offset; Increase Brightness
return _ERROR_FINISH;
}
}
return _ERROR_SUCCESS;
}
//--------------------------------------------------
// Description : Adjust ADC offset
// Input Value : Adjusting setting
// Output Value : Measure status
//--------------------------------------------------
BYTE CAutoTuneAdcOffset(BYTE ucColor, BYTE *pMargin)
{
BYTE temp;
if(CAutoMeasureColor(ucColor, _MEASURE_COLORS_MIN, pMargin) != _ERROR_SUCCESS)
return _ERROR_ABORT;
if(*pMargin > _WHITEBALANCE_MIN_LEVEL)
{
temp = *pMargin - _WHITEBALANCE_MIN_LEVEL;
CAutoChangeAdcOffset(ucColor, ((temp > 8) ? 8 : temp), 0); // Increase Offset; Decrease Brightness
}
else if(*pMargin < _WHITEBALANCE_MIN_LEVEL)
{
temp = _WHITEBALANCE_MIN_LEVEL - *pMargin;
if(*pMargin == 0)
CAutoChangeAdcOffset(ucColor, temp + 4, 1); // Decrease Offset; Increase Brightness
else
CAutoChangeAdcOffset(ucColor, temp, 1); // Decrease Offset; Increase Brightness
}
return _ERROR_SUCCESS;
}
//--------------------------------------------------
// Description : Change ADC gain
// Input Value : Input information
// Output Value : Return 1 if overrange
//--------------------------------------------------
BYTE CAutoChangeAdcGain(BYTE ucColor, BYTE ucDelta, BYTE ucInc)
{
BYTE overrange = 0;
if(ucInc)
{
if(stAdcData.AdcGain[ucColor] >= ucDelta)
stAdcData.AdcGain[ucColor] -= ucDelta;
else
{
stAdcData.AdcGain[ucColor] = 0;
overrange = 1;
}
}
else
{
if ((0xff - ucDelta) >= stAdcData.AdcGain[ucColor])
stAdcData.AdcGain[ucColor] += ucDelta;
else
{
stAdcData.AdcGain[ucColor] = 0xff;
overrange = 1;
}
}
CAdjustAdcGain();
return overrange;
}
//--------------------------------------------------
// Description : Change ADC offset
// Input Value : Input information
// Output Value : Return 1 if overrange
//--------------------------------------------------
BYTE CAutoChangeAdcOffset(BYTE ucColor, BYTE ucDelta, BYTE ucInc)
{
BYTE overrange = 0;
if(ucInc)
{
if(stAdcData.AdcOffset[ucColor] >= ucDelta)
stAdcData.AdcOffset[ucColor] -= ucDelta;
else
{
stAdcData.AdcOffset[ucColor] = 0;
overrange = 1;
}
}
else
{
if ((0xff - ucDelta) >= stAdcData.AdcOffset[ucColor])
stAdcData.AdcOffset[ucColor] += ucDelta;
else
{
stAdcData.AdcOffset[ucColor] = 0xff;
overrange = 1;
}
}
CAdjustAdcOffset();
return overrange;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -