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

📄 drvauto.c

📁 mstar 776 开发的车载dvd
💻 C
📖 第 1 页 / 共 4 页
字号:

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

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

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

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

        pstModesetting->u8Phase = u8BestPhase2;
    }
    #endif

    MDrv_ADC_SetADCPhase(pstModesetting->u8Phase);

    AUTOMSG(printf("AutoPhase 0x%bx\n", pstModesetting->u8Phase);)
    return TRUE;
}

//*************************************************************************
//Function name: _MDrv_Auto_GainReport
//Passing parameter:
//  U8 u8Type: report AUTO_MIN_[RGB] or AUTO_MAX_[RGB]
//  U8 u8DelayMS: delay how long to get the report, usually, the delay will be 1 * VSyncTime
//Return parameter:
//  U8: the min/max gain report
//Description: Auto-tune R/G/B Offset of ADC.
//*************************************************************************
U8 _MDrv_Auto_GainReport(U8 u8Type, U8 u8DelayMS)
{
    U8 u8Value, u8Ready;
    U8 u8Bank;

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

    MDrv_WriteByteMask(BK_SC_IP1F2_0F_L, u8Type, _BIT2 | _BIT1 | _BIT0);
    MDrv_Timer_Delayms(u8DelayMS);

    // Sometimes the gain report will give a very un-reasonable value,
    // So, we've to wait the IP1F2_0E[1] to be ready (=1) to get the gain report
    // For safety reason, you may use this flow:
    //    (1) Set what to get AUTO_MIN_[RGB] or AUTO_MAX_[RGB]
    //    (2) wait for ready bit to be off
    //                           (because sometimes when you change the AUTO_MIN_[RGB] or AUTO_MAX_[RGB],
    //                                you'll get a ready immediately but the report is the old value)
    //    (3) wait for ready bit to be on
    //    (4) get the report when ready bit is on (note: see source code below)
    //
    // For quick response, you may get the report when ready bit is on, the report is rarely wrong if ready bit is on.

    /*
    // wait for ready bit to be off
    while(MDrv_ReadByte(BK_SC_IP1F2_0E_L) & (0x1 << 1))
    {
        u8Ready = MDrv_ReadByte(BK_SC_IP1F2_0E_L);
        u8Value = MDrv_ReadByte(BK_SC_IP1F2_11_L);
        printf("DA:C=0x%bx,R=0x%bx,V=0x%bx\n", MDrv_ReadByte(BK_SC_IP1F2_0F_L), u8Ready, u8Value);
    }

    // wait for ready bit to be on
    while(!(MDrv_ReadByte(BK_SC_IP1F2_0E_L) & (0x1 << 1)))
    {
        u8Ready = MDrv_ReadByte(BK_SC_IP1F2_0E_L);
        u8Value = MDrv_ReadByte(BK_SC_IP1F2_11_L);
        printf("DA:C=0x%bx,R=0x%bx,V=0x%bx\n", MDrv_ReadByte(BK_SC_IP1F2_0F_L), u8Ready, u8Value);
    }
    */

    while(1)
    {
        // It's important to read the 2 values by this order
        // (1) ready bit first
        // (2) report next
        // and no waste time between these 2 commands
        u8Ready = MDrv_ReadByte(BK_SC_IP1F2_0E_L);
        u8Value = MDrv_ReadByte(BK_SC_IP1F2_11_L);

        // Check if the report is reasonable here
        if(u8Ready & (0x1 << 1))
        {
            AUTOMSG(printf("C=0x%bx,R=0x%bx,V=0x%bx,Mask=0x%bx\n", MDrv_ReadByte(BK_SC_IP1F2_0F_L), u8Ready, u8Value, BITMASK(2:0));)
            break;
        }
    }

    MDrv_WriteByte( BK_SELECT_00, u8Bank );

    return u8Value;
}

