- toolkit V2.8.0.1@14806 - BSL V1.8.0.0@14590 - tcpserver: V1.4.3.0@14676 (marshaller V2.4.0.1@14551)
558 lines
23 KiB
C
558 lines
23 KiB
C
/**************************************************************************************
|
|
|
|
Copyright (c) Hilscher Gesellschaft fuer Systemautomation mbH. All Rights Reserved.
|
|
|
|
***************************************************************************************
|
|
|
|
$Id: cifXInterrupt.c 14244 2021-10-18 12:30:23Z RMayer $:
|
|
|
|
Description:
|
|
cifX Toolkit Interrupt handling routines (ISR/DSR)
|
|
|
|
Changes:
|
|
Date Description
|
|
-----------------------------------------------------------------------------------
|
|
2021-10-15 - Rework handling in DSR function, added ulHostCOSFlagsSaved variable
|
|
2018-10-10 - Updated header and definitions to new Hilscher defines
|
|
- Derived from cifX Toolkit V1.6.0.0
|
|
|
|
**************************************************************************************/
|
|
|
|
#include "cifXHWFunctions.h"
|
|
#include "cifXErrors.h"
|
|
#include "cifXEndianess.h"
|
|
|
|
/*****************************************************************************/
|
|
/*! \addtogroup CIFX_TOOLKIT_FUNCS cifX DPM Toolkit specific functions
|
|
* \{ */
|
|
/*****************************************************************************/
|
|
|
|
/*****************************************************************************/
|
|
/*! Low-Level interrupt handler
|
|
* \param ptDevInstance Instance that probably generated an IRQ (on PCI devices
|
|
* the routine decides if it was an IRQ for shared interrupt lines)
|
|
* \param fPCIIgnoreGlobalIntFlag Ignore the global interrupt flag on PCI cards,
|
|
* to detect shared interrupts. This might be necessary
|
|
* if the user has already filtered out all shared IRQs
|
|
* \return CIFX_TKIT_IRQ_DSR_REQUESTED/CIFX_TKIT_IRQ_HANDLED on success
|
|
* CIFX_TKIT_IRQ_OTHERDEVICE if the IRQ is not from the device */
|
|
/*****************************************************************************/
|
|
int cifXTKitISRHandler(PDEVICEINSTANCE ptDevInstance, int fPCIIgnoreGlobalIntFlag)
|
|
{
|
|
int iRet;
|
|
|
|
/* Check if DPM is available, if not, it cannot be our card, that caused the interrupt */
|
|
if( HWIF_READ32(ptDevInstance, *(uint32_t*)ptDevInstance->pbDPM) == CIFX_DPM_INVALID_CONTENT)
|
|
return CIFX_TKIT_IRQ_OTHERDEVICE;
|
|
|
|
if(!ptDevInstance->fIrqEnabled)
|
|
{
|
|
/* Irq is disabled on device, so we assume the user activated the interrupts,
|
|
but wants to poll the card. */
|
|
|
|
USER_Trace(ptDevInstance,
|
|
TRACE_LEVEL_ERROR,
|
|
"cifXTKitISRHandler() : We received an interrupt, but IRQs are disabled!");
|
|
|
|
iRet = CIFX_TKIT_IRQ_OTHERDEVICE;
|
|
|
|
} else
|
|
{
|
|
/* We are working in interrupt mode */
|
|
uint32_t ulChannel;
|
|
int iIrqToDsrBuffer = ptDevInstance->iIrqToDsrBuffer;
|
|
IRQ_TO_DSR_BUFFER_T* ptIsrToDsrBuffer = &ptDevInstance->atIrqToDsrBuffer[iIrqToDsrBuffer];
|
|
HIL_DPM_HANDSHAKE_ARRAY_T* ptHandshakeBuffer = &ptIsrToDsrBuffer->tHandshakeBuffer;
|
|
|
|
/* on a DPM module every handshake cell can be read individually,
|
|
on a PCI module the complete handshake register block must be read sequentially */
|
|
if( (!ptDevInstance->fPCICard) ||
|
|
(!ptDevInstance->pbHandshakeBlock) )
|
|
{
|
|
/* DPM card */
|
|
|
|
++ptDevInstance->ulIrqCounter;
|
|
ptIsrToDsrBuffer->fValid = 1;
|
|
|
|
/* Check if we have a handshake block, if so, we read it completely on DPM hardwares
|
|
to make sure, illegally activated handshake cells, don't cause interrupts */
|
|
if (NULL != ptDevInstance->pbHandshakeBlock)
|
|
{
|
|
HWIF_READN( ptDevInstance,
|
|
ptHandshakeBuffer,
|
|
ptDevInstance->pbHandshakeBlock,
|
|
sizeof(*ptHandshakeBuffer));
|
|
} else
|
|
{
|
|
/* We do not have a handshake block, so we have to read them one by one */
|
|
/* and only for the available channels */
|
|
ptHandshakeBuffer->atHsk[0].ulValue = HWIF_READ32(ptDevInstance, ptDevInstance->tSystemDevice.ptHandshakeCell->ulValue);
|
|
|
|
for(ulChannel = 0; ulChannel < ptDevInstance->ulCommChannelCount; ++ulChannel)
|
|
{
|
|
PCHANNELINSTANCE ptChannel = (PCHANNELINSTANCE)ptDevInstance->pptCommChannels[ulChannel];
|
|
uint32_t ulBlockID = ptChannel->ulBlockID;
|
|
|
|
ptHandshakeBuffer->atHsk[ulBlockID].ulValue = HWIF_READ32(ptDevInstance, ptChannel->ptHandshakeCell->ulValue);
|
|
}
|
|
}
|
|
|
|
/* we need to check in DSR which handshake bits have changed */
|
|
iRet = CIFX_TKIT_IRQ_DSR_REQUESTED;
|
|
|
|
} else
|
|
{
|
|
/* PCI card */
|
|
|
|
uint32_t ulIrqState0 = LE32_TO_HOST(HWIF_READ32(ptDevInstance, ptDevInstance->ptGlobalRegisters->ulIRQState_0));
|
|
uint32_t ulIrqState1 = LE32_TO_HOST(HWIF_READ32(ptDevInstance, ptDevInstance->ptGlobalRegisters->ulIRQState_1));
|
|
|
|
/* First check if we have generated this interrupt by reading the global IRQ status bit */
|
|
if( !fPCIIgnoreGlobalIntFlag &&
|
|
(0 == (ulIrqState0 & MSK_IRQ_STA0_INT_REQ)) )
|
|
{
|
|
/* we have not generated this interrupt, so it must be another device on shared IRQ */
|
|
iRet = CIFX_TKIT_IRQ_OTHERDEVICE;
|
|
|
|
} else
|
|
{
|
|
HIL_DPM_HANDSHAKE_ARRAY_T* ptHandshakeBlock = (HIL_DPM_HANDSHAKE_ARRAY_T*)ptDevInstance->pbHandshakeBlock;
|
|
|
|
/* confirm all interrupts.
|
|
We can safely clear handshake interrupts here, as we are reading the handshake flags below,
|
|
so we won't miss an IRQ.*/
|
|
HWIF_WRITE32(ptDevInstance, ptDevInstance->ptGlobalRegisters->ulIRQState_0, HOST_TO_LE32(ulIrqState0));
|
|
HWIF_WRITE32(ptDevInstance, ptDevInstance->ptGlobalRegisters->ulIRQState_1, HOST_TO_LE32(ulIrqState1));
|
|
|
|
++ptDevInstance->ulIrqCounter;
|
|
ptIsrToDsrBuffer->fValid = 1;
|
|
|
|
/* Only read first 8 Handshake cells, due to a netX hardware issue. Reading flags 8-15 may
|
|
also confirm IRQs for Handshake cell 0-7 due to an netX internal readahead buffer */
|
|
ptHandshakeBuffer->atHsk[HIL_DPM_SYSTEM_CHANNEL_INDEX].ulValue = HWIF_READ32( ptDevInstance, ptHandshakeBlock->atHsk[HIL_DPM_SYSTEM_CHANNEL_INDEX].ulValue);
|
|
ptHandshakeBuffer->atHsk[HIL_DPM_HANDSHAKE_CHANNEL_INDEX].ulValue = HWIF_READ32( ptDevInstance, ptHandshakeBlock->atHsk[HIL_DPM_HANDSHAKE_CHANNEL_INDEX].ulValue);
|
|
|
|
for(ulChannel = 0; ulChannel < ptDevInstance->ulCommChannelCount; ++ulChannel)
|
|
ptHandshakeBuffer->atHsk[HIL_DPM_COM_CHANNEL_START_INDEX + ulChannel].ulValue = HWIF_READ32(ptDevInstance, ptHandshakeBlock->atHsk[HIL_DPM_COM_CHANNEL_START_INDEX + ulChannel].ulValue);
|
|
|
|
/* we need to check in DSR which handshake bits have changed */
|
|
iRet = CIFX_TKIT_IRQ_DSR_REQUESTED;
|
|
}
|
|
}
|
|
}
|
|
|
|
return iRet;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/*! Process IO Areas for changes / callbacks
|
|
* \param ptChannel Channel Instance
|
|
* \param ptIoArea IO Area
|
|
* \param usChangedBits Bits that have changed since last IRQ
|
|
* \param usUnequalBits Bits that are unequal between host and netX
|
|
* \param fOutput !=0 if an output area is processed */
|
|
/*****************************************************************************/
|
|
static void ProcessIOArea(PCHANNELINSTANCE ptChannel,
|
|
PIOINSTANCE ptIoArea,
|
|
uint16_t usChangedBits,
|
|
uint16_t usUnequalBits,
|
|
int fOutput)
|
|
{
|
|
uint16_t usBitMask = (uint16_t)(1 << ptIoArea->bHandshakeBit);
|
|
|
|
if(usChangedBits & usBitMask)
|
|
{
|
|
PFN_NOTIFY_CALLBACK pfnCallback = NULL;
|
|
uint8_t bIOBitState = DEV_GetIOBitstate(ptChannel, ptIoArea, fOutput);
|
|
|
|
switch(bIOBitState)
|
|
{
|
|
case HIL_FLAGS_EQUAL:
|
|
if(0 == (usUnequalBits & usBitMask))
|
|
pfnCallback = ptIoArea->pfnCallback;
|
|
break;
|
|
|
|
case HIL_FLAGS_NOT_EQUAL:
|
|
if(usUnequalBits & usBitMask)
|
|
pfnCallback = ptIoArea->pfnCallback;
|
|
break;
|
|
|
|
case HIL_FLAGS_CLEAR:
|
|
if(0 == (ptChannel->usNetxFlags & usBitMask))
|
|
pfnCallback = ptIoArea->pfnCallback;
|
|
break;
|
|
|
|
case HIL_FLAGS_SET:
|
|
if(ptChannel->usNetxFlags & usBitMask)
|
|
pfnCallback = ptIoArea->pfnCallback;
|
|
break;
|
|
}
|
|
|
|
if(pfnCallback)
|
|
pfnCallback(ptIoArea->ulNotifyEvent, 0, NULL, ptIoArea->pvUser);
|
|
|
|
OS_SetEvent(ptChannel->ahHandshakeBitEvents[ptIoArea->bHandshakeBit]);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/*! Deferred interrupt handler
|
|
* \param ptDevInstance Instance the DSR is requested for */
|
|
/*****************************************************************************/
|
|
void cifXTKitDSRHandler(PDEVICEINSTANCE ptDevInstance)
|
|
{
|
|
if(!ptDevInstance->fResetActive)
|
|
{
|
|
/* Get actual data buffer index */
|
|
uint32_t ulChannel = 0;
|
|
PCHANNELINSTANCE ptChannel = &ptDevInstance->tSystemDevice;
|
|
int iIrqToDsrBuffer = 0;
|
|
IRQ_TO_DSR_BUFFER_T* ptIrqToDsrBuffer = NULL;
|
|
|
|
#ifdef CIFX_TOOLKIT_ENABLE_DSR_LOCK
|
|
/* Lock against ISR */
|
|
OS_IrqLock(ptDevInstance->pvOSDependent);
|
|
#else
|
|
|
|
/* ATTENTION: The IrqToDsr Buffer handling implies a "always" higher priority */
|
|
/* of the ISR function. This does usually happens on physical ISR functions */
|
|
/* but does not work if the ISR and DSR are handled as a threads! */
|
|
|
|
#endif
|
|
|
|
iIrqToDsrBuffer = ptDevInstance->iIrqToDsrBuffer;
|
|
ptIrqToDsrBuffer = &ptDevInstance->atIrqToDsrBuffer[iIrqToDsrBuffer];
|
|
|
|
if(!ptIrqToDsrBuffer->fValid)
|
|
{
|
|
/* Interrupt did not provide data yet */
|
|
|
|
#ifdef CIFX_TOOLKIT_ENABLE_DSR_LOCK
|
|
/* Release lock against ISR */
|
|
OS_IrqUnlock(ptDevInstance->pvOSDependent);
|
|
#endif
|
|
|
|
return;
|
|
} else
|
|
{
|
|
/* Flip data buffer so IRQ uses the other buffer */
|
|
ptDevInstance->iIrqToDsrBuffer ^= 0x01;
|
|
|
|
/* Invalidate the buffer, we are now handling */
|
|
ptIrqToDsrBuffer->fValid = 0;
|
|
}
|
|
|
|
#ifdef CIFX_TOOLKIT_ENABLE_DSR_LOCK
|
|
/* Release lock against ISR */
|
|
OS_IrqUnlock(ptDevInstance->pvOSDependent);
|
|
#endif
|
|
|
|
/* Only process rest of flags if NSF_READY is set. This must be done to prevent
|
|
confusion of the toolkit during a system start (xSysdeviceReset) */
|
|
if(ptIrqToDsrBuffer->tHandshakeBuffer.atHsk[0].t8Bit.bNetxFlags & NSF_READY)
|
|
{
|
|
/*--------------------------------------------------------------------*/
|
|
/* Evaluate device synchronisation flags, the flags are fixed 16 Bit */
|
|
/*--------------------------------------------------------------------*/
|
|
uint16_t usChangedSyncBits;
|
|
uint16_t usOldNSyncFlags = ptDevInstance->tSyncData.usNSyncFlags; /* Remember last known netX flags */
|
|
|
|
/* Get pointer to the new flag data from ISR */
|
|
HIL_DPM_HANDSHAKE_CELL_T* ptSyncCell = &ptIrqToDsrBuffer->tHandshakeBuffer.atHsk[NETX_HSK_SYNCH_FLAG_POS];
|
|
|
|
/* Get the actual flags */
|
|
ptDevInstance->tSyncData.usNSyncFlags = LE16_TO_HOST(ptSyncCell->t16Bit.usNetxFlags);
|
|
|
|
/* Check if there are changed bits since last interrupt from netX side, */
|
|
/* and only process sync if bits have chanded! */
|
|
if ( 0 != (usChangedSyncBits = usOldNSyncFlags ^ ptDevInstance->tSyncData.usNSyncFlags))
|
|
{
|
|
uint32_t ulBitPos;
|
|
uint16_t usUnequalSyncBits;
|
|
|
|
/* Create unequal bit mask */
|
|
usUnequalSyncBits = ptDevInstance->tSyncData.usNSyncFlags ^ ptDevInstance->tSyncData.usHSyncFlags;
|
|
|
|
/* Signal sync events */
|
|
for(ulBitPos = 0; ulBitPos < NETX_NUM_OF_SYNCH_FLAGS; ++ulBitPos)
|
|
{
|
|
/* There is a valid channel */
|
|
uint16_t usBitMask = (uint16_t)(1 << ulBitPos);
|
|
PCHANNELINSTANCE ptSyncChannel = NULL;
|
|
|
|
if (ulBitPos >= ptDevInstance->ulCommChannelCount)
|
|
break;
|
|
|
|
ptSyncChannel = (PCHANNELINSTANCE)ptDevInstance->pptCommChannels[ulBitPos];
|
|
|
|
if ( usChangedSyncBits & usBitMask)
|
|
{
|
|
uint8_t bState = HIL_FLAGS_NOT_EQUAL;
|
|
int fProcess = 0;
|
|
|
|
/* Handle Sync interrupts, read actual state and set bState accordingly */
|
|
if( HIL_SYNC_MODE_HST_CTRL == HWIF_READ8(ptDevInstance, ptSyncChannel->ptCommonStatusBlock->bSyncHskMode))
|
|
bState = HIL_FLAGS_EQUAL;
|
|
|
|
/* Check which mode to handle */
|
|
/* HIL_FLAGS_NOT_EQUAL corresponds to DEVICE_CONTROLLED */
|
|
if( (bState == HIL_FLAGS_NOT_EQUAL) &&
|
|
(usUnequalSyncBits & usBitMask) )
|
|
{
|
|
fProcess = 1;
|
|
|
|
} else if( (bState == HIL_FLAGS_EQUAL) &&
|
|
(0 == (usUnequalSyncBits & usBitMask)) )
|
|
{
|
|
fProcess = 1;
|
|
}
|
|
|
|
if(fProcess)
|
|
{
|
|
/* There is a valid channel */
|
|
/* Check if we have a callback assigned */
|
|
if (ptSyncChannel->tSynch.pfnCallback)
|
|
ptSyncChannel->tSynch.pfnCallback( CIFX_NOTIFY_SYNC, 0, NULL, ptSyncChannel->tSynch.pvUser);
|
|
|
|
/* Signal event to allow waiting for sync state without callback */
|
|
if( ptDevInstance->tSyncData.ahSyncBitEvents[ulBitPos])
|
|
OS_SetEvent(ptDevInstance->tSyncData.ahSyncBitEvents[ulBitPos]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------*/
|
|
/* Evaluate all changed handshake bits on all channels */
|
|
/* Start with SYSTEM channel */
|
|
do
|
|
{
|
|
uint16_t usChangedBits;
|
|
uint16_t usUnequalBits;
|
|
uint16_t usOldNetxFlags = ptChannel->usNetxFlags; /* Remember last known netX flags */
|
|
uint32_t ulIdx;
|
|
|
|
/* Address the handshake cell */
|
|
HIL_DPM_HANDSHAKE_CELL_T* ptHskCell = &ptIrqToDsrBuffer->tHandshakeBuffer.atHsk[ptChannel->ulBlockID];
|
|
|
|
if(ptChannel->bHandshakeWidth == HIL_HANDSHAKE_SIZE_8BIT)
|
|
{
|
|
ptChannel->usNetxFlags = ptHskCell->t8Bit.bNetxFlags;
|
|
} else
|
|
{
|
|
ptChannel->usNetxFlags = LE16_TO_HOST(ptHskCell->t16Bit.usNetxFlags);
|
|
}
|
|
|
|
/* Check which bits have changed since last interrupt from netX side */
|
|
usChangedBits = usOldNetxFlags ^ ptChannel->usNetxFlags;
|
|
usUnequalBits = ptChannel->usNetxFlags ^ ptChannel->usHostFlags;
|
|
|
|
/* Check if we have a valid channel (not for the bootloader) */
|
|
if(ptChannel->fIsChannel)
|
|
{
|
|
/*------------------------------------------*/
|
|
/* Process CHANNEL flags */
|
|
/*------------------------------------------*/
|
|
|
|
/* -----------------------------------------*/
|
|
/* Check COM Flag and I/O areas */
|
|
/* -----------------------------------------*/
|
|
if(usChangedBits & NCF_COMMUNICATING)
|
|
{
|
|
OS_SetEvent(ptChannel->ahHandshakeBitEvents[NCF_COMMUNICATING_BIT_NO]);
|
|
|
|
/* check if notification is registered */
|
|
if (NULL != ptChannel->tComState.pfnCallback)
|
|
{
|
|
CIFX_NOTIFY_COM_STATE_T tData;
|
|
|
|
tData.ulComState = (ptChannel->usNetxFlags & NCF_COMMUNICATING);
|
|
|
|
ptChannel->tComState.pfnCallback( CIFX_NOTIFY_COM_STATE,
|
|
sizeof(tData),
|
|
&tData,
|
|
ptChannel->tComState.pvUser);
|
|
}
|
|
}
|
|
|
|
/* Check IO - Input Areas */
|
|
for(ulIdx = 0; ulIdx < ptChannel->ulIOInputAreas; ++ulIdx)
|
|
{
|
|
ProcessIOArea(ptChannel,
|
|
ptChannel->pptIOInputAreas[ulIdx],
|
|
usChangedBits,
|
|
usUnequalBits,
|
|
0);
|
|
}
|
|
|
|
/* Check IO - Output Areas */
|
|
for(ulIdx = 0; ulIdx < ptChannel->ulIOOutputAreas; ++ulIdx)
|
|
{
|
|
ProcessIOArea(ptChannel,
|
|
ptChannel->pptIOOutputAreas[ulIdx],
|
|
usChangedBits,
|
|
usUnequalBits,
|
|
1);
|
|
}
|
|
|
|
/* -----------------------------------------*/
|
|
/* Check COS Flags */
|
|
/* -----------------------------------------*/
|
|
/* Check netX for new COS flags */
|
|
/* -----------------------------------------*/
|
|
if( usUnequalBits & NCF_NETX_COS_CMD)
|
|
{
|
|
uint32_t ulNewCOSFlags = 0;
|
|
|
|
/* Lock flag access */
|
|
OS_EnterLock(ptChannel->pvLock);
|
|
|
|
/* Read the flags and acknowledge them */
|
|
ulNewCOSFlags = LE32_TO_HOST(HWIF_READ32(ptDevInstance, ptChannel->ptCommonStatusBlock->ulCommunicationCOS));
|
|
|
|
/* Check if they have changed */
|
|
if(ptChannel->ulDeviceCOSFlags != ulNewCOSFlags)
|
|
{
|
|
ptChannel->ulDeviceCOSFlagsChanged = ptChannel->ulDeviceCOSFlags ^ ulNewCOSFlags;
|
|
ptChannel->ulDeviceCOSFlags = ulNewCOSFlags;
|
|
}
|
|
|
|
DEV_ToggleBit(ptChannel, HCF_NETX_COS_ACK);
|
|
|
|
/* Unlock flag access */
|
|
OS_LeaveLock(ptChannel->pvLock);
|
|
}
|
|
|
|
/* Signal netX COS command flag change */
|
|
if( usChangedBits & NCF_NETX_COS_CMD)
|
|
OS_SetEvent(ptChannel->ahHandshakeBitEvents[NCF_NETX_COS_CMD_BIT_NO]);
|
|
|
|
/* --------------------------------------------------*/
|
|
/* Process our own COS flags (Write them to device) */
|
|
/* --------------------------------------------------*/
|
|
/* Check if we have new COS flags to write */
|
|
if ( ptChannel->ulHostCOSFlagsSaved != ptChannel->ulHostCOSFlags)
|
|
{
|
|
/* Check if it is allowed to write new flags */
|
|
if( !(usUnequalBits & NCF_HOST_COS_ACK))
|
|
{
|
|
/* Lock flag access */
|
|
OS_EnterLock(ptChannel->pvLock);
|
|
|
|
/* Update COS flags */
|
|
HWIF_WRITE32(ptDevInstance, ptChannel->ptControlBlock->ulApplicationCOS, HOST_TO_LE32(ptChannel->ulHostCOSFlags));
|
|
|
|
/* Store the written values */
|
|
ptChannel->ulHostCOSFlagsSaved = ptChannel->ulHostCOSFlags;
|
|
|
|
/* Signal new COS flags */
|
|
DEV_ToggleBit(ptChannel, HCF_HOST_COS_CMD);
|
|
|
|
/* Remove all enable flags from the local COS flags */
|
|
ptChannel->ulHostCOSFlags &= ~(HIL_APP_COS_BUS_ON_ENABLE | HIL_APP_COS_INITIALIZATION_ENABLE | HIL_APP_COS_LOCK_CONFIGURATION_ENABLE);
|
|
|
|
/* Unlock flag access */
|
|
OS_LeaveLock(ptChannel->pvLock);
|
|
}
|
|
}
|
|
|
|
/* Signal host COS acknowledge flag change */
|
|
if( usChangedBits & NCF_HOST_COS_ACK)
|
|
OS_SetEvent(ptChannel->ahHandshakeBitEvents[NCF_HOST_COS_ACK_BIT_NO]);
|
|
|
|
} else
|
|
{
|
|
/*------------------------------------------*/
|
|
/* Process SYSTEM DEVICE Hardware COS flags */
|
|
/*------------------------------------------*/
|
|
/*----------------------------------------------------*/
|
|
/* Check if the hardware signals new system COS flags */
|
|
/*----------------------------------------------------*/
|
|
if( usUnequalBits & NSF_NETX_COS_CMD)
|
|
{
|
|
/* Read the flags and acknowledge them */
|
|
HIL_DPM_SYSTEM_CHANNEL_T* ptSyschannel = (HIL_DPM_SYSTEM_CHANNEL_T*)ptChannel->pbDPMChannelStart;
|
|
uint32_t ulNewCOSFlags = 0;
|
|
|
|
/* Lock flag access */
|
|
OS_EnterLock(ptChannel->pvLock);
|
|
|
|
/* Read the actual "System COS" flags */
|
|
ulNewCOSFlags = LE32_TO_HOST(HWIF_READ32(ptDevInstance, ptSyschannel->tSystemState.ulSystemCOS));
|
|
|
|
/* Read the flags and acknowledge them */
|
|
if(ptChannel->ulDeviceCOSFlags != ulNewCOSFlags)
|
|
{
|
|
ptChannel->ulDeviceCOSFlagsChanged = ptChannel->ulDeviceCOSFlags ^ ulNewCOSFlags;
|
|
ptChannel->ulDeviceCOSFlags = ulNewCOSFlags;
|
|
}
|
|
|
|
DEV_ToggleBit(ptChannel, HSF_NETX_COS_ACK);
|
|
|
|
/* Unlock flag access */
|
|
OS_LeaveLock(ptChannel->pvLock);
|
|
}
|
|
|
|
/* Signal COS CMD bits */
|
|
if(usChangedBits & NSF_NETX_COS_CMD)
|
|
OS_SetEvent(ptChannel->ahHandshakeBitEvents[NSF_NETX_COS_CMD_BIT_NO]);
|
|
|
|
/* Signal COS ACK bits */
|
|
if(usChangedBits & NSF_HOST_COS_ACK)
|
|
OS_SetEvent(ptChannel->ahHandshakeBitEvents[NSF_HOST_COS_ACK_BIT_NO]);
|
|
}
|
|
|
|
/*------------------------------------------*/
|
|
/* Process the send receive MBX flags */
|
|
/*------------------------------------------*/
|
|
/* Check Receive Mailbox */
|
|
if( usChangedBits & ptChannel->tRecvMbx.ulRecvACKBitmask)
|
|
{
|
|
if( (usUnequalBits & ptChannel->tRecvMbx.ulRecvACKBitmask) &&
|
|
(NULL != ptChannel->tRecvMbx.pfnCallback) )
|
|
{
|
|
CIFX_NOTIFY_RX_MBX_FULL_DATA_T tRxData;
|
|
|
|
tRxData.ulRecvCount = LE16_TO_HOST(HWIF_READ16(ptDevInstance, ptChannel->tRecvMbx.ptRecvMailboxStart->usWaitingPackages));
|
|
|
|
ptChannel->tRecvMbx.pfnCallback(CIFX_NOTIFY_RX_MBX_FULL,
|
|
sizeof(tRxData),
|
|
&tRxData,
|
|
ptChannel->tRecvMbx.pvUser);
|
|
}
|
|
OS_SetEvent(ptChannel->ahHandshakeBitEvents[ptChannel->tRecvMbx.bRecvACKBitoffset]);
|
|
}
|
|
|
|
/* Check Send Mailbox */
|
|
if( usChangedBits & ptChannel->tSendMbx.ulSendCMDBitmask)
|
|
{
|
|
if( (0 == (usUnequalBits & ptChannel->tSendMbx.ulSendCMDBitmask)) &&
|
|
(NULL != ptChannel->tSendMbx.pfnCallback) )
|
|
{
|
|
CIFX_NOTIFY_TX_MBX_EMPTY_DATA_T tTxData;
|
|
|
|
tTxData.ulMaxSendCount = LE16_TO_HOST(HWIF_READ16(ptDevInstance, ptChannel->tSendMbx.ptSendMailboxStart->usPackagesAccepted));
|
|
|
|
ptChannel->tSendMbx.pfnCallback(CIFX_NOTIFY_TX_MBX_EMPTY,
|
|
sizeof(tTxData),
|
|
&tTxData,
|
|
ptChannel->tSendMbx.pvUser);
|
|
}
|
|
OS_SetEvent(ptChannel->ahHandshakeBitEvents[ptChannel->tSendMbx.bSendCMDBitoffset]);
|
|
}
|
|
|
|
/* Next channel */
|
|
if(ulChannel < ptDevInstance->ulCommChannelCount)
|
|
ptChannel = ptDevInstance->pptCommChannels[ulChannel];
|
|
|
|
ulChannel++;
|
|
|
|
} while(ulChannel <= ptDevInstance->ulCommChannelCount);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/*! \} */
|
|
/*****************************************************************************/
|