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

📄 framesync.c

📁 很难得的最好的rtd3523系列原厂源码LCD驱动开发
💻 C
字号:
//----------------------------------------------------------------------------------------------------
// ID Code      : FrameSync.c No.0000
// Update Note  : 
//
//----------------------------------------------------------------------------------------------------

#define __FRAMESYNC__

#include "..\Header\Include.h"

//x.hu, for video frame sync counter
BYTE ucVideoSyncCnt=0;

//--------------------------------------------------
// Description  : Detect frame sync status
// Input Value  : None
// Output Value : Return _FALSE if frame sync is ok, _TRUE while PLL mislock, buffer underflow/overflow
//--------------------------------------------------
bit CFrameSyncDetect(void)
{
    if(GET_POWERSTATUS() && GET_MODESTABLE())
    {
        CScalerRead(_STATUS0_02, 1, pData, _NON_AUTOINC);

        if((pData[0] & 0x03) == 0)
        {
            if((pData[0] & 0x80) == 0)
            {
            	return _FALSE;                
            }
        }
    }

	//x.hu, for video on 5150+2013B
	//don't mask this, because sometimes the image can't display correctly.
	// 20050627
	/*if(GET_INPUTSOURCE_TYPE() == _SOURCE_VIDEO8)
		return _FALSE;
				//if(GET_INPUTSOURCE_TYPE() == _SOURCE_VIDEO8) {
				if (GET_INPUTPORT_TYPE(stSystemData.InputSource) == _VIDEO_AV_PORT || \
					GET_INPUTPORT_TYPE(stSystemData.InputSource) == _VIDEO_AV2_PORT	) {
					if (ucVideoSyncCnt++ < 10) {
						return _FALSE;
					}
					else {
						ucVideoSyncCnt = 0;
    					CLR_FRAMESYNCSTATUS();
						return _TRUE;
					}
				}  	
*/	// x.hu, test to mask this, may be updated


    CLR_FRAMESYNCSTATUS();

    return _TRUE;
}

//--------------------------------------------------
// Description  : Finetune last line problem
// Input Value  : Dclk offset
// Output Value : Return _TRUE if there is no timing change
//--------------------------------------------------
bit CFrameSyncLastLineFinetune(WORD *pDelta)
{
#if(_LAST_LINE_FINETUNE == _LAST_LINE_METHOD_0)

    WORD dvtotal;
    LWORD dclktotal = 0;

    CScalerSetByte(_LAST_LINE_H_44, 0x00);

    if(CFrameSyncTestSync(*pDelta))     return _FALSE;

    CScalerRead(_LAST_LINE_H_44, 2, pData, _AUTOINC);
    dclktotal = ((WORD)(pData[0] & 0x0f) << 8) | pData[1];

    CScalerSetByte(_LAST_LINE_H_44, 0x80);
    CTimerDelayXms(40);
    CScalerRead(_LAST_LINE_H_44, 2, pData, _AUTOINC);
    dvtotal = ((WORD)(pData[0] & 0x0f) << 8) | pData[1];

    dclktotal = dclktotal + (LWORD)stDisplayInfo.DHTotal * (dvtotal + 1 - stDisplayInfo.DVHeight);

    dvtotal = dclktotal / 1280;
    dvtotal = dclktotal - ((LWORD)dvtotal * 1280);

    *pDelta	= (dvtotal > (1280 - 128)) ? (*pDelta + 3) : ((dvtotal < 128) ? (*pDelta - 3) : *pDelta);

    return _TRUE;

#endif

#if(_LAST_LINE_FINETUNE == _LAST_LINE_METHOD_1)

#endif

#if(_LAST_LINE_FINETUNE == _LAST_LINE_METHOD_2)

#endif

}

//--------------------------------------------------
// Description  : Finetune Dclk offset for spread spectrum
// Input Value  : Dclk offset
// Output Value : Return _FALSE if there is no timing change
//--------------------------------------------------
BYTE CFrameSyncSpreadSpectrumFinetune(WORD *pDelta)
{
    //Enable the spread spectrum function
    CAdjustSpreadSpectrumRange(_DCLK_SPREAD_RANGE);

    *pDelta = *pDelta + tDCLK_OFFSET[_DCLK_SPREAD_RANGE];

    if(CFrameSyncTestSync(*pDelta))     return 2;

    if(pData[0])
    {
        //Fine-tune DCLK offset 
        if(CFrameSyncTestSync((pData[0] & 0x02) ? (*pDelta - 1) : (*pDelta + 1)))     return 2;

        if(pData[0] & 0x03)     return 1;   //Frame sync fail!
    }

    return 0;
}

//--------------------------------------------------
// Description  : Calculate the suitable framesync point
// Input Value  : None
// Output Value : Return Dclk offset
//--------------------------------------------------
WORD CFrameSyncFastDo(void)
{
    LWORD aclkcnt = 0;
    LWORD offset;
    BYTE mcode, div;

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

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

    CTimerDelayXms(60);

    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 = ((LWORD *)pData)[0];

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

    CScalerRead(_DPLL_M_AE, 1, &mcode, _NON_AUTOINC);
    mcode += 2;

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

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

    offset = 32768 - offset;

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

    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

    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;

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

    // Disable spread spectrum
    CAdjustSpreadSpectrumRange(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
    {
        // Read the DCLK offset
        CScalerRead(_DCLK_FINE_TUNE_OFFSET_MSB_B5, 2, pData, _AUTOINC);
        buffer  = (((WORD)pData[0] & 0x0f) << 8) | pData[1];

        // 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;
}


⌨️ 快捷键说明

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