//*************************************************************************
//Function name: MDrv_Auto_TuneOffset
//Passing parameter:
//  U8 u8VSyncTime: VSync time
//  MS_ADC_SETTING * pstADCSetting: ADC setting of Current PC mode
//Return parameter:
//  BOOLEAN: Success status. (If faile, return FALSE.)
//Description: Auto-tune R/G/B Offset of ADC.
//*************************************************************************
#define AUTO_OFFSET_SW_MODE 1
BOOLEAN MDrv_Auto_TuneOffset(U8 u8VSyncTime, MS_ADC_SETTING *pstADCSetting)
{
    MS_ADC_SETTING tempADCSetting;
    U8 u8OffsetDelta = 0x80; // adjust step
    U8 u8ATGStatus = 0; // auto gain status//ERROR FIX Prevent Tool 070522
    U8 u8FlowFlag = 0x00; // underflow or overflow flag
    U8 u8Bank;

    tempADCSetting.u8RedGain = 0x80;
    tempADCSetting.u8GreenGain = 0x80;
    tempADCSetting.u8BlueGain = 0x80;
    MDrv_ADC_SetGain(&tempADCSetting);

    tempADCSetting.u8RedOffset = 0x80;
    tempADCSetting.u8GreenOffset = 0x80;
    tempADCSetting.u8BlueOffset = 0x80;

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

    while(1)
    {
        u8OffsetDelta /= 2; // next

        if(u8OffsetDelta == 0x00) // check end
            break;

        MDrv_ADC_SetOffset(&tempADCSetting);
        MDrv_Timer_Delayms(u8VSyncTime * 3); // wait stable
        MDrv_Auto_WaitStatusReady(BK_SC_IP1F2_0E_L, _BIT1);

#if AUTO_OFFSET_SW_MODE
        {
            U8 u8ResultR,u8ResultG,u8ResultB;

            u8ResultR = _MDrv_Auto_GainReport(AUTO_MIN_R, u8VSyncTime);
            u8ResultG = _MDrv_Auto_GainReport(AUTO_MIN_G, u8VSyncTime);
            u8ResultB = _MDrv_Auto_GainReport(AUTO_MIN_B, u8VSyncTime);

            if (u8ResultR == 0x00)
                u8ATGStatus |= _BIT2;
            else
                u8ATGStatus &= ~_BIT2;

            if (u8ResultG == 0x00)
                u8ATGStatus |= _BIT1;
            else
                u8ATGStatus &= ~_BIT1;


            if (u8ResultB == 0x00)
                u8ATGStatus |= _BIT0;
            else
                u8ATGStatus &= ~_BIT0;
        }
#else
        u8ATGStatus = MDrv_ReadByte(BK_SC_IP1F2_0E_H); // get auto gain status
#endif

        // red
        if(_bit2_(u8ATGStatus))
        {
            tempADCSetting.u8RedOffset += u8OffsetDelta;
            u8FlowFlag |= _BIT0;
        }
        else
        {
            tempADCSetting.u8RedOffset -= u8OffsetDelta;
            u8FlowFlag |= _BIT1;
        }

        // green
        if(_bit1_(u8ATGStatus))
        {
            tempADCSetting.u8GreenOffset += u8OffsetDelta;
            u8FlowFlag |= _BIT2;
        }
        else
        {
            tempADCSetting.u8GreenOffset -= u8OffsetDelta;
            u8FlowFlag |= _BIT3;
        }

        // blue
        if(_bit0_(u8ATGStatus))
        {
            tempADCSetting.u8BlueOffset += u8OffsetDelta;
            u8FlowFlag |= _BIT4;
        }
        else
        {
            tempADCSetting.u8BlueOffset -= u8OffsetDelta;
            u8FlowFlag |= _BIT5;
        }
        AUTOMSG(printf("OffATG=0x%bx,FF=0x%bx\n", u8ATGStatus, u8FlowFlag);)
    } // while

    // adjust offset after auto-tune
    if(u8FlowFlag == 0x3f)
    {
        pstADCSetting->u8RedOffset = tempADCSetting.u8RedOffset;
        pstADCSetting->u8GreenOffset = tempADCSetting.u8GreenOffset;
        pstADCSetting->u8BlueOffset = tempADCSetting.u8BlueOffset;
    }

    // if calibration successed, will write new value, else, write original value
    MDrv_ADC_SetOffset(pstADCSetting);

    MDrv_WriteByte( BK_SELECT_00, u8Bank );

    return (u8FlowFlag == 0x3F ? TRUE : FALSE);
}

//*************************************************************************
//Function name: MDrv_Auto_TuneGain
//Passing parameter:
//  U8 u8VSyncTime: VSync time
//  MS_ADC_SETTING * pstADCSetting: ADC setting of Current PC mode
//Return parameter:
//  BOOLEAN: Success status. (If faile, return FALSE.)
//Description: Auto-tune R/G/B gain of ADC.
//*************************************************************************
#define AUTO_GAIN_SW_MODE 0
BOOLEAN MDrv_Auto_TuneGain(U8 u8VSyncTime, MS_ADC_SETTING *pstADCSetting)
{
    MS_ADC_SETTING tempADCSetting;
    U8 u8GainDelta = 0x80; // adjust step
    U8 u8ATGStatus; // auto gain status
    U8 u8FlowFlag = 0x00; // underflow or overflow flag
    U8 u8Bank;

    tempADCSetting.u8RedGain = 0x80;
    tempADCSetting.u8GreenGain = 0x80;
    tempADCSetting.u8BlueGain = 0x80;

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

    while (1)
    {
        u8GainDelta /= 2; // next

        if (u8GainDelta == 0x00) // check end
            break;

        MDrv_ADC_SetGain(&tempADCSetting);
        MDrv_Timer_Delayms(u8VSyncTime * 3); // wait stable
        MDrv_Auto_WaitStatusReady(BK_SC_IP1F2_0E_L, _BIT1);

#if AUTO_GAIN_SW_MODE
        {
            U8 u8ResultR,u8ResultG,u8ResultB;

            u8ResultR = _MDrv_Auto_GainReport(AUTO_MAX_R, u8VSyncTime);
            u8ResultG = _MDrv_Auto_GainReport(AUTO_MAX_G, u8VSyncTime);
            u8ResultB = _MDrv_Auto_GainReport(AUTO_MAX_B, u8VSyncTime);

            if (u8ResultR == 0xFF)
                u8ATGStatus |= _BIT7;
            else
                u8ATGStatus &= ~_BIT7;

            if (u8ResultG == 0xFF)
                u8ATGStatus |= _BIT6;
            else
                u8ATGStatus &= ~_BIT6;


            if (u8ResultB == 0xFF)
                u8ATGStatus |= _BIT5;
            else
                u8ATGStatus &= ~_BIT5;
        }
#else
        u8ATGStatus = MDrv_ReadByte(BK_SC_IP1F2_0E_L); // get auto gain status
#endif

        // red
        if (_bit7_(u8ATGStatus))
        {
            tempADCSetting.u8RedGain -= u8GainDelta;
            u8FlowFlag |= _BIT0;
        }
        else
        {
            tempADCSetting.u8RedGain += u8GainDelta;
            u8FlowFlag |= _BIT1;
        }

        // green
        if (_bit6_(u8ATGStatus))
        {
            tempADCSetting.u8GreenGain -= u8GainDelta;
            u8FlowFlag |= _BIT2;
        }
        else
        {
            tempADCSetting.u8GreenGain += u8GainDelta;
            u8FlowFlag |= _BIT3;
        }

        // blue
        if (_bit5_(u8ATGStatus))
        {
            tempADCSetting.u8BlueGain -= u8GainDelta;
            u8FlowFlag |= _BIT4;
        }
        else
        {
            tempADCSetting.u8BlueGain += u8GainDelta;
            u8FlowFlag |= _BIT5;
        }
        AUTOMSG(printf("GainATG=0x%bx,FF=0x%bx\n", u8ATGStatus, u8FlowFlag);)
    } // while

    // adjust gain after auto-tune
    if (u8FlowFlag == 0x3f)
    {
        pstADCSetting->u8RedGain = tempADCSetting.u8RedGain;
        pstADCSetting->u8GreenGain = tempADCSetting.u8GreenGain;
        pstADCSetting->u8BlueGain = tempADCSetting.u8BlueGain;
    }

    // if calibration successed, will write new value, else, write original value
    MDrv_ADC_SetOffset(pstADCSetting);

    MDrv_WriteByte( BK_SELECT_00, u8Bank );

    return (u8FlowFlag == 0x3F ? TRUE : FALSE);
}


//*************************************************************************
//Function name: MDrv_Auto_ColorYUV
//Passing parameter:
//  U8 u8VSyncTime: VSync time
//  MS_ADC_SETTING * pstADCSetting: ADC setting of Current YCbCr mode
//Return parameter:
//  BOOLEAN: Success status. (If faile, return FALSE.)
//Description: Auto-tune Y gain of ADC.
//*************************************************************************
#if COMPONENT_AUTO_SW_MODE
BOOLEAN MDrv_Auto_ColorYUV(U8 u8VSyncTime, MS_ADC_SETTING *pstADCSetting)
{
    MS_ADC_SETTING tempADCSetting;
    U8 u8Bank; // bank buffer
    U8 u8ATGStatus, u8Tmp, u8FlowFlag;
    U8 u8ResultR,u8ResultG,u8ResultB;

⌨️ 快捷键说明

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