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

📄 auto.c

📁 车载 液晶显示器的主控程序(主要使用芯片为 MYSON MTV512 单片机、RealTek 2323 Scare 芯片、TVP5147(视频解码)。配Sharp 8寸液晶显示器 )。
💻 C
📖 第 1 页 / 共 4 页
字号:
    if(_ERROR_SUCCESS != result)  return result;

    // Set threshold 0x80 for Phase Search
    CScalerSetByte(_DIFF_THRESHOLD_79, 0x80);

    maxsum  = CAutoPhaseSearch(_COLOR_SELECT, _HWAUTO_STEP_8, HWAUTOSTEPNUM(8), HWAUTOSTEPSTART(0), &result);
    if(maxsum == 0xffffffffL)     return _ERROR_INPUT;
    if(maxsum == 0)               return _ERROR_ABORT;

    if(maxsum < ((LWORD)stModeInfo.IVHeight * 1024 * 3 / 2))
    {
        // Decrease threshold to 0x40 for Phase Search
        CScalerSetByte(_DIFF_THRESHOLD_79, 0x40);

        maxsum  = CAutoPhaseSearch(_COLOR_SELECT, _HWAUTO_STEP_8, HWAUTOSTEPNUM(8), HWAUTOSTEPSTART(0), &result);
        if(maxsum == 0xffffffffL)     return _ERROR_INPUT;
        if(maxsum == 0)               return _ERROR_ABORT;

        if(maxsum < ((LWORD)stModeInfo.IVHeight * 1024 * 3 / 2))
            return _ERROR_PHASE;
    }

    maxsum  = CAutoPhaseSearch(_COLOR_SELECT, _HWAUTO_STEP_2, HWAUTOSTEPNUM(8), HWAUTOSTEPSTART((result - 8) & 0x3f), &result);
    if(maxsum == 0xffffffffL)     return _ERROR_INPUT;
    if(maxsum == 0)               return _ERROR_ABORT;

    // Search phase by weighting SOD
    phase   = (result - 3) & 0x3f;
    CAdjustPhase(phase);

    if(_ERROR_SUCCESS != CAutoReadPhaseInfo(_COLOR_SELECT))   return _ERROR_INPUT;
    temp0   = ((LWORD *)pData)[0];

    phase   = (phase + 1) & 0x3f;
    CAdjustPhase(phase);

    if(_ERROR_SUCCESS != CAutoReadPhaseInfo(_COLOR_SELECT))   return _ERROR_INPUT;
    temp1   = ((LWORD *)pData)[0];

    result  = (result + 3) & 0x3f;
    maxsum  = 0;
    do
    {
        phase   = (phase + 1) & 0x3f;
        CAdjustPhase(phase);

        if(_ERROR_SUCCESS != CAutoReadPhaseInfo(_COLOR_SELECT))   return _ERROR_INPUT;

        temp2   = ((LWORD *)pData)[0];

        ((LWORD *)pData)[0] = temp2 + temp1 + temp0
                              - ((temp1 > temp0 ? temp1 - temp0 : temp0 - temp1) / 2)
                              - ((temp1 > temp2 ? temp1 - temp2 : temp2 - temp1) / 2);

        if(((LWORD *)pData)[0] > maxsum)
        {
            maxsum  = ((LWORD *)pData)[0];
            best    = (phase - 1) & 0x3f;
        }

        temp0   = temp1;
        temp1   = temp2;
    }
    while(phase != result);

    stModeUserData.Phase    = best;
    CAdjustPhase(stModeUserData.Phase);

    CScalerSetByte(_DIFF_THRESHOLD_79, 0x40);

    return _ERROR_SUCCESS;
}

//--------------------------------------------------
// Description  : Auto position process
// Input Value  : None
// Output Value : Measure status
//--------------------------------------------------
BYTE CAutoDoAutoPosition(void)
{
    BYTE result;
    SWORD dtemp, ctemp, atemp;

    result  = CAutoMeasurePositionV(_MIN_NOISE_MARGIN);
    if(_ERROR_SUCCESS != result)    return result;

    result  = CAutoMeasurePositionH(_MIN_NOISE_MARGIN);
    if(_ERROR_SUCCESS != result)    return result;

    /////////////////////////////////
    // Calculate Vertical Position //
    /////////////////////////////////
    CScalerRead(_IPV_ACT_STA_H_0D, 2, pData, _AUTOINC);
    ctemp = (((WORD)(pData[0] & 0x07)) << 8) | pData[1];

    CScalerRead(_IVS_DELAY_11, 1, pData, _AUTOINC);
    CScalerRead(_VGIP_HV_DELAY_13, 1, &pData[1], _AUTOINC);
    dtemp = (((WORD)(pData[1] & _BIT1)) << 8) | pData[0];

    dtemp = usVStartPos - dtemp;

    atemp = abs(usVEndPos - usVStartPos + 1 - stModeInfo.IVHeight) / 2;

    while(_TRUE)
    {
        if(abs(stModeUserData.VPosition + (ctemp - dtemp) - stModeInfo.IVStartPos + atemp) <= ucVStartBias)
        {
#if(_V_POSITION_DIRECTION == _LAST_LINE_METHOD_0)
            stModeUserData.VPosition += ctemp - dtemp + atemp;
#endif

#if(_V_POSITION_DIRECTION == _LAST_LINE_METHOD_1)
            stModeUserData.VPosition -= ctemp - dtemp + atemp;
#endif
            break;
        }
        else
        {
            stModeUserData.VPosition = stModeInfo.IVStartPos;
            break;
        }
    }

    CAdjustVPosition();

    ///////////////////////////////////
    // Calculate Horizontal Position //
    ///////////////////////////////////
    CScalerRead(_IPH_ACT_STA_H_09, 2, pData, _AUTOINC);
    ctemp = (((WORD)(pData[0] & 0x07)) << 8) | pData[1];

    CScalerRead(_IHS_DELAY_12, 2, pData, _AUTOINC);
    dtemp = (((WORD)(pData[1] & _BIT0)) << 8) | pData[0];

    dtemp = usHStartPos - dtemp - 2;

    while(_TRUE)
    {
        if(abs(stModeUserData.HPosition + (ctemp - dtemp) - stModeInfo.IHStartPos) <= ucHStartBias)
        {
            stModeUserData.HPosition += ctemp - dtemp;
            break;
        }
        else
        {
            stModeUserData.HPosition = stModeInfo.IHStartPos;
            break;
        }
    }

    CAdjustHPosition();

    return _ERROR_SUCCESS;
}

//--------------------------------------------------
// Description  : Tune ADC gain and offset
// Input Value  : None
// Output Value : Measure status
//--------------------------------------------------
BYTE CAutoTuneBalance(void)
{
    BYTE rev, result0, result1, color, count;

    rev = CAutoMeasurePositionV(_MIN_NOISE_MARGIN);
    if(rev != _ERROR_SUCCESS)    return rev;

    rev = CAutoMeasurePositionH(_MIN_NOISE_MARGIN);
    if(rev != _ERROR_SUCCESS)    return rev;

    color = _BLUE;
    while(_TRUE)
    {
        count = 0x30;

        do
        {
            rev = CAutoTuneAdcGain(color, &result0);

            if(rev == _ERROR_ABORT)     return rev;
            if(rev == _ERROR_FINISH)    break;

            rev = CAutoTuneAdcOffset(color, &result1);

            if(rev == _ERROR_ABORT)     return rev;

            if(result0 == _WHITEBALANCE_MAX_LEVEL)
                break;
        }
        while(--count);

        if(color == _BLUE)
            color = _GREEN;
        else if(color == _GREEN)
            color = _RED;
        else
            break;
    }

    return _ERROR_SUCCESS;
}

//--------------------------------------------------
// Description  : Get max or min color value
// Input Value  : Measure information
// Output Value : Measure status
//--------------------------------------------------
BYTE CAutoMeasureColor(BYTE ucColor, BYTE ucPar, BYTE *pMargin)
{
    CScalerSetBit(_AUTO_ADJ_CTRL0_7A, ~(_BIT2 | _BIT1 | _BIT0), (ucColor == 3) ? ucColor : ( 2 - ucColor));

    if(ucPar == _MEASURE_COLORS_MIN)
    {
        pData[0] = 0x12;
        pData[1] = 0x80;
        pData[2] = 0x00;
        pData[3] = 0x00;
        pData[4] = (usVStartPos > 9) ? 9 : (usVStartPos - 1);
        pData[5] = pData[4] + 1;
    }
    else
    {
        pData[0] = ((usHStartPos >> 4) & 0x70) | (HIBYTE(usHEndPos) & 0x0f);
        pData[1] = (LOBYTE(usHStartPos));
        pData[2] = (LOBYTE(usHEndPos));
        pData[3] = ((usVStartPos >> 4) & 0x70) | (HIBYTE(usVEndPos) & 0x0f);
        pData[4] = (LOBYTE(usVStartPos));
        pData[5] = (LOBYTE(usVEndPos));
    }
    CScalerWrite(_H_BOUNDARY_H_70, 6, pData, _AUTOINC);

    CScalerSetByte(_AUTO_ADJ_CTRL1_7D, 0x01 | ((ucPar & 0x01) << 5));

    pData[0] = CAutoWaitFinish();

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

    CScalerRead(_AUTO_PHASE_0_87, 1, pMargin, _AUTOINC);

    if(ucPar == _MEASURE_COLORS_MIN)
        *pMargin ^= 0xff;

    return _ERROR_SUCCESS;
}

