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

📄 autofunc.c

📁 主要用于液晶电视解码,内置51单片机,全部代码用C编写,编译环境为KEILC
💻 C
📖 第 1 页 / 共 2 页
字号:
            msAdjustAdcClock(wHTotalBff + 1); // find increment
            wActualWidth = msAutoGetActualWidth(ucVSyncTime);
            if (wActualWidth == wStdWidth) // match width
                wHTotalBff++;
        }
    }

#ifdef AUTO_DEBUG_EN
    printf("\r\nH. Total = %x", wHTotalBff);
    printf("(%d)", wHTotalBff);
#endif

    // check horizontal total range
    if (abs(wHTotalBff - (StandardModeHTotal)) < ADJUST_CLOCK_RANGE)
    {
        g_ModeSetting.HTotal= wHTotalBff;
        bResult = TRUE;
    #ifdef AUTO_DEBUG_EN
        putstr("\r\nmsAutoTuneHTotal success");
    #endif
    }

    msAdjustAdcClock(g_ModeSetting.HTotal); // setting ADC clock
    msAdjustAdcPhase(g_ModeSetting.Phase); // setting ADC phase

    return bResult;
}

///////////////////////////////////////////////////////////////////////////////
// <Function>: msAutoGetPhaseVal
//
// <Description>: get auto phase value.
//
// <Returns> : auto phase value.
///////////////////////////////////////////////////////////////////////////////
DWORD msAutoGetPhaseVal(void)
{
    DWordType dwPhaseValBff; // double word buffer
    BYTE ucBank;

    ucBank = msReadByte( BK0_00_REGBK);

    msWriteByte( BK0_00_REGBK, REG_BANK_SCALER );

    msAutoWaitStatusReady(BK0_DB_ATPCTRL, _BIT1);
    dwPhaseValBff.separate._byte0 = msReadByte(BK0_DC_ATPV1);
    dwPhaseValBff.separate._byte1 = msReadByte(BK0_DD_ATPV2);
    dwPhaseValBff.separate._byte2 = msReadByte(BK0_DE_ATPV3);
    dwPhaseValBff.separate._byte3 = msReadByte(BK0_DF_ATPV4);

    msWriteByte( BK0_00_REGBK, ucBank );

    return dwPhaseValBff.total;
}

///////////////////////////////////////////////////////////////////////////////
// <Function>: msAutoTunePhase
//
// <Description>: auto-tune phase.
//
// <Returns> : Success status.
//
// <Parameter>:  -  <Flow>  -  <Description>
//-----------------------------------------------------------------------------
//  ucVSyncTime  -    In    -   VSync time
///////////////////////////////////////////////////////////////////////////////
#define AUTO_PHASE_STEP 4

BOOL msAutoTunePhase(BYTE ucVSyncTime)
{
    BYTE ucIndex; // loop index

    DWORD dwAutoPhaseVal; // auto phase value result
#if AUTO_PHASE_METHOD
{
    DWORD dwMiniPhaseVal = -1; // minimum phase value
    BYTE ucWorstPhase1, ucWorstPhase2;

    ucWorstPhase1 = 0x00; // initizlize
    for (ucIndex=ucWorstPhase1; ucIndex<=0x3f; ucIndex+=AUTO_PHASE_STEP)
    {
        msAdjustAdcPhase(ucIndex);
        Delay1ms_WatchDog(ucVSyncTime); // delay 1 frame
        dwAutoPhaseVal = msAutoGetPhaseVal();

        if (dwAutoPhaseVal < dwMiniPhaseVal) // check minimum
        {
            ucWorstPhase1 = ucIndex; // refresh best phase
            dwMiniPhaseVal = dwAutoPhaseVal; // refresh minimum value
        }

        if (msAutoCheckSyncLoss()) // check no signal
            return FALSE;
    } // for

     // initizlize
    ucWorstPhase2= (ucWorstPhase1 - AUTO_PHASE_STEP + 1) & 0x3f;
    ucWorstPhase1 = (ucWorstPhase1 + AUTO_PHASE_STEP) & 0x3f;
    dwMiniPhaseVal = -1;
    for (ucIndex=ucWorstPhase2; ucIndex!=ucWorstPhase1; ucIndex=((ucIndex+1)&0x3f))
    {
        msAdjustAdcPhase(ucIndex);
        Delay1ms_WatchDog(ucVSyncTime); // delay 1 frame
        dwAutoPhaseVal = msAutoGetPhaseVal();

        if (dwAutoPhaseVal < dwMiniPhaseVal) // check minimum
        {
            ucWorstPhase2 = ucIndex; // refresh best phase
            dwMiniPhaseVal = dwAutoPhaseVal; // refresh minimum value
        }

        if (msAutoCheckSyncLoss()) // check no signal
            return FALSE;
    } // for

    g_ModeSetting.Phase = (ucWorstPhase2 + (0x3f / 2)) & 0x3f;
}
#else
{
    DWORD dwMaxPhaseVal = 0; // maximum phase value
    BYTE ucBestPhase1, ucBestPhase2;

    ucBestPhase1 = 0x00; // initizlize
    for (ucIndex=ucBestPhase1; ucIndex<=0x3f; ucIndex+=AUTO_PHASE_STEP)
    {
        msAdjustAdcPhase(ucIndex);
        Delay1ms_WatchDog(ucVSyncTime); // delay 1 frame
        dwAutoPhaseVal = msAutoGetPhaseVal();

        if (dwAutoPhaseVal > dwMaxPhaseVal) // check maximum
        {
            ucBestPhase1 = ucIndex; // refresh best phase
            dwMaxPhaseVal = dwAutoPhaseVal; // refresh maximum value
        }

        if (msAutoCheckSyncLoss()) // check no signal
            return FALSE;
    } // for

     // initizlize
    ucBestPhase2= (ucBestPhase1 - AUTO_PHASE_STEP + 1) & 0x3f;
    ucBestPhase1 = (ucBestPhase1 + AUTO_PHASE_STEP) & 0x3f;
    dwMaxPhaseVal = 0;
    for (ucIndex=ucBestPhase2; ucIndex!=ucBestPhase1; ucIndex=((ucIndex+1)&0x3f))
    {
        msAdjustAdcPhase(ucIndex);
        Delay1ms_WatchDog(ucVSyncTime); // delay 1 frame
        dwAutoPhaseVal = msAutoGetPhaseVal();

        if (dwAutoPhaseVal > dwMaxPhaseVal) // check maximum
        {
            ucBestPhase2 = ucIndex; // refresh best phase
            dwMaxPhaseVal = dwAutoPhaseVal; // refresh maximum value
        }

        if (msAutoCheckSyncLoss()) // check no signal
            return FALSE;
    } // for

    g_ModeSetting.Phase = ucBestPhase2;
}
#endif

#ifdef AUTO_DEBUG_EN
    printf("\r\nAuto Phase = %x", g_ModeSetting.Phase);
#endif
    msAdjustAdcPhase(g_ModeSetting.Phase);

    return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
// <Function>: msAutoTuneOffset
//
// <Description>: auto-tune R/G/B Offset.
//
// <Returns> : Success status.
//
// <Parameter>:  -  <Flow>  -  <Description>
//-----------------------------------------------------------------------------
//  ucVSyncTime  -    In    -   VSync time
///////////////////////////////////////////////////////////////////////////////
BOOL msAutoTuneOffset(BYTE ucVSyncTime)
{
    BYTE ucRedOffset = 0x80, ucGreenOffset = 0x80, ucBlueOffset = 0x80;
    BYTE ucOffsetDelta = 0x80; // adjust step
    BYTE ucATGStatus; // auto gain status
    BYTE ucFlowFlag = 0x00; // underflow or overflow flag
    BYTE ucBank;

    ucBank = msReadByte( BK0_00_REGBK);

#ifdef AUTO_DEBUG_EN
    putstr("\r\nAuto Offset:");
#endif

    while(1)
    {
        ucOffsetDelta /= 2; // next
        if (ucOffsetDelta == 0x00) // check end
            break;

        msAdjustAdcOffset(ucRedOffset, ucGreenOffset, ucBlueOffset); // program R/G/B offset
        Delay1ms_WatchDog(ucVSyncTime * 3); // wait stable

        msWriteByte( BK0_00_REGBK, REG_BANK_SCALER );
        msAutoWaitStatusReady(BK0_C8_ATGCTRL, _BIT1);

        ucATGStatus = msReadByte(BK0_C9_ATGST); // get auto gain status

        // red
        if (_bit2_(ucATGStatus))
        {
            ucRedOffset += ucOffsetDelta;
            ucFlowFlag |= _BIT0;
        }
        else
        {
            ucRedOffset -= ucOffsetDelta;
            ucFlowFlag |= _BIT1;
        }

        // green
        if (_bit1_(ucATGStatus))
        {
            ucGreenOffset += ucOffsetDelta;
            ucFlowFlag |= _BIT2;
        }
        else
        {
            ucGreenOffset -= ucOffsetDelta;
            ucFlowFlag |= _BIT3;
        }

        // blue
        if (_bit0_(ucATGStatus))
        {
            ucBlueOffset += ucOffsetDelta;
            ucFlowFlag |= _BIT4;
        }
        else
        {
            ucBlueOffset -= ucOffsetDelta;
            ucFlowFlag |= _BIT5;
        }
    } // while

    // adjust offset after auto-tune
    g_PcSetting.AdcRedOffset= ucRedOffset;
    g_PcSetting.AdcGreenOffset= ucGreenOffset;
    g_PcSetting.AdcBlueOffset= ucBlueOffset;
    msAdjustAdcOffset(g_PcSetting.AdcRedOffset, g_PcSetting.AdcGreenOffset, g_PcSetting.AdcBlueOffset);

    msWriteByte( BK0_00_REGBK, ucBank );

    if (ucFlowFlag == 0x3f)
       return TRUE;
    else
       return FALSE;
}

///////////////////////////////////////////////////////////////////////////////
// <Function>: msAutoTuneGain
//
// <Description>: auto-tune R/G/B gain.
//
// <Returns> : Success status.
//
// <Parameter>:  -  <Flow>  -  <Description>
//-----------------------------------------------------------------------------
//  ucVSyncTime  -    In    -   VSync time
///////////////////////////////////////////////////////////////////////////////
BOOL msAutoTuneGain(BYTE ucVSyncTime)
{
    BYTE ucRedGain = 0x80, ucGreenGain = 0x80, ucBlueGain = 0x80;
    BYTE ucGainDelta = 0x80; // adjust step
    BYTE ucATGStatus; // auto gain status
    BYTE ucFlowFlag = 0x00; // underflow or overflow flag
    BYTE ucResultR,ucResultB,ucResultG;
    BYTE ucBank;

    ucBank = msReadByte( BK0_00_REGBK);

#ifdef AUTO_DEBUG_EN
        putstr("\r\nAuto Gain:");
#endif

    while(1)
    {
        ucGainDelta /= 2; // next
        if (ucGainDelta == 0x00) // check end
            break;

        msAdjustAdcGain(ucRedGain, ucGreenGain, ucBlueGain); // program R/G/B gain
        Delay1ms_WatchDog(ucVSyncTime * 3); // wait stable

        msWriteByte( BK0_00_REGBK, REG_BANK_SCALER );
        msAutoWaitStatusReady(BK0_C8_ATGCTRL, _BIT1);

        ucATGStatus = msReadByte(BK0_C8_ATGCTRL); // get auto gain status

#ifdef AUTO_PATCH_01
        msWriteByte(BK0_CA_ATFCHSEL, 0x03);
        ucResultR = msReadByte(BK0_CD_ATGVALUE);

	    msWriteByte(BK0_CA_ATFCHSEL, 0x04);
	    ucResultG = msReadByte(BK0_CD_ATGVALUE);

        msWriteByte(BK0_CA_ATFCHSEL, 0x05);
        ucResultB = msReadByte(BK0_CD_ATGVALUE);

        if( ucResultR == 0xFF )
            ucATGStatus |= _BIT7;
        else
            ucATGStatus &= ~_BIT7;

        if( ucResultB == 0xFF )
            ucATGStatus |= _BIT5;
        else
            ucATGStatus &= ~_BIT5;

	    if( ucResultG== 0xFF )
            ucATGStatus |= _BIT6;
        else
            ucATGStatus &= ~_BIT6;
#endif

        // red
        if (_bit7_(ucATGStatus))
        {
            ucRedGain -= ucGainDelta;
            ucFlowFlag |= _BIT0;
        }
        else
        {
            ucRedGain += ucGainDelta;
            ucFlowFlag |= _BIT1;
        }

        // green
        if (_bit6_(ucATGStatus))
        {
            ucGreenGain -= ucGainDelta;
            ucFlowFlag |= _BIT2;
        }
        else
        {
            ucGreenGain += ucGainDelta;
            ucFlowFlag |= _BIT3;
        }

        // blue
        if (_bit5_(ucATGStatus))
        {
            ucBlueGain -= ucGainDelta;
            ucFlowFlag |= _BIT4;
        }
        else
        {
            ucBlueGain += ucGainDelta;
            ucFlowFlag |= _BIT5;
        }
    } // while

    // adjust gain after auto-tune
    g_PcSetting.AdcRedGain= ucRedGain;
    g_PcSetting.AdcGreenGain= ucGreenGain;
    g_PcSetting.AdcBlueGain= ucBlueGain;
    msAdjustAdcGain(g_PcSetting.AdcRedGain, g_PcSetting.AdcGreenGain, g_PcSetting.AdcBlueGain);

    msWriteByte( BK0_00_REGBK, ucBank );

    if (ucFlowFlag == 0x3f)
       return TRUE;
    else
       return FALSE;
}

/*
BOOL msAutoColorYUV(BYTE ucVSyncTime)
{
    BYTE ucBank; // bank buffer
    BYTE ucRedGain, ucGreenGain, ucBlueGain, ucTmp, ucATGStatus, ucFlowFlag=0;

    ucBank = msReadByte(BK0_00_REGBK); // store bank

    msAdjustAdcOffset(0x7C, 0x7F, 0x7C); // Should be in default value
    msAdjustAdcGain(0x80, 0x80, 0x80);
    Delay1ms_WatchDog(ucVSyncTime*3);

    msWriteByte(BK0_00_REGBK, REG_BANK1_ADC_ACE_MCU);
    msWriteByte(BK1_18_CALEN, 0x1C); // CALEN
    Delay1ms_WatchDog(ucVSyncTime*3);

    ucRedGain = 130; // Should be SMPTE 75% color pattern
    ucGreenGain = 30;
    ucBlueGain = 130; // Should be SMPTE 75% color pattern

    msWriteByte(BK0_00_REGBK, REG_BANK_SCALER);
    for (ucTmp=0; ucTmp<0xFF; ucTmp++)
    {
        msAdjustAdcGain(ucRedGain, ucGreenGain, ucBlueGain);
        Delay1ms_WatchDog(ucVSyncTime*3);
        msAutoWaitStatusReady(BK0_C8_ATGCTRL, _BIT1);
        ucATGStatus = msReadByte(BK0_C8_ATGCTRL); // get auto gain status

        // Red - Pr
        if ( !(ucFlowFlag&_BIT0) )
        {
            if (_bit7_(ucATGStatus))
            {
                g_PcSetting.AdcRedGain= ucRedGain; // Save your ADC value
                ucFlowFlag |= _BIT0;
            }
            else
            {
                ucRedGain++;
                ucFlowFlag |= _BIT1;
            }
        }

        // Green - Y
        if ( !(ucFlowFlag&_BIT2) )
        {
            if (_bit6_(ucATGStatus))
            {
                g_PcSetting.AdcGreenGain= ucGreenGain; // Save your ADC value
                ucFlowFlag |= _BIT2;
            }
            else
            {
                ucGreenGain++;
                ucFlowFlag |= _BIT3;
            }
        }

        // Blue - Pb
        if ( !(ucFlowFlag&_BIT4) )
        {
            if (_bit5_(ucATGStatus))
            {
                g_PcSetting.AdcBlueGain = ucBlueGain; // Save your ADC value
                ucFlowFlag |= _BIT4;
            }
            else
            {
                ucBlueGain++;
                ucFlowFlag |= _BIT5;
            }
        }

        if ( ucFlowFlag==0x3F )
            break;
    }

    msWriteByte(BK0_00_REGBK, REG_BANK1_ADC_ACE_MCU);
    msWriteByte(BK1_18_CALEN, 0xFC); // CALEN

    msWriteByte(BK0_00_REGBK, ucBank);

    if (ucFlowFlag == 0x3f)
       return TRUE;
    else
       return FALSE;

}
*/

#endif

⌨️ 快捷键说明

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