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

📄 framesync.c

📁 realtek LCD monitor, TV开发源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
//--------------------------------------------------
// Description  : Calculate the suitable framesync point
// Input Value  : None
// Output Value : Return Dclk offset
//--------------------------------------------------
WORD CFrameSyncFastDo(void)
{
    DWORD aclkcnt = 0;
    DWORD offset;
    BYTE mcode, div;

    CScalerSetBit(_SYNC_SELECT_47, ~(_BIT1 | _BIT0), 0x00);

    CScalerSetBit(_STABLE_PERIOD_H_50, ~_BIT4, _BIT4);
    CAdjustSyncProcessorMeasureStart();

    if(CTimerPollingEventProc(60, CMiscModeMeasurePollingEvent))
    {

        CScalerSetBit(_MEAS_HS_PERIOD_H_52, ~_BIT6, _BIT6);
        CScalerSetByte(_MEAS_ACTIVE_REGION_59, 0x00);

        pData[0] = 0;
        CScalerRead(_MEAS_ACTIVE_REGION_59, 3, &pData[1], _NON_AUTOINC);

        aclkcnt = ((DWORD *)pData)[0];

        CScalerSetBit(_MEAS_HS_PERIOD_H_52, ~(_BIT7 | _BIT5), 0x00);

        CScalerPageSelect(_PAGE1);
        CScalerRead(_P1_DPLL_M_BF, 1, &mcode, _NON_AUTOINC);
        mcode += 2;

        CScalerRead(_P1_DPLL_N_C0, 1, &div, _NON_AUTOINC);
        div = 0x01 << ((div & 0x30) >> 4);

        offset = (DWORD)32768 * div * 2 * _DPLL_N_CODE * stDisplayInfo.DHTotal / aclkcnt * stDisplayInfo.DVHeight / mcode;

        offset = 32768 - offset;

//        CScalerSetBit(_SYNC_SELECT_47, ~(_BIT1 | _BIT0), _BIT1);

    }
    else
    {
        offset = 0xffff;
    }

    CScalerSetBit(_STABLE_PERIOD_H_50, ~_BIT4, 0x00);
    return (WORD)offset;
}

//--------------------------------------------------
// Description  : Apply Dclk frequency and get the overflow/underflow information
// Input Value  : Dclk offset
// Output Value : Return _FALSE if there is no timing change
//--------------------------------------------------
bit CFrameSyncTestSync(WORD usOffset)
{
    CScalerSetBit(_SYNC_SELECT_47, ~_BIT0, 0x00);
    CAdjustSyncProcessorMeasureStart();

    // Apply Dclk frequency setting
    CAdjustDclkOffset(usOffset);

    CScalerSetByte(_STATUS0_02, 0x00);                      // Clear Status

    CTimerWaitForEvent(_EVENT_DVS);                         // Wait for Frame End

    CTimerWaitForEvent(_EVENT_DVS);                         // Wait for Frame End

    // Issac added for interlaced mode 2006-08-29
    CTimerWaitForEvent(_EVENT_DVS);                         // Wait for Frame End

    if(CModeIsChange())
        return _TRUE;

    CScalerRead(_STATUS0_02, 1, pData, _NON_AUTOINC);       // Read status

    // Input timing changed
    if (pData[0] & 0x60)
        return _TRUE;

    // Save underflow/overflow information into pData[0]
    pData[0] &= 0x03;

    return _FALSE;                                          // Success
}

