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

📄 autofunc.c

📁 主要用于液晶电视解码,内置51单片机,全部代码用C编写,编译环境为KEILC
💻 C
📖 第 1 页 / 共 2 页
字号:

#define _AUTOFUNC_C_

#include <math.h>
#include "types.h"
#include "board.h"
#if VGA_ENABLE

#include "global.h"
#include "ms_reg.h"
#include "adjust.h"
#include "ms_rwreg.h"
#include "misc.h"
#include "DEBUG.h"
#include "power.h"
#include "AutoFunc.h"
#include "detect.h"
#include "panel.h"
#include "mstar.h"
///////////////////////////////////////////////////////////////////////////////
// <Function>: msAutoGeometry
//
// <Description>: Auto geometry for analog port.
///////////////////////////////////////////////////////////////////////////////
#define ThresholdData 0x60

#if(ENABLE_WATCH_DOG)
void Delay1ms_WatchDog( WORD wValue )
{
    WatchDogClear();
    while( wValue )
    {
        if( wValue > 500 )
        {
            Delay1ms(500);
            wValue -= 500;
            WatchDogClear();
        }
        else
        {
            Delay1ms(wValue);
            wValue = 0;
        }
    }
    WatchDogClear();
}
#endif
BOOL msAutoGeometry(AutoTuneType AutoParam)
{
    BYTE ucBank; // bank buffer
    BYTE ucBk0_01;
    BYTE ucBk1_01;
    BYTE ucVSyncTime; // VSync time

    ucBank = msReadByte(BK0_00_REGBK); // store bank

    // Disable DB buffer
    msWriteByte( BK0_00_REGBK, REG_BANK1_ADC_ACE_MCU ); // bank 1
    ucBk1_01 = msReadByte( BK1_01_DBFC);
    msWriteByte( BK1_01_DBFC, 0x00 );

    msWriteByte( BK0_00_REGBK, REG_BANK_SCALER ); // bank 0
    ucBk0_01 = msReadByte( BK0_01_DBFC);
    msWriteByte( BK0_01_DBFC, 0x00 );
    msAdjustAdcGain(0x80, 0x80, 0x80);
    msAdjustAdcOffset(0x90, 0x90, 0x90);

    ucVSyncTime = msCalculateVSyncTime(); // get VSync time

     // auto position valid data theshold
    if (AutoParam & AUTO_TUNE_VALID_DATA)
        if (msAutoSetValidData(ucVSyncTime+3) == FALSE) AutoParam = AUTO_TUNE_NULL;
    else // fixed valid data
        msWriteByte(BK0_CC_AOVDV, ThresholdData); // set valid data threshold

    // auto horizontal total
    if (AutoParam & AUTO_TUNE_FREQ)
        if (msAutoTuneHTotal(ucVSyncTime*2) == FALSE) AutoParam = AUTO_TUNE_NULL;

    // auto phase
    if (AutoParam & AUTO_TUNE_PHASE)
        if (msAutoTunePhase(ucVSyncTime+3) == FALSE) AutoParam = AUTO_TUNE_NULL;

    // auto position
    if (AutoParam & AUTO_TUNE_POSITION)
        if (msAutoTunePosition(ucVSyncTime) == FALSE) AutoParam = AUTO_TUNE_NULL;

    msWriteByte(BK0_00_REGBK, REG_BANK_SCALER); // select register bank scaler
    msWriteByte(BK0_C8_ATGCTRL, 0x11); // enable auto gain function

    // auto RGB offset
    if (AutoParam & AUTO_TUNE_RGB_OFFSET)
        if (msAutoTuneOffset(ucVSyncTime) == FALSE)
            AutoParam= AUTO_TUNE_NULL; // auto-tune ADC offset

    // auto RGB gain
    if (AutoParam & AUTO_TUNE_RGB_GAIN)
        if (msAutoTuneGain(ucVSyncTime) == FALSE)
            AutoParam= AUTO_TUNE_NULL; // auto-tune ADC gain

    msWriteByte(BK0_00_REGBK, REG_BANK_SCALER); // select register bank scaler
    msWriteByte(BK0_C8_ATGCTRL, 0x00); // disable auto gain function
    msWriteByte(BK0_CC_AOVDV, 0x40); // set valid data threshold

    msAdjustAdcGain(g_PcSetting.AdcRedGain, g_PcSetting.AdcGreenGain, g_PcSetting.AdcBlueGain);
    msAdjustAdcOffset(g_PcSetting.AdcRedOffset, g_PcSetting.AdcGreenOffset, g_PcSetting.AdcBlueOffset);
   // Recover DB buffer setting
    msWriteByte( BK0_01_DBFC, ucBk0_01);

    msWriteByte( BK0_00_REGBK, REG_BANK1_ADC_ACE_MCU ); // bank 1
    msWriteByte( BK1_01_DBFC, ucBk1_01);

    msWriteByte(BK0_00_REGBK, ucBank); // recovery bank

    if (AutoParam) // success
        return TRUE;
    else // fail
    {
        putstr("\r\nAuto failed");
        return FALSE;
    }
}

///////////////////////////////////////////////////////////////////////////////
// <Function>: msAutoCheckSyncLoss
//
// <Description>: Check Sync loss status.
//
// <Returns> :
///////////////////////////////////////////////////////////////////////////////
BOOL msAutoCheckSyncLoss(void)
{
//#if UseINT
    if (g_bInputTimingChangeFlag)
    {
    #ifdef AUTO_DEBUG_EN
        putstr("\r\ng_bInputTimingChange=1");
        printf("\r\nVt=%x",msGetVerticalTotal());
    #endif
        return TRUE;
    }
//#endif

    // check H/VSync change
    if ((abs(g_wHorizontalPeriod - msGetHorizontalPeriod()) > HPeriod_Torlance) ||
        (abs(g_wVerticalTotal - msGetVerticalTotal()) > VTotal_Torlance))
    {
        SrcFlags|= bHSyncLoss;
        SrcFlags|= bVSyncLoss;
        g_bInputTimingChangeFlag = 1;
    #ifdef AUTO_DEBUG_EN
        printf("\r\nHP=%x",msGetHorizontalPeriod());
        printf("\r\nVt=%x",msGetVerticalTotal());
    #endif
        return TRUE;
    }

    return FALSE;
}

///////////////////////////////////////////////////////////////////////////////
// <Function>: msAutoSetValidData
//
// <Description>: Auto set valid data value.
//
// <Parameter>:  -  <Flow>  -  <Description>
//-----------------------------------------------------------------------------
//  ucVSyncTime  -    In    -   VSync time
///////////////////////////////////////////////////////////////////////////////
BOOL msAutoSetValidData(BYTE ucVSyncTime)
{
    BYTE ucValidData; // valide dataa value
    BYTE ucPhaseIndex; // phase index

    WORD wComapreHPos; // compare horizontal position

    BYTE ucBank = msReadByte( BK0_00_REGBK);

    msWriteByte( BK0_00_REGBK, REG_BANK_SCALER );

    for (ucValidData=0x04; ucValidData!=0x10; ucValidData++)
    {
        msWriteByte(BK0_CC_AOVDV, ucValidData << 4); // set valid data threshold

        msAdjustAdcPhase(0x00); // set phase
        Delay1ms_WatchDog(ucVSyncTime);
        wComapreHPos = msAutoGetPosition(BK0_D0_AOHST_L, ucVSyncTime); // horizontal position
        for (ucPhaseIndex=0x01; ucPhaseIndex!=0x10; ucPhaseIndex++)
        {
            msAdjustAdcPhase(ucPhaseIndex * 4); // set phase
            Delay1ms_WatchDog(ucVSyncTime);
            if (abs(wComapreHPos - msAutoGetPosition(BK0_D0_AOHST_L, ucVSyncTime)) > 3) // check lose data
                break;

            if (msAutoCheckSyncLoss()) // check Sync change
            {
                msWriteByte( BK0_00_REGBK, ucBank );
            #ifdef AUTO_DEBUG_EN
                putstr("\r\nmsAutoSetValidData() failed");
            #endif
                return FALSE;
            }
        } // for

        if (ucPhaseIndex == 0x10)
            break;
    } // for

    msWriteByte( BK0_00_REGBK, ucBank );
    return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
// <Function>: autoWaitStatusReady
//
// <Description>: Wait for status ready.
//
// <Parameter>:  -  <Flow>  -  <Description>
//-----------------------------------------------------------------------------
//   ucRegIndex  -    In    -   Register index
//   ucRegMask   -    In    -   Status mask
///////////////////////////////////////////////////////////////////////////////
void msAutoWaitStatusReady(BYTE ucRegIndex, BYTE ucRegMask)
{
    WORD wDummy = 250; // loop dummy

#if ENABLE_MCU_USE_INTERNAL_CLOCK
    wDummy = 1000;
#endif

    while (!(msReadByte(ucRegIndex) & ucRegMask) && (wDummy--)) ;
}

///////////////////////////////////////////////////////////////////////////////
// <Function>: autoWaitStatusReady
//
// <Description>: Wait for status ready.
//
// <Returns> : Auto position value.
//
// <Parameter>:  -  <Flow>  -  <Description>
//-----------------------------------------------------------------------------
//   ucRegIndex  -    In    -   Register index
//   ucVSyncTime -    In    -   VSync time
///////////////////////////////////////////////////////////////////////////////
WORD msAutoGetPosition(BYTE ucRegIndex, BYTE ucVSyncTime)
{
    WORD wComparePos, wAutoPos; // position buffer
    BYTE ucDummy = 20; // loop dummy
    BYTE ucCount = 0; // counter of compare alike

    BYTE ucBank = msReadByte( BK0_00_REGBK);

    msWriteByte( BK0_00_REGBK, REG_BANK_SCALER );

    while(ucDummy--)
    {
        msAutoWaitStatusReady(BK0_CB_ATOCTRL, _BIT1); // auto position result ready

        wAutoPos = msReadWord(ucRegIndex+1); // get auto position
        if (wAutoPos == wComparePos) // match
            ucCount++;
        else // different
        {
            ucCount = 0; // reset counter
            wComparePos = wAutoPos; // reset position
        }

        if (ucCount == 3) // match counter ok
            break;

        if (msAutoCheckSyncLoss()) // check no signal
        {
            msWriteByte( BK0_00_REGBK, ucBank );
            return -1; // return fail
        }

        Delay1ms_WatchDog(ucVSyncTime); // wait next frame
    } // while

    msWriteByte( BK0_00_REGBK, ucBank );
    return wAutoPos;
}

///////////////////////////////////////////////////////////////////////////////
// <Function>: autoWaitStatusReady
//
// <Description>: Wait for status ready.
//
// <Parameter>:  -  <Flow>  -  <Description>
//-----------------------------------------------------------------------------
//  ucVSyncTime  -    In    -   VSync time
///////////////////////////////////////////////////////////////////////////////
BOOL msAutoTunePosition(BYTE ucVSyncTime)
{
    WORD wPosBff; // position buffer
    BYTE ucBank;

#ifdef AUTO_DEBUG_EN
    printf("\r\nmsAutoTunePosition(%d)", ucVSyncTime);
#endif


    ucBank = msReadByte( BK0_00_REGBK);
    msWriteByte( BK0_00_REGBK, REG_BANK_SCALER );

    // horizotal position
    wPosBff = msAutoGetPosition(BK0_D0_AOHST_L, ucVSyncTime); // auto horizontal start position detected result
    if (wPosBff > StandardModeWidth ) // check overflow
    {
        msWriteByte( BK0_00_REGBK, ucBank );
        return FALSE;
    }
#if 0 // todo: test!!
    wPosBff -= 1;		// 20051101 Antony patch for Auto-H.Position
#endif
    g_ModeSetting.HStart= wPosBff;

    msWriteWord(BK0_08_SPRHST_H, wPosBff);
   // g_ModeSetting.DefaultHStart = wPosBff;

    // vertical positoin
    wPosBff = msAutoGetPosition(BK0_CE_AOVST_L, ucVSyncTime); // auto vertical start position detected result
    if (wPosBff >StandardModeHeight) // check overflow
    {
        msWriteByte( BK0_00_REGBK, ucBank );
        return FALSE;
    }
    g_ModeSetting.VStart= wPosBff;

    if( StandardModeHeight == 350 ) // if IBM VGA 640x350 then use 640x400 resolution and move to middle of screen
        wPosBff -= ((400-350)/2);

    msWriteWord(BK0_06_SPRVST_H, wPosBff);

    msWriteByte( BK0_00_REGBK, ucBank );
    return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
// <Function>: msAdcGetTransPos
//
// <Description>: Get trans-position.
//
// <Returns> : Trans-phase.
//
// <Parameter>:  -  <Flow>  -  <Description>
//-----------------------------------------------------------------------------
//  ucVSyncTime  -    In    -   VSync time
///////////////////////////////////////////////////////////////////////////////
BYTE msAutoGetTransPos(BYTE ucVSyncTime)
{
    WORD wComparePos; // compare start position
    BYTE ucAdjustPhase = 0x20, ucPhaseDelta = 0x20; // phase data buffer

    msAdjustAdcPhase(0x00); // intialize
    wComparePos = msAutoGetPosition(BK0_D0_AOHST_L, ucVSyncTime);
    while (1)
    {
        msAdjustAdcPhase(ucAdjustPhase); // set phase

        ucPhaseDelta /= 2; // next step
        if (ucPhaseDelta == 0x00) // check end
            break;

        if (msAutoGetPosition(BK0_D0_AOHST_L, ucVSyncTime) == wComparePos) // find critical phase
      	    ucAdjustPhase += ucPhaseDelta; // right shift
        else
      	    ucAdjustPhase -= ucPhaseDelta; // left shift

        if (msAutoCheckSyncLoss()) // check no signal
            return -1;

    } // while

    return (ucAdjustPhase);
}

///////////////////////////////////////////////////////////////////////////////
// <Function>: msAutoGetActualWidth
//
// <Description>: Get actual image width.
//
// <Returns> : Actual width.
//
// <Parameter>:  -  <Flow>  -  <Description>
//-----------------------------------------------------------------------------
//  ucVSyncTime  -    In    -   VSync time
///////////////////////////////////////////////////////////////////////////////
WORD msAutoGetActualWidth(BYTE ucVSyncTime)
{
    WORD wHStart; // actual horizontal start

    msAdjustAdcPhase(0x00); // initialize phase value
    wHStart = msAutoGetPosition(BK0_D0_AOHST_L, ucVSyncTime); // horizontal start position
    msAutoGetTransPos(ucVSyncTime); // seek critical phase

    return ((msAutoGetPosition(BK0_D4_AOHEND_L, ucVSyncTime) - wHStart) + 1); // actual image width
}

///////////////////////////////////////////////////////////////////////////////
// <Function>: msAutoTuneHTotal
//
// <Description>: auto-tune horizontal total.
//
// <Returns> : Success status.
//
// <Parameter>:  -  <Flow>  -  <Description>
//-----------------------------------------------------------------------------
//  ucVSyncTime  -    In    -   VSync time
///////////////////////////////////////////////////////////////////////////////
BOOL msAutoTuneHTotal(BYTE ucVSyncTime)
{
    WORD wActualWidth; // actual width
    WORD wStdWidth; // standard width
    WORD wHTotalBff; // horizontal total buffer
    BOOL bResult = FALSE;

    msAdjustAdcPhase(0x00); // initialize phase value
    wActualWidth = msAutoGetPosition(BK0_D4_AOHEND_L, ucVSyncTime) - msAutoGetPosition(BK0_D0_AOHST_L, ucVSyncTime);
    // get standard display width
    wStdWidth = StandardModeWidth;
    if (abs(wActualWidth - wStdWidth) > (wStdWidth / 4)) // check actual width over standard
    {
    #ifdef AUTO_DEBUG_EN
        putstr("\r\nmsAutoTuneHTotal failed-1");
    #endif
        return FALSE;
    }

    wHTotalBff = g_ModeSetting.HTotal; // intialize horizontal total buffer
    if (abs(wActualWidth - wStdWidth) > 1) // check width difference
    {
        // calculate horizontal total
        wHTotalBff = ((DWORD)g_ModeSetting.HTotal* wStdWidth) / wActualWidth;
        // check over range of adjusting
        if (abs(wHTotalBff - StandardModeHTotal > ADJUST_CLOCK_RANGE))
        {
        #ifdef AUTO_DEBUG_EN
            putstr("\r\nmsAutoTuneHTotal failed-2");
            printf("\r\nwHTotalBff=%d", wHTotalBff);
            printf("\r\nwStdWidth=%d", wStdWidth);
            printf("\r\nwActualWidth=%d", wActualWidth);
        #endif
            return FALSE;
        }

        msAdjustAdcClock(wHTotalBff); // set clock
    }

    // check width
    wActualWidth = msAutoGetActualWidth(ucVSyncTime);
    if (wActualWidth != wStdWidth) // match width
    {
        // adjust horizontal total
        wHTotalBff = wHTotalBff + (wStdWidth - wActualWidth);
        msAdjustAdcClock(wHTotalBff);

        wActualWidth = msAutoGetActualWidth(ucVSyncTime);
        // adjust horizontal total again
        wHTotalBff = wHTotalBff + (wStdWidth - wActualWidth);
    }

    if (wHTotalBff & 0x01) // match width and check odd
    {
        msAdjustAdcClock(wHTotalBff - 1); // find decrement
        wActualWidth = msAutoGetActualWidth(ucVSyncTime);
        if (wActualWidth == wStdWidth) // match width
            wHTotalBff--;
        else
        {

⌨️ 快捷键说明

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