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

📄 zl5011xpac.c

📁 Zalink50114----TDMoIP芯片驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
   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 + -