📄 adjust.c
字号:
void CAdjustDPLL(DWORD ulFreq)
{
/*
WORD mcode;
BYTE div;
// We want to set DPLL offset to middle(2048), so the target DPLL M/N setting should be 16/15 of target frequency.
mcode = ulFreq * 8 * _DPLL_N_CODE * 16 / ((DWORD)_RTD_XTAL * 15);
div = 1; // Output DPLL for DCLK
mcode = (mcode + 2) >> 2; // Round to integer
// Original Formula : M_Code/Ich = 36.67 must be constant
// Ich = M_Code * 100 / 3667
// Ich = 1u + D0[0]*1u + D0[1]*2u + D0[2]*4u + D0[3]*8u (A)
// Calculate the Ich,
pData[5] = ((WORD)mcode * 100 / 3667) - 1;
pData[6] = 0x00;
if(pData[5] >= 8)
{
pData[5] -= 8;
pData[6] |= 0x08;
}
if(pData[5] >= 4)
{
pData[5] -= 4;
pData[6] |= 0x04;
}
if(pData[5] >= 2)
{
pData[5] -= 2;
pData[6] |= 0x02;
}
if(pData[5] >= 1)
{
pData[5] -= 1;
pData[6] |= 0x01;
}
pData[0] = mcode - 2;
#if(_M2PLL_USE == _ON)
pData[1] = ((1 == div) ? 0x00 : 0x10) | ((_DPLL_N_CODE / _RTD_M2PLL_RATIO) - 2);
#else
pData[1] = ((1 == div) ? 0x00 : 0x10) | (_DPLL_N_CODE - 2);
#endif
pData[2] = 0x80 | pData[6];
pData[3] = 0x17;
CScalerPageSelect(_PAGE1);
CScalerWrite(_P1_DPLL_M_BF, 4, pData, _AUTOINC);
CScalerSetBit(_P1_DPLL_OTHER_C3, ~_BIT1, _BIT1);
if((bit)CScalerGetBit(_P1_DPLL_N_C0, _BIT7))
{
CScalerSetBit(_P1_DPLL_N_C0, ~_BIT6, _BIT6);
CTimerDelayXms(2);
CScalerSetBit(_P1_DPLL_N_C0, ~_BIT6, 0x00);
}
// Dclk frequency in Hz
((DWORD *)pData)[0] = (DWORD)_RTD_XTAL * 1000 / (div * 2) * mcode / _DPLL_N_CODE;
// Offset resolution (Dclk / 2^15) in Hz
((DWORD *)pData)[1] = ((DWORD *)pData)[0] >> 15;
// Target frequency of Dclk in Hz
mcode = (((DWORD *)pData)[0] - (ulFreq * 1000)) / ((DWORD *)pData)[1];
mcode = mcode & 0x0fff;
//Enable DDS spread spectrum output function
CScalerSetBit(_P1_EVEN_FIXED_LAST_LINE_CTRL_CA, ~_BIT0, _BIT0);
CAdjustDclkOffset(mcode); */
WORD mcode;
BYTE div;
// We want to set DPLL offset to middle(2048), so the target DPLL M/N setting should be 16/15 of target frequency.
mcode = ulFreq * 8 * _DPLL_N_CODE * 16 / ((DWORD)_RTD_XTAL * 15);
//DebugPrintf("\n CAdjustDPLL =%x, ",(UINT8)(mcode>>8));
//DebugPrintf("%x ",(UINT8)(mcode));
if((GET_PNL_OUTPUT_BUS() == _PANEL_TTL) || (Panel[ucPanelSelect]->DHWidth < 1000))
{
if(mcode<120)
{
div = 4; // Output DPLL/2 for DCLK
mcode = (mcode + 0) >> 0; // Round to integer
//div = 2; // Output DPLL/2 for DCLK
//mcode = (mcode + 1) >> 1; // Round to integer
}
else
{
div = 1; // Output DPLL for DCLK
mcode = (mcode + 2) >> 2; // Round to integer
}
}
else
{
div = 1; // Output DPLL for DCLK
mcode = (mcode + 2) >> 2; // Round to integer
}
// Original Formula : M_Code/Ich = 36.67 must be constant
// Ich = M_Code * 100 / 3667
// Ich = 1u + D0[0]*1u + D0[1]*2u + D0[2]*4u + D0[3]*8u (A)
// Calculate the Ich,
pData[5] = ((WORD)mcode * 100 / 3667) - 1;
pData[6] = 0x00;
if(pData[5] >= 8)
{
pData[5] -= 8;
pData[6] |= 0x08;
}
if(pData[5] >= 4)
{
pData[5] -= 4;
pData[6] |= 0x04;
}
if(pData[5] >= 2)
{
pData[5] -= 2;
pData[6] |= 0x02;
}
if(pData[5] >= 1)
{
pData[5] -= 1;
pData[6] |= 0x01;
}
pData[0] = mcode - 2;
#if(_M2PLL_USE == _ON)
pData[1] = ((1 == div) ? 0x00 : 0x10) | ((_DPLL_N_CODE / _RTD_M2PLL_RATIO) - 2);
#else
if((GET_PNL_OUTPUT_BUS() == _PANEL_TTL) || (Panel[ucPanelSelect]->DHWidth < 1000))
{
if(div==2)
pData[1] = 0x10 | (_DPLL_N_CODE - 2);
else if(div==4)
pData[1] = 0x20 | (_DPLL_N_CODE - 2);
else//div==1
pData[1] = 0x00 | (_DPLL_N_CODE - 2);
}
else
pData[1] = ((1 == div) ? 0x00 : 0x10) | (_DPLL_N_CODE - 2);
#endif
pData[2] = 0x80 | pData[6];
pData[3] = 0x17;
CScalerPageSelect(_PAGE1);
CScalerWrite(_P1_DPLL_M_BF, 4, pData, _AUTOINC);
CScalerSetBit(_P1_DPLL_OTHER_C3, ~_BIT1, _BIT1);
if((bit)CScalerGetBit(_P1_DPLL_N_C0, _BIT7))
{
CScalerSetBit(_P1_DPLL_N_C0, ~_BIT6, _BIT6);
CTimerDelayXms(2);
CScalerSetBit(_P1_DPLL_N_C0, ~_BIT6, 0x00);
}
// Dclk frequency in Hz
((DWORD *)pData)[0] = (DWORD)_RTD_XTAL * 1000 / (div * 2) * mcode / _DPLL_N_CODE;
// Offset resolution (Dclk / 2^15) in Hz
((DWORD *)pData)[1] = ((DWORD *)pData)[0] >> 15;
// Target frequency of Dclk in Hz
mcode = (((DWORD *)pData)[0] - (ulFreq * 1000)) / ((DWORD *)pData)[1];
mcode = mcode & 0x0fff;
//Enable DDS spread spectrum output function
CScalerSetBit(_P1_EVEN_FIXED_LAST_LINE_CTRL_CA, ~_BIT0, _BIT0);
CAdjustDclkOffset(mcode);
}
//--------------------------------------------------
// Description :
// Input Value :
// Output Value :
//--------------------------------------------------
void CAdjustUpdateCenterData(void)
{
WORD delta;
stModeUserCenterData.CenterHPos = stModeUserData.HPosition;
stModeUserCenterData.CenterVPos = stModeUserData.VPosition;
CAdjustCheckAdcClockRange(stModeUserData.Clock, &delta);
if(delta < _CLOCK_BIAS)
{
stModeUserCenterData.CenterClock = stModeInfo.IHTotal;
}
else
{
if(stModeUserData.Clock < stModeInfo.IHTotal)
{
if((stModeUserData.Clock - stModeInfo.IHTotal + delta) < _CLOCK_BIAS)
{
stModeUserCenterData.CenterClock = stModeInfo.IHTotal - delta + _CLOCK_BIAS;
}
else
{
stModeUserCenterData.CenterClock = stModeUserData.Clock;
}
}
else
{
if((stModeInfo.IHTotal + delta - stModeUserData.Clock) < _CLOCK_BIAS)
{
stModeUserCenterData.CenterClock = stModeInfo.IHTotal + delta - _CLOCK_BIAS;
}
else
{
stModeUserCenterData.CenterClock = stModeUserData.Clock;
}
}
}
}
//--------------------------------------------------
// Description : Check if the ADC clock (IHTotal) is out of range. Range = (BackPorch + FrontPorch) * 2 / 5 .
// Input Value : usClock --> ADC Clock (IHTotal)
// Output Value : Return _TRUE if not out of range
//--------------------------------------------------
bit CAdjustCheckAdcClockRange(WORD usClock, WORD *delta)
{
*delta = (stModeInfo.IHTotal - stModeInfo.IHWidth * 8 / 10) / 2;
if((usClock > stModeInfo.IHTotal) && ((usClock - stModeInfo.IHTotal) > *delta))
return _FALSE;
if((usClock <= stModeInfo.IHTotal) && ((stModeInfo.IHTotal - usClock) > *delta))
return _FALSE;
// yc 060222 for usClock error no display
if(usClock < (stModeInfo.IHStartPos + _CAPTURE_HDELAY - (ucHStartBias + _PROGRAM_HDELAY) + stModeInfo.IHWidth))
return _FALSE;
return _TRUE;
}
//--------------------------------------------------
// Description : Set ADC clock (IHTotal)
// Input Value : usClock --> Target ADC clock
// Output Value : None
//--------------------------------------------------
void CAdjustAdcClock(WORD usClock)
{
//#define _PE_VALUE 175 // Unit: ps
DWORD pllclock, icode, SUM_I;
BYTE mcode;
SBYTE kcode,g_value = 1;
WORD delta, pcode;
static BYTE vco_divider = 2;
BYTE g_value_divider[6] = {4, 16, 64, 128, 256, 512};
#if (_APLL_FAST_LOCK)
DWORD temp2662;
#endif
CAdjustEnableWatchDog(_WD_DV_TIMEOUT);
CScalerPageSelect(_PAGE1);
#if(_APLL_FAST_LOCK)
//set the FAST PLL CONTROL
CScalerSetBit(_P1_FAST_PLL_CTRL_AA, ~(_BIT5 | _BIT1), (_BIT5 | _BIT1));
#endif
/********************************************************
Fvco : Frequency of APLL
Fxtal : Frequency of Crystal
IHF : Input Horizontal Frequency
usClock : Divider number of input clock
stModeInfo.IHFreq = 10 * IHF(in KHz)
_RTD_XTAl : Defined crystal clock unit in KHz
Fvco = Fxtal*(M + K/16)/N1 = IHF * usClock * vco_divider
Assum N1 = 2
(M + K/16) = IHF * usClock * N1 * vco_divider / Fxtal
stModeInfo.IHFreq UINT in 100Hz
*********************************************************/
//ADC sampling clock, UNIT in KHz
pllclock = (DWORD)stModeInfo.IHFreq * usClock / 10;
vco_divider = pllclock < 100000 ? 4 : 2;
//Get (M + K/16) * 1024
pllclock = ((((pllclock * _APLL_N_CODE * vco_divider) << 4 )/(DWORD)(_RTD_XTAL)) << 6);
CScalerPageSelect(_PAGE1);
CScalerSetByte(_P1_PLL_DIV_CTRL_A0, 0x08);
// CScalerSetByte(_P1_FAST_PLL_CTRL_AA, 0x24); //Ming-Yen
// CScalerSetByte(_P1_PE_TRACKING_METHOD_B7, 0x02); //Ming-Yen
// CScalerSetByte(_P1_DDS_MIX_1_B8, 0x0c); //Ming-Yen
CScalerSetByte(_P1_DDS_MIX_2_B9, 0xff);
CScalerSetByte(_P1_PLL_CRNT_AE, 0x63);
//CScalerSetByte(_P1_PLL_WD_AF, 0x08);
CScalerSetBit(_P1_PLLDIV_H_B1, ~(_BIT6 | _BIT5 | _BIT4), (vco_divider == 2) ? (_BIT6 | _BIT5) : (_BIT6 | _BIT5 | _BIT4));
//Set the divide number
CScalerSetBit(_P1_PLLDIV_H_B1, 0xf0, (BYTE)(((usClock - 1) >> 8) & 0x0f));
CScalerSetByte(_P1_PLLDIV_L_B2, (BYTE)((usClock - 1) & 0x00ff));
////////////////////////////////////////
CAdjustGetAPLLSetting(usClock);
////////////////////////////////////////
//Set N code
CScalerSetBit(_P1_PLL_N_AD, 0xf8, ((_APLL_N_CODE - 2) & 0x07));
//Get M, K code, M + K/16 = pllclock / 1024
mcode = pllclock >> 10; //M is the integer part
delta = (DWORD)pllclock - ((DWORD)mcode << 10);
//K is the fraction part quantized by 16
kcode = (delta) >> 6;
#if(_APLL_FAST_LOCK)
//SUM_I is the truncated part by calculation quantized by 1024
SUM_I = ((DWORD)delta << 4) - ((DWORD)kcode << 10);
#endif
//K is range from -8 ~ 7
if(kcode>7)
{
mcode +=1;
kcode -= 16;
}
else if(kcode<(-8))
{
mcode -=1;
kcode += 16;
}
//set M, N, K code
CScalerSetByte(_P1_PLL_M_AC, (mcode - 3));
CScalerSetBit(_P1_PLL_N_AD, 0x0f, (((kcode & 0x0f) << 4) | (_APLL_N_CODE - 2)));
#if (_APLL_FAST_LOCK)
SUM_I = SUM_I << 12; // over flow need to modify
//set SUM_I
temp2662 = SUM_I & 0x07ffffff;
pData[0] = (BYTE)((temp2662 >>24) & 0x000000ff);
pData[1] = (BYTE)((temp2662 >>16) & 0x000000ff);
pData[2] = (BYTE)((temp2662 >>8) & 0x000000ff);
pData[3] = (BYTE)(temp2662 & 0x000000ff);
CScalerWrite(_P1_FAST_PLL_ISUM_AB, 4, pData, _NON_AUTOINC);
#endif
/****************************************************************************
Formula :
I_gain Ths PE(UNIT) 1
--------- x ------- = ------------------------------------ x -----
2^22 Tbck Txclk x 16N/(16M +- K) x 1/16 8
I_gain Ths PE(UNIT) 1
--------- x ----------- = ------------------------------------ x -----
2^22 Tclk x N Txclk x 16N/(16M +- K) x 1/16 8
2^22 x PE_U x (16M +- K) 1
I_gain = ----------------------------- x -----
Ths 8
2^19 x PE_U x (16M +- K)
= -----------------------------
Ths
= IHF x 2^19 x PE_U x (16M +- K)
****************************************************************************/
// (M + K/16) = pllclock / 1024
// 16M + K = 16 * pllclock / 1024
// 2^19 * 2^4 / 2^10 = 2^13
// _PE_VALUE UNIT is ps, so result has to multiply 10^(-12)
// stModeInfo.IHFreq/10 UNIT is KHz, so result has to multiply 10^2
icode = (DWORD)((stModeInfo.IHFreq) * 120/*usPEValue*/ * pllclock)/(DWORD)1220702;
icode &= 0x00007fff;
CScalerSetByte(_P1_I_CODE_M_A1,(BYTE)(icode >> 8));
CScalerSetByte(_P1_I_CODE_L_A2, (BYTE)icode);
// Set the P code
pcode = (7 * icode * _RTD_XTAL / stModeInfo.IHFreq /_APLL_N_CODE) >> 7;
if(pcode > 255)
{
for(pData[0] = 9; pData[0] < 15; pData[0]++)
{
if((pcode >> pData[0]) == 0)
break;
}
pcode = pcode / g_value_divider[(pData[0] - 9)];
g_value = pData[0] - 7;
}
CScalerSetByte(_P1_P_CODE_MAPPING_METHOD_B6, g_value << 2);
CScalerSetByte(_P1_DDS_MIX_2_B9, 0x05); //set the P_code_max
CScalerSetByte(_P1_DDS_MIX_3_BA, 0x1e);
CScalerSetByte(_P1_P_CODE_A3, (BYTE)pcode);
#if (_APLL_FAST_LOCK)
//CScalerSetByte(_P1_FAST_PLL_CTRL_AA, 0x60);
CScalerSetBit(_P1_FAST_PLL_CTRL_AA, ~(_BIT6 | _BIT5 | _BIT3), (_BIT6 | _BIT5 | _BIT3));
#else
//Enable Double buffer write in PLL M/N K
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -