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

📄 zl5011xinterrupts.c

📁 Zalink50114----TDMoIP芯片驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
            (void)zl5011xHostInterruptDisable();

            (void)zl5011xAdmDisableInterrupt(zl5011xParams, ZL5011X_ENABLE_INT_0_1);
            zl5011xIsrDeviceTable[index] = NULL;

            (void)zl5011xHostInterruptEnable();
            break;
         }
      }
   }

   if (status == ZL5011X_OK)
   {
      if (index >= ZL5011X_ISR_MAX_NUMBER_DEVICES)
      {
         status = ZL5011X_ERROR;

         ZL5011X_TRACE(ZL5011X_ISR_FN_ID,
               "zl5011xIsrRemoveDevice: ERROR, device not found",
               0, 0, 0, 0, 0, 0);
      }
   }

   return status;
}

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

 Function:
    zl5011xIsrHandler

 Description:
   The Isr Task checks each device and puts a message in the queue for any
   interrupts that occurred.

 Inputs:
   None

 Outputs:
   none

 Returns:
    zlStatusE

 Remarks:

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

zlStatusE zl5011xIsrHandler(void)
{
   zl5011xParamsS* zl5011xParams;
   zlStatusE status = ZL5011X_OK;
   Uint32T index= 0;
   Uint32T admIntrStatus= 0, intrBit=0;
   Uint32T loop;
   Uint32T reg;

#ifdef _DEBUG
   Uint32T tempTraceFnFilter = 0;
   Uint32T tempTraceCtxtFnFilter = 0;
   Uint32T tempTraceCtxtFilter = 0;

   if (zl5011xTraceIsrEnable == ZL5011X_FALSE)
   {
      /* disable the trace during the interrupt handler */
      tempTraceFnFilter = zl5011xTraceFnFilter;
      tempTraceCtxtFnFilter = zl5011xTraceCtxtFnFilter;
      tempTraceCtxtFilter = zl5011xTraceCtxtFilter;

      zl5011xTraceFnFilter = 0;
      zl5011xTraceCtxtFnFilter = 0;
      zl5011xTraceCtxtFilter = 0;
   }
#endif

   ZL5011X_TRACE(ZL5011X_ISR_FN_ID,
         "zl5011xIsrHandler:",
         0,0,0,0,0,0);

   for (index = 0; index <ZL5011X_ISR_MAX_NUMBER_DEVICES; index++)
   {
      zl5011xParams = zl5011xIsrDeviceTable[index];

      if( zl5011xParams != NULL)
      {
         ZL5011X_TRACE(ZL5011X_ISR_FN_ID, "zl5011xIsrHandler: %u (%08X)",
               index, (Uint32T)zl5011xParams, 0,0,0,0);

         /* read interrupt status to see if any intr bits set */
         (void)zl5011xAdmGetInterruptStatus( zl5011xParams, &admIntrStatus);

         /* mask out any interrupts that are not for this interrupt pin */
         admIntrStatus &= zl5011xParams->interruptMasks.admMasks[ZL5011X_INTERRUPT_ZERO];

         /* scan along the ADM intr word from LSB */
         for (intrBit= 1; intrBit <= ZL5011X_MAX_ADM_BIT_POSN; intrBit = intrBit << 1)
         {
            if ((intrBit & admIntrStatus) != 0)
            {
               /* send a message to the application regarding this interrupt */
               if (status ==ZL5011X_OK)
               {
                  status = zl5011xIsrCompose(zl5011xParams, intrBit);
               }
               else
               {
                  /* if failed at any point, then stop checking */
                  break;
               }
            }
         }

         /* clear interrupts in this device */
         (void)zl5011xAdmClearInterruptSource( zl5011xParams, admIntrStatus);
      }

      if (status != ZL5011X_OK)
      {
         break;
      }
   }

   /* if the interrupt has been serviced successfully, then re-enable the interrupt from
      the devices (int0) */
   if (status == ZL5011X_OK)
   {
      reg = ZL5011X_ADM_MOD_CONSTAT;

      for (loop = 0; loop < ZL5011X_ISR_MAX_NUMBER_DEVICES; loop++)
      {
         if (zl5011xIsrDeviceTable[loop] != NULL)
         {
            *(Uint32T *)(reg + zl5011xIsrDeviceTable[loop]->baseAdd) |= ZL5011X_ENABLE_INT_0;
         }
      }
   }

   if (status != ZL5011X_OK)
   {
      ZL5011X_TRACE(ZL5011X_ISR_FN_ID,
            "zl5011xIsrHandler: failed (%d)",
            status, 0, 0, 0, 0, 0);
   }

#ifdef _DEBUG
   if (zl5011xTraceIsrEnable == ZL5011X_FALSE)
   {
      /* restore the trace variables now that the interrupt has finished */
      zl5011xTraceFnFilter = tempTraceFnFilter;
      zl5011xTraceCtxtFnFilter = tempTraceCtxtFnFilter;
      zl5011xTraceCtxtFilter = tempTraceCtxtFilter;
   }
#endif

   return status;
}

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

 Function:
    zl5011xIsrQueueUpInterrupts

 Description:
     This function is called in the Isr Task, it sends messages to the DPR task
     using the message queue.
 Inputs:
   zl5011xParams      Pointer to the structure for this device instance
   pIntr             Pointer to the structure for interrupt data
 Structure Inputs:
    zl5011xParams
    interruptSource
    activeInterrupts
    context

 Outputs:

 Returns:
    zlStatusE

 Remarks:

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

