📄 zl5011xpac.c
字号:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xPacDpllRefSetSingleLimit(zl5011xParamsS *zl5011xParams,
zl5011xBooleanE secondaryRef, Uint16T highLimit, Uint16T lowLimit)
{
zlStatusE status = ZL5011X_OK;
Uint32T bits;
ZL5011X_TRACE(ZL5011X_PAC_FN_ID,
"zl5011xPacDpllRefSetSingleLimit: ref %d, high %d, low %d",
secondaryRef, highLimit, lowLimit, 0, 0, 0);
status = ZL5011X_CHECK_BOOLEAN(secondaryRef);
if (status == ZL5011X_OK)
{
if (lowLimit >= highLimit)
{
status = ZL5011X_PARAMETER_INVALID;
}
else
{
bits = (highLimit << ZL5011X_DPLL_CHK_SINGLE_HIGH_BITS) |
(lowLimit << ZL5011X_DPLL_CHK_SINGLE_LOW_BITS);
status = zl5011xWrite(zl5011xParams,
ZL5011X_DPLL_CHK_SINGLE_PERIOD + ((Uint32T)secondaryRef * ZL5011X_DPLL_CHK_SIZE),
bits);
zl5011xParams->wanIf.clock.sync.refCheck[secondaryRef].singlePeriodHigh = highLimit;
zl5011xParams->wanIf.clock.sync.refCheck[secondaryRef].singlePeriodLow = lowLimit;
}
}
return(status);
}
/*******************************************************************************
Function:
zl5011xPacDpllRefSetHighLimit
Description:
Sets the high limit for the multi period check on the reference input.
Inputs:
zl5011xParams Pointer to the structure for this device instance
secondaryRef ZL5011X_FALSE for primary reference
ZL5011X_TRUE for secondary reference
highLimit upper limit used for determining a valid reference
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xPacDpllRefSetHighLimit(zl5011xParamsS *zl5011xParams,
zl5011xBooleanE secondaryRef, Uint32T highLimit)
{
zlStatusE status = ZL5011X_OK;
Uint32T bits;
ZL5011X_TRACE(ZL5011X_PAC_FN_ID,
"zl5011xPacDpllRefSetHighLimit: ref %d, high %d",
secondaryRef, highLimit, 0, 0, 0, 0);
status = ZL5011X_CHECK_BOOLEAN(secondaryRef);
if (status == ZL5011X_OK)
{
if (highLimit > ZL5011X_DPLL_CHK_HIGH_MASK)
{
status = ZL5011X_PARAMETER_INVALID;
}
else
{
bits = (highLimit << ZL5011X_DPLL_CHK_HIGH_BITS);
status = zl5011xWrite(zl5011xParams,
ZL5011X_DPLL_CHK_MULTI_PERIOD_HIGH + ((Uint32T)secondaryRef * ZL5011X_DPLL_CHK_SIZE),
bits);
zl5011xParams->wanIf.clock.sync.refCheck[secondaryRef].multiPeriodHigh = highLimit;
}
}
return(status);
}
/*******************************************************************************
Function:
zl5011xPacDpllRefSetLowLimit
Description:
Sets the low limit for the multi period check on the reference input.
Inputs:
zl5011xParams Pointer to the structure for this device instance
secondaryRef ZL5011X_FALSE for primary reference
ZL5011X_TRUE for secondary reference
lowLimit lower limit used for determining a valid reference
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xPacDpllRefSetLowLimit(zl5011xParamsS *zl5011xParams,
zl5011xBooleanE secondaryRef, Uint32T lowLimit)
{
zlStatusE status = ZL5011X_OK;
Uint32T bits;
ZL5011X_TRACE(ZL5011X_PAC_FN_ID,
"zl5011xPacDpllRefSetLowLimit: ref %d, low %d",
secondaryRef, lowLimit, 0, 0, 0, 0);
status = ZL5011X_CHECK_BOOLEAN(secondaryRef);
if (status == ZL5011X_OK)
{
if (lowLimit > ZL5011X_DPLL_CHK_LOW_MASK)
{
status = ZL5011X_PARAMETER_INVALID;
}
else
{
bits = (lowLimit << ZL5011X_DPLL_CHK_LOW_BITS);
status = zl5011xWrite(zl5011xParams,
ZL5011X_DPLL_CHK_MULTI_PERIOD_LOW + ((Uint32T)secondaryRef * ZL5011X_DPLL_CHK_SIZE),
bits);
zl5011xParams->wanIf.clock.sync.refCheck[secondaryRef].multiPeriodLow = lowLimit;
}
}
return(status);
}
/*******************************************************************************
Function:
zl5011xPacDpllRefSetCycleCount
Description:
Sets the number of clock cycles over which the multi-period check on
the reference input should run.
Inputs:
zl5011xParams Pointer to the structure for this device instance
secondaryRef ZL5011X_FALSE for primary reference
ZL5011X_TRUE for secondary reference
cycleCount number of cycles to used for determining a valid reference
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xPacDpllRefSetCycleCount(zl5011xParamsS *zl5011xParams,
zl5011xBooleanE secondaryRef, Uint16T cycleCount)
{
zlStatusE status = ZL5011X_OK;
Uint32T bits;
ZL5011X_TRACE(ZL5011X_PAC_FN_ID,
"zl5011xPacDpllRefSetCycleCount: ref %d, cnt %d",
secondaryRef, cycleCount, 0, 0, 0, 0);
status = ZL5011X_CHECK_BOOLEAN(secondaryRef);
if (status == ZL5011X_OK)
{
if (cycleCount > ZL5011X_DPLL_CHK_CNT_MASK)
{
status = ZL5011X_PARAMETER_INVALID;
}
else
{
bits = ((cycleCount - 1) << ZL5011X_DPLL_CHK_CNT_BITS);
status = zl5011xWrite(zl5011xParams,
ZL5011X_DPLL_CHK_MULTI_PERIOD_CNT + ((Uint32T)secondaryRef * ZL5011X_DPLL_CHK_SIZE),
bits);
zl5011xParams->wanIf.clock.sync.refCheck[secondaryRef].multiPeriodCount = cycleCount;
}
}
return(status);
}
/*******************************************************************************
Function:
zl5011xPacDpllRefEnableLimits
Description:
Enable limits checking for the DPLL reference
Inputs:
zl5011xParams Pointer to the structure for this device instance
secondaryRef ZL5011X_FALSE for primary reference
ZL5011X_TRUE for secondary reference
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xPacDpllRefEnableLimits(zl5011xParamsS *zl5011xParams,
zl5011xBooleanE secondaryRef)
{
zlStatusE status = ZL5011X_OK;
Uint32T bits;
ZL5011X_TRACE(ZL5011X_PAC_FN_ID,
"zl5011xPacDpllRefEnableLimits: ref %d",
secondaryRef, 0, 0, 0, 0, 0);
status = ZL5011X_CHECK_BOOLEAN(secondaryRef);
if (status == ZL5011X_OK)
{
if (secondaryRef == ZL5011X_FALSE)
{
bits = ZL5011X_DPLL_REF_LIMITS_MASK << ZL5011X_DPLL_PRIMARY_REF_LIMITS_BITS;
}
else
{
bits = ZL5011X_DPLL_REF_LIMITS_MASK << ZL5011X_DPLL_SECONDARY_REF_LIMITS_BITS;
}
status = zl5011xReadModWrite(zl5011xParams,
ZL5011X_PAC_INTERRUPT_MASK, bits, bits);
}
return(status);
}
/*******************************************************************************
Function:
zl5011xPacDpllRefSetLimits
Description:
Sets the limits for the reference input using percentage offset from
the nominal for both the single and the multi-period checks.
Inputs:
zl5011xParams Pointer to the structure for this device instance
secondaryRef ZL5011X_FALSE for primary reference
ZL5011X_TRUE for secondary reference
cycleCount how many cycles to run the multi-cycle period check over
singlePercentTolerance_x_10 the tolerance to be applied to the single cycle
check in percentage x 10. i.e. a value of 10
is equal to 1.0%
multiPercentTolerance_x_10 the tolerance to be applied to the multi cycle
check in percentage x 10. i.e. a value of 10
is equal to 1.0%
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xPacDpllRefSetLimits(zl5011xParamsS *zl5011xParams,
zl5011xBooleanE secondaryRef, Uint16T cycleCount,
Uint16T singlePercentTolerance_x_10, Uint16T multiPercentTolerance_x_10)
{
zlStatusE status = ZL5011X_OK;
Uint64T target64;
Uint32T tolerance, target;
ZL5011X_TRACE(ZL5011X_PAC_FN_ID,
"zl5011xPacDpllRefSetLimits: ref %d, cnt %d, sgl %d, multi %d",
secondaryRef, cycleCount, singlePercentTolerance_x_10, multiPercentTolerance_x_10, 0, 0);
status = ZL5011X_CHECK_BOOLEAN(secondaryRef);
if (status == ZL5011X_OK)
{
/* calculate the number of clock cycles for a single period of the reference clock */
target = zl5011xParams->systemClockFreq / zl5011xParams->wanIf.clock.sync.refInputFreqHz;
/* work out the maximum offset from the target frequency */
tolerance = (target * singlePercentTolerance_x_10) / 1000;
/* add in one to just ensure that we are rounding up */
tolerance++;
if (tolerance > target)
{
status = ZL5011X_PARAMETER_INVALID;
}
}
if (status == ZL5011X_OK)
{
status = zl5011xPacDpllRefSetSingleLimit(zl5011xParams,
secondaryRef, (Uint16T)(target + tolerance), (Uint16T)(target - tolerance));
}
#ifdef _ZL5011X_DISABLE_64_BIT_OPERATIONS
if (status == ZL5011X_OK)
{
Uint64T res64;
mpz_init2(target64, 96);
mpz_init2(res64, 96);
mpz_set_ui(target64, zl5011xParams->systemClockFreq);
mpz_mul_ui(res64, target64, cycleCount);
mpz_tdiv_q_ui(target64, res64, zl5011xParams->wanIf.clock.sync.refInputFreqHz);
target = mpz_get_ui(target64);
mpz_mul_ui(res64, target64, multiPercentTolerance_x_10);
mpz_tdiv_q_ui(target64, res64, 1000);
tolerance = mpz_get_ui(target64) + 1;
mpz_clear(target64);
mpz_clear(res64);
}
#else
if (status == ZL5011X_OK)
{
/* calculate the number of clock cycles for the multiple periods
of the reference clock */
target64 = zl5011xParams->systemClockFreq;
target64 *= cycleCount;
target64 /= zl5011xParams->wanIf.clock.sync.refInputFreqHz;
target = target64;
/* work out the maximum offset from the target frequency */
tolerance = (target64 * multiPercentTolerance_x_10) / 1000;
/* add in one to just ensure that we are rounding up */
tolerance++;
}
#endif
if (status == ZL5011X_OK)
{
if (tolerance > target)
{
status = ZL5011X_PARAMETER_INVALID;
}
}
if (status == ZL5011X_OK)
{
status = zl5011xPacDpllRefSetHighLimit(zl5011xParams,
secondaryRef, target + tolerance);
}
if (status == ZL5011X_OK)
{
status = zl5011xPacDpllRefSetLowLimit(zl5011xParams,
secondaryRef, target - tolerance);
}
if (status == ZL5011X_OK)
{
status = zl5011xPacDpllRefSetCycleCount(zl5011xParams,
secondaryRef, cycleCount);
}
if (status == ZL5011X_OK)
{
status = zl5011xPacDpllRefEnableLimits(zl5011xParams,
secondaryRef);
}
return(status);
}
/*******************************************************************************
Function:
zl5011xPacSetAsyncMode
Description:
This function configures the PAC block for async operation (not using the DPLL).
Inputs:
zl5011xParams Pointer to the structure for this device instance
Outputs:
None
Returns:
zlStatusE
Remarks:
*******************************************************************************/
zlStatusE zl5011xPacSetAsyncMode(zl5011xParamsS *zl5011xParams)
{
Uint32T bits;
zlStatusE status = ZL5011X_OK;
ZL5011X_TRACE(ZL5011X_PAC_FN_ID, "zl5011xPacSetAsyncMode:", 0, 0, 0, 0, 0, 0);
/* cross map from the Wan interf
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -