📄 framesync.c
字号:
//**********************************************************************************************************
// The Software is proprietary, confidential, and valuable to Realtek Semiconductor
// Corporation ("Realtek"). All rights, including but not limited to copyrights,
// patents, trademarks, trade secrets, mask work rights, and other similar rights and interests,
// are reserved to Realtek. Without prior written consent from Realtek, copying, reproduction,
// modification, distribution, or otherwise is strictly prohibited. The Software shall be
// kept strictly in confidence, and shall not be disclosed to or otherwise accessed by
// any third party. @ <2003> - <2008> The Software is provided "AS IS" without any warranty of any kind,
// express, implied, statutory or otherwise.
//**********************************************************************************************************
//----------------------------------------------------------------------------------------------------
// ID Code : FrameSync.c No.0000
// Update Note :
//----------------------------------------------------------------------------------------------------
#define __FRAMESYNC__
#include "Common\Header\Include.h"
//Anderson 071219 for 2545LR, 248xRD, 248xRD
#if(_SCALER_SERIES_TYPE == _RTD2472D_SERIES)
//--------------------------------------------------
// 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] & 0x63) == 0)
{
if(GET_INPUTSOURCE_TYPE() == _SOURCE_YPBPR)
return _FALSE;
//Anderson 080130 for FRC Support Start
//V403 modify
// APLL miss-lock must be checked even in FRC mode
#if(_FRC_SUPPORT == _ON)
if(((pData[0] & 0x03) == 0) || GET_FRCSTATUS())
#endif
{
// V010 Patch Note (30) : Add APLL New Mode Setting
#if(_WD_APLL == _ON)
if((pData[0] & 0x80) == 0x00)
#endif
return _FALSE;
}
//Anderson 080130 for FRC Support End
}
}
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_NONE)
if(CFrameSyncTestSync(*pDelta))
return _FALSE;
else
return _TRUE;
#endif
#if(_LAST_LINE_FINETUNE == _LAST_LINE_METHOD_0)
// Formula: Tne DEN End to DEN Start Length must be (1280*N)
// CPT's Panels.
WORD dvtotal;
DWORD dclktotal = 0;
CScalerSetDataPortByte(_DISP_ACCESS_PORT_2A, _DISP_NEW_DV_CTRL_22, 0x00);
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 + (DWORD)stDisplayInfo.DHTotal * (dvtotal + 1 - stDisplayInfo.DVHeight);
dvtotal = dclktotal / 1280;
dvtotal = dclktotal - ((DWORD)dvtotal * 1280);
*pDelta = (dvtotal > (1280 - 128)) ? (*pDelta + 3) : ((dvtotal < 128) ? (*pDelta - 3) : *pDelta);
CScalerSetDataPortByte(_DISP_ACCESS_PORT_2A, _DISP_NEW_DV_CTRL_22, 0xa0);
return _TRUE;
#endif
#if(_LAST_LINE_FINETUNE == _LAST_LINE_METHOD_1)
// Formula: Tne DEN End to DEN Start Length must be (4096*N + 128)
// Samsung's Panels.
WORD dvtotal;
DWORD dclktotal = 0;
CScalerSetDataPortByte(_DISP_ACCESS_PORT_2A, _DISP_NEW_DV_CTRL_22, 0x00);
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 + (DWORD)stDisplayInfo.DHTotal * (dvtotal + 1 - stDisplayInfo.DVHeight) - 128;
dvtotal = dclktotal / 4096;
dvtotal = dclktotal - ((DWORD)dvtotal * 4096);
*pDelta = (dvtotal > (4096 - 128)) ? (*pDelta + 3) : ((dvtotal < 128) ? (*pDelta - 3) : *pDelta);
CScalerSetDataPortByte(_DISP_ACCESS_PORT_2A, _DISP_NEW_DV_CTRL_22, 0xa0);
return _TRUE;
#endif
#if(_LAST_LINE_FINETUNE == _LAST_LINE_METHOD_2)
// Formula: Fixed to target last line pixels
DWORD dclktotal;
DWORD dclktarget;
WORD dvtotal;
WORD lastlinepixels;
SWORD offsetnew;
// Turn off new timing method
CScalerSetDataPortByte(_DISP_ACCESS_PORT_2A, _DISP_NEW_DV_CTRL_22, 0x00);
// Measure DVTotal
CScalerSetByte(_LAST_LINE_H_44, 0x80);
if(CFrameSyncTestSync(*pDelta)) return _FALSE;
CScalerRead(_LAST_LINE_H_44, 2, pData, _AUTOINC);
dvtotal = ((WORD)(pData[0] & 0x0f) << 8) | pData[1];
// Measure last line clock numbers
CScalerSetByte(_LAST_LINE_H_44, 0x00);
if(CFrameSyncTestSync(*pDelta)) return _FALSE;
CScalerRead(_LAST_LINE_H_44, 2, pData, _AUTOINC);
lastlinepixels = ((WORD)(pData[0] & 0x0f) << 8) | pData[1];
// Calculate total display clock numbers in a frame
dclktotal = (DWORD)stDisplayInfo.DHTotal * dvtotal + lastlinepixels;
// Calculate mininum path of target clock numbers
if(lastlinepixels > _LAST_LINE_TARGET)
{
if((lastlinepixels - _LAST_LINE_TARGET) > (stDisplayInfo.DHTotal / 2))
dclktarget = (DWORD)stDisplayInfo.DHTotal * (dvtotal + 1) + _LAST_LINE_TARGET; // +
else
dclktarget = (DWORD)stDisplayInfo.DHTotal * (dvtotal) + _LAST_LINE_TARGET; // -
}
else
{
if((_LAST_LINE_TARGET - lastlinepixels) > (stDisplayInfo.DHTotal / 2))
dclktarget = (DWORD)stDisplayInfo.DHTotal * (dvtotal - 1) + _LAST_LINE_TARGET; // -
else
dclktarget = (DWORD)stDisplayInfo.DHTotal * (dvtotal) + _LAST_LINE_TARGET; // +
}
// Calculate and apply new offset
offsetnew = (((SDWORD)dclktotal - (SDWORD)dclktarget) * ((SDWORD)32768 - (SDWORD)*pDelta)) * 2 / (SDWORD)dclktotal;
offsetnew = (offsetnew / 2) + ((offsetnew > 0) ? (offsetnew & 0x01) : -(offsetnew & 0x01));
offsetnew = offsetnew + *pDelta;
if(CFrameSyncTestSync(offsetnew)) return _FALSE;
// Check underflow/overflow. If failed, try another side.
if(pData[0])
{
if(pData[0] & 0x02)
dclktarget = dclktarget + stDisplayInfo.DHTotal;
else
dclktarget = dclktarget - stDisplayInfo.DHTotal;
offsetnew = (((SDWORD)dclktotal - (SDWORD)dclktarget) * ((SDWORD)32768 - (SDWORD)*pDelta)) * 2 / (SDWORD)dclktotal;
offsetnew = (offsetnew / 2) + ((offsetnew > 0) ? (offsetnew & 0x01) : -(offsetnew & 0x01));
offsetnew = offsetnew + *pDelta;
if(CFrameSyncTestSync(offsetnew)) return _FALSE;
}
*pDelta = offsetnew;
return _TRUE;
#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
//0905 sephinroth start
if(((stModeInfo.IHWidth == 800) && (stModeInfo.IVHeight == 600) && (abs(stModeInfo.IVFreq - 722) < 10))
|| ((stModeInfo.IHWidth == 832) && (stModeInfo.IVHeight == 624) && (abs(stModeInfo.IVFreq - 745) < 10)))
{
CAdjustDclkSpreadSpectrumRange(0);
*pDelta = *pDelta + tDCLK_OFFSET[0];
}
else
{
CAdjustDclkSpreadSpectrumRange(_DCLK_SPREAD_RANGE);
*pDelta = *pDelta + tDCLK_OFFSET[_DCLK_SPREAD_RANGE];
}
//0905 sephinroth end
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -