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

📄 adjust.c

📁 RTD2662板卡源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
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 + -