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