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

📄 drvauto.c

📁 mstar 776 开发的车载dvd
💻 C
📖 第 1 页 / 共 4 页
字号:
#if 1
    //may_070406_checkfullscreen
    //if(u16PosBff > MAX_PC_AUTO_H_START || u16PosBff < MIN_PC_AUTO_H_START)
    if(u16PosBff > MDrv_Mode_GetStdModeResH(pstModesetting->u8ModeIndex)) // check overflow
    {
        AUTOMSG(printf("H start limit: %u\n", u16PosBff));
        u16PosBff = MDrv_Mode_GetStdModeHStart(pstModesetting->u8ModeIndex);
        bResult = FALSE;
    }
#else
    if(u16PosBff > MDrv_Mode_GetStdModeResH(pstModesetting->u8ModeIndex)) // check overflow
    {
        MDrv_WriteByte( BK_SELECT_00, u8Bank );
        return FALSE;
    }
#endif

    pstModesetting->u16HorizontalStart = u16PosBff;
    pstModesetting->u16DefaultHStart = u16PosBff;

    MDrv_Write2Byte(BK_SC_IP1F2_05_L, u16PosBff);

    AUTOMSG(printf("AutoPosition HStart=0x%x\n", pstModesetting->u16DefaultHStart);)

    // vertical positoin
    u16PosBff = MDrv_Auto_GetPosition(BK_SC_IP1F2_12_L, u8VSyncTime); // auto vertical start position detected result

    if( abs(MDrv_Mode_GetStdModeResV(pstModesetting->u8ModeIndex)-(MDrv_Auto_GetPosition(BK_SC_IP1F2_14_L, u8VSyncTime)-MDrv_Auto_GetPosition(BK_SC_IP1F2_12_L, u8VSyncTime))) >
        (MDrv_Mode_GetStdModeResV(pstModesetting->u8ModeIndex)/4) )
    {
        u16PosBff = MDrv_Mode_GetStdModeVStart(pstModesetting->u8ModeIndex);
    }

#if 1
    //may_070406_checkfullscreen
    if(u16PosBff > MDrv_Mode_GetStdModeResV(pstModesetting->u8ModeIndex)) // check overflow
    {
        AUTOMSG(printf("V start limit: %u\n", u16PosBff));
        u16PosBff = MDrv_Mode_GetStdModeVStart(pstModesetting->u8ModeIndex);
        bResult = FALSE;
    }
#else
    if(u16PosBff > MDrv_Mode_GetStdModeResV(pstModesetting->u8ModeIndex)) // check overflow
    {
        MDrv_WriteByte( BK_SELECT_00, u8Bank );
        return FALSE;
    }
#endif
    pstModesetting->u16VerticalStart = u16PosBff;
    pstModesetting->u16DefaultVStart = u16PosBff;

    #if 0
    if(MDrv_Mode_GetStdModeResV(pstModesetting->u8ModeIndex) == 350) // if IBM VGA 640x350 then use 640x400 resolution and move to middle of screen
    {
        u16PosBff -= ((400 - 350) / 2);
    }
    #endif

    MDrv_Write2Byte(BK_SC_IP1F2_04_L, u16PosBff);
    MDrv_WriteByte( BK_SELECT_00, u8Bank );

    AUTOMSG(printf("AutoPosition VStart=0x%x\n", pstModesetting->u16VerticalStart);)
    return bResult;
}

//*************************************************************************
//Function name: MDrv_Auto_GetTransPos
//Passing parameter:
//  U8 u8VSyncTime : VSync time
//Return parameter:
//  U8: If faile, return -1. else return phase setting
//Description: Get trans-position.
//*************************************************************************
U8 MDrv_Auto_GetTransPos(U8 u8VSyncTime)
{
    U16 u16ComparePos; // compare start position
    U8 u8AdjustPhase = 0x20,u8PhaseDelta = 0x20; // phase data buffer
    U8 u8Bank;

    u8Bank = MDrv_ReadByte( BK_SELECT_00 );
    MDrv_WriteByte( BK_SELECT_00, REG_BANK_IP1F2 );

    MDrv_ADC_SetADCPhase(0x00); // intialize
    u16ComparePos = MDrv_Auto_GetPosition(BK_SC_IP1F2_13_L, u8VSyncTime);
    while(1)
    {
        MDrv_ADC_SetADCPhase(u8AdjustPhase); // set phase

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

        if(MDrv_Auto_GetPosition(BK_SC_IP1F2_13_L, u8VSyncTime) == u16ComparePos) // find critical phase
            u8AdjustPhase += u8PhaseDelta; // right shift
        else
            u8AdjustPhase -= u8PhaseDelta; // left shift

        if(MDrv_Auto_CheckSyncLoss()) // check no signal
        {
            MDrv_WriteByte( BK_SELECT_00, u8Bank );
            return -1;
        }
    } // while

    MDrv_WriteByte( BK_SELECT_00, u8Bank );
    return (u8AdjustPhase);
}

//*************************************************************************
//Function name: MDrv_Auto_GetActualWidth
//Passing parameter:
//  U8 u8VSyncTime : VSync time
//Return parameter:
//  U16: return actual image width
//Description: Get actual image width.
//*************************************************************************
U16 MDrv_Auto_GetActualWidth(U8 u8VSyncTime)
{
    U16 u16HStart; // actual horizontal start
    U8 u8Bank;
    U16 u16Width;

    u8Bank = MDrv_ReadByte( BK_SELECT_00 );
    MDrv_WriteByte( BK_SELECT_00, REG_BANK_IP1F2 );

    MDrv_ADC_SetADCPhase(0x00); // initialize phase value
    u16HStart = MDrv_Auto_GetPosition(BK_SC_IP1F2_13_L, u8VSyncTime); // horizontal start position
    MDrv_Auto_GetTransPos(u8VSyncTime); // seek critical phase

    u16Width = ((MDrv_Auto_GetPosition(BK_SC_IP1F2_15_L, u8VSyncTime) - u16HStart) + 1); // actual image width

    MDrv_WriteByte( BK_SELECT_00, u8Bank );
    return u16Width;
}

//*************************************************************************
//Function name: MDrv_Auto_TuneHTotal
//Passing parameter:
//  U8 u8VSyncTime: VSync time
//  MS_PCADC_MODESETTING_TYPE *pstModesetting: Current PC mode setting
//Return parameter:
//  BOOLEAN: Success status. (If faile, return FALSE.)
//Description: auto-tune horizontal total.
//*************************************************************************
BOOLEAN MDrv_Auto_TuneHTotal(U8 u8VSyncTime, MS_PCADC_MODESETTING_TYPE *pstModesetting)
{
    U16 u16ActualWidth; // actual width
    U16 u16StdWidth; // standard width
    U16 u16HTotalBff; // horizontal total buffer
    BOOLEAN bResult = FALSE;

    MDrv_ADC_SetADCPhase(0x00); // initialize phase value

    u16ActualWidth = MDrv_Auto_GetPosition(BK_SC_IP1F2_15_L, u8VSyncTime) - MDrv_Auto_GetPosition(BK_SC_IP1F2_13_L, u8VSyncTime);

    AUTOHTMSG(printf("\r\n"));
    AUTOHTMSG(printf("\r\nTuneHTotal"));
    AUTOHTMSG(printf("\r\nModeIdx=%bu", pstModesetting->u8ModeIndex));

    // get standard display width
    u16StdWidth = MDrv_Mode_GetStdModeResH(pstModesetting->u8ModeIndex);

    AUTOHTMSG(printf("\r\nActualWidth=%x", u16ActualWidth));
    AUTOHTMSG(printf("\r\nStdWidth=%x", u16StdWidth));
    AUTOHTMSG(printf("\r\n"));

    // kevin 071025_0 test if(abs(u16ActualWidth - u16StdWidth) > (u16StdWidth / 6)) // check actual width over standard
    if(abs(u16ActualWidth - u16StdWidth) > (u16StdWidth / 3)) // check actual width over standard
    {
        AUTOHTMSG(printf("\r\nAct Width Over"));
        return FALSE;
    }

    //u16HTotalBff = pstModesetting->u16HorizontalTotal; // intialize horizontal total buffer
    //AUTOHTMSG(printf("\r\nInit HT=0x%x", u16HTotalBff));
    u16HTotalBff = MDrv_Mode_GetStdModeHTotal(pstModesetting->u8ModeIndex);
    AUTOHTMSG(printf("\r\nTbl HT=0x%x", u16HTotalBff));
    if(abs(u16ActualWidth - u16StdWidth) > 1) // check width difference
    {
        // calculate horizontal total
        u16HTotalBff = ((U32) pstModesetting->u16HorizontalTotal * u16StdWidth) / u16ActualWidth;
        AUTOHTMSG(printf("\r\nCal HT=0x%x", u16HTotalBff));
        // check over range of adjusting
        if(abs(u16HTotalBff - MDrv_Mode_GetStdModeHTotal(pstModesetting->u8ModeIndex)) > ADJUST_CLOCK_RANGE)
        {
            AUTOHTMSG(printf("\r\nAct HT Over"));
            return FALSE;
        }
        MDrv_ADC_SetADCClk(u16HTotalBff); // set clock
    }

    // check width
    AUTOHTMSG(printf("\r\nCheck Width"));
    u16ActualWidth = MDrv_Auto_GetActualWidth(u8VSyncTime);
    AUTOHTMSG(printf("\r\nActualWidth=%x", u16ActualWidth));
    if(u16ActualWidth != u16StdWidth) // match width
    {
        AUTOHTMSG(printf("\r\n Width --> Not Match"));
        // adjust horizontal total
        u16HTotalBff = u16HTotalBff + (u16StdWidth - u16ActualWidth);
        MDrv_ADC_SetADCClk(u16HTotalBff);

        u16ActualWidth = MDrv_Auto_GetActualWidth(u8VSyncTime);
        AUTOHTMSG(printf(", ActualWidth=%x", u16ActualWidth));
        // adjust horizontal total again
        u16HTotalBff = u16HTotalBff + (u16StdWidth - u16ActualWidth);
    }
    //AUTOHTMSG(printf("--> 1st Match"));

    if(u16HTotalBff & 0x01) // match width and check odd
    {
        MDrv_ADC_SetADCClk(u16HTotalBff - 1); // find decrement
        u16ActualWidth = MDrv_Auto_GetActualWidth(u8VSyncTime);
        if(u16ActualWidth == u16StdWidth) // match width
        {
            AUTOHTMSG(printf("--> 2nd Match"));
            u16HTotalBff--;
        }
        else
        {
            AUTOHTMSG(printf("--> 2nd Not Match"));

            MDrv_ADC_SetADCClk(u16HTotalBff + 1); // find increment
            u16ActualWidth = MDrv_Auto_GetActualWidth(u8VSyncTime);
            AUTOHTMSG(printf("\r\nActualWidth=%x", u16ActualWidth));
            if(u16ActualWidth == u16StdWidth) // match width
            {
                AUTOHTMSG(printf("--> 3rd Match"));
                u16HTotalBff++;
            }
        }
    }

    if (u16HTotalBff & 0x01)// kevin 071102_0 only for demo
        u16HTotalBff++;

    AUTOHTMSG(printf("\r\n Temp Htol=0x%x", u16HTotalBff));
    AUTOHTMSG(printf("\r\n Get Htol=0x%x",MDrv_Mode_GetStdModeHTotal(pstModesetting->u8ModeIndex)));
    AUTOHTMSG(printf("\r\n CLK Range=0x%x", ADJUST_CLOCK_RANGE));
    AUTOHTMSG(printf("\r\n CLK Range=0x%x", (g_PcadcModeSetting.u16HorizontalTotal/4)));

    // check horizontal total range
    AUTOHTMSG(printf("\r\n Chk Hor. Range --> "));
    if(abs(u16HTotalBff - (MDrv_Mode_GetStdModeHTotal(pstModesetting->u8ModeIndex))) <= ADJUST_CLOCK_RANGE)
    {
        AUTOHTMSG(printf("OK"));

        pstModesetting->u16HorizontalTotal = u16HTotalBff;
        pstModesetting->u16DefaultHTotal = u16HTotalBff;
        bResult = TRUE;
    }
    else
    {
        AUTOHTMSG(printf("NG =0x%x", abs(u16HTotalBff - (MDrv_Mode_GetStdModeHTotal(pstModesetting->u8ModeIndex)))));
    }

    MDrv_ADC_SetADCClk(pstModesetting->u16HorizontalTotal); // setting ADC clock
    MDrv_ADC_SetADCPhase(pstModesetting->u8Phase); // setting ADC phase

    AUTOHTMSG(printf("AutoHtt 0x%x\n", pstModesetting->u16HorizontalTotal);)
    return bResult;
}

