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

📄 zl5011xpac.c

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