static zlStatusE zl5011xIsrQueueUpInterrupts(zl5011xParamsS *zl5011xParams,
      zl5011xInterruptQueueDataS *pIntr)
{
   zlStatusE status= ZL5011X_OK;

   if (zl5011xIsrMsgQId == OS_MSG_Q_INVALID)
   {
      status = ZL5011X_NOT_RUNNING;

      ZL5011X_TRACE(ZL5011X_ISR_FN_ID, "zl5011xIsrQueueUpInterrupts: queue uninitialised",
            0, 0, 0, 0, 0, 0);
   }

   if (status == ZL5011X_OK)
   {
      pIntr->zl5011xParams = zl5011xParams;


      if (OS_MSG_Q_SEND(zl5011xIsrMsgQId, (char *)pIntr, sizeof(zl5011xInterruptQueueDataS),
            OS_NO_WAIT, 0) == OS_ERROR)
      {
          status = ZL5011X_ERROR;

          ZL5011X_TRACE(ZL5011X_ISR_FN_ID, "zl5011xIsrQueueUpInterrupts: ERROR queueing "
               "Message: block no %d intr reg 0x%.08lx, queued to DPR",
               pIntr->interruptSource, pIntr->activeInterrupts, 0,0,0,0);
      }
   }

   return status;
}

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

 Function:
    zl5011xIsrEnableInterruptSourceStructInit

 Description:
   This is the initialisation function for zl5011xIsrEnableInterruptSource

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

 Returns:
    zlStatusE

 Remarks:

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

zlStatusE zl5011xIsrEnableInterruptSourceStructInit(zl5011xParamsS *zl5011xParams,
      zl5011xIsrInterruptSourceS *par)
{
   zlStatusE status = ZL5011X_OK;

   status = ZL5011X_CHECK_POINTERS(zl5011xParams, par);

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

      par->interruptBits = 0;
      par->interruptSource = ZL5011X_NO_INTERRUPT;
      par->context = (Uint32T)ZL5011X_INVALID_CONTEXT;
      par->portNumber = (Uint8T)ZL5011X_INVALID;
   }

   return status;
}

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

 Function:
    zl5011xIsrEnableInterruptSource

 Description:
   This function is used to enable the interrupt sources used to drive the
   application interrupt (int 0 on the device).
   This does not include any of the interrupt sources that are
   controlled by the API ISR. The API interrupts are controlled when the
   relevant function is configured.

   It is intended that this would only need to be called once at initialisation,
   to indicate which problems the application is interested in.

   The interrupt enables are characterised by the block which generates them.
   This is part of the InterruptSource parameter structure, which also
   contains a 32bit register bit-pattern (usually) corresponding to the
   pattern of the enable bits in the block. In some cases these bits are in
   context memory, and for these a context number is associated with them.
   Interrupts which are associated with registers rather than contexts have the
   context number set to invalid_context. Some blocks have both types: context &
   register, in these cases the context number is used to distinguish them
   (PLA, TFQ).

   The top level mask contained in the ADM block is updated to enable the
   relevant block interrupt. Note that the CPU, MM and PKQ have interrupts
   but are not masked in the blocks themselves but in the ADM top level mask,
   therefore their interruptBits parameter uses the bit position in this ADM reg.

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

  Structure Inputs:
      interruptBits  bits set to enable the interrupt
      interruptSource   block where bits are set
      context        context (may be associated with the interrupt)
      portNumber     LAN port (may be associated with the interrupt)
   The function parameters are in a structure (see above), the various parts of
   which are used as appropriate.

 Outputs:

 Returns:
    zlStatusE

 Remarks:

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

zlStatusE zl5011xIsrEnableInterruptSource(zl5011xParamsS *zl5011xParams,
      zl5011xIsrInterruptSourceS *par)
{
   zlStatusE status = ZL5011X_OK;
   zl5011xInterruptValueE intSrc, apiSrc;
   Uint32T temp;
   Uint8T internalPortNum;

   status = ZL5011X_CHECK_POINTERS(zl5011xParams, par);

   if (status == ZL5011X_OK)
   {
      ZL5011X_TRACE(ZL5011X_ISR_FN_ID,
            "zl5011xIsrEnableInterruptSource: dev %08X, intSrc %d, ctxt %d, port %d, bits %08X",
            (Uint32T)zl5011xParams, par->interruptSource, par->context, par->portNumber, par->interruptBits, 0);
   }

   if (status == ZL5011X_OK)
   {
      /* these application interrupts can only be enabled if the interrupt is running */
      if (zl5011xIsrAppIntNum == (Uint32T)ZL5011X_INVALID)
      {
         status = ZL5011X_NOT_RUNNING;
      }
   }

   if (status == ZL5011X_OK)
   {
      /* the default interrupt to connect to is int 0. This may be overridden in some
         instances, depending on the state of the api interrupt */
      intSrc = ZL5011X_INTERRUPT_ZERO;

      if (zl5011xIsrApiIntNum != (Uint32T)ZL5011X_INVALID)
      {
         apiSrc = ZL5011X_INTERRUPT_ONE;
      }
      else
      {
         apiSrc = ZL5011X_INTERRUPT_ZERO;
      }

      switch (par->interruptSource)
      {
         case ZL5011X_GRANULE_INTERRUPT:
            status = zl5011xGmEnableInterrupts( zl5011xParams, par->interruptBits);
            break;

         case ZL5011X_WAN_CLK_INTERRUPT:
            status = zl5011xPacEnableInterrupts(zl5011xParams, par->interruptBits);
            intSrc = apiSrc;
            break;

         case ZL5011X_PACKET_RX_INTERRUPT:
            temp = par->interruptBits;

            if ((temp & (ZL5011X_1BIT_MASK << ZL5011X_PACKET_RX_PW_INT)) != 0)
            {
               zl5011xParams->interruptMasks.pkcPwInterruptEnabled = ZL5011X_TRUE;

               temp &= ~(ZL5011X_1BIT_MASK << ZL5011X_PACKET_RX_PW_INT);
            }

            status = zl5011xPkcEnableInterrupts(zl5011xParams, temp);
            break;

         case ZL5011X_MAC_IF_INTERRUPT:

⌨️ 快捷键说明

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