//--------------------------------------------------
// Description  : Adjust ADC gain
// Input Value  : Adjusting setting
// Output Value : Measure status
//--------------------------------------------------
BYTE CAutoTuneAdcGain(BYTE ucColor, BYTE *pMargin)
{
    BYTE temp;

    if(CAutoMeasureColor(ucColor, _MEASURE_COLORS_MAX, pMargin) != _ERROR_SUCCESS)
        return _ERROR_ABORT;

    if(*pMargin > _WHITEBALANCE_MAX_LEVEL)
    {
        temp  = *pMargin - _WHITEBALANCE_MAX_LEVEL;
                
        // Non-zero return value of Change_ADC_Gain() means ADC gain reaches maximum.
        if(CAutoChangeAdcGain(ucColor, temp, 0))                  // Increase Gain; Decrease Contrast
        {
            if(CAutoChangeAdcOffset(ucColor, 4, 0))               // Increase Offset; Decrease Brightness
                return _ERROR_FINISH;
        }
    }
    else if(*pMargin < _WHITEBALANCE_MAX_LEVEL)
    {
        temp  = _WHITEBALANCE_MAX_LEVEL - *pMargin;

        // Non-zero return value of Change_ADC_Gain() means ADC gain reaches minimum.
        if(CAutoChangeAdcGain(ucColor, temp, 1))                  // Decrease Gain; Increase Contrast
        {
            if(CAutoChangeAdcOffset(ucColor, 4, 1))               // Decrease Offset; Increase Brightness
                return _ERROR_FINISH;
        }
    }

    return _ERROR_SUCCESS;
}

//--------------------------------------------------
// Description  : Adjust ADC offset
// Input Value  : Adjusting setting
// Output Value : Measure status
//--------------------------------------------------
BYTE CAutoTuneAdcOffset(BYTE ucColor, BYTE *pMargin)
{
    BYTE temp;

    if(CAutoMeasureColor(ucColor, _MEASURE_COLORS_MIN, pMargin) != _ERROR_SUCCESS)
        return _ERROR_ABORT;

    if(*pMargin > _WHITEBALANCE_MIN_LEVEL)
    {
        temp = *pMargin - _WHITEBALANCE_MIN_LEVEL;

        CAutoChangeAdcOffset(ucColor, ((temp > 8) ? 8 : temp), 0);     // Increase Offset; Decrease Brightness
    }
    else if(*pMargin < _WHITEBALANCE_MIN_LEVEL)
    {
        temp = _WHITEBALANCE_MIN_LEVEL - *pMargin;

        if(*pMargin == 0)
            CAutoChangeAdcOffset(ucColor, temp + 4, 1);       // Decrease Offset; Increase Brightness
        else
            CAutoChangeAdcOffset(ucColor, temp, 1);           // Decrease Offset; Increase Brightness
    }

    return _ERROR_SUCCESS;
}

//--------------------------------------------------
// Description  : Change ADC gain
// Input Value  : Input information
// Output Value : Return 1 if overrange
//--------------------------------------------------
BYTE CAutoChangeAdcGain(BYTE ucColor, BYTE ucDelta, BYTE ucInc)
{
    BYTE overrange = 0;

    if(ucInc)
    {
        if(stAdcData.AdcGain[ucColor] >= ucDelta)
            stAdcData.AdcGain[ucColor] -= ucDelta;
        else
        {
            stAdcData.AdcGain[ucColor] = 0;
            overrange = 1;
        }
    }
    else
    {
        if ((0xff - ucDelta) >= stAdcData.AdcGain[ucColor])
            stAdcData.AdcGain[ucColor] += ucDelta;
        else
        {
            stAdcData.AdcGain[ucColor] = 0xff;
            overrange = 1;
        }
    }

    CAdjustAdcGain();
    
    return overrange;
}

//--------------------------------------------------
// Description  : Change ADC offset
// Input Value  : Input information
// Output Value : Return 1 if overrange
//--------------------------------------------------
BYTE CAutoChangeAdcOffset(BYTE ucColor, BYTE ucDelta, BYTE ucInc)
{
    BYTE overrange = 0;

    if(ucInc)
    {
        if(stAdcData.AdcOffset[ucColor] >= ucDelta)
            stAdcData.AdcOffset[ucColor] -= ucDelta;
        else
        {
            stAdcData.AdcOffset[ucColor] = 0;
            overrange = 1;
        }
    }
    else
    {
        if ((0xff - ucDelta) >= stAdcData.AdcOffset[ucColor])
            stAdcData.AdcOffset[ucColor] += ucDelta;
        else
        {
            stAdcData.AdcOffset[ucColor] = 0xff;
            overrange = 1;
        }
    }

    CAdjustAdcOffset();
    
    return overrange;
}

⌨️ 快捷键说明

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