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

📄 auto.c

📁 车载 液晶显示器的主控程序(主要使用芯片为 MYSON MTV512 单片机、RealTek 2323 Scare 芯片、TVP5147(视频解码)。配Sharp 8寸液晶显示器 )。
💻 C
📖 第 1 页 / 共 4 页
字号:
//--------------------------------------------------
// Description  : Measure position V
// Input Value  : ucNoiseMarginV    --> Noise margin for V
// Output Value : Measure status
//--------------------------------------------------
BYTE CAutoMeasurePositionV(BYTE ucNoiseMarginV)
{
    WORD lbound, rbound;

    rbound  = stModeInfo.IHTotal;                                                 // Totol Clock Number
    lbound  = (LWORD)rbound * stModeInfo.IHSyncPulseCount / stModeInfo.IHCount;   // Clock number in HSYNC pulse

    CScalerSetBit(_VGIP_HV_DELAY_13, 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;
}
*/

//version 200D
//--------------------------------------------------
// 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  = (LWORD)rbound * stModeInfo.IHSyncPulseCount / stModeInfo.IHCount;   // Clock number in HSYNC pulse

    CScalerSetBit(_VGIP_HV_DELAY_13, 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 : 
//--------------------------------------------------
LWORD CAutoPhaseSearch(BYTE ucSelColor, BYTE ucSelStep, BYTE ucSelStepNum, BYTE ucSelStepStart, BYTE *ucPhaseResult)
{
    LWORD 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);

    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))
            return 0xffffffff;

        CScalerRead(_AUTO_PHASE_3_84, 3, pData, _AUTOINC);

        pData[3]    = 0;

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

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

    CScalerSetByte(_AUTO_ADJ_CTRL1_7D, 0x00);

    CTimerWaitForEvent(_EVENT_IVS);

    pData[0] = CAutoWaitFinish();

    if(pData[0] != _ERROR_SUCCESS)  return 0xffffffff;

    *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;
    LWORD   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 - (LWORD)stModeInfo.IHTotal * (LWORD)stModeInfo.IHSyncPulseCount / stModeInfo.IHCount) * 4 / 10;

    stop    = 0;
    count   = 10;

    do
    {
        // Measure Horizontal Start/End
        result      = CAutoMeasurePositionH(_MIN_NOISE_MARGIN + 0x10);

        if(result != _ERROR_SUCCESS)    return result;

        usHEndPos   = usHEndPos + 1 - usHStartPos;

        if(usHEndPos < stModeInfo.IHWidth)
        {
            if((stModeInfo.IHWidth - usHEndPos) >= (2 * delta))
            {
                stop    = 1;
            }
            else
            {
                usHStartPos = (LWORD)(stModeInfo.IHWidth - usHEndPos) * (stModeUserData.Clock)
                            / (LWORD)stModeInfo.IHWidth;
                usHStartPos = (usHStartPos + 2) & 0xfffc;

                //if((usHStartPos + (stModeInfo.IHTotal - stModeUserData.Clock)) > usDelta)
                if((usHStartPos + stModeInfo.IHTotal) > (delta + stModeUserData.Clock))
                {
                    stop    = 1;
                }
                else
                {
                    stModeUserData.Clock += usHStartPos;
                }
            }
        }
        else
        {
            if((usHEndPos - stModeInfo.IHWidth) >= (2 * delta))
            {
                stop    = 1;
            }
            else
            {
                usHStartPos = (LWORD)(usHEndPos - stModeInfo.IHWidth) * (stModeUserData.Clock)
                            / (LWORD)stModeInfo.IHWidth;
                usHStartPos = (usHStartPos + 2) & 0xfffc;

                //if((usHStartPos + (stModeUserData.Clock - stModeInfo.IHTotal)) > usDelta)
                if((usHStartPos + stModeUserData.Clock) > (delta + stModeInfo.IHTotal))
                {
                    stop    = 1;
                }
                else
                {
                    stModeUserData.Clock -= usHStartPos;
                }
            }
        }

        if(stop)   break;

        CAdjustAdcClock(stModeUserData.Clock);

        if(usHStartPos == 0)  break;
    }
    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))
        {
            ((LWORD *)pData)[0]   = 0;
        }
        else
        {
            ((LWORD *)pData)[0]   = CAutoPhaseSearch(_COLOR_SELECT, _HWAUTO_STEP_8, HWAUTOSTEPNUM(8), HWAUTOSTEPSTART(0), &phase);

            if (0xffffffffL == ((LWORD *)pData)[0])   return _ERROR_INPUT;
        }

        if(maxval < ((LWORD *)pData)[0])
        {
            maxval    = ((LWORD *)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 > ((LWORD)stModeInfo.IHWidth << 10)) ? count : stop;
    CAdjustAdcClock(stModeUserData.Clock);

#endif

⌨️ 快捷键说明

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