//--------------------------------------------------
// Description  : Adjust Dclk offset to meet frame sync
// Input Value  : None
// Output Value : Return 0 if sucess
//--------------------------------------------------
BYTE CFrameSyncDo(void)
{
    WORD buffer, delta;
    BYTE fine, result = 0;

    // Read the DCLK offset
    CScalerPageSelect(_PAGE1);
    CScalerRead(_P1_DCLK_FINE_TUNE_OFFSET_MSB_C4, 2, pData, _AUTOINC);
    buffer  = (((WORD)pData[0] & 0x0f) << 8) | pData[1];

    // Disable the Fixed DVTOTAL & Last Line Length Fucntion
    CScalerSetBit(_P1_EVEN_FIXED_LAST_LINE_CTRL_CA, ~_BIT1, 0x00);

    // Disable spread spectrum
    CAdjustDclkSpreadSpectrumRange(0);

    // Fast Framesync method
    delta = CFrameSyncFastDo();

    if(CFrameSyncTestSync(delta))   return 2;

    if(pData[0] == 0)
    {
        result |= _BIT0;

        if(CFrameSyncTestSync(delta + _OFFSET_STEP))   return 2;
        if(pData[0] == 0)   result |= _BIT1;

        if(CFrameSyncTestSync(delta - _OFFSET_STEP))   return 2;
        if(pData[0] == 0)   result |= _BIT2;

        if(result == (_BIT0 | _BIT1))
            delta += _OFFSET_STEP / 2;
        else if(result == (_BIT0 | _BIT2))
            delta -= _OFFSET_STEP / 2;
    }

    if(result == 0)     // Fast search fail, do iteration search
    {
        // Apply Dclk frequency setting
        CAdjustDclkOffset(buffer);

        // Search first satisfied DCLK setting for frame-sync
        result  = 0x00;
        fine    = _SEARCH_TIME;
        do
        {
            if(CFrameSyncTestSync(buffer))    return 2;

            if(pData[0] == 0)   break;

            if(pData[0] & 0x02)
                buffer  -= (result & 0x01) ? (_OFFSET_STEP / 2) : _OFFSET_STEP;
            else
                buffer  += (result & 0x02) ? (_OFFSET_STEP / 2) : _OFFSET_STEP;

            result  = pData[0];
        }
        while(--fine);

        if(fine == 0x00)    return 1;

        // If default offset is OK....
        if(result == 0x00)
        {
            if(CFrameSyncTestSync(buffer + _OFFSET_STEP))     return 2;
            result  = pData[0] ? pData[0] : 0x01;
        }

        // Search most satisfied DCLK setting for frame-sync
        delta = buffer;
        fine  = 4;
        do
        {
            WORD temp = (result & 0x01) ? delta + (_OFFSET_STEP / 2) : delta - (_OFFSET_STEP / 2);

            if(CFrameSyncTestSync(temp))      return 2;

            if(pData[0])    break;

            delta   = temp;
        }
        while(--fine);

        delta   = (buffer + delta) >> 1;
    }

    if(!CFrameSyncLastLineFinetune(&delta))      return 2;

    result = CFrameSyncSpreadSpectrumFinetune(&delta);
    if(result != 0)     return result;

    SET_FRAMESYNCSTATUS();

    return 0;
}

//--------------------------------------------------
// Description  : Modify Display Vertical Start Position
// Input Value  : Enable or Disable
// Output Value : None
//--------------------------------------------------
void CFrameSyncModifyDVStartPos(bit enable)
{
    if(enable)
    {
        stDisplayInfo.DVStartPos = (DWORD)35 * 2 * stDisplayInfo.DVHeight / stModeInfo.IVHeight / 10;
        stDisplayInfo.DVStartPos = ((stDisplayInfo.DVStartPos >> 1) + (stDisplayInfo.DVStartPos & 0x01));
        if(stDisplayInfo.DVStartPos < 6)
            stDisplayInfo.DVStartPos = 6;
    }
    else
    {
        stDisplayInfo.DVStartPos = (LOBYTE(_PANEL_DV_START));
    }
}

#if((_TMDS_SUPPORT == _ON) || (_YPBPR_SUPPORT == _ON) || (_VIDEO_SUPPORT == _ON) )
//--------------------------------------------------
// Description  : Set Frame Sync Fine Tune for Even/Odd field
// Input Value  : Even field before or after odd filed
// Output Value : None
//--------------------------------------------------
void CFrameSyncFineTune(bit field)
{
    WORD ustemp;

    CScalerRead(_IV_DV_DELAY_CLK_ODD_41, LENGTH(1), pData, _NON_AUTOINC);
    ustemp = (WORD)pData[0] * 16 + 16;

    if(field)   // Even field before Odd field
    {
        if(ustemp > (stModeInfo.IHTotal / 2))
        {
            ustemp -= stModeInfo.IHTotal / 2;
            CScalerSetByte(_IV_DV_DELAY_CLK_EVEN_42, (ustemp - 16) / 16);
        }
        else
        {
            CScalerSetByte(_IPV_ACT_STA_L_19, CScalerGetBit(_IPV_ACT_STA_L_19, 0xff) + 1);
            ustemp += stModeInfo.IHTotal;
            CScalerSetByte(_IV_DV_DELAY_CLK_ODD_41, (ustemp - 16) / 16);
            ustemp -= stModeInfo.IHTotal / 2;
            CScalerSetByte(_IV_DV_DELAY_CLK_EVEN_42, (ustemp - 16) / 16);
        }
    }
    else    // Even field after Odd field
    {
        ustemp += stModeInfo.IHTotal / 2;
        CScalerSetByte(_IV_DV_DELAY_CLK_EVEN_42, ((ustemp + 8) / 16) - 1);
    }

    CScalerSetBit(_FS_DELAY_FINE_TUNING_43, ~(_BIT1), _BIT1);
}
#endif  // End of #if((_TMDS_SUPPORT == _ON) || (_YPBPR_SUPPORT == _ON) || (_VIDEO_SUPPORT == _ON) )


#endif  // End of #if(_SCALER_SERIES_TYPE == _RTD2472D_SERIES)

//Anderson 071219 for 2545LR, 248xRD, 248xRD

⌨️ 快捷键说明

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