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

📄 zl5011xinterrupts.c

📁 Zalink50114----TDMoIP芯片驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
   status = ZL5011X_CHECK_POINTERS(zl5011xParams, par);

   if (status == ZL5011X_OK)
   {
      ZL5011X_TRACE(ZL5011X_ISR_FN_ID,
            "zl5011xIsrDisableFreezeStructInit:",
            0, 0, 0, 0, 0, 0);

      par->interruptBits= 0;
   }

   return status;
}

/*******************************************************************************

 Function:
    zl5011xIsrDisableFreeze

 Description:
   This function does the exact opposite of the IsrEnableFreeze function, it uses
   the same parameter structure (see below) as that function. Here
   the freeze mode is disabled if the bit is set.

   The top level mask contained in the ADM block is updated to cancel the
   ability of the relevant block or part-of-block to freeze the hardware.

 Inputs:
   zl5011xParams      Pointer to the structure for this device instance
   par               pointer to  parameter structure

 Structure Inputs:
   interruptBits - bits set to Disable the interrupt corresponding to the
                        ADM hardware freeze Enable register.

 Outputs:

 Returns:
    zlStatusE

 Remarks:

*******************************************************************************/

zlStatusE zl5011xIsrDisableFreeze(zl5011xParamsS *zl5011xParams, zl5011xIsrDisableFreezeS *par)
{
   zlStatusE status = ZL5011X_OK;

   status = ZL5011X_CHECK_POINTERS(zl5011xParams, par);

   if (status == ZL5011X_OK)
   {
      ZL5011X_TRACE(ZL5011X_ISR_FN_ID,
            "zl5011xIsrDisableFreeze: dev %08X, bits %08X",
            (Uint32T)zl5011xParams, par->interruptBits, 0, 0, 0, 0);
   }

   if (status == ZL5011X_OK)
   {
      status= zl5011xAdmDisableInterruptSource(zl5011xParams,
            ZL5011X_INTERRUPT_FROZEN, par->interruptBits);
   }

   return status;
}

/*****************   STATIC FUNCTION DEFINTIONS   *****************************/

/*******************************************************************************

 Function:
    zl5011xIsrCompose

 Description:
   This function is used to get from the device the first interrupt
   present in the given status word (i.e. depends on order of coding) and to write
   it in an  intr message ready for sending to the DPR
   This is also a convenient function to tidy up any intrs not cleared by reading.

 Inputs:
    zl5011xParams     Pointer to the structure for this device instance
   admIntrBit        block interrupt to be serviced
 Outputs:
   None

 Returns:
    zlStatusE

 Remarks:

*******************************************************************************/

static zlStatusE  zl5011xIsrCompose(zl5011xParamsS *zl5011xParams, Uint32T admIntrBit)
{
   zlStatusE status = ZL5011X_OK;
   Uint32T currTime;

   zl5011xBooleanE matchedInt = ZL5011X_TRUE;

   Uint32T admIntrBitLocal;

   zl5011xInterruptQueueDataS intrMsg;

   Uint8T temp8;

   ZL5011X_TRACE(ZL5011X_ISR_FN_ID,
         "zl5011xIsrCompose:  ADM Intr Status  0x%.08lx ",
         admIntrBit, 0, 0, 0, 0, 0);

   /* set defaults for the data fields - since not all fields will be
      relevant to the different interrupts */
   intrMsg.activeInterrupts = 0;
   intrMsg.context = (Uint32T)ZL5011X_INVALID_CONTEXT;
   intrMsg.misc = 0;

   switch (admIntrBit)
   {
      case ZL5011X_1BIT_MASK << ZL5011X_WAN_TX_ERROR_INTERRUPT:
         intrMsg.interruptSource = ZL5011X_WAN_TX_ERROR_INTERRUPT;

         do
         {
            (void)zl5011xTfmGetNextError(zl5011xParams, &(intrMsg.context), &(intrMsg.activeInterrupts));
            status = zl5011xIsrQueueUpInterrupts(zl5011xParams, &intrMsg);

            if (status != ZL5011X_OK)
            {
               /* if cannot queue the message then don't continue */
               break;
            }

            /* read a message off of the queue. The only way to find out if there are
               more messages on the queue is to reset the interrupt bit and see if it gets set
               again */
            (void)zl5011xAdmClearInterruptSource( zl5011xParams, admIntrBit);
            (void)zl5011xAdmGetInterruptStatus( zl5011xParams, &admIntrBitLocal);
         } while ((admIntrBitLocal & admIntrBit) != 0);

         /* already sent the message to the queue, so indicate that there is nothing left to do */
         matchedInt = ZL5011X_FALSE;
         break;

      case ZL5011X_1BIT_MASK << ZL5011X_WAN_TX_INFO_INTERRUPT:
         intrMsg.interruptSource = ZL5011X_WAN_TX_INFO_INTERRUPT;

         do
         {
            (void)zl5011xTfmGetNextInfo(zl5011xParams, &(intrMsg.context));
            status = zl5011xIsrQueueUpInterrupts(zl5011xParams, &intrMsg);

            if (status != ZL5011X_OK)
            {
               /* if cannot queue the message then don't continue */
               break;
            }

            /* read a message off of the queue. The only way to find out if there are
               more messages on the queue is to reset the interrupt bit and see if it gets set
               again */
            (void)zl5011xAdmClearInterruptSource( zl5011xParams, admIntrBit);
            (void)zl5011xAdmGetInterruptStatus( zl5011xParams, &admIntrBitLocal);
         } while ((admIntrBitLocal & admIntrBit) != 0);

         /* already sent the message to the queue, so indicate that there is nothing left to do */
         matchedInt = ZL5011X_FALSE;
         break;

      case ZL5011X_1BIT_MASK << ZL5011X_WAN_TX_QUEUE_INTERRUPT:
         intrMsg.interruptSource = ZL5011X_WAN_TX_QUEUE_INTERRUPT;

         do
         {
            (void)zl5011xTfqGetNextError(zl5011xParams, &(intrMsg.context), &(intrMsg.activeInterrupts));
            status = zl5011xIsrQueueUpInterrupts(zl5011xParams, &intrMsg);

            if (status != ZL5011X_OK)
            {
               /* if cannot queue the message then don't continue */
               break;
            }

            /* read a message off of the queue. The only way to find out if there are
               more messages on the queue is to reset the interrupt bit and see if it gets set
               again */
            (void)zl5011xAdmClearInterruptSource( zl5011xParams, admIntrBit);
            (void)zl5011xAdmGetInterruptStatus( zl5011xParams, &admIntrBitLocal);
         } while ((admIntrBitLocal & admIntrBit) != 0);

         /* already sent the message to the queue, so indicate that there is nothing left to do */
         matchedInt = ZL5011X_FALSE;
         break;

      case ZL5011X_1BIT_MASK << ZL5011X_WAN_TX_GRANULES_INTERRUPT:
         intrMsg.interruptSource = ZL5011X_WAN_TX_GRANULES_INTERRUPT;
         (void)zl5011xTfqClearGranuleThresholdIntr(zl5011xParams);
         break;

      case ZL5011X_1BIT_MASK << ZL5011X_WAN_RX_ERROR_INTERRUPT:
         intrMsg.interruptSource = ZL5011X_WAN_RX_ERROR_INTERRUPT;

         do
         {
            (void)zl5011xPlaGetNextError(zl5011xParams, &(intrMsg.context), &(intrMsg.activeInterrupts));
            status = zl5011xIsrQueueUpInterrupts(zl5011xParams, &intrMsg);

            if (status != ZL5011X_OK)
            {
               /* if cannot queue the message then don't continue */
               break;
            }

            /* read a message off of the queue. The only way to find out if there are
               more messages on the queue is to reset the interrupt bit and see if it gets set
               again */
            (void)zl5011xAdmClearInterruptSource( zl5011xParams, admIntrBit);
            (void)zl5011xAdmGetInterruptStatus( zl5011xParams, &admIntrBitLocal);
         } while ((admIntrBitLocal & admIntrBit) != 0);

         /* already sent the message to the queue, so indicate that there is nothing left to do */
         matchedInt = ZL5011X_FALSE;
         break;

      case ZL5011X_1BIT_MASK << ZL5011X_WAN_CLK_INTERRUPT:
         /* the PAC status will be handled by the api interrupt rather than the
            application if it is running */
         intrMsg.interruptSource = ZL5011X_WAN_CLK_INTERRUPT;
         (void)zl5011xPacGetStatus(zl5011xParams, &(intrMsg.activeInterrupts));

         /* if the slew rate interrupt is enabled then need to mask it out, since it may
            be set again immediately. The other interrupts are status changes, so only
            need to reset the interrupt */
         if ((intrMsg.activeInterrupts & (ZL5011X_1BIT_MASK << ZL5011X_DPLL_SLEW_RATE_INT)) != 0)
         {
            (void)zl5011xPacDisableInterrupts(zl5011xParams, ZL5011X_1BIT_MASK << ZL5011X_DPLL_SLEW_RATE_INT);
         }

         /* if any of the DPLL interrupt bits are set then retrieve the status, since the application is
            going to need that to determine what has happened */
         if ((intrMsg.activeInterrupts & ((ZL5011X_1BIT_MASK << ZL5011X_DPLL_LOCK_INT) |
            (ZL5011X_1BIT_MASK << ZL5011X_DPLL_REF_CHANGE_INT) | (ZL5011X_1BIT_MASK << ZL5011X_DPLL_HOLDOVER_INT))) != 0)
         {
            (void)zl5011xPacDpllGetStatusValue(zl5011xParams,  &(intrMsg.misc));
         }

         /* Now clear any interrupts that were active */
         (void)zl5011xPacClearInterrupts(zl5011xParams, intrMsg.activeInterrupts);
         break;

      case ZL5011X_1BIT_MASK << ZL5011X_MAC_IF_INTERRUPT:
         /* the PKI status will be handled by the api interrupt rather than the
            application if it is running */
         intrMsg.interruptSource = ZL5011X_MAC_IF_INTERRUPT;
         (void)zl5011xPkiGetPcsStatus(zl5011xParams, &(intrMsg.activeInterrupts));
         break;

      case ZL5011X_1BIT_MASK << ZL5011X_PACKET_TX_INTERRUPT:
         intrMsg.interruptSource = ZL5011X_PACKET_TX_INTERRUPT;
         (void)zl5011xPkqGetDropStatus(zl5011xParams, &(intrMsg.activeInterrupts));

         /* the packet queue interrupt is a threshold, so may remain asserted. Therefore, the
            only option is to clear the interrupt at the top level. The application can
            turn this int back on again after taking any corrective action */
         (void)zl5011xAdmDisableInterruptSource(zl5011xParams, ZL5011X_INTERRUPT_ZERO, ZL5011X_1BIT_MASK << admIntrBit);
         break;

      case ZL5011X_1BIT_MASK << ZL5011X_PACKET_RX_INTERRUPT:
         intrMsg.interruptSource = ZL5011X_PACKET_RX_INTERRUPT;
         (void)zl5011xPkcGetInterruptStatus(zl5011xParams, &(intrMsg.activeInterrupts));

         /* get the current tick time - for updating the PW bit times */
         currTime = OS_TICK_GET();

         /* service any PW interrupts first */
         while ((intrMsg.activeInterrupts & (ZL5011X_1BIT_MASK << ZL5011X_PACKET_RX_PW_INT)) != 0)
         {
            /* send this message with just the PW interrupt bit sent */
            intrMsg.activeInterrupts = ZL5011X_1BIT_MASK << ZL5011X_PACKET_RX_PW_INT;

            (void)zl5011xPkcGetPwStatus(zl5011xParams, &(intrMsg.context), &(intrMsg.misc));

            if (intrMsg.context < ZL5011X_MAX_NUMBER_CONTEXTS)
            {
               /* update the PW statistics for the context */
               if (zl5011xParams->packetIf.packetRx.contextRxPacketMatch[intrMsg.context].statusByte.value == (Uint32T)ZL5011X_INVALID)
               {
                  /* first update so intialise the stats */
                  zl5011xParams->packetIf.packetRx.contextRxPacketMatch[intrMsg.context].statusByte.lCount = 0;
                  zl5011xParams->packetIf.packetRx.contextRxPacketMatch[intrMsg.context].statusByte.lTime = 0;
                  zl5011xParams->packetIf.packetRx.contextRxPacketMatch[intrMsg.context].statusByte.lTimePrev = currTime;

                  zl5011xParams->packetIf.packetRx.contextRxPacketMatch[intrMsg.context].statusByte.rCount = 0;
                  zl5011xParams->packetIf.packetRx.contextRxPacketMatch[intrMsg.context].statusByte.rTime = 0;
                  zl5011xParams->packetIf.packetRx.contextRxPacketMatch[intrMsg.context].statusByte.rTimePrev = currTime;
               }
               else
               {
                  if ((intrMsg.misc & ZL5011X_PKT_PW_L_BIT_MASK) !=
                     (zl5011xParams->packetIf.packetRx.contextRxPacketMatch[intrMsg.context].statusByte.value & ZL5011X_PKT_PW_L_BIT_MASK))
                  {
                     if ((intrMsg.misc & ZL5011X_PKT_PW_L_BIT_MASK) != 0)
                     {
                        /* count how many times the bit gets set */
                        zl5011xParams->packetIf.packetRx.contextRxPacketMatch[intrMsg.context].statusByte.lCount++;
                     }
                     else
                     {
                        /* now that the bit has been cleared, update the time that it was set for */
                        zl5011xParams->packetIf.packetRx.contextRxPacketMatch[intrMsg.context].statusByte.lTime += currTime -
                              zl5011xParams->packetIf.packetRx.contextRxPacketMatch[intrMsg.context].statusByte.lTimePrev;
                     }

                     zl5011xParams->packetIf.packetRx.contextRxPacketMatch[intrMsg.context].statusByte.lTimePrev = currTime;
                  }

                  if ((intrMsg.misc & ZL5011X_PKT_PW_R_BIT_MASK) !=
                     (zl5011xParams->packetIf.packetRx.contextRxPacketMatch[intrMsg.context].statusByte.value & ZL5011X_PKT_PW_R_BIT_MASK))
                  {
                     if ((intrMsg.misc & ZL5011X_PKT_PW_R_BIT_MASK) != 0)
                     {
                        /* count how many times the bit gets set */
                        zl5011xParams->packetIf.packetRx.contextRxPacketMatch[intrMsg.context].statusByte.rCount++;
                     }
                     else
                     {
                        /* now that the bit has been cleared, update the time that it was set for */
                        zl5011xParams->packetIf.packetRx.contextRxPacketMatch[intrMsg.context].statusByte.rTime += currTime -
                              zl5011xParams->packetIf.packetRx.contextRxPacketMatch[intrMsg.context].statusByte.rTimePrev;
                     }

                     zl5011xParams->packetIf.packetRx.contextRxPacketMatch[intrMsg.context].statusByte.rTimePrev = currTime;
                  }
               }

               zl5011xParams->packetIf.packetRx.contextRxPacketMatch[intrMsg.context].statusByte.value = intrMsg.misc;

               if (zl5011xIsrPwReportEnableFlag == ZL5011X_TRUE)
               {
                  status = zl5011xIsrQueueUpInterrupts(zl5011xParams, &intrMsg);
               }
            }

            if (status != ZL5011X_OK)
            {
               /* if cannot queue the message then don't continue */
               break;
            }

            /* read a message off of the queue. The only way to find out if there are
               more messages on the queue is to reset the interrupt bit and see if it
               gets set again */
            (void)zl5011xPkcClearInterrupts(zl5011xParams, intrMsg.activeInterrupts);
            (void)zl5011xPkcGetInterruptStatus(zl5011xParams, &(intrMsg.activeInterrupts));
         }

         /* if there are any other interrupts that need to be serviced then let a message
            be sent. If not, then set the flag to indicate that the message has already
            been handled */
         if ((intrMsg.activeInterrupts & ~(ZL5011X_1BIT_MASK << ZL5011X_PACKET_RX_PW_INT)) == 0)
         {
            matchedInt = ZL5011X_FALSE;
         }
         break;

      case ZL5011X_1BIT_MASK << ZL5011X_TASK_MSG_INTERRUPT:
         intrMsg.interruptSource = ZL5011X_TASK_MSG_INTERRUPT;
         (void)zl5011xTmGetInterruptStatus(zl5011xParams, &(intrMsg.activeInterrupts));

         /* if the TM raises an interrupt, then it is probably going to persist,
            so disable the interrupt */
         (void)zl5011xTmDisableInterrupts(zl5011xParams, intrMsg.activeInterrupts);
         break;

      case ZL5011X_1BIT_MASK << ZL5011X_GRANULE_INTERRUPT:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -