⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 auto.c

📁 RTD2662板卡源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
                usHStartPos = (DWORD)(usHEndPos - stModeInfo.IHWidth) * (stModeUserData.Clock)
                            / (DWORD)stModeInfo.IHWidth;

                if(usHStartPos <= 2)    break;
                usHStartPos = (usHStartPos + 2) & 0xfffc;

                //if((stModeInfo.IHTotal - (stModeUserData.Clock - usHStartPos)) > usDelta)
                if((usHStartPos + stModeInfo.IHTotal) > (delta + stModeUserData.Clock))
                {
                    stop    = 1;
                }
                else
                {
                    stModeUserData.Clock -= usHStartPos;
                }
            }
        }
        if(stop)   break;
        CAdjustAdcClock(stModeUserData.Clock);
    }
    while(--count);
    if((count == 0) || (stop == 1))
		return _ERROR_ABORT;
    // Prevent from 1/2-line moire and smear effect.
    if((usHEndPos >= stModeInfo.IHWidth && (stModeUserData.Clock - stModeInfo.IHTotal) == 4)
       || (usHEndPos < stModeInfo.IHWidth && (stModeInfo.IHTotal - stModeUserData.Clock) == 4))
    {
        stModeUserData.Clock = stModeInfo.IHTotal;
        CAdjustAdcClock(stModeUserData.Clock);
        result    = CAutoMeasurePositionH(_MIN_NOISE_MARGIN + 0x10);
        if(result != _ERROR_SUCCESS)
			return result;
        usHEndPos   = usHEndPos + 1 - usHStartPos;
    }

#if(_AUTO_CLOCK_PRECISION < 4)
    // Save 4N clock
    stop    = stModeUserData.Clock;
    stModeUserData.Clock += (stModeInfo.IHWidth >= usHEndPos) ? 4 : 2;
    CAdjustAdcClock(stModeUserData.Clock);
    // 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;
        usHEndPos   = usHEndPos + 1 - usHStartPos;
        if(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;
                CAdjustAdcClock(stModeUserData.Clock);
                continue;
            }
            break;
        }
        delta                   -= _AUTO_CLOCK_PRECISION;
        stModeUserData.Clock    -= _AUTO_CLOCK_PRECISION;
        CAdjustAdcClock(stModeUserData.Clock);
    }
    while(_TRUE);
    maxval = maxval / 3;
    stModeUserData.Clock    = (maxval > ((DWORD)stModeInfo.IHWidth << 10)) ? count : stop;
//	if (stModeUserData.Clock > 100)
//		stModeUserData.Clock = 100;	// within range
    CAdjustAdcClock(stModeUserData.Clock);
#endif
    return _ERROR_SUCCESS;
}