//*************************************************************************
//Function name: MDrv_Auto_GetPhaseVal
//Passing parameter: NO
//Return parameter:
//  U32: Return full image sun of difference value between two pixles
//Description: Get auto phase value.
//*************************************************************************
U32 MDrv_Auto_GetPhaseVal(void)
{
    DWordType dwPhaseValBff; // double word buffer
    U8 u8Bank;

    u8Bank = MDrv_ReadByte( BK_SELECT_00 );
    MDrv_WriteByte( BK_SELECT_00, REG_BANK_IP1F2 );

    MDrv_Auto_WaitStatusReady(BK_SC_IP1F2_19_L, _BIT1);
    dwPhaseValBff.separate._byte0 = MDrv_ReadByte(BK_SC_IP1F2_1A_L);
    dwPhaseValBff.separate._byte1 = MDrv_ReadByte(BK_SC_IP1F2_1A_H);
    dwPhaseValBff.separate._byte2 = MDrv_ReadByte(BK_SC_IP1F2_1B_L);
    dwPhaseValBff.separate._byte3 = MDrv_ReadByte(BK_SC_IP1F2_1B_H);

    MDrv_WriteByte( BK_SELECT_00, u8Bank );

    return dwPhaseValBff.u32Total;
}

//*************************************************************************
//Function name: MDrv_Auto_TunePhase
//Passing parameter:
//  U8 u8VSyncTime: VSync time
//  MS_PCADC_MODESETTING_TYPE *pstModesetting: Current PC mode setting
//Return parameter:
//  BOOLEAN: Success status. (If faile, return FALSE.)
//Description: auto-tune phase.
//*************************************************************************
#define AUTO_PHASE_STEP 4

BOOLEAN MDrv_Auto_TunePhase(U8 u8VSyncTime, MS_PCADC_MODESETTING_TYPE *pstModesetting)
{
    U8 u8Index; // loop index

    U32 u32AutoPhaseVal; // auto phase value result
    #if AUTO_PHASE_METHOD
    {
        U32 u32MiniPhaseVal = -1; // minimum phase value
        U8 u8WorstPhase1,u8WorstPhase2;

        u8WorstPhase1 = 0x00; // initizlize
        for(u8Index = u8WorstPhase1; u8Index <= 0x3f; u8Index += AUTO_PHASE_STEP)
        {
            MDrv_ADC_SetADCPhase(u8Index);
            MDrv_Timer_Delayms(u8VSyncTime); // delay 1 frame
            u32AutoPhaseVal = MDrv_Auto_GetPhaseVal();

            if(u32AutoPhaseVal < u32MiniPhaseVal) // check minimum
            {
                u8WorstPhase1 = u8Index; // refresh best phase
                u32MiniPhaseVal = u32AutoPhaseVal; // refresh minimum value
            }

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

        // initizlize
        u8WorstPhase2 = (u8WorstPhase1 - AUTO_PHASE_STEP + 1) & 0x3f;
        u8WorstPhase1 = (u8WorstPhase1 + AUTO_PHASE_STEP) & 0x3f;
        u32MiniPhaseVal = -1;
        for(u8Index = u8WorstPhase2; u8Index != u8WorstPhase1; u8Index = ((u8Index + 1) & 0x3f))
        {
            MDrv_ADC_SetADCPhase(u8Index);
            MDrv_Timer_Delayms(u8VSyncTime); // delay 1 frame
            u32AutoPhaseVal = MDrv_Auto_GetPhaseVal();

            if(u32AutoPhaseVal < u32MiniPhaseVal) // check minimum
            {
                u8WorstPhase2 = u8Index; // refresh best phase
                u32MiniPhaseVal = u32AutoPhaseVal; // refresh minimum value
            }

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

        pstModesetting->u8Phase = (u8WorstPhase2 + (0x3f / 2)) & 0x3f;
    }
    #else
    {
        U32 u32MaxPhaseVal = 0; // maximum phase value
        U8 u8BestPhase1,u8BestPhase2;

        u8BestPhase1 = 0x00; // initizlize
        for(u8Index = u8BestPhase1; u8Index <= 0x3f; u8Index += AUTO_PHASE_STEP)
        {
            MDrv_ADC_SetADCPhase(u8Index);
            MDrv_Timer_Delayms(u8VSyncTime); // delay 1 frame
            u32AutoPhaseVal = MDrv_Auto_GetPhaseVal();

            if(u32AutoPhaseVal > u32MaxPhaseVal) // check maximum
            {
                u8BestPhase1 = u8Index; // refresh best phase
                u32MaxPhaseVal = u32AutoPhaseVal; // refresh maximum value
            }

⌨️ 快捷键说明

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