?? zl5011xinterrupts.c
字號:
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 + -