📄 framesync.c
字号:
//--------------------------------------------------
// 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 + -