//--------------------------------------------------
// Description  : Auto phase process
// Input Value  : None
// Output Value : Measure status
//--------------------------------------------------
BYTE CAutoDoAutoPhase(void)
{
    BYTE  result, phase, best;
    DWORD maxsum, temp0, temp1, temp2;

    result = CAutoMeasurePositionH(_MIN_NOISE_MARGIN);
    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 < ((DWORD)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 < ((DWORD)stModeInfo.IVHeight * 1024 * 3 / 2))
            return _ERROR_PHASE;
    }

    // Issac:
    // Please do not delete these backup code below.
    /*if(((DWORD)stModeInfo.IHFreq * stModeInfo.IHTotal / 1000) < 530)
    {
        BYTE  count, ucSelStep, ucSelColor;

        CScalerSetByte(_AUTO_ADJ_CTRL1_7D, 0x00);

        ucSelStep   = (0x01 << _HWAUTO_STEP_2);
        count       = ((result - 8) & 0x3f);
        ucSelColor  = count + (8 * ucSelStep);
        maxsum      = 0;
        best        = 0;

        do
        {
            CAdjustPhase(count);

            if(_ERROR_SUCCESS != CAutoReadPhaseInfo(_COLOR_SELECT))   return _ERROR_INPUT;

            if(((DWORD *)pData)[0] > maxsum)
            {
                maxsum  = ((DWORD *)pData)[0];
                best    = count;
            }

            count += ucSelStep;
        }
        while(count < ucSelColor);

        CScalerSetByte(_AUTO_ADJ_CTRL1_7D, 0x00);

        result = best & 0x3f;
    }
    else
    */	 
	{
    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   = ((DWORD *)pData)[0];

    phase   = (phase + 1) & 0x3f;
    CAdjustPhase(phase);

    if(_ERROR_SUCCESS != CAutoReadPhaseInfo(_COLOR_SELECT))
		return _ERROR_INPUT;
    temp1   = ((DWORD *)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   = ((DWORD *)pData)[0];

        ((DWORD *)pData)[0] = temp2 + temp1 + temp0
                              - ((temp1 > temp0 ? temp1 - temp0 : temp0 - temp1) / 2)
                              - ((temp1 > temp2 ? temp1 - temp2 : temp2 - temp1) / 2);

        if(((DWORD *)pData)[0] > maxsum)
        {
            maxsum  = ((DWORD *)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_18, 2, pData, _AUTOINC);
    ctemp = (((WORD)(pData[0] & 0x07)) << 8) | pData[1];

    CScalerRead(_IVS_DELAY_1C, 1, pData, _AUTOINC);
    CScalerRead(_VGIP_HV_DELAY_1E, 1, &pData[1], _AUTOINC);
    dtemp = (((WORD)(pData[1] & _BIT1)) << 8) | pData[0];
    dtemp = usVStartPos - dtemp;
    atemp = (stModeInfo.IVHeight - (usVEndPos - usVStartPos + 1));
    if(atemp > 3)
    atemp = abs(usVEndPos - usVStartPos + 1 - stModeInfo.IVHeight) / 2;
    else
        atemp = 0;
    while(_TRUE)
    {
        if(abs(stModeUserData.VPosition + (ctemp - dtemp) - stModeInfo.IVStartPos + atemp) <= ucVStartBias)
        {
#if(_V_POSITION_DIRECTION == _V_POSITION_METHOD_0)
            stModeUserData.VPosition += ctemp - dtemp + atemp;
#endif

#if(_V_POSITION_DIRECTION == _V_POSITION_METHOD_1)
            stModeUserData.VPosition -= ctemp - dtemp + atemp;
#endif
            break;
        }
        else
        {
            stModeUserData.VPosition = stModeInfo.IVStartPos;
            break;
        }
    }
    CAdjustVPosition();
    ///////////////////////////////////
    // Calculate Horizontal Position //
    ///////////////////////////////////
    CScalerRead(_IPH_ACT_STA_H_14, 2, pData, _AUTOINC);
    ctemp = (((WORD)(pData[0] & 0x07)) << 8) | pData[1];
    CScalerRead(_IHS_DELAY_1D, 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;
}

#define _AUTO_VGA_MAX_LEVEL                          242
#define _AUTO_VGA_MIN_LEVEL                           2
#define _AUTO_COMPONENT_Y_MAX_LEVEL         250
#define _AUTO_COMPONENT_Y_MIN_LEVEL         12
#define _AUTO_COMPONENT_PB_MAX_LEVEL       240
#define _AUTO_COMPONENT_PR_MAX_LEVEL       240
#define _AUTO_VIDEO8_Y_MAX_LEVEL                 248 
#define _AUTO_VIDEO8_Y_MIN_LEVEL                 2//12
#define _AUTO_VIDEO8_C_MAX_LEVEL                 236 //this value can't over 240 


#define _CHROMA_BLACK_LEVEL             0x80

void CGetTargetValue(UINT8* max_value, UINT8* min_value, UINT8 color)
{
        switch(_GET_INPUT_SOURCE())
        {
               case _SOURCE_VGA:
			  *max_value = _AUTO_VGA_MAX_LEVEL;
			  *min_value = _AUTO_VGA_MIN_LEVEL;			  
			  break;
		 case _SOURCE_YPBPR:
		 	  if(color == _GREEN)
		 	  {
		 	      *max_value = _AUTO_COMPONENT_Y_MAX_LEVEL;
				*min_value = _AUTO_COMPONENT_Y_MIN_LEVEL;
		 	  }
			  else
			  {
			      *max_value = (color == _RED) ? _AUTO_COMPONENT_PR_MAX_LEVEL : _AUTO_COMPONENT_PB_MAX_LEVEL;			      
			      *min_value = _CHROMA_BLACK_LEVEL;
			  }
			  break;
			  
#if(_VIDEO_AUTO_WHITE_BLANCE == _ENABLE)			  
	        case _SOURCE_VIDEO_AV: //VIDEO8
	        case _SOURCE_VIDEO_SV: //VIDEO8
	        case _SOURCE_VIDEO_TV: //VIDEO8
	                if(color == _GREEN)
	                {
	                   *max_value = _AUTO_VIDEO8_Y_MAX_LEVEL;
			     *min_value = _AUTO_VIDEO8_Y_MIN_LEVEL;
	                }
			  else
			  {
			     *max_value = _AUTO_VIDEO8_C_MAX_LEVEL;
			     *min_value = _CHROMA_BLACK_LEVEL;
			  }
		         break;
#endif				 
				
        }
}
/*
#define VIDEO8_Y_MAX_LEVEL          250 
#define VIDEO8_Y_MIN_LEVEL           6
#define VIDEO8_C_MAX_LEVEL          240
*/

//--------------------------------------------------
// Description  : Tune ADC gain and offset
// Input Value  : None
// Output Value : Measure status
//--------------------------------------------------
BYTE CAutoTuneBalance(void)
{
	BYTE rev, result0, result1, color, count;
	BYTE xdata ucMax_Value, ucMin_Value;

	if(_GET_INPUT_SOURCE() == _SOURCE_VGA)// VGA
	{		
       	for(count=0;count<3;count++)
		{
       		stAdcData.AdcGain[count] = 0x80;
       		stAdcData.AdcOffset[count] = 0x80;
		}
		CAdjustAdcGainOffset();//jerry0921
	}
	else if(_GET_INPUT_SOURCE() == _SOURCE_YPBPR )// YPBPR
	{	
		for(count=0;count<3;count++)
    		{
       		stYPbPrData.YPbPrGain[count] = 0x80;
       		stYPbPrData.YPbPrOffset[count] = 0x80;
    		}
		CAdjustAdcGainOffset();//jerry0921
	}
#if(_VIDEO_AUTO_WHITE_BLANCE == _ENABLE)
	else if(bSourceVideo())// AV / SV / TV
	{	
		SET_CONTRAST(50);				// set OSD default value  to 50
		SET_SATURATION(50);				// set OSD default value to 50
		SET_VDC_GAIN(0x80);
		SET_VDC_OFFSET(0x80);
		SET_VDC_CHROMA(0x80);
		CVideoSetVDCContrast(0x80);
 		CVideoSetVDCBrightness(0x80);
		CVideoSetVDCSaturation(0x80);
	#if(sRGB_Color_Enhance == _ENABLE)
		CAdjustSaturationHue(50, _TRUE);// set to OSD default value is 50
	#endif
	}
#endif


    	rev = CAutoMeasurePositionV(_MIN_NOISE_MARGIN);
    	if(rev != _ERROR_SUCCESS)    return rev;

    	rev = CAutoMeasurePositionH(_MIN_NOISE_MARGIN);
    	if(rev != _ERROR_SUCCESS)    return rev;

    	if(CAutoMeasureColor(_BLUE, _MEASURE_COLORS_MAX, &rev) != _ERROR_SUCCESS)       return _ERROR_ABORT;
    	if(rev < 0x60)              return _ERROR_ABORT;

    	if(CAutoMeasureColor(_GREEN, _MEASURE_COLORS_MAX, &rev) != _ERROR_SUCCESS)      return _ERROR_ABORT;
    	if(rev < 0x60)              return _ERROR_ABORT;

    	if(CAutoMeasureColor(_RED, _MEASURE_COLORS_MAX, &rev) != _ERROR_SUCCESS)        return _ERROR_ABORT;
    	if(rev < 0x60)              return _ERROR_ABORT;

	if(bSourceVideo())
		color = _GREEN;			  //we don't measure the blue color in VIDEO8 auto color
	else
    	       color = _BLUE;
	
    	while(_TRUE)
    	{
        	count = 0x30;

		CGetTargetValue(&ucMax_Value, &ucMin_Value, color);

        	do
        	{
		
			rev = CAutoTuneDeviceGain(color, &result0, ucMax_Value);

            		if(rev == _ERROR_ABORT)     return rev;
            		if(rev == _ERROR_FINISH)    break;
			rev = CAutoTuneDeviceOffset(color, &result1, ucMin_Value);
		#if(_VIDEO_AUTO_WHITE_BLANCE == _ENABLE)
        	if(bSourceVideo())
			{
                        //Chroma doesn't need to adjust the offset
				if(color != _GREEN)
				result1 = ucMin_Value;
			}		
		#endif
            		if(rev == _ERROR_ABORT)     
				return rev;

            		if((result0 == ucMax_Value) && (result1 == ucMin_Value))
                		break;

            		if((count > 8) && (result0 <= (ucMax_Value + 1)) && (result0 >= (ucMax_Value - 1))
                		&& (result1 <= (ucMin_Value + 1)) && (result1 >= (ucMin_Value - 1)))
            		{
                		count = 8;
            		}
		}
		while(--count);

		if(color == _BLUE)				// 2 : Blue or PB
            		color = _GREEN;
		else if(color == _GREEN)		// 1: Green or Y
            		color = _RED;
		else 						// 0: Red or PR
            		break;
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -