📄 zl5011xpac.c
字号:
}
else
{
/* store the reference setting, and the frequency that it corresponds to */
zl5011xParams->wanIf.clock.sync.refInputFreq = dpllRefFreq;
zl5011xParams->wanIf.clock.sync.refInputFreqHz = dpllFreq;
}
}
if (status == ZL5011X_OK)
{
switch (config)
{
case ZL5011X_DPLL_SLAVE_CONNECTION:
outputEnable = ZL5011X_FALSE;
break;
case ZL5011X_DPLL_MASTER_CONNECTION:
outputEnable = masterOutputEnable;
break;
case ZL5011X_DPLL_EXTERNAL_CONNECTION:
outputEnable = ZL5011X_TRUE;
break;
default :
status = ZL5011X_PARAMETER_INVALID;
break;
}
}
if (status == ZL5011X_OK)
{
zl5011xParams->wanIf.clock.sync.dpllConfig = config;
status = zl5011xPacDpllOutputEnable(zl5011xParams, outputEnable);
}
if (config == ZL5011X_DPLL_MASTER_CONNECTION)
{
/* the DPLL is being used, so configure it */
if (status == ZL5011X_OK)
{
status = zl5011xPacDpllInitialise(zl5011xParams, dpllRefFreq);
}
if (status == ZL5011X_OK)
{
status = zl5011xPacDpllSetCentreFreq(zl5011xParams);
}
if (status == ZL5011X_OK)
{
status = zl5011xPacDpllSetCentreInverseFreq(zl5011xParams);
}
if (status == ZL5011X_OK)
{
status = zl5011xPacDpllSetT1InverseFreq(zl5011xParams);
}
if (status == ZL5011X_OK)
{
status = zl5011xPacDpllSetJ2InverseFreq(zl5011xParams);
}
if (status == ZL5011X_OK)
{
status = zl5011xPacDpllSetSlewRate(zl5011xParams, ZL5011X_DPLL_DEFAULT_SLEW_RATE,
ZL5011X_DPLL_DEFAULT_BANDWIDTH);
}
if (status == ZL5011X_OK)
{
status = zl5011xPacDpllSetRefPriority(zl5011xParams, priority);
}
if (status == ZL5011X_OK)
{
status = zl5011xPacDpllSetClockMode(zl5011xParams, ZL5011X_DPLL_AUTOMATIC_OPERATION);
}
if (status == ZL5011X_OK)
{
status = zl5011xPacSetJitterReductionMode(zl5011xParams, ZL5011X_TRUE,
ZL5011X_PAC_SYNC_DEFAULT_TDL_FILTER);
}
if (status == ZL5011X_OK)
{
status = zl5011xPacDpllSetMtieMode(zl5011xParams, ZL5011X_TRUE);
}
}
else
{
/* the DPLL is not being used, so put it into powerdown */
if (status == ZL5011X_OK)
{
status = zl5011xPacDpllDisable(zl5011xParams);
}
if (status == ZL5011X_OK)
{
/* enable jitter reduction on the DPLLs */
status = zl5011xPacSetJitterReductionMode(zl5011xParams, ZL5011X_TRUE,
ZL5011X_PAC_ASYNC_DEFAULT_TDL_FILTER);
}
}
if (config != ZL5011X_DPLL_SLAVE_CONNECTION)
{
/* if the connection is either master or external, then set up the
two reference sources */
if (status == ZL5011X_OK)
{
status = zl5011xPacDpllSetPrimaryRef(zl5011xParams, primaryRefConfig);
}
if (status == ZL5011X_OK)
{
status = zl5011xPacDpllSetSecondaryRef(zl5011xParams, secondaryRefConfig);
}
}
return(status);
}
/*******************************************************************************
Function:
zl5011xPacDpllOutputEnable
Description:
Controls whether the PLL_PRI and PLL_SEC signals on the device are enabled
or tri-stated. These signals can be used to provide clock source muxing for
an external DPLL or LIU.
Inputs:
zl5011xParams Pointer to the structure for this device instance
enable ZL5011X_TRUE to enable the PLL_PRI an PLL_SEC outputs
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xPacDpllOutputEnable(zl5011xParamsS *zl5011xParams,
zl5011xBooleanE enable)
{
Uint32T bits;
zlStatusE status = ZL5011X_OK;
ZL5011X_TRACE(ZL5011X_PAC_FN_ID, "zl5011xPacDpllOutputEnable: %d", enable, 0, 0, 0, 0, 0);
status = ZL5011X_CHECK_BOOLEAN(enable);
if (status == ZL5011X_OK)
{
bits = 0;
if (enable == ZL5011X_TRUE)
{
bits |= ZL5011X_PAC_DPLL_OUTPUT_ENABLE << ZL5011X_PAC_DPLL_CONFIG_BITS;
}
status = zl5011xReadModWrite(zl5011xParams, ZL5011X_PAC_SETUP,
bits, ZL5011X_PAC_DPLL_CONFIG_MASK << ZL5011X_PAC_DPLL_CONFIG_BITS);
zl5011xParams->wanIf.clock.sync.dpllOutputEnable = enable;
}
return(status);
}
/*******************************************************************************
Function:
zl5011xPacDpllInitialise
Description:
This function initialises the DPLL. The frame pulse information etc. is derived
from that already programmed for the TIF.
Inputs:
zl5011xParams Pointer to the structure for this device instance
refFreq frequency of the reference inputs to the DPLL
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xPacDpllInitialise(zl5011xParamsS *zl5011xParams,
zl5011xDpllRefInputFreqE refFreq)
{
Uint32T bits;
zlStatusE status = ZL5011X_OK;
ZL5011X_TRACE(ZL5011X_PAC_FN_ID, "zl5011xPacDpllInitialise: ref freq %d", refFreq, 0, 0, 0, 0, 0);
/* set the reference speed bits */
bits = ((Uint32T)refFreq & ZL5011X_DPLL_REF_SPEED_MASK) << ZL5011X_DPLL_REF_SPEED_BITS;
/* set the polarity of the frame pulse */
if (zl5011xParams->wanIf.framePulsePolarity == ZL5011X_POSITIVE)
{
bits |= ZL5011X_1BIT_MASK << ZL5011X_DPLL_FRAME_POLARITY_BIT;
}
/* work out how to generate the required frame pulse for the TIF block */
switch (zl5011xParams->wanIf.framePulseWidth)
{
case ZL5011X_WAN_FRAME_HALF_BIT :
if (zl5011xParams->wanIf.refClkPolarity == ZL5011X_POSITIVE)
{
bits |= (ZL5011X_1BIT_MASK << ZL5011X_DPLL_FRAME_ALIGNMENT_BIT) |
(ZL5011X_1BIT_MASK << ZL5011X_DPLL_CLOCK_ALIGNMENT_BIT);
}
break;
case ZL5011X_WAN_FRAME_1_5_BITS_CENTRED : /* intentional fall-through */
case ZL5011X_WAN_FRAME_2_BITS_CENTRED :
if (zl5011xParams->wanIf.refClkPolarity == ZL5011X_POSITIVE)
{
bits |= (ZL5011X_1BIT_MASK << ZL5011X_DPLL_FRAME_ALIGNMENT_BIT) |
(ZL5011X_1BIT_MASK << ZL5011X_DPLL_CLOCK_ALIGNMENT_BIT);
}
/* use a 2 bit wide frame pulse */
bits |= ZL5011X_DPLL_FRAME_WIDTH_MASK << ZL5011X_DPLL_FRAME_WIDTH_BITS;
break;
case ZL5011X_WAN_FRAME_FULL_BIT_ALIGNED :
if (zl5011xParams->wanIf.refClkPolarity == ZL5011X_NEGATIVE)
{
bits |= ZL5011X_1BIT_MASK << ZL5011X_DPLL_FRAME_ALIGNMENT_BIT;
}
/* use a 1 bit wide frame pulse */
bits |= ZL5011X_1BIT_MASK << ZL5011X_DPLL_FRAME_WIDTH_BITS;
break;
case ZL5011X_WAN_FRAME_FULL_BIT_CENTRED :
if (zl5011xParams->wanIf.refClkPolarity == ZL5011X_POSITIVE)
{
bits |= (ZL5011X_1BIT_MASK << ZL5011X_DPLL_FRAME_ALIGNMENT_BIT) |
(ZL5011X_1BIT_MASK << ZL5011X_DPLL_CLOCK_ALIGNMENT_BIT);
}
/* use a 1 bit wide frame pulse */
bits |= ZL5011X_1BIT_MASK << ZL5011X_DPLL_FRAME_WIDTH_BITS;
break;
default :
status = ZL5011X_PARAMETER_INVALID;
}
if (status == ZL5011X_OK)
{
if ((zl5011xParams->wanIf.wanMode == ZL5011X_WAN_FRAMED_8M) ||
(zl5011xParams->wanIf.wanMode == ZL5011X_WAN_STBUS_8M) ||
(zl5011xParams->wanIf.wanMode == ZL5011X_WAN_HMVIP_8M) ||
(zl5011xParams->wanIf.wanMode == ZL5011X_WAN_H1X0_8M_X1_CLOCK) ||
(zl5011xParams->wanIf.wanMode == ZL5011X_WAN_H1X0_8M_X2_CLOCK))
{
bits |= ZL5011X_1BIT_MASK << ZL5011X_DPLL_BACKPLANE_SPEED_BIT;
}
}
if (status == ZL5011X_OK)
{
status = zl5011xWrite(zl5011xParams, ZL5011X_DPLL_CONTROL, bits);
}
return(status);
}
/*******************************************************************************
Function:
zl5011xPacDpllDisable
Description:
Sets the DPLL circuitry into power down mode.
Inputs:
zl5011xParams Pointer to the structure for this device instance
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xPacDpllDisable(zl5011xParamsS *zl5011xParams)
{
zlStatusE status = ZL5011X_OK;
ZL5011X_TRACE(ZL5011X_PAC_FN_ID, "zl5011xPacDpllDisable:", 0, 0, 0, 0, 0, 0);
/* set the powerdown bit in the DPLL control register */
status = zl5011xWrite(zl5011xParams,
ZL5011X_DPLL_CONTROL,
ZL5011X_1BIT_MASK << ZL5011X_DPLL_POWERDOWN_BIT);
return(status);
}
/*******************************************************************************
Function:
zl5011xPacDpllSetCentreFreq
Description:
The centre frequency of the DPLL should be as near to 65.536MHz as possible.
The setting required is calculated, using the system clock frequency provided
during initialisation of the device.
Inputs:
zl5011xParams Pointer to the structure for this device instance
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xPacDpllSetCentreFreq(zl5011xParamsS *zl5011xParams)
{
zlStatusE status = ZL5011X_OK;
Uint32T countValue;
Uint32T bits;
Uint64T calc64;
ZL5011X_TRACE(ZL5011X_PAC_FN_ID, "zl5011xPacDpllSetCentreFreq:", 0, 0, 0, 0, 0, 0);
if (status == ZL5011X_OK)
{
/* before doing any division requiring the system clock freq, check that
it is not 0 */
if (zl5011xParams->systemClockFreq == 0)
{
status = ZL5011X_ERROR;
}
}
#ifdef _ZL5011X_DISABLE_64_BIT_OPERATIONS
if (status == ZL5011X_OK)
{
Uint64T res64;
mpz_init2(calc64, 96);
mpz_init2(res64, 96);
mpz_set_ui(calc64, ZL5011X_DPLL_TARGET_FREQ_KHZ);
mpz_mul_ui(res64, calc64, ZL5011X_DPLL_CENTRE_FREQ_MASK + 1);
mpz_div_ui(calc64, res64, zl5011xParams->systemClockFreq / 1000);
countValue = mpz_get_ui(calc64);
mpz_clear(calc64);
mpz_clear(res64);
}
#else
if (status == ZL5011X_OK)
{
calc64 = (Uint64T)ZL5011X_DPLL_TARGET_FREQ_KHZ * (ZL5011X_DPLL_CENTRE_FREQ_MASK + 1);
countValue = (Uint32T)(calc64 / (zl5011xParams->systemClockFreq / 1000));
}
#endif
if (status == ZL5011X_OK)
{
zl5011xParams->wanIf.clock.sync.dpllCentreCount = countValue;
ZL5011X_TRACE(ZL5011X_PAC_FN_ID, "zl5011xPacDpllSetCentreFreq: count = %u", countValue, 0, 0, 0, 0, 0);
bits = (countValue & ZL5011X_DPLL_CENTRE_FREQ_MASK) << ZL5011X_DPLL_CENTRE_FREQ_BITS;
status = zl5011xWrite(zl5011xParams,
ZL5011X_DPLL_CENTRE_FREQ, bits);
}
return(status);
}
/*******************************************************************************
Function:
zl5011xPacDpllSetCentreInverseFreq
Description:
The inverse of the centre frequency is required by the DPLL
Inputs:
zl5011xParams Pointer to the structure for this device instance
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xPacDpllSetCentreInverseFreq(zl5011xParamsS *zl5011xParams)
{
zlStatusE status = ZL5011X_OK;
Uint32T countValue;
ZL5011X_TRACE(ZL5011X_PAC_FN_ID, "zl5011xPacDpllSetCentreInverseFreq:", 0, 0, 0, 0, 0, 0);
/* the calculation used to determine the inverse frequency is :-
REAL_MAX_INVERSE_VALUE / center frequency count
However, the maximum number is larger than a 32 bit integer, so the divide
is done in two stages :-
MAX_INVERSE_VALUE / (center frequency count / 2)
where MAX_INVERSE_VALUE = (REAL_MAX_INVERSE_VALUE / 2) */
if ((zl5011xParams->wanIf.clock.sync.dpllCentreCount / 2) != 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -