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

📄 auto.c

📁 realtek LCD monitor, TV开发源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    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 + -