nxdrvlinux/libcifx/Toolkit/Source/cifXHWFunctions.c
Sebastian Doell ac2f4d1789 Add initial driver source based on svn versions:
- toolkit V2.8.0.1@14806
 - BSL V1.8.0.0@14590
 - tcpserver: V1.4.3.0@14676 (marshaller V2.4.0.1@14551)
2024-02-05 09:23:09 +01:00

2503 lines
94 KiB
C

/**************************************************************************************
Copyright (c) Hilscher Gesellschaft fuer Systemautomation mbH. All Rights Reserved.
***************************************************************************************
$Id: cifXHWFunctions.c 14802 2023-05-10 09:39:47Z RMayer $:
Description:
cifX API Hardware handling functions implementation
Changes:
Date Description
-----------------------------------------------------------------------------------
2023-04-18 Added new option parameter for HWIF_READN / WRITEN function, to be able to
recognize single HWIF_READ16/WRITE32 and HWIF_READ32/WRITE32 accesses
2023-02-07 Added wait flag in DEV_Reset_Execute()
Used DEV_Reset_Execute() to signal reset functions on APP_CPU/iDPM handling
2022-01-04 Using new reset definition mask HIL_SYS_CONTROL_RESET_PARAM_FLAG_MASK in reset function
2021-10-15 Added ulHostCOSFlagsSaved variable handling
2020-08-18 After reset, fResetActive needs to be cleared before Handshake Cells
are re-evaluated
2019-11-26 Use CIFX_DMA_STATE_* defines in DEV_DMAState()
2019-11-13 Locking in DEV_ReadHandshakeFlags() includes Handshake Cell accesses
2019-10-30 Increase timeout during updatestart to firmware (e.g. initial startup
may take longer than subsequent starts)
2019-10-16 Reworked reset function handling and parameter passing
2019-10-08 - Fix reset handling for use case IDPM & APP CPU
- Split Dev_DoResetEx(), offer separate updatestart function
2019-03-21 Add timeout during resets for netX4000/4100 based PCI(e) devices to
prevent DPM accesses during reset.
2018-11-06 Add reset handling for IDPM and APP CPUs.
2018-10-10 - Updated header and definitions to new Hilscher defines
- Derived from cifX Toolkit V1.6.0.0
**************************************************************************************/
/*****************************************************************************/
/*! \file cifXHWFunctions.c
* cifX API Hardware handling functions implementation */
/*****************************************************************************/
#include "cifXHWFunctions.h"
#include "cifXErrors.h"
#include "cifXEndianess.h"
#include "Hil_Packet.h"
#include "Hil_SystemCmd.h"
/*****************************************************************************/
/*! \addtogroup CIFX_TK_HARDWARE Hardware Access
* \{ */
/*****************************************************************************/
/*****************************************************************************/
/*! Sends a Packet to the device/channel
* \param ptChannel Channel instance to send a packet
* \param ptSendPkt Packet to send
* \param ulTimeout Maximum time in ms to wait for an empty mailbox
* \return CIFX_NO_ERROR on success */
/*****************************************************************************/
int32_t DEV_PutPacket(PCHANNELINSTANCE ptChannel, CIFX_PACKET* ptSendPkt, uint32_t ulTimeout)
{
int32_t lRet = CIFX_DEV_MAILBOX_FULL;
if(!DEV_IsReady(ptChannel))
return CIFX_DEV_NOT_READY;
/* Check if packet fits into the mailbox */
if( (LE32_TO_HOST(ptSendPkt->tHeader.ulLen) + HIL_PACKET_HEADER_SIZE) > ptChannel->tSendMbx.ulSendMailboxLength)
return CIFX_DEV_MAILBOX_TOO_SHORT;
if(DEV_WaitForBitState(ptChannel, ptChannel->tSendMbx.bSendCMDBitoffset, HIL_FLAGS_EQUAL, ulTimeout))
{
/* Copy packet to mailbox */
++ptChannel->tSendMbx.ulSendPacketCnt;
HWIF_WRITEN(ptChannel->pvDeviceInstance,
ptChannel->tSendMbx.ptSendMailboxStart->abSendMailbox,
ptSendPkt,
LE32_TO_HOST(ptSendPkt->tHeader.ulLen) + HIL_PACKET_HEADER_SIZE);
/* Lock flag access */
OS_EnterLock(ptChannel->pvLock);
/* Signal new packet */
DEV_ToggleBit(ptChannel, ptChannel->tSendMbx.ulSendCMDBitmask);
/* Unlock flag access */
OS_LeaveLock(ptChannel->pvLock);
lRet = CIFX_NO_ERROR;
}
return lRet;
}
/*****************************************************************************/
/*! Retrieves a Packet from the device/channel
* \param ptChannel Channel instance to receive a packet from
* \param ptRecvPkt Pointer to place received Packet in
* \param ulRecvBufferSize Length of the receive buffer
* \param ulTimeout Maximum time in ms to wait for an empty mailbox
* \return CIFX_NO_ERROR on success */
/*****************************************************************************/
int32_t DEV_GetPacket( PCHANNELINSTANCE ptChannel, CIFX_PACKET* ptRecvPkt, uint32_t ulRecvBufferSize, uint32_t ulTimeout)
{
int32_t lRet = CIFX_NO_ERROR;
uint32_t ulCopySize = 0;
CIFX_PACKET* ptPacket = NULL;
if(!DEV_IsReady(ptChannel))
return CIFX_DEV_NOT_READY;
if(!DEV_WaitForBitState(ptChannel, ptChannel->tRecvMbx.bRecvACKBitoffset, HIL_FLAGS_NOT_EQUAL, ulTimeout))
return CIFX_DEV_GET_NO_PACKET;
++ptChannel->tRecvMbx.ulRecvPacketCnt;
ptPacket = (CIFX_PACKET*)ptChannel->tRecvMbx.ptRecvMailboxStart->abRecvMailbox;
ulCopySize = LE32_TO_HOST(HWIF_READ32(ptChannel->pvDeviceInstance, ptPacket->tHeader.ulLen)) + HIL_PACKET_HEADER_SIZE;
if(ulCopySize > ulRecvBufferSize)
{
/* We have to free the mailbox, read as much as possible */
ulCopySize = ulRecvBufferSize;
lRet = CIFX_BUFFER_TOO_SHORT;
}
HWIF_READN(ptChannel->pvDeviceInstance, ptRecvPkt, ptPacket, ulCopySize);
/* Lock flag access */
OS_EnterLock(ptChannel->pvLock);
/* Signal read packet done */
DEV_ToggleBit(ptChannel, ptChannel->tRecvMbx.ulRecvACKBitmask);
/* Unlock flag access */
OS_LeaveLock(ptChannel->pvLock);
return lRet;
}
/*****************************************************************************/
/*! Exchanges a packet with the device
* ATTENTION: This function will poll for receive packet, and will discard
* any packets that do not match the send packet. So don't use
* it during active data transfers
* \param pvChannel Channel instance to exchange a packet
* \param ptSendPkt Send packet pointer
* \param ptRecvPkt Pointer to place received Packet in
* \param ulRecvBufferSize Length of the receive buffer
* \param ulTimeout Maximum time in ms to wait for an empty mailbox
* \param pvPktCallback Packet callback for unhandled receive packets
* \param pvUser User data for callback function
* \return CIFX_NO_ERROR on success */
/*****************************************************************************/
int32_t DEV_TransferPacket( void* pvChannel, CIFX_PACKET* ptSendPkt, CIFX_PACKET* ptRecvPkt,
uint32_t ulRecvBufferSize, uint32_t ulTimeout,
PFN_RECV_PKT_CALLBACK pvPktCallback, void* pvUser)
{
int32_t lCount = 0;
int32_t lRet = CIFX_NO_ERROR;
PCHANNELINSTANCE ptChannel = (PCHANNELINSTANCE)pvChannel;
if( (lRet = DEV_PutPacket(ptChannel, ptSendPkt, ulTimeout)) == CIFX_NO_ERROR)
{
do
{
if( (lRet = DEV_GetPacket(ptChannel, ptRecvPkt, ulRecvBufferSize, ulTimeout)) == CIFX_NO_ERROR)
{
/* Check if we got the answer */
if( ((LE32_TO_HOST(ptRecvPkt->tHeader.ulCmd) & ~HIL_MSK_PACKET_ANSWER) == LE32_TO_HOST(ptSendPkt->tHeader.ulCmd)) &&
(ptRecvPkt->tHeader.ulSrc == ptSendPkt->tHeader.ulSrc) &&
(ptRecvPkt->tHeader.ulId == ptSendPkt->tHeader.ulId) &&
(ptRecvPkt->tHeader.ulSrcId == ptSendPkt->tHeader.ulSrcId) )
{
/* We got the answer message */
/* lRet = ptRecvPkt->tHeader.ulState; */ /* Do not deliver back this information */
break;
} else
{
/* This is not our packet, check if the user wants it */
if( NULL != pvPktCallback)
{
pvPktCallback(ptRecvPkt, pvUser);
}
}
/* Reset error, in case we might drop out of the loop, with no proper answer,
returning a "good" state */
lRet = CIFX_DEV_GET_TIMEOUT;
lCount++;
} else
{
/* Error during packet receive */
break;
}
} while ( lCount < 10);
}
return lRet;
}
/*****************************************************************************/
/*! Waits for a given handshake bit state on the channel (polling mode)
* \param ptChannel Channel instance to wait for bitstate
* \param ulBitNumber BitNumber to wait for (Bitnumber is used for
* indexing the event array in IRQ mode)
* \param bState State the handshake bit should be in after returning
* from this function
* \param ulTimeout Maximum time in ms to wait for the desired bit state
* \return 0 on error/timeout, 1 on success */
/*****************************************************************************/
static int DEV_WaitForBitState_Poll(PCHANNELINSTANCE ptChannel, uint32_t ulBitNumber, uint8_t bState, uint32_t ulTimeout)
{
uint8_t bActualState;
int iRet = 0;
uint32_t ulBitMask = 1 << ulBitNumber;
int32_t lStartTime = 0;
DEV_ReadHandshakeFlags(ptChannel, 0, 1);
if( (HIL_FLAGS_CLEAR == bState) ||
(HIL_FLAGS_SET == bState) )
{
bActualState = (ptChannel->usNetxFlags & ulBitMask)? HIL_FLAGS_SET : HIL_FLAGS_CLEAR;
} else
{
if((ptChannel->usHostFlags ^ ptChannel->usNetxFlags) & ulBitMask)
bActualState = HIL_FLAGS_NOT_EQUAL;
else
bActualState = HIL_FLAGS_EQUAL;
}
/* The desired state is already there, so just return true */
if(bActualState == bState)
return 1;
/* If no timeout is given, don't try to wait for the Bit change */
if(0 == ulTimeout)
return 0;
lStartTime = (int32_t)OS_GetMilliSecCounter();
/* Poll for desired bit state */
while(bActualState != bState)
{
uint32_t ulDiffTime = 0L;
DEV_ReadHandshakeFlags(ptChannel, 0, 1);
if( (HIL_FLAGS_CLEAR == bState) ||
(HIL_FLAGS_SET == bState) )
{
bActualState = (ptChannel->usNetxFlags & ulBitMask)? HIL_FLAGS_SET : HIL_FLAGS_CLEAR;
} else
{
if((ptChannel->usHostFlags ^ ptChannel->usNetxFlags) & ulBitMask)
bActualState = HIL_FLAGS_NOT_EQUAL;
else
bActualState = HIL_FLAGS_EQUAL;
}
if(bActualState == bState)
{
iRet = 1;
break;
}
/* Check for timeout */
ulDiffTime = OS_GetMilliSecCounter() - lStartTime;
if ( ulDiffTime > ulTimeout)
{
break;
}
OS_Sleep(0);
}
return iRet;
}
/*****************************************************************************/
/*! Waits for a given handshake bit state on the channel (irq mode)
* \param ptChannel Channel instance to wait for bitstate
* \param ulBitNumber BitNumber to wait for (Bitnumber is used for
* indexing the event array in IRQ mode)
* \param bState State the handshake bit should be in after returning
* from this function
* \param ulTimeout Maximum time in ms to wait for the desired bit state
* \return 0 on error/timeout, 1 on success */
/*****************************************************************************/
static int DEV_WaitForBitState_Irq(PCHANNELINSTANCE ptChannel, uint32_t ulBitNumber, uint8_t bState, uint32_t ulTimeout)
{
uint8_t bActualState;
int iRet = 0;
uint32_t ulBitMask = 1 << ulBitNumber;
int32_t lStartTime = 0;
uint32_t ulInternalTimeout = ulTimeout;
if( (HIL_FLAGS_CLEAR == bState) ||
(HIL_FLAGS_SET == bState) )
{
bActualState = (ptChannel->usNetxFlags & ulBitMask)? HIL_FLAGS_SET : HIL_FLAGS_CLEAR;
} else
{
if((ptChannel->usHostFlags ^ ptChannel->usNetxFlags) & ulBitMask)
bActualState = HIL_FLAGS_NOT_EQUAL;
else
bActualState = HIL_FLAGS_EQUAL;
}
/* The desired state is already there, so just return true */
if(bActualState == bState)
return 1;
/* If no timeout is given, don't try to wait for the Bit change */
if(0 == ulTimeout)
return 0;
/* Just wait for the Interrupt event to be signalled. This bit was toggled if the interrupt
is executed, so we don't need to check bit state afterwards
Note: Wait first time with timeout 0 and check if the state is the expected one.
If not it was a previously set event and we need to wait with the user supplied time out */
lStartTime = (int32_t)OS_GetMilliSecCounter();
do
{
uint32_t ulCurrentTime;
uint32_t ulDiffTime;
/* Wait for DSR to signal Handshake bit change event */
(void)OS_WaitEvent(ptChannel->ahHandshakeBitEvents[ulBitNumber], ulInternalTimeout);
ulCurrentTime = OS_GetMilliSecCounter();
ulDiffTime = ulCurrentTime - lStartTime;
/* Adjust timeout for next run */
ulInternalTimeout = ulTimeout - ulDiffTime;
/* Check bit state */
if( (HIL_FLAGS_CLEAR == bState) ||
(HIL_FLAGS_SET == bState) )
{
bActualState = (ptChannel->usNetxFlags & ulBitMask)? HIL_FLAGS_SET : HIL_FLAGS_CLEAR;
} else
{
if((ptChannel->usHostFlags ^ ptChannel->usNetxFlags) & ulBitMask)
bActualState = HIL_FLAGS_NOT_EQUAL;
else
bActualState = HIL_FLAGS_EQUAL;
}
if(bActualState == bState)
{
iRet = 1;
break;
}
if( ulDiffTime >= ulTimeout)
{
/* Timeout expired */
break;
}
} while(iRet == 0);
return iRet;
}
/*****************************************************************************/
/*! Waits for a given handshake bit state on the channel
* (IRQ/Polling Wrapper function)
* \param ptChannel Channel instance to wait for bitstate
* \param ulBitNumber BitNumber to wait for (Bitnumber is used for
* indexing the event array in IRQ mode)
* \param bState State the handshake bit should be in after returning
* from this function
* \param ulTimeout Maximum time in ms to wait for the desired bit state
* \return 0 on error/timeout, 1 on success */
/*****************************************************************************/
int DEV_WaitForBitState(PCHANNELINSTANCE ptChannel, uint32_t ulBitNumber, uint8_t bState, uint32_t ulTimeout)
{
if( ((PDEVICEINSTANCE)(ptChannel->pvDeviceInstance))->fIrqEnabled)
return DEV_WaitForBitState_Irq(ptChannel, ulBitNumber, bState, ulTimeout);
else
return DEV_WaitForBitState_Poll(ptChannel, ulBitNumber, bState, ulTimeout);
}
/*****************************************************************************/
/*! Get expected handshake bit state from IOArea
* \param ptChannel Channel instance
* \param ptIOInstance Pointer to IOInstance
* \param fOutput !=0 for output areas
* \return Expected handshake bit state */
/*****************************************************************************/
uint8_t DEV_GetIOBitstate(PCHANNELINSTANCE ptChannel, PIOINSTANCE ptIOInstance, int fOutput)
{
uint8_t bRet = ptIOInstance->bHandshakeBitState;
uint8_t* pbIOHskMode = NULL;
if(fOutput)
pbIOHskMode = &ptChannel->ptCommonStatusBlock->bPDOutHskMode;
else
pbIOHskMode = &ptChannel->ptCommonStatusBlock->bPDInHskMode;
switch(HWIF_READ8(ptChannel->pvDeviceInstance, *pbIOHskMode))
{
case HIL_IO_MODE_BUFF_DEV_CTRL:
bRet = HIL_FLAGS_NOT_EQUAL;
break;
case HIL_IO_MODE_UNCONTROLLED:
bRet = HIL_FLAGS_NONE;
break;
case HIL_IO_MODE_BUFF_HST_CTRL:
bRet = HIL_FLAGS_EQUAL;
break;
case HIL_IO_MODE_DEFAULT:
default:
/* Use data from channel information read on startup,
as I/O Mode is not provided in DPM */
break;
}
return bRet;
}
/*****************************************************************************/
/*! Toggles the given command handshake bit
* \param ptChannel Channel instance to change for bit for
* \param ulBitMask Bitmask to eXOR into command bits */
/*****************************************************************************/
void DEV_ToggleBit(PCHANNELINSTANCE ptChannel, uint32_t ulBitMask)
{
ptChannel->usHostFlags ^= (uint16_t)ulBitMask;
if( ptChannel->bHandshakeWidth == HIL_HANDSHAKE_SIZE_8BIT)
{
HWIF_WRITE8(ptChannel->pvDeviceInstance, ptChannel->ptHandshakeCell->t8Bit.bHostFlags, (uint8_t)ptChannel->usHostFlags);
} else
{
/* Write 16 Bit handshake */
HWIF_WRITE16(ptChannel->pvDeviceInstance, ptChannel->ptHandshakeCell->t16Bit.usHostFlags, HOST_TO_LE16(ptChannel->usHostFlags));
}
}
/*****************************************************************************/
/*! Waits for Sync state on the channel (polling mode)
* \param ptChannel Channel instance to wait for bitstate
* \param bState State the handshake bit should be in after returning
* from this function
* \param ulTimeout Maximum time in ms to wait for the desired bit state
* \return 0 on error/timeout, 1 on success */
/*****************************************************************************/
static int DEV_WaitForSyncState_Poll(PCHANNELINSTANCE ptChannel, uint8_t bState, uint32_t ulTimeout)
{
uint8_t bActualState;
int iRet = 0;
uint32_t ulBitMask = 1 << ptChannel->ulChannelNumber;
int32_t lStartTime = 0;
PDEVICEINSTANCE ptDevInst = (PDEVICEINSTANCE)ptChannel->pvDeviceInstance;
DEV_ReadHandshakeFlags(ptChannel, 1, 1);
if((ptDevInst->tSyncData.usHSyncFlags ^ ptDevInst->tSyncData.usNSyncFlags) & ulBitMask)
bActualState = HIL_FLAGS_NOT_EQUAL;
else
bActualState = HIL_FLAGS_EQUAL;
/* The desired state is already there, so just return true */
if(bActualState == bState)
return 1;
/* If no timeout is given, don't try to wait for the Bit change */
if(0 == ulTimeout)
return 0;
lStartTime = (int32_t)OS_GetMilliSecCounter();
/* Poll for desired bit state */
while(bActualState != bState)
{
uint32_t ulDiffTime = 0L;
DEV_ReadHandshakeFlags(ptChannel, 1, 1);
if((ptDevInst->tSyncData.usHSyncFlags ^ ptDevInst->tSyncData.usNSyncFlags) & ulBitMask)
bActualState = HIL_FLAGS_NOT_EQUAL;
else
bActualState = HIL_FLAGS_EQUAL;
if(bActualState == bState)
{
iRet = 1;
break;
}
/* Check for timeout */
ulDiffTime = OS_GetMilliSecCounter() - lStartTime;
if ( ulDiffTime > ulTimeout)
{
break;
}
OS_Sleep(0);
}
return iRet;
}
/*****************************************************************************/
/*! Waits for sync state on the channel (irq mode)
* \param ptChannel Channel instance to wait for bitstate
* \param bState State the handshake bit should be in after returning
* from this function
* \param ulTimeout Maximum time in ms to wait for the desired bit state
* \return 0 on error/timeout, 1 on success */
/*****************************************************************************/
static int DEV_WaitForSyncState_Irq(PCHANNELINSTANCE ptChannel, uint8_t bState, uint32_t ulTimeout)
{
uint8_t bActualState;
int iRet = 0;
uint32_t ulBitMask = 1 << ptChannel->ulChannelNumber;
int32_t lStartTime = 0;
uint32_t ulInternalTimeout = ulTimeout;
PDEVICEINSTANCE ptDevInstance = (PDEVICEINSTANCE)ptChannel->pvDeviceInstance;
if((ptDevInstance->tSyncData.usHSyncFlags ^ ptDevInstance->tSyncData.usNSyncFlags) & ulBitMask)
bActualState = HIL_FLAGS_NOT_EQUAL;
else
bActualState = HIL_FLAGS_EQUAL;
/* The desired state is already there, so just return true */
if(bActualState == bState)
return 1;
/* If no timeout is given, don't try to wait for the Bit change */
if(0 == ulTimeout)
return 0;
/* Just wait for the Interrupt event to be signalled. This bit was toggled if the interrupt
is executed, so we don't need to check bit state afterwards.*/
lStartTime = (int32_t)OS_GetMilliSecCounter();
do
{
uint32_t ulCurrentTime;
uint32_t ulDiffTime;
/* Wait for DSR to signal Handshake bit change event */
(void)OS_WaitEvent(ptDevInstance->tSyncData.ahSyncBitEvents[ptChannel->ulChannelNumber], ulInternalTimeout);
ulCurrentTime = OS_GetMilliSecCounter();
ulDiffTime = ulCurrentTime - lStartTime;
/* Adjust timeout for next run */
ulInternalTimeout = ulTimeout - ulDiffTime;
/* Check bit state */
if((ptDevInstance->tSyncData.usHSyncFlags ^ ptDevInstance->tSyncData.usNSyncFlags) & ulBitMask)
bActualState = HIL_FLAGS_NOT_EQUAL;
else
bActualState = HIL_FLAGS_EQUAL;
if(bActualState == bState)
{
iRet = 1;
break;
}
if( ulDiffTime >= ulTimeout)
{
/* Timeout expired */
break;
}
} while(iRet == 0);
return iRet;
}
/*****************************************************************************/
/*! Waits for sync state
* (IRQ/Polling Wrapper function)
* \param ptChannel Channel instance to wait for bitstate
* \param bState State the handshake bit should be in after returning
* from this function
* \param ulTimeout Maximum time in ms to wait for the desired bit state
* \return 0 on error/timeout, 1 on success */
/*****************************************************************************/
int DEV_WaitForSyncState(PCHANNELINSTANCE ptChannel, uint8_t bState, uint32_t ulTimeout)
{
if( ((PDEVICEINSTANCE)(ptChannel->pvDeviceInstance))->fIrqEnabled)
return DEV_WaitForSyncState_Irq(ptChannel, bState, ulTimeout);
else
return DEV_WaitForSyncState_Poll(ptChannel, bState, ulTimeout);
}
/*****************************************************************************/
/*! Toggles the given sync bit
* \param ptDevInstance Device instance
* \param ulBitMask Bitmask to eXOR into command bits */
/*****************************************************************************/
void DEV_ToggleSyncBit(PDEVICEINSTANCE ptDevInstance, uint32_t ulBitMask)
{
/* Write 16 Bit handshake */
HIL_DPM_HANDSHAKE_ARRAY_T* ptHandshakeBlock = (HIL_DPM_HANDSHAKE_ARRAY_T*)ptDevInstance->pbHandshakeBlock;
OS_EnterLock(ptDevInstance->tSyncData.pvLock);
ptDevInstance->tSyncData.usHSyncFlags ^= (uint16_t)ulBitMask;
HWIF_WRITE16(ptDevInstance, ptHandshakeBlock->atHsk[1].t16Bit.usHostFlags, HOST_TO_LE16(ptDevInstance->tSyncData.usHSyncFlags));
OS_LeaveLock(ptDevInstance->tSyncData.pvLock);
}
/*****************************************************************************/
/*! Reads the actual state of the host handshake bits for the given channel
* \param ptChannel Channel instance to change for bit for
* \param fReadHostCOS !=0 if Application COS should be read */
/*****************************************************************************/
void DEV_ReadHostFlags(PCHANNELINSTANCE ptChannel, int fReadHostCOS)
{
PDEVICEINSTANCE ptDevInstance = (PDEVICEINSTANCE)ptChannel->pvDeviceInstance;
if(ptChannel->bHandshakeWidth == HIL_HANDSHAKE_SIZE_8BIT)
ptChannel->usHostFlags = HWIF_READ8(ptChannel->pvDeviceInstance, ptChannel->ptHandshakeCell->t8Bit.bHostFlags);
else
ptChannel->usHostFlags = LE16_TO_HOST(HWIF_READ16(ptChannel->pvDeviceInstance, ptChannel->ptHandshakeCell->t16Bit.usHostFlags));
/* Also read host sync flags, as they might not be set to zero on flash based devices */
if( (ptDevInstance->pbHandshakeBlock != NULL) &&
(ptChannel->fIsSysDevice) )
{
HIL_DPM_HANDSHAKE_ARRAY_T* ptHandshakeBlock = (HIL_DPM_HANDSHAKE_ARRAY_T*)ptDevInstance->pbHandshakeBlock;
ptDevInstance->tSyncData.usHSyncFlags = LE16_TO_HOST(HWIF_READ16(ptChannel->pvDeviceInstance, ptHandshakeBlock->atHsk[1].t16Bit.usHostFlags));
}
if(NULL != ptChannel->ptCommonStatusBlock)
ptChannel->ulDeviceCOSFlags = LE32_TO_HOST(HWIF_READ32(ptChannel->pvDeviceInstance, ptChannel->ptCommonStatusBlock->ulCommunicationCOS));
if( fReadHostCOS)
{
if(NULL != ptChannel->ptControlBlock)
{
ptChannel->ulHostCOSFlags = LE32_TO_HOST(HWIF_READ32(ptChannel->pvDeviceInstance, ptChannel->ptControlBlock->ulApplicationCOS));
ptChannel->ulHostCOSFlagsSaved = ptChannel->ulHostCOSFlags;
}
}
}
/*****************************************************************************/
/*! Reads the actual state of the handshake bits for the given channel
* \param ptChannel Channel instance to change for bit for
* \param fReadSyncFlags !=0 if sync flags should be updated
* \param fLockNeeded !=0 if flag access lock is needed. */
/*****************************************************************************/
void DEV_ReadHandshakeFlags(PCHANNELINSTANCE ptChannel, int fReadSyncFlags, int fLockNeeded)
{
uint16_t usCOSAckBitMask = 0;
uint32_t ulNewCOSFlags = 0;
/* Read sync flags */
PDEVICEINSTANCE ptDevInstance = (PDEVICEINSTANCE)ptChannel->pvDeviceInstance;
/* Lock Handshake Cell and COS flag accesses */
if(fLockNeeded)
OS_EnterLock(ptChannel->pvLock);
if( (ptDevInstance->pbHandshakeBlock != NULL) &&
fReadSyncFlags )
{
HIL_DPM_HANDSHAKE_ARRAY_T* ptHandshakeBlock = (HIL_DPM_HANDSHAKE_ARRAY_T*)ptDevInstance->pbHandshakeBlock;
ptDevInstance->tSyncData.usNSyncFlags = LE16_TO_HOST(HWIF_READ16(ptDevInstance, ptHandshakeBlock->atHsk[1].t16Bit.usNetxFlags));
}
if(ptChannel->bHandshakeWidth == HIL_HANDSHAKE_SIZE_8BIT)
{
/* Read 8 Bit handshake */
ptChannel->usNetxFlags = HWIF_READ8(ptDevInstance, ptChannel->ptHandshakeCell->t8Bit.bNetxFlags);
} else
{
/* Read 16 Bit handshake */
ptChannel->usNetxFlags = LE16_TO_HOST(HWIF_READ16(ptDevInstance, ptChannel->ptHandshakeCell->t16Bit.usNetxFlags));
}
/* Read device COS command state two times */
if(ptChannel->fIsSysDevice)
{
/* This is the system device */
HIL_DPM_SYSTEM_CHANNEL_T* ptSysChannel = (HIL_DPM_SYSTEM_CHANNEL_T*)ptChannel->pbDPMChannelStart;
if ((ptChannel->usNetxFlags ^ ptChannel->usHostFlags) & NSF_NETX_COS_CMD)
{
ulNewCOSFlags = LE32_TO_HOST(HWIF_READ32(ptDevInstance, ptSysChannel->tSystemState.ulSystemCOS)); /* Read actual COS flags */
usCOSAckBitMask = HSF_NETX_COS_ACK;
}
} else if(NULL != ptChannel->ptCommonStatusBlock)
{
/* This is a communication channel */
if ((ptChannel->usNetxFlags ^ ptChannel->usHostFlags) & NCF_NETX_COS_CMD)
{
ulNewCOSFlags = LE32_TO_HOST(HWIF_READ32(ptDevInstance, ptChannel->ptCommonStatusBlock->ulCommunicationCOS)); /* Read actual COS flags */
usCOSAckBitMask = HCF_NETX_COS_ACK;
}
}
if (usCOSAckBitMask)
{
/* Read the flags and acknowledge */
if(ptChannel->ulDeviceCOSFlags != ulNewCOSFlags)
{
ptChannel->ulDeviceCOSFlagsChanged = ptChannel->ulDeviceCOSFlags ^ ulNewCOSFlags;
ptChannel->ulDeviceCOSFlags = ulNewCOSFlags;
}
DEV_ToggleBit(ptChannel, usCOSAckBitMask);
}
/* Unlock Handshake Cell and COS flag accesses */
if(fLockNeeded)
OS_LeaveLock(ptChannel->pvLock);
}
/*****************************************************************************/
/*! Wait for NOT READY in poll mode
* \param ptChannel Channel instance to check
* \param ulTimeout Wait time
* \return 1 if channel is NOT ready */
/*****************************************************************************/
int DEV_WaitForNotReady_Poll(PCHANNELINSTANCE ptChannel, uint32_t ulTimeout)
{
/* Poll for Ready bit */
int iActualState = 0;
uint32_t ulDiffTime = 0L;
int32_t lStartTime = (int32_t)OS_GetMilliSecCounter();
/* We do nothing without a timeout */
if( ulTimeout == 0)
return iActualState;
/* Check which READY to use */
if(ptChannel->fIsSysDevice)
{
/* This is the system channel which will reset the whole card */
do
{
/* Check if firmware is READY because we need the DPM Layout */
DEVICEINSTANCE* ptDevInstance = (DEVICEINSTANCE*)ptChannel->pvDeviceInstance;
if( (LE32_TO_HOST(HWIF_READ32(ptChannel->pvDeviceInstance, ptDevInstance->tSystemDevice.ptHandshakeCell->ulValue)) == CIFX_DPM_INVALID_CONTENT) ||
(LE32_TO_HOST(HWIF_READ32(ptChannel->pvDeviceInstance, ptDevInstance->tSystemDevice.ptHandshakeCell->ulValue)) == CIFX_DPM_NO_MEMORY_ASSIGNED) ||
(0 == (HWIF_READ8(ptChannel->pvDeviceInstance, ptDevInstance->tSystemDevice.ptHandshakeCell->t8Bit.bNetxFlags) & NSF_READY)) )
{
/* Card is not ready anymore */
iActualState = 1;
break;
}
/* Check time */
ulDiffTime = OS_GetMilliSecCounter() - lStartTime;
OS_Sleep(0);
} while (ulDiffTime < ulTimeout);
} else
{
/* This is a communication channel which is restarted */
do
{
if( (LE32_TO_HOST(HWIF_READ32(ptChannel->pvDeviceInstance, ptChannel->ptCommonStatusBlock->ulCommunicationCOS)) == CIFX_DPM_INVALID_CONTENT) ||
(LE32_TO_HOST(HWIF_READ32(ptChannel->pvDeviceInstance, ptChannel->ptCommonStatusBlock->ulCommunicationCOS)) == CIFX_DPM_NO_MEMORY_ASSIGNED) ||
(!DEV_IsReady(ptChannel)) )
{
/* Channel is not READY anymore */
iActualState = 1;
break;
}
/* Check time */
ulDiffTime = OS_GetMilliSecCounter() - lStartTime;
/* Wait until firmware is down */
OS_Sleep(1);
} while (ulDiffTime < ulTimeout);
}
return iActualState;
}
/*****************************************************************************/
/*! Wait for READY in poll mode
* \param ptChannel Channel instance to check
* \param ulTimeout Wait time
* \return 1 if channel is ready */
/*****************************************************************************/
int DEV_WaitForReady_Poll(PCHANNELINSTANCE ptChannel, uint32_t ulTimeout)
{
/* Poll for Ready bit */
int iActualState = 0;
uint32_t ulDiffTime = 0L;
int32_t lStartTime = (int32_t)OS_GetMilliSecCounter();
/* We do nothing without a timeout */
if( ulTimeout == 0)
return iActualState;
/* Check which READY to use */
if(ptChannel->fIsSysDevice)
{
/* This is the system channel of the whole card */
/* Wait until firmware is running */
OS_Sleep( 10);
do
{
DEVICEINSTANCE* ptDevInstance = (DEVICEINSTANCE*)ptChannel->pvDeviceInstance;
char szCookie[5] = {0};
/* Read the DPM cookie */
HWIF_READN(ptDevInstance, szCookie, ptDevInstance->pbDPM, 4);
/* We need to check for a valid cookie */
if ( (0 == OS_Strcmp( szCookie, CIFX_DPMSIGNATURE_BSL_STR)) ||
(0 == OS_Strcmp( szCookie, CIFX_DPMSIGNATURE_FW_STR)) )
{
/* Check if firmware is READY because we need the DPM Layout */
if( (LE32_TO_HOST(HWIF_READ32(ptChannel->pvDeviceInstance, ptDevInstance->tSystemDevice.ptHandshakeCell->ulValue)) != CIFX_DPM_INVALID_CONTENT) &&
(LE32_TO_HOST(HWIF_READ32(ptChannel->pvDeviceInstance, ptDevInstance->tSystemDevice.ptHandshakeCell->ulValue)) != CIFX_DPM_NO_MEMORY_ASSIGNED) )
{
/* Check if firmware is READY because we need the DPM Layout */
if(HWIF_READ8(ptChannel->pvDeviceInstance, ptDevInstance->tSystemDevice.ptHandshakeCell->t8Bit.bNetxFlags) & NSF_READY)
{
DEV_ReadHostFlags(&ptDevInstance->tSystemDevice, 0);
iActualState = 1;
break;
}
}
}
ulDiffTime = OS_GetMilliSecCounter() - lStartTime;
/* Wait until firmware is running */
OS_Sleep(1);
} while ( ulDiffTime < ulTimeout);
} else
{
/* This is a communication channel which is restarted */
/* Check if this is a real channel (not for bootloader */
if( ptChannel->fIsChannel)
{
do
{
/* Wait until the channel is running */
OS_Sleep( 1);
/* Wait for READY */
if( DEV_IsReady(ptChannel))
{
DEV_ReadHostFlags(ptChannel, 0);
iActualState = 1;
break;
}
ulDiffTime = OS_GetMilliSecCounter() - lStartTime;
} while ( ulDiffTime < ulTimeout);
}
}
return iActualState;
}
/*****************************************************************************/
/*! Wait for NOT RUNNING in poll mode
* \param ptChannel Channel instance to check
* \param ulTimeout Wait time
* \return 1 if channel is NOT running */
/*****************************************************************************/
int DEV_WaitForNotRunning_Poll(PCHANNELINSTANCE ptChannel, uint32_t ulTimeout)
{
/* Poll for Ready bit */
int iActualState = 1;
uint32_t ulDiffTime = 0L;
int32_t lStartTime = (int32_t)OS_GetMilliSecCounter();
/* We not processing a system channel */
if(ptChannel->fIsSysDevice)
return iActualState;
/* Check user timeout */
if( 0 == ulTimeout)
{
if( DEV_IsRunning(ptChannel))
iActualState = 0;
} else
{
/* User wants to wait */
while(DEV_IsRunning(ptChannel))
{
/* Check for timeout */
ulDiffTime = OS_GetMilliSecCounter() - lStartTime;
if(ulDiffTime > ulTimeout)
{
iActualState = 0;
break;
}
OS_Sleep(1);
}
}
return iActualState;
}
/*****************************************************************************/
/*! Wait for RUNNING in poll mode
* \param ptChannel Channel instance to check
* \param ulTimeout Wait time
* \return 1 if channel is RUNNING */
/*****************************************************************************/
int DEV_WaitForRunning_Poll(PCHANNELINSTANCE ptChannel, uint32_t ulTimeout)
{
/* Poll for Ready bit */
int iActualState = 1;
uint32_t ulDiffTime = 0L;
int32_t lStartTime = (int32_t)OS_GetMilliSecCounter();
/* We not processing a system channel, so always return a valid state */
if(ptChannel->fIsSysDevice)
return iActualState;
/* Check user timeout */
if( 0 == ulTimeout)
{
/* Just return the actual state */
iActualState = DEV_IsRunning(ptChannel);
} else
{
/* User wants to wait */
while(!DEV_IsRunning(ptChannel))
{
/* Check for timeout */
ulDiffTime = OS_GetMilliSecCounter() - lStartTime;
if(ulDiffTime > ulTimeout)
{
iActualState = 0;
break;
}
OS_Sleep(1);
}
}
return iActualState;
}
/*****************************************************************************/
/*! Writes the saved state of the handshake bits to the given channel
* \param ptChannel Channel instance to write bits to */
/*****************************************************************************/
void DEV_WriteHandshakeFlags(PCHANNELINSTANCE ptChannel)
{
if(ptChannel->bHandshakeWidth == HIL_HANDSHAKE_SIZE_8BIT)
{
/* Read 8 Bit handshake */
HWIF_WRITE8(ptChannel->pvDeviceInstance, ptChannel->ptHandshakeCell->t8Bit.bHostFlags, (uint8_t)ptChannel->usHostFlags);
} else
{
/* Read 16 Bit handshake */
HWIF_WRITE16(ptChannel->pvDeviceInstance, ptChannel->ptHandshakeCell->t16Bit.usHostFlags, HOST_TO_LE16(ptChannel->usHostFlags));
}
}
/*****************************************************************************/
/*! Checks if the channel is ready
* \param ptChannel Channel instance to check
* \return 1 if channel is ready */
/*****************************************************************************/
int DEV_IsReady(PCHANNELINSTANCE ptChannel)
{
int iRet = 0;
/* Handshake flags are read on interrupt, so no need to read them here */
if(!((PDEVICEINSTANCE)(ptChannel->pvDeviceInstance))->fIrqEnabled)
DEV_ReadHandshakeFlags(ptChannel, 0, 1);
if(ptChannel->fIsSysDevice)
{
if(ptChannel->usNetxFlags & NSF_READY)
{
iRet = 1;
}
} else
{
if(ptChannel->ulDeviceCOSFlags & HIL_COMM_COS_READY)
{
iRet = 1;
}
}
return iRet;
}
/*****************************************************************************/
/*! Checks if the channel is running
* \param ptChannel Channel instance to check
* \return 1 if channel is ready and running */
/*****************************************************************************/
int DEV_IsRunning(PCHANNELINSTANCE ptChannel)
{
int iRet = 0;
/* Handshake flags are read on interrupt, so no need to read them here */
if(!((PDEVICEINSTANCE)(ptChannel->pvDeviceInstance))->fIrqEnabled)
DEV_ReadHandshakeFlags(ptChannel, 0, 1);
/* only a Communication channel can be running */
if(!ptChannel->fIsSysDevice)
{
if( (ptChannel->ulDeviceCOSFlags & HIL_COMM_COS_READY) &&
(ptChannel->ulDeviceCOSFlags & HIL_COMM_COS_RUN) )
{
iRet = 1;
}
}
return iRet;
}
/*****************************************************************************/
/*! Checks if the channel is communicating
* \param ptChannel Channel instance to check
* \param plError CIFX_NO_ERROR on successful read
* \return 1 if channel is communicating */
/*****************************************************************************/
int DEV_IsCommunicating(PCHANNELINSTANCE ptChannel, int32_t* plError)
{
int iRet = 0;
/* Only communication channels are allowed */
if( ptChannel->fIsSysDevice)
{
*plError = CIFX_INVALID_HANDLE;
/* Handshake flags are read during DEV_IsReady() */
}else if( !DEV_IsReady(ptChannel))
{
*plError = CIFX_DEV_NOT_READY;
} else if( !(ptChannel->ulDeviceCOSFlags & HIL_COMM_COS_RUN))
{
*plError = CIFX_DEV_NOT_RUNNING;
} else if ( ptChannel->usNetxFlags & NCF_COMMUNICATING)
{
iRet = 1;
*plError = CIFX_NO_ERROR;
} else
{
*plError = CIFX_DEV_NO_COM_FLAG;
}
return iRet;
}
/*****************************************************************************/
/*! Returns the actual state of the device mailbox
* \param ptChannel Channel instance to check
* \param pulRecvPktCnt Number of pending packets to receive
* \param pulSendPktCnt Number of packets that can be sent to the device
* \return CIFX_NO_ERROR on success */
/*****************************************************************************/
int32_t DEV_GetMBXState(PCHANNELINSTANCE ptChannel, uint32_t* pulRecvPktCnt, uint32_t* pulSendPktCnt)
{
int32_t lRet = CIFX_NO_ERROR;
/* Is Device installed and active */
if(ptChannel->ulOpenCount == 0)
{
lRet = CIFX_DRV_CHANNEL_NOT_INITIALIZED;
/* Check if mailbox is available */
} else if(ptChannel->tRecvMbx.ulRecvMailboxLength == 0)
{
lRet = CIFX_FUNCTION_NOT_AVAILABLE;
/* Check if device is READY */
} else if(!DEV_IsReady(ptChannel))
{
lRet = CIFX_DEV_NOT_READY;
} else
{
/* Get receive MBX state */
*pulRecvPktCnt = LE16_TO_HOST(HWIF_READ16(ptChannel->pvDeviceInstance, ptChannel->tRecvMbx.ptRecvMailboxStart->usWaitingPackages));
/* Get send MBX state */
*pulSendPktCnt = LE16_TO_HOST(HWIF_READ16(ptChannel->pvDeviceInstance, ptChannel->tSendMbx.ptSendMailboxStart->usPackagesAccepted));
}
return lRet;
}
/*****************************************************************************/
/*! Triggers/Disables the cifX application Watchdog
* \param ptChannel Channel instance to trigger watchdog on
* \param ulTriggerCmd CIFX_WATCHDOG_START to start/trigger watchdog,
* CIFX_WATCHDOG_STOP to stop watchdog
* \param pulTriggerValue Last watchdog trigger value
* (informational use only)
* \return CIFX_NO_ERROR on success */
/*****************************************************************************/
int32_t DEV_TriggerWatchdog(PCHANNELINSTANCE ptChannel, uint32_t ulTriggerCmd, uint32_t* pulTriggerValue)
{
int32_t lRet = CIFX_DEV_NOT_RUNNING;
if( (NULL == ptChannel) ||
(NULL == pulTriggerValue) )
return CIFX_INVALID_POINTER;
/* Is Device installed and active */
if(ptChannel->ulOpenCount == 0)
{
/* Init error occurred */
lRet = CIFX_DRV_CHANNEL_NOT_INITIALIZED;
/* Check if device is running */
} else if(DEV_IsRunning(ptChannel))
{
lRet = CIFX_NO_ERROR;
/* Process command */
if(ulTriggerCmd == CIFX_WATCHDOG_START)
{
/* Copy host value to device value */
*pulTriggerValue = LE32_TO_HOST(HWIF_READ32(ptChannel->pvDeviceInstance, ptChannel->ptCommonStatusBlock->ulHostWatchdog));
HWIF_WRITE32(ptChannel->pvDeviceInstance, ptChannel->ptControlBlock->ulDeviceWatchdog, HOST_TO_LE32(*pulTriggerValue));
} else if(ulTriggerCmd == CIFX_WATCHDOG_STOP)
{
/* Stop watchdog function */
HWIF_WRITE32(ptChannel->pvDeviceInstance, ptChannel->ptControlBlock->ulDeviceWatchdog, 0);
*pulTriggerValue = 0;
} else
{
/* Unknown command */
lRet = CIFX_INVALID_COMMAND;
}
}
return lRet;
}
/*****************************************************************************/
/*! Handle the application BUS state COS flag
* \param ptChannel Channel instance
* \param ulCmd new state to set (CIFX_BUS_STATE_ON / CIFX_BUS_STATE_OFF)
* \param pulState Buffer to store actual state
* \param ulTimeout timeout to wait for communication to start/stop
* \return CIFX_NO_ERROR on success */
/*****************************************************************************/
int32_t DEV_BusState(PCHANNELINSTANCE ptChannel, uint32_t ulCmd, uint32_t* pulState, uint32_t ulTimeout)
{
int32_t lRet = CIFX_NO_ERROR;
if( NULL == pulState) return CIFX_INVALID_POINTER;
/* Read actual BUS state */
*pulState = (LE32_TO_HOST(HWIF_READ32(ptChannel->pvDeviceInstance, ptChannel->ptCommonStatusBlock->ulCommunicationCOS)) & HIL_COMM_COS_BUS_ON) ? CIFX_BUS_STATE_ON : CIFX_BUS_STATE_OFF;
switch (ulCmd)
{
case CIFX_BUS_STATE_ON:
{
/* Check if the BUS is already ON */
(void)DEV_IsCommunicating(ptChannel, &lRet); /* lRet evaluated */
if( !*pulState &&
(CIFX_DEV_NO_COM_FLAG == lRet) )
{
/* BUS is OFF */
int32_t lTemp = DEV_DoHostCOSChange(ptChannel,
HIL_APP_COS_BUS_ON | HIL_APP_COS_BUS_ON_ENABLE, /* set mask */
0, /* clear mask */
HIL_APP_COS_BUS_ON_ENABLE, /* post clear mask */
CIFX_DEV_BUS_STATE_ON_TIMEOUT,
ulTimeout);
/* Only update return value, if handshaking did not succeed, so
we can wait for COM_BIT below */
if(lTemp != CIFX_NO_ERROR)
lRet = lTemp;
}
if(ulTimeout && (CIFX_DEV_NO_COM_FLAG == lRet))
{
/* Wait for Bus is active if user want it */
if (DEV_WaitForBitState( ptChannel, NCF_COMMUNICATING_BIT_NO, HIL_FLAGS_SET, ulTimeout))
{
lRet = CIFX_NO_ERROR;
} else
{
/* Return Error */
lRet = CIFX_DEV_NO_COM_FLAG;
}
*pulState = (LE32_TO_HOST(HWIF_READ32(ptChannel->pvDeviceInstance, ptChannel->ptCommonStatusBlock->ulCommunicationCOS)) & HIL_COMM_COS_BUS_ON) ?
CIFX_BUS_STATE_ON : CIFX_BUS_STATE_OFF;
}
}
break;
case CIFX_BUS_STATE_OFF:
{
int fWaitCommFlag = 1;
/* Check if the BUS is off */
if(!DEV_IsReady(ptChannel))
{
lRet = CIFX_DEV_NOT_READY;
fWaitCommFlag = 0;
} else if(*pulState || DEV_IsCommunicating(ptChannel, &lRet))
{
/* BUS is ON */
lRet = DEV_DoHostCOSChange(ptChannel,
HIL_APP_COS_BUS_ON_ENABLE, /* set mask */
HIL_APP_COS_BUS_ON, /* clear mask */
HIL_APP_COS_BUS_ON_ENABLE, /* post clear mask */
CIFX_DEV_BUS_STATE_OFF_TIMEOUT,
ulTimeout);
if(CIFX_DEV_FUNCTION_FAILED == lRet)
{
fWaitCommFlag = 0;
}
}
/* Check if user wants to wait for the BUS state */
if(ulTimeout && fWaitCommFlag)
{
/* Wait until BUS is OFF */
if(DEV_WaitForBitState(ptChannel, NCF_COMMUNICATING_BIT_NO, HIL_FLAGS_CLEAR, ulTimeout))
{
/* Set actual state */
lRet = CIFX_NO_ERROR;
} else
{
/* Return error */
lRet = CIFX_DEV_BUS_STATE_OFF_TIMEOUT;
}
*pulState = (LE32_TO_HOST(HWIF_READ32(ptChannel->pvDeviceInstance, ptChannel->ptCommonStatusBlock->ulCommunicationCOS)) & HIL_COMM_COS_BUS_ON) ?
CIFX_BUS_STATE_ON : CIFX_BUS_STATE_OFF;
}
}
break;
case CIFX_BUS_STATE_GETSTATE:
{
/* Update the COS flags */
if (0 == DEV_IsRunning(ptChannel))
lRet = CIFX_DEV_NOT_RUNNING;
}
break;
default:
/* Unknown command */
lRet = CIFX_INVALID_COMMAND;
break;
}
return lRet;
}
/*****************************************************************************/
/*! Read the application COS flag state
* \param ptChannel Channel instance
* \param pulState returned host state (CIFX_HOST_STATE_READY /
* CIFX_HOST_STATE_NOT_READY)
* \return CIFX_NO_ERROR on success, or CIFX_DEV_NOT_READY */
/*****************************************************************************/
int32_t DEV_GetHostState(PCHANNELINSTANCE ptChannel, uint32_t* pulState)
{
/* Don't return any state if card is not ready */
if(!DEV_IsReady(ptChannel))
return CIFX_DEV_NOT_READY;
*pulState = (ptChannel->ulHostCOSFlags & HIL_APP_COS_APPLICATION_READY)? CIFX_HOST_STATE_READY : CIFX_HOST_STATE_NOT_READY;
return CIFX_NO_ERROR;
}
/*****************************************************************************/
/*! Set the application ready COS flag
* \param ptChannel Channel instance
* \param ulNewState new state to set (CIFX_HOST_STATE_READY /
* CIFX_HOST_STATE_NOT_READY)
* \param ulTimeout timeout to wait for communication to start/stop
* \return CIFX_NO_ERROR on success */
/*****************************************************************************/
int32_t DEV_SetHostState(PCHANNELINSTANCE ptChannel, uint32_t ulNewState, uint32_t ulTimeout)
{
int32_t lRet = CIFX_NO_ERROR;
UNREFERENCED_PARAMETER(ulTimeout); /* prevent compiler warnings */
/* Don't set host state if card is not configured */
if(!DEV_IsReady(ptChannel))
return CIFX_DEV_NOT_READY;
switch(ulNewState)
{
case CIFX_HOST_STATE_NOT_READY:
/* Check user timeout */
if( 0 == ulTimeout)
{
/* Just set the state */
/* Lock flag access */
OS_EnterLock(ptChannel->pvLock);
/* Clear the application ready flag */
ptChannel->ulHostCOSFlags &= ~HIL_APP_COS_APPLICATION_READY;
/* Unlock flag access */
OS_LeaveLock(ptChannel->pvLock);
} else
{
lRet = DEV_DoHostCOSChange(ptChannel,
0, /* set mask */
HIL_APP_COS_APPLICATION_READY, /* clear mask */
0, /* post clear mask */
CIFX_DEV_HOST_STATE_CLEAR_TIMEOUT,
ulTimeout);
}
break;
case CIFX_HOST_STATE_READY:
/* Check user timeout */
if( 0 == ulTimeout)
{
/* Just set the state */
/* Lock flag access */
OS_EnterLock(ptChannel->pvLock);
/* Clear the application ready flag */
ptChannel->ulHostCOSFlags |= HIL_APP_COS_APPLICATION_READY;
/* Unlock flag access */
OS_LeaveLock(ptChannel->pvLock);
} else
{
lRet = DEV_DoHostCOSChange(ptChannel,
HIL_APP_COS_APPLICATION_READY, /* set mask */
0, /* clear mask */
0, /* post clear mask */
CIFX_DEV_HOST_STATE_SET_TIMEOUT,
ulTimeout);
}
break;
default:
lRet = CIFX_INVALID_COMMAND;
break;
}
return lRet;
}
/*****************************************************************************/
/*! Read/Write Block
* \param ptChannel Channel Instance
* \param pvBlock Pointer to the block to copy
* \param ulOffset Start offset to copy from/to
* \param ulBlockLen Total Length of the Block
* \param pvDest Source/Destination buffer
* \param ulDestLen Length of the Source/Destination Buffer
* \param ulCmd CIFX_CMD_READ_DATA/CIFX_CMD_WRITE_DATA
* \param fWriteAllowed !=0 if Write is allowed to the Block
* \return CIFX_NO_ERROR on success */
/*****************************************************************************/
int32_t DEV_ReadWriteBlock(PCHANNELINSTANCE ptChannel, void* pvBlock, uint32_t ulOffset, uint32_t ulBlockLen, void* pvDest, uint32_t ulDestLen, uint32_t ulCmd, int fWriteAllowed)
{
int32_t lRet = CIFX_NO_ERROR;
if( (ulOffset + ulDestLen) > ulBlockLen)
return CIFX_INVALID_ACCESS_SIZE; /* Size too long */
/* Process the state block area command */
switch (ulCmd)
{
case CIFX_CMD_WRITE_DATA:
if(fWriteAllowed)
{
/* Write control block */
HWIF_WRITEN( ptChannel->pvDeviceInstance,
((uint8_t*)pvBlock) + ulOffset,
(uint8_t *)pvDest,
ulDestLen);
} else
{
lRet = CIFX_INVALID_COMMAND;
}
break;
case CIFX_CMD_READ_DATA:
/* It is allowed to read the control block back */
HWIF_READN( ptChannel->pvDeviceInstance,
(uint8_t *)pvDest,
((uint8_t*)pvBlock) + ulOffset,
ulDestLen);
break;
default:
/* Unknown command */
lRet = CIFX_INVALID_COMMAND;
break;
} /* end switch */
/* Always deliver back system errors */
if( (CIFX_NO_ERROR == lRet) &&
!DEV_IsRunning(ptChannel) )
lRet = CIFX_DEV_NOT_RUNNING;
return lRet;
}
/*****************************************************************************/
/*! Returns the state of the given handshake bit/mask
* \param ptChannel Channel instance
* \param ulBitMsk Bitmask to check for
* \return HIL_FLAGS_EQUAL/HIL_FLAGS_NOT_EQUAL */
/*****************************************************************************/
uint8_t DEV_GetHandshakeBitState(PCHANNELINSTANCE ptChannel, uint32_t ulBitMsk)
{
uint8_t bRet = HIL_FLAGS_EQUAL;
/* Handshake flags are read on interrupt, so no need to read them here */
if(!((PDEVICEINSTANCE)(ptChannel->pvDeviceInstance))->fIrqEnabled)
DEV_ReadHandshakeFlags(ptChannel, 0, 1);
if((ptChannel->usHostFlags ^ ptChannel->usNetxFlags) & ulBitMsk)
bRet = HIL_FLAGS_NOT_EQUAL;
return bRet;
}
/*****************************************************************************/
/*! Check the COS flags on this device
* \param ptDevInstance Device instance */
/*****************************************************************************/
void DEV_CheckCOSFlags(PDEVICEINSTANCE ptDevInstance)
{
/* Note: We assume, we only get here in polling mode */
uint32_t ulChannel;
if(!OS_WaitMutex(ptDevInstance->tSystemDevice.pvInitMutex, 0))
{
if(g_ulTraceLevel & TRACE_LEVEL_DEBUG)
{
USER_Trace(ptDevInstance,
TRACE_LEVEL_DEBUG,
"DEV_CheckCOSFlags(): Skipping COS Flag handling. Device is in system reset!");
}
} else
{
/* Evaluate COS bits on Communication channels */
for(ulChannel = 0; ulChannel < ptDevInstance->ulCommChannelCount; ulChannel++)
{
PCHANNELINSTANCE ptChannel = ptDevInstance->pptCommChannels[ulChannel];
uint32_t ulCOSChanged = 0;
/* Check if we have an valid channel (not for the bootloader) */
if( (0 == ptChannel->ptControlBlock) ||
(0 == ptChannel->ptCommonStatusBlock) )
return;
if(!OS_WaitMutex(ptChannel->pvInitMutex, 0))
{
if(g_ulTraceLevel & TRACE_LEVEL_DEBUG)
{
USER_Trace(ptDevInstance,
TRACE_LEVEL_DEBUG,
"DEV_CheckCOSFlags(): Skipping Channel #%d, which is currently initializing!",
ulChannel);
}
} else
{
/*------------------------------------------*/
/* Process our own COS flags */
/*------------------------------------------*/
if( ptChannel->ulHostCOSFlags != LE32_TO_HOST(HWIF_READ32(ptDevInstance, ptChannel->ptControlBlock->ulApplicationCOS)))
{
/* We have to update our COS flags */
/* Check if we can signal a new COS state */
if( DEV_WaitForBitState(ptChannel, HCF_HOST_COS_CMD_BIT_NO, HIL_FLAGS_EQUAL, 0))
{
/* Lock flag access */
OS_EnterLock(ptChannel->pvLock);
/* Update flags */
HWIF_WRITE32(ptDevInstance, ptChannel->ptControlBlock->ulApplicationCOS, HOST_TO_LE32(ptChannel->ulHostCOSFlags));
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);
OS_LeaveLock(ptChannel->pvLock);
}
}
/*------------------------------------------*/
/* Process now Hardware COS flags */
/*------------------------------------------*/
/* Handshake flags are read on interrupt, so no need to read them here */
if(!((PDEVICEINSTANCE)(ptChannel->pvDeviceInstance))->fIrqEnabled)
DEV_ReadHandshakeFlags(ptChannel, 0, 1);
/* Get the changed COS flags bitmask */
ulCOSChanged = ptChannel->ulDeviceCOSFlagsChanged;
if(ulCOSChanged != 0)
{
/* TODO: Signal change event */
}
#if 0
if(ulCOSChanged & HIL_COMM_COS_RESTART_REQUIRED)
{
/* Firmware requests a restart */
}
if(ulCOSChanged & HIL_COMM_COS_CONFIG_AVAIL)
{
/* Configuration changed state */
}
if(ulCOSChanged & HIL_COMM_COS_CONFIG_LOCKED)
{
/* Configuration locked */
}
#endif
/* We've processed all pending COS flags on this channel */
ptChannel->ulDeviceCOSFlagsChanged &= ~ulCOSChanged;
OS_ReleaseMutex(ptChannel->pvInitMutex);
}
}
OS_ReleaseMutex(ptDevInstance->tSystemDevice.pvInitMutex);
}
}
/*****************************************************************************/
/*! Performs a channel initialization
* \param ptChannel Channel instance
* \param ulTimeout Timeout to wait for channel to become READY
* \return CIFX_NO_ERROR on success */
/*****************************************************************************/
int32_t DEV_DoChannelInit(PCHANNELINSTANCE ptChannel, uint32_t ulTimeout)
{
int32_t lRet = CIFX_NO_ERROR;
PDEVICEINSTANCE ptDevInst = (PDEVICEINSTANCE)ptChannel->pvDeviceInstance;
int fRunning = DEV_IsRunning(ptChannel);
if(!OS_WaitMutex(ptChannel->pvInitMutex, CIFX_TO_WAIT_COS_CMD))
{
/* This should only happen, if the DEV_CheckCOSFlags function is still busy checking
for COS changed on this channel */
if(g_ulTraceLevel & TRACE_LEVEL_ERROR)
{
USER_Trace(ptDevInst,
TRACE_LEVEL_ERROR,
"DEV_DoChannelInit(): Error getting Mutex. Access to device COS flags is locked!");
}
lRet = CIFX_DRV_CMD_ACTIVE;
} else
{
lRet = DEV_DoHostCOSChange(ptChannel,
HIL_APP_COS_INITIALIZATION | HIL_APP_COS_INITIALIZATION_ENABLE, /* set mask */
0, /* clear mask */
HIL_APP_COS_INITIALIZATION_ENABLE, /* post clear mask */
CIFX_DEV_FUNCTION_FAILED,
CIFX_TO_WAIT_COS_CMD);
/* Signal Initialisation */
if(CIFX_NO_ERROR == lRet)
{
/* The card has recognized the initialisation, so we can wait until the card has processed it*/
/* Card was running before, so wait for running flag to vanish */
if(fRunning)
{
/* Check if the Firmware has removed it's running flag,
or if it's set now, and it was changed during last COS */
if( (0 == (ptChannel->ulDeviceCOSFlags & HIL_COMM_COS_RUN)) ||
( (ptChannel->ulDeviceCOSFlags & HIL_COMM_COS_RUN) &&
(ptChannel->ulDeviceCOSFlagsChanged & HIL_COMM_COS_RUN) ) )
{
/* FW already removed it's RUN Flag during Channel Init command sequence. No need to
wait for running flag to vanish */
if(g_ulTraceLevel & TRACE_LEVEL_DEBUG)
{
USER_Trace(ptDevInst,
TRACE_LEVEL_DEBUG,
"DEV_DoChannelInit(): Firmware removed HIL_COMM_COS_RUN early! Skipping wait for NotRunning-State");
}
} else if( !DEV_WaitForNotRunning_Poll( ptChannel, CIFX_TO_WAIT_HW_RESET_ACTIVE))
{
lRet = CIFX_DEV_RESET_TIMEOUT;
if(g_ulTraceLevel & TRACE_LEVEL_ERROR)
{
USER_Trace(ptDevInst,
TRACE_LEVEL_ERROR,
"DEV_DoChannelInit(): Error waiting for channel to leave running state!");
}
}
}
/* Card is in restart */
if(CIFX_NO_ERROR == lRet)
{
/* Check if user wants to wait until the card is READY again */
/* now wait for the channel and it must be at least READY */
uint32_t ulTempTimeout = ( CIFX_TO_WAIT_HW > ulTimeout) ? ulTimeout : CIFX_TO_WAIT_HW;
if( DEV_WaitForNotReady_Poll( ptChannel, ulTempTimeout) )
{
/* Firmware started after warm start process */
if( 0 != ulTimeout)
{
/* now wait for the channel and it must be at least READY */
if( !DEV_WaitForReady_Poll( ptChannel, ulTimeout) )
{
lRet = CIFX_DEV_NOT_READY;
if(g_ulTraceLevel & TRACE_LEVEL_WARNING)
{
USER_Trace((PDEVICEINSTANCE)(ptChannel->pvDeviceInstance),
TRACE_LEVEL_WARNING,
"DEV_DoChannelInit(): Channel did not enter READY state during timeout!");
}
}
}
}
}
}
OS_ReleaseMutex(ptChannel->pvInitMutex);
}
return lRet;
}
/*****************************************************************************/
/*! Mark device to be in reset state and clear device internal structure for
* reset preparation
* \param ptDevInstance Device instance */
/*****************************************************************************/
static void DEV_Reset_Prepare(PDEVICEINSTANCE ptDevInstance)
{
uint32_t ulIdx = 0;
/* Reset is now active and DSR will ignore all incoming interrupts from now on */
ptDevInstance->fResetActive = 1;
/* Zero out all internal flags */
OS_EnterLock(ptDevInstance->tSystemDevice.pvLock);
ptDevInstance->tSystemDevice.usHostFlags = 0;
ptDevInstance->tSystemDevice.usNetxFlags = 0;
OS_LeaveLock(ptDevInstance->tSystemDevice.pvLock);
for ( ulIdx = 0; ulIdx < ptDevInstance->ulCommChannelCount; ulIdx++)
{
OS_EnterLock(ptDevInstance->pptCommChannels[ulIdx]->pvLock);
ptDevInstance->pptCommChannels[ulIdx]->usHostFlags = 0;
ptDevInstance->pptCommChannels[ulIdx]->usNetxFlags = 0;
ptDevInstance->pptCommChannels[ulIdx]->ulDeviceCOSFlags = 0;
ptDevInstance->pptCommChannels[ulIdx]->ulHostCOSFlags = 0;
OS_LeaveLock(ptDevInstance->pptCommChannels[ulIdx]->pvLock);
}
}
/*****************************************************************************/
/*! After reset, re-read the device flags to continue communication
* \param ptDevInstance Device instance */
/*****************************************************************************/
static void DEV_Reset_Finish(PDEVICEINSTANCE ptDevInstance)
{
uint32_t ulIdx = 0;
/* Reset not active anymore */
ptDevInstance->fResetActive = 0;
/* Reset is finished, so we can now update our internal states */
if(ptDevInstance->fIrqEnabled)
{
(void)cifXTKitISRHandler(ptDevInstance,1);
cifXTKitDSRHandler(ptDevInstance);
} else
{
/* Re-Read all handshake flags, as they will have reset */
OS_EnterLock(ptDevInstance->tSystemDevice.pvLock);
DEV_ReadHostFlags( &ptDevInstance->tSystemDevice, 0);
DEV_ReadHandshakeFlags(&ptDevInstance->tSystemDevice, 1, 0);
OS_LeaveLock(ptDevInstance->tSystemDevice.pvLock);
for ( ulIdx = 0; ulIdx < ptDevInstance->ulCommChannelCount; ulIdx++)
{
OS_EnterLock(ptDevInstance->pptCommChannels[ulIdx]->pvLock);
DEV_ReadHostFlags( ptDevInstance->pptCommChannels[ulIdx], 1);
DEV_ReadHandshakeFlags(ptDevInstance->pptCommChannels[ulIdx], 0, 0);
OS_LeaveLock(ptDevInstance->pptCommChannels[ulIdx]->pvLock);
}
}
}
/*****************************************************************************/
/*! Setup device reset and wait until firmware removes READY bit
* \param ptDevInstance Device instance
* \param bHostFlagsChange Host Flags to be set in SystemChannel
* \param fWaitOnDevice Wait on device state if != 0
* \return CIFX_NO_ERROR on success */
/*****************************************************************************/
static int32_t DEV_Reset_Execute(PDEVICEINSTANCE ptDevInstance, uint8_t bHostFlagsChange, uint8_t fWaitOnDevice)
{
PCHANNELINSTANCE ptSysDevice = &ptDevInstance->tSystemDevice;
HIL_DPM_SYSTEM_CHANNEL_T* ptSysChannel = (HIL_DPM_SYSTEM_CHANNEL_T*)ptSysDevice->pbDPMChannelStart;
int32_t lRet = CIFX_NO_ERROR;
uint8_t bHostFlags = HWIF_READ8(ptDevInstance, ptSysDevice->ptHandshakeCell->t8Bit.bHostFlags);
/* Lock flag access */
OS_EnterLock(ptSysDevice->pvLock);
/* Insert the reset cookie */
HWIF_WRITE32(ptDevInstance, ptSysChannel->tSystemControl.ulSystemCommandCOS, HOST_TO_LE32(HIL_SYS_RESET_COOKIE));
/* Activate the Reset */
HWIF_WRITE8(ptDevInstance, ptSysDevice->ptHandshakeCell->t8Bit.bHostFlags, (bHostFlags | bHostFlagsChange));
/* Leave flag access */
OS_LeaveLock(ptSysDevice->pvLock);
if( fWaitOnDevice)
{
/* Wait until card has recognized the reset */
if( !DEV_WaitForNotReady_Poll( ptSysDevice, CIFX_TO_WAIT_HW_RESET_ACTIVE))
lRet = CIFX_DEV_RESET_TIMEOUT;
}
return lRet;
}
/*****************************************************************************/
/*! Performs a system restart on a device and waits for card to get ready again
* \param ptChannel Channel instance (ALWAYS the system channel)
* \param ulTimeout Timeout to wait for device to become ready
* \param ulParam Reset parameter
* \return CIFX_NO_ERROR on success */
/*****************************************************************************/
int32_t DEV_DoSystemStart(PCHANNELINSTANCE ptChannel, uint32_t ulTimeout, uint32_t ulParam )
{
PDEVICEINSTANCE ptDevInstance = (PDEVICEINSTANCE)ptChannel->pvDeviceInstance;
PCHANNELINSTANCE ptSysDevice = &ptDevInstance->tSystemDevice;
HIL_DPM_SYSTEM_CHANNEL_T* ptSysChannel = (HIL_DPM_SYSTEM_CHANNEL_T*)ptSysDevice->pbDPMChannelStart;
uint32_t ulSystemStatus = LE32_TO_HOST(HWIF_READ32(ptDevInstance, ptSysChannel->tSystemState.ulSystemStatus));
int32_t lRet = CIFX_NO_ERROR;
/* Card was running before, so wait for running flag to vanish */
if(!DEV_IsReady(ptSysDevice))
return CIFX_DEV_NOT_READY;
if(!OS_WaitMutex(ptDevInstance->tSystemDevice.pvInitMutex, CIFX_TO_WAIT_COS_CMD))
{
if(g_ulTraceLevel & TRACE_LEVEL_ERROR)
{
USER_Trace(ptDevInstance,
TRACE_LEVEL_ERROR,
"DEV_DoSystemStart(): Error locking access to device!");
}
lRet = CIFX_DRV_INIT_STATE_ERROR;
}else
{
/* Set SystemControl value in the DPM to signal RESET "ONLY SYSTEM CHANNEL" */
/* this is a coldstart and does not use any parameters */
uint32_t ulSystemControl = HIL_SYS_CONTROL_RESET_MODE_COLDSTART | (ulParam & HIL_SYS_CONTROL_RESET_PARAM_FLAG_MASK);
HWIF_WRITE32(ptDevInstance, ptSysChannel->tSystemControl.ulSystemControl, HOST_TO_LE32((ulSystemControl)));
if ( HIL_SYS_STATUS_IDPM == (HIL_SYS_STATUS_IDPM & ulSystemStatus) &&
HIL_SYS_STATUS_APP == (HIL_SYS_STATUS_APP & ulSystemStatus) )
{
/* If we're running with an enabled IDPM and APP CPU, no reset
* will be executed. We just signal the reset state to the COM CPU by using the HSF_RESET flag */
/* Activate the Reset */
/* ATTENTION: Do not wait on the device, because the reset will be handled by the COM-CPU, */
/* and tehrefore the APP CPU has to remove its MCP_CPU_ID_APP0 bit (see netX MCP register). */
lRet = DEV_Reset_Execute(ptDevInstance, HSF_RESET, 0 );
} else
{
/* Prepare reset */
DEV_Reset_Prepare(ptDevInstance);
/* Perform the Reset */
lRet = DEV_Reset_Execute(ptDevInstance, HSF_RESET, 1);
if((CIFX_NO_ERROR != lRet) && (g_ulTraceLevel & TRACE_LEVEL_ERROR))
{
USER_Trace(ptDevInstance,
TRACE_LEVEL_ERROR,
"DEV_DoSystemStart(): Error waiting for device to leave READY state!");
}
/* Now wait for the card to come back */
if(CIFX_NO_ERROR == lRet)
{
/* Prohibit access to possibly uninitialized PCI memory during reset of netX4000 based PCI devices.
Timeout of 1s was communicated to be the upper boundary. */
if( (ptDevInstance->fPCICard) &&
(( eCHIP_TYPE_NETX4000 == ptDevInstance->eChipType) ||
( eCHIP_TYPE_NETX4100 == ptDevInstance->eChipType) ) )
OS_Sleep(1000);
/* now wait for card to become READY */
if( !DEV_WaitForReady_Poll( ptSysDevice, ( 0 == ulTimeout) ? CIFX_TO_WAIT_HW : ulTimeout) )
{
lRet = CIFX_DEV_NOT_READY;
if(g_ulTraceLevel & TRACE_LEVEL_ERROR)
{
USER_Trace(ptDevInstance,
TRACE_LEVEL_ERROR,
"DEV_DoSystemStart(): Error waiting for device to become ready!");
}
}
/* Re-read device handshake flags */
DEV_Reset_Finish(ptDevInstance);
}
/* it is not possible to distinguish between success and failure since do not know the correct state after reset */
/* so write meaningful dpm content into log file, to let the user verify current system state */
if(g_ulTraceLevel & TRACE_LEVEL_DEBUG)
{
char szCookie[5];
HWIF_READN(ptDevInstance, szCookie, ptDevInstance->pbDPM, 4);
/* split messages for better readability */
USER_Trace(ptDevInstance, TRACE_LEVEL_DEBUG, "DEV_DoSystemStart(): (system status after reset)");
USER_Trace(ptDevInstance, TRACE_LEVEL_DEBUG, " -DPM-Cookie : '%02X','%02X','%02X','%02X'",
szCookie[0],
szCookie[1],
szCookie[2],
szCookie[3]);
USER_Trace(ptDevInstance, TRACE_LEVEL_DEBUG, " -System Status : 0x%X",
LE32_TO_HOST(HWIF_READ32(ptDevInstance, ptSysChannel->tSystemState.ulSystemStatus)) );
USER_Trace(ptDevInstance, TRACE_LEVEL_DEBUG, " -System Error : 0x%X",
LE32_TO_HOST(HWIF_READ32(ptDevInstance, ptSysChannel->tSystemState.ulSystemError)) );
USER_Trace(ptDevInstance, TRACE_LEVEL_DEBUG, " -Boot Error : 0x%X",
LE32_TO_HOST(HWIF_READ32(ptDevInstance, ptSysChannel->tSystemState.ulBootError)) );
}
}
OS_ReleaseMutex(ptDevInstance->tSystemDevice.pvInitMutex);
}
return lRet;
}
/*****************************************************************************/
/*! Performs a system bootstart on a device and wait for card to get ready again
* \param ptChannel Channel instance (ALWAYS the system channel)
* \param ulTimeout Timeout to wait for device to become ready
* \param ulParam Reset parameter
* \return CIFX_NO_ERROR on success */
/*****************************************************************************/
int32_t DEV_DoSystemBootstart(PCHANNELINSTANCE ptChannel, uint32_t ulTimeout, uint32_t ulParam)
{
PDEVICEINSTANCE ptDevInstance = (PDEVICEINSTANCE)ptChannel->pvDeviceInstance;
PCHANNELINSTANCE ptSysDevice = &ptDevInstance->tSystemDevice;
HIL_DPM_SYSTEM_CHANNEL_T* ptSysChannel = (HIL_DPM_SYSTEM_CHANNEL_T*)ptSysDevice->pbDPMChannelStart;
uint32_t ulSystemStatus = LE32_TO_HOST(HWIF_READ32(ptDevInstance, ptSysChannel->tSystemState.ulSystemStatus));
int32_t lRet = CIFX_NO_ERROR;
/* Card was running before, so wait for running flag to vanish */
if(!DEV_IsReady(ptSysDevice))
return CIFX_DEV_NOT_READY;
if(!OS_WaitMutex(ptDevInstance->tSystemDevice.pvInitMutex, CIFX_TO_WAIT_COS_CMD))
{
if(g_ulTraceLevel & TRACE_LEVEL_ERROR)
{
USER_Trace(ptDevInstance,
TRACE_LEVEL_ERROR,
"DEV_DoSystemBootstart(): Error locking access to device!");
}
lRet = CIFX_DRV_INIT_STATE_ERROR;
} else
{
/* Signal BOOTSTART RESET "ONLY SYSTEM CHANNEL" */
/* Write the reset mode to DPM */
uint32_t ulSystemControl = HIL_SYS_CONTROL_RESET_MODE_BOOTSTART | (ulParam & HIL_SYS_CONTROL_RESET_PARAM_FLAG_MASK);
HWIF_WRITE32(ptDevInstance, ptSysChannel->tSystemControl.ulSystemControl, HOST_TO_LE32((ulSystemControl)));
if ( HIL_SYS_STATUS_IDPM == (HIL_SYS_STATUS_IDPM & ulSystemStatus) &&
HIL_SYS_STATUS_APP == (HIL_SYS_STATUS_APP & ulSystemStatus) )
{
/* If we're running with an enabled IDPM and APP CPU, no reset
* will be executed. We just signal the reset state to the COM CPU by using the HSF_RESET flag */
/* Activate the Reset (including BOOTSTART bit) */
/* ATTENTION: Do not wait on the device, because the reset will be handled by the COM-CPU, */
/* and tehrefore the APP CPU has to remove its MCP_CPU_ID_APP0 bit (see netX MCP register). */
lRet = DEV_Reset_Execute(ptDevInstance, (uint8_t)(HSF_RESET | HSF_BOOTSTART), 0);
} else
{
/* Prepare reset */
DEV_Reset_Prepare(ptDevInstance);
/* Perform the Reset (including BOOTSTART bit) */
lRet = DEV_Reset_Execute(ptDevInstance, (uint8_t)(HSF_RESET | HSF_BOOTSTART), 1);
if((CIFX_NO_ERROR != lRet) && (g_ulTraceLevel & TRACE_LEVEL_ERROR))
{
USER_Trace(ptDevInstance,
TRACE_LEVEL_ERROR,
"DEV_DoSystemBootstart(): Error waiting for device to leave READY state!");
}
/* Now wait for the card to come back */
if(CIFX_NO_ERROR == lRet)
{
/* Prohibit access to possibly uninitialized PCI memory during reset of netX4000 based PCI devices.
Timeout of 1s was communicated to be the upper boundary. */
if( (ptDevInstance->fPCICard) &&
(( eCHIP_TYPE_NETX4000 == ptDevInstance->eChipType) ||
( eCHIP_TYPE_NETX4100 == ptDevInstance->eChipType) ) )
OS_Sleep(1000);
/* now wait for card to become READY */
if( !DEV_WaitForReady_Poll( ptSysDevice, ( 0 == ulTimeout) ? CIFX_TO_WAIT_HW : ulTimeout) )
{
lRet = CIFX_DEV_NOT_READY;
if(g_ulTraceLevel & TRACE_LEVEL_ERROR)
{
USER_Trace(ptDevInstance,
TRACE_LEVEL_ERROR,
"DEV_DoSystemBootstart(): Error waiting for device to become ready!");
}
} else
{
/* Check if the Bootloader is running */
char szCookie[5] = {0};
/* Read the DPM cookie */
HWIF_READN(ptDevInstance, szCookie, ptDevInstance->pbDPM, 4);
/* on DPM cards we need to check the for a valid cookie */
if (0 != OS_Strcmp( szCookie, CIFX_DPMSIGNATURE_BSL_STR))
{
/* Failed to set the device into boot mode */
if(g_ulTraceLevel & TRACE_LEVEL_ERROR)
{
USER_Trace(ptDevInstance,
TRACE_LEVEL_ERROR,
"DEV_DoSystemBootstart(): Error setting card into boot mode!");
}
lRet = CIFX_DEV_FUNCTION_FAILED;
}
}
/* Re-read device handshake flags */
DEV_Reset_Finish(ptDevInstance);
}
}
OS_ReleaseMutex(ptDevInstance->tSystemDevice.pvInitMutex);
}
return lRet;
}
/*****************************************************************************/
/*! Performs update start on a device and waits for card to get ready again
* \param ptChannel Channel instance (ALWAYS the system channel)
* \param ulTimeout Timeout to wait for device to become ready
* \param ulParam Reset parameter
* \return CIFX_NO_ERROR on success */
/*****************************************************************************/
int32_t DEV_DoUpdateStart(PCHANNELINSTANCE ptChannel, uint32_t ulTimeout, uint32_t ulParam)
{
PDEVICEINSTANCE ptDevInstance = (PDEVICEINSTANCE)ptChannel->pvDeviceInstance;
PCHANNELINSTANCE ptSysDevice = &ptDevInstance->tSystemDevice;
HIL_DPM_SYSTEM_CHANNEL_T* ptSysChannel = (HIL_DPM_SYSTEM_CHANNEL_T*)ptSysDevice->pbDPMChannelStart;
uint32_t ulSystemStatus = LE32_TO_HOST(HWIF_READ32(ptDevInstance, ptSysChannel->tSystemState.ulSystemStatus));
int32_t lRet = CIFX_NO_ERROR;
/* Card was running before, so wait for running flag to vanish */
if(!DEV_IsReady(ptSysDevice))
return CIFX_DEV_NOT_READY;
if(!OS_WaitMutex(ptDevInstance->tSystemDevice.pvInitMutex, CIFX_TO_WAIT_COS_CMD))
{
if(g_ulTraceLevel & TRACE_LEVEL_ERROR)
{
USER_Trace(ptDevInstance,
TRACE_LEVEL_ERROR,
"DEV_DoUpdateStart(): Error locking access to device!");
}
lRet = CIFX_DRV_INIT_STATE_ERROR;
}else
{
/* Signal UPDATESTART RESET "ONLY SYSTEM CHANNEL" */
/* Write the reset mode to DPM */
uint32_t ulSystemControl = HIL_SYS_CONTROL_RESET_MODE_UPDATESTART | (ulParam & HIL_SYS_CONTROL_RESET_PARAM_FLAG_MASK);
HWIF_WRITE32(ptDevInstance, ptSysChannel->tSystemControl.ulSystemControl, HOST_TO_LE32((ulSystemControl)));
if ( HIL_SYS_STATUS_IDPM == (HIL_SYS_STATUS_IDPM & ulSystemStatus) &&
HIL_SYS_STATUS_APP == (HIL_SYS_STATUS_APP & ulSystemStatus) )
{
/* If we're running with an enabled IDPM and APP CPU, no reset
* will be executed. We just signal the reset state to the COM CPU by using the HSF_RESET flag */
/* Activate the Reset */
/* ATTENTION: Do not wait on the device, because the reset will be handled by the COM-CPU, */
/* and tehrefore the APP CPU has to remove its MCP_CPU_ID_APP0 bit (see netX MCP register). */
lRet = DEV_Reset_Execute(ptDevInstance, HSF_RESET, 0);
} else
{
char szCookie[5] = {0};
/* Prepare reset */
DEV_Reset_Prepare(ptDevInstance);
/* Perform the Reset */
lRet = DEV_Reset_Execute(ptDevInstance, HSF_RESET, 1);
if(((CIFX_NO_ERROR != lRet)) && (g_ulTraceLevel & TRACE_LEVEL_ERROR))
{
USER_Trace(ptDevInstance,
TRACE_LEVEL_ERROR,
"DEV_DoUpdateStart(): Error waiting for device to leave READY state!");
}
/* Now wait for the card to come back */
if(CIFX_NO_ERROR == lRet)
{
/* Prohibit access to possibly uninitialized PCI memory during reset of netX4000 based PCI devices.
Timeout of 1s was communicated to be the upper boundary. */
if( (ptDevInstance->fPCICard) &&
(( eCHIP_TYPE_NETX4000 == ptDevInstance->eChipType) ||
( eCHIP_TYPE_NETX4100 == ptDevInstance->eChipType) ) )
OS_Sleep(1000);
/* now wait for card to become READY */
if( !DEV_WaitForReady_Poll( ptSysDevice, CIFX_TO_WAIT_HW ) )
{
lRet = CIFX_DEV_NOT_READY;
if(g_ulTraceLevel & TRACE_LEVEL_ERROR)
{
USER_Trace(ptDevInstance,
TRACE_LEVEL_ERROR,
"DEV_DoUpdateStart(): Error waiting for device to become ready!");
}
} else
{
/* Check if MFW is running */
HWIF_READN(ptDevInstance, szCookie, ptDevInstance->pbDPM, 4);
if (0 != OS_Strcmp( szCookie, CIFX_DPMSIGNATURE_BSL_STR))
{
/* Failed to set the device into boot mode */
if(g_ulTraceLevel & TRACE_LEVEL_ERROR)
{
USER_Trace(ptDevInstance,
TRACE_LEVEL_ERROR,
"DEV_DoUpdateStart(): Error setting card into update mode!");
}
lRet = CIFX_DEV_FUNCTION_FAILED;
}else
{
/* This is an updatestart, expected one additional reset to be performed by MFW */
if(g_ulTraceLevel & TRACE_LEVEL_DEBUG)
{
USER_Trace(ptDevInstance,
TRACE_LEVEL_DEBUG,
"DEV_DoUpdateStart(): Waiting for update being applied.");
}
/* Wait until card has recognized the reset back to firmware */
if( !DEV_WaitForNotReady_Poll( ptSysDevice, ( 0 == ulTimeout) ? CIFX_TO_FIRMWARE_UPDATE : ulTimeout))
{
lRet = CIFX_DEV_RESET_TIMEOUT;
if(g_ulTraceLevel & TRACE_LEVEL_ERROR)
{
USER_Trace(ptDevInstance,
TRACE_LEVEL_ERROR,
"DEV_DoUpdateStart(): Error waiting for device to leave READY state during update!");
}
/* 2nd reset not triggered in time. Possible causes:
- timeout too short
- hardware doesn't support updatestart */
}
/* Only continue if update timeout was sufficient */
if(CIFX_NO_ERROR == lRet)
{
/* Prohibit access to possibly uninitialized PCI memory during reset of netX4000 based PCI devices.
Timeout of 1s was communicated to be the upper boundary. */
if( (ptDevInstance->fPCICard) &&
(( eCHIP_TYPE_NETX4000 == ptDevInstance->eChipType) ||
( eCHIP_TYPE_NETX4100 == ptDevInstance->eChipType) ) )
OS_Sleep(1000);
/* now wait for card to become READY again */
if( !DEV_WaitForReady_Poll( ptSysDevice, CIFX_TO_FIRMWARE_START) )
{
lRet = CIFX_DEV_NOT_READY;
if(g_ulTraceLevel & TRACE_LEVEL_ERROR)
{
USER_Trace(ptDevInstance,
TRACE_LEVEL_ERROR,
"DEV_DoUpdateStart(): Error waiting for device to become ready!");
}
}
}
}
}
/* Re-read device handshake flags */
DEV_Reset_Finish(ptDevInstance);
}
/* Log the current DPM state */
if(g_ulTraceLevel & TRACE_LEVEL_DEBUG)
{
HWIF_READN(ptDevInstance, szCookie, ptDevInstance->pbDPM, 4);
/* split messages for better readability */
USER_Trace(ptDevInstance, TRACE_LEVEL_DEBUG, "DEV_DoUpdateStart(): (system status after reset)");
USER_Trace(ptDevInstance, TRACE_LEVEL_DEBUG, " -DPM-Cookie : '%02X','%02X','%02X','%02X'",
szCookie[0],
szCookie[1],
szCookie[2],
szCookie[3]);
USER_Trace(ptDevInstance, TRACE_LEVEL_DEBUG, " -System Status : 0x%X",
LE32_TO_HOST(HWIF_READ32(ptDevInstance, ptSysChannel->tSystemState.ulSystemStatus)) );
USER_Trace(ptDevInstance, TRACE_LEVEL_DEBUG, " -System Error : 0x%X",
LE32_TO_HOST(HWIF_READ32(ptDevInstance, ptSysChannel->tSystemState.ulSystemError)) );
USER_Trace(ptDevInstance, TRACE_LEVEL_DEBUG, " -Boot Error : 0x%X",
LE32_TO_HOST(HWIF_READ32(ptDevInstance, ptSysChannel->tSystemState.ulBootError)) );
}
}
OS_ReleaseMutex(ptDevInstance->tSystemDevice.pvInitMutex);
}
return lRet;
}
/*****************************************************************************/
/*! Do a handshake for the ulApplicationCOS bits in DPM. This function will
* wait for access to ulApplicationCOS (via HSF_HOST_COS_CMD), toggle bits and
* wait for firmware to acknowledge COS. After handshaking is completed this
* function will clear bits in internal HostCOS flags defined in PostClearCOSMask
* \param ptChannel Channel instance
* \param ulSetCOSMask Host COS Bits to set
* \param ulClearCOSMask Host COS Bits to clear
* \param ulPostClearCOSMask Host COS Bits to clear after handshaking has completed
* \param lSignallingError Error to return if signalling was not acknowledged
* \param ulTimeout Timeout to wait handshake complete
* \return CIFX_NO_ERROR on success */
/*****************************************************************************/
int32_t DEV_DoHostCOSChange(PCHANNELINSTANCE ptChannel,
uint32_t ulSetCOSMask, uint32_t ulClearCOSMask,
uint32_t ulPostClearCOSMask, int32_t lSignallingError,
uint32_t ulTimeout)
{
int32_t lRet = CIFX_NO_ERROR;
/* Check if we are able to send a COS command */
if( !DEV_WaitForBitState( ptChannel, HCF_HOST_COS_CMD_BIT_NO, HIL_FLAGS_EQUAL, ulTimeout))
{
/* Wait for access to COS bits failed */
if(0 == ulTimeout)
{
/* User did not want to wait, so remember his flags, and update them with
next COS handshake. PostClearMask will be cleared by DSR or DEV_CheckCOSFlags() */
OS_EnterLock(ptChannel->pvLock);
ptChannel->ulHostCOSFlags |= ulSetCOSMask;
ptChannel->ulHostCOSFlags &= ~ulClearCOSMask;
OS_LeaveLock(ptChannel->pvLock);
lRet = CIFX_NO_ERROR;
} else
{
lRet = CIFX_DEV_FUNCTION_FAILED;
}
} else
{
/* Lock flag access */
OS_EnterLock(ptChannel->pvLock);
ptChannel->ulHostCOSFlags |= ulSetCOSMask;
ptChannel->ulHostCOSFlags &= ~ulClearCOSMask;
HWIF_WRITE32(ptChannel->pvDeviceInstance, ptChannel->ptControlBlock->ulApplicationCOS, HOST_TO_LE32(ptChannel->ulHostCOSFlags));
ptChannel->ulHostCOSFlagsSaved = ptChannel->ulHostCOSFlags;
DEV_ToggleBit(ptChannel, HCF_HOST_COS_CMD);
/* Reset the enable bit in the local flags */
ptChannel->ulHostCOSFlags &= ~ulPostClearCOSMask;
/* Unlock flag access */
OS_LeaveLock(ptChannel->pvLock);
/* Wait until card has acknowledged the COS flag */
if( !DEV_WaitForBitState( ptChannel, HCF_HOST_COS_CMD_BIT_NO, HIL_FLAGS_EQUAL, ulTimeout))
{
/* Wait for acknowledge from FW to COS handshake failed */
if(0 == ulTimeout)
{
/* User did not want to wait, so tell him everything is OK */
lRet = CIFX_NO_ERROR;
} else
{
lRet = lSignallingError;
}
} else
{
lRet = CIFX_NO_ERROR;
}
}
return lRet;
}
#ifdef CIFX_TOOLKIT_DMA
/*****************************************************************************/
/*! Setup DMA buffers
* \param ptChannel Channel instance
* \return CIFX_NO_ERROR on success */
/*****************************************************************************/
int32_t DEV_SetupDMABuffers( PCHANNELINSTANCE ptChannel)
{
int32_t lRet = CIFX_NO_ERROR;
uint32_t ulChannelNumber = 0;
uint32_t ulDMAChIdx = 0;
uint32_t ulBaseBuffer = 0;
NETX_DMA_CHANNEL_CONFIG* pDMACtrl_1 = NULL;
NETX_DMA_CHANNEL_CONFIG* pDMACtrl_2 = NULL;
CIFX_DMABUFFER_T* ptDMABuffer_1 = NULL;
CIFX_DMABUFFER_T* ptDMABuffer_2 = NULL;
/*
netX Buffer Layout
---------------------------------- 0
| MemBaseBuffer |
| used for (Host-->netX) |
|----------------------------------| BufferSize
| MemBaseBuffer + BufferSize |
| used for (netX-->Host) |
---------------------------------- BufferSize * 2
DMA channel layout:
n = Communication channel number
DMACh n = Input data
DMACh n+1 = Output data
*/
/* Get the device instance from the channel instance */
PDEVICEINSTANCE ptDevInstance = (PDEVICEINSTANCE)ptChannel->pvDeviceInstance;
/* Get the DMA control registers */
ulChannelNumber = ptChannel->ulChannelNumber ;
ulDMAChIdx = ulChannelNumber * 2; /* 2 DMA channels per communication channel */
/* Get the corresponding netX DMA control register */
pDMACtrl_1 = &ptDevInstance->ptGlobalRegisters->atDmaCtrl[ulDMAChIdx + eDMA_INPUT_BUFFER_IDX]; /* Input channel */
pDMACtrl_2 = &ptDevInstance->ptGlobalRegisters->atDmaCtrl[ulDMAChIdx + eDMA_OUTPUT_BUFFER_IDX];/* Output channel */
/* Get the user created DMA buffers */
ptDMABuffer_1 = &ptDevInstance->atDmaBuffers[ulDMAChIdx + eDMA_INPUT_BUFFER_IDX]; /* Input buffer */
ptDMABuffer_2 = &ptDevInstance->atDmaBuffers[ulDMAChIdx + eDMA_OUTPUT_BUFFER_IDX]; /* Output buffer */
/*------------------------------------*/
/* Setup INPUT DMA channel and buffer */
/*------------------------------------*/
/* Insert the physical buffer address */
/* Channel N is used as direction netX->Host, so we need to substract "BufferSize" from the pointer to get the DMA at proper location */
/* Switch to ONE buffer operation!!!!! */
ulBaseBuffer = ptDMABuffer_1->ulPhysicalAddress - ptDMABuffer_1->ulSize;
pDMACtrl_1->aulMemBaseBuffer[0] = HOST_TO_LE32(ulBaseBuffer);
pDMACtrl_1->aulMemBaseBuffer[1] = HOST_TO_LE32(ulBaseBuffer);
pDMACtrl_1->aulMemBaseBuffer[2] = HOST_TO_LE32(ulBaseBuffer);
pDMACtrl_1->ulBufCtrl = HOST_TO_LE32((ptDMABuffer_1->ulSize / 256) << 24); /* Setup buffer size */
/*-------------------------------------*/
/* Setup OUTPUT DMA channel and buffer */
/*-------------------------------------*/
/* Insert the physical buffer address */
/* Channel N+1 is used as direction Host->netX so we can use the given pointer to get the DMA buffer*/
/* Switch to ONE buffer operation!!!!! */
ulBaseBuffer = ptDMABuffer_2->ulPhysicalAddress;
pDMACtrl_2->aulMemBaseBuffer[0] = HOST_TO_LE32(ulBaseBuffer);
pDMACtrl_2->aulMemBaseBuffer[1] = HOST_TO_LE32(ulBaseBuffer);
pDMACtrl_2->aulMemBaseBuffer[2] = HOST_TO_LE32(ulBaseBuffer);
pDMACtrl_2->ulBufCtrl = HOST_TO_LE32((ptDMABuffer_2->ulSize / 256) << 24); /* Setup buffer size */
return lRet;
}
/*****************************************************************************/
/*! Handle the application DMA state COS flag
* \param ptChannel Channel instance
* \param ulCmd new state to set (CIFX_DMA_STATE_ON / CIFX_DMA_STATE_OFF)
* \param pulState Buffer to store actual state
* \return CIFX_NO_ERROR on success */
/*****************************************************************************/
int32_t DEV_DMAState(PCHANNELINSTANCE ptChannel, uint32_t ulCmd, uint32_t* pulState)
{
int32_t lRet = CIFX_NO_ERROR;
if( NULL == pulState)
return CIFX_INVALID_POINTER;
/* Check if device is READY */
if(!DEV_IsReady(ptChannel))
return CIFX_DEV_NOT_READY;
/* Read actual DMA state */
*pulState = (LE32_TO_HOST(HWIF_READ32(ptChannel->pvDeviceInstance, ptChannel->ptCommonStatusBlock->ulCommunicationCOS)) & HIL_COMM_COS_DMA) ?
CIFX_DMA_STATE_ON : CIFX_DMA_STATE_OFF;
switch (ulCmd)
{
case CIFX_DMA_STATE_ON:
{
/* Check if the DMA is already ON */
if(CIFX_DMA_STATE_ON != *pulState)
{
/* Setup DMA buffers always, to make sure HIL_COMM_COS_DMA state is handled correctly */
(void)DEV_SetupDMABuffers(ptChannel);
/* DMA is OFF, signal new DMA state */
lRet = DEV_DoHostCOSChange(ptChannel,
HIL_APP_COS_DMA | HIL_APP_COS_DMA_ENABLE, /* set mask */
0, /* clear mask */
HIL_APP_COS_DMA_ENABLE, /* post clear mask */
CIFX_DEV_DMA_STATE_ON_TIMEOUT,
CIFX_TO_WAIT_COS_ACK); /* Alwas wait for the card ACK */
/* Read actual state */
*pulState = (LE32_TO_HOST(HWIF_READ32(ptChannel->pvDeviceInstance, ptChannel->ptCommonStatusBlock->ulCommunicationCOS)) & HIL_COMM_COS_DMA) ?
CIFX_DMA_STATE_ON : CIFX_DMA_STATE_OFF;
}
}
break;
case CIFX_DMA_STATE_OFF:
{
/* Check if the DMA is already OFF */
if(CIFX_DMA_STATE_OFF != *pulState)
{
/* DMA is ON, signal new DMA state */
lRet = DEV_DoHostCOSChange(ptChannel,
HIL_APP_COS_DMA_ENABLE, /* set mask */
HIL_APP_COS_DMA, /* clear mask */
HIL_APP_COS_DMA_ENABLE, /* post clear mask */
CIFX_DEV_DMA_STATE_OFF_TIMEOUT,
CIFX_TO_WAIT_COS_ACK); /* Alwas wait for the card ACK */
/* Read actual state */
*pulState = (LE32_TO_HOST(HWIF_READ32(ptChannel->pvDeviceInstance, ptChannel->ptCommonStatusBlock->ulCommunicationCOS)) & HIL_COMM_COS_DMA) ?
CIFX_BUS_STATE_ON : CIFX_BUS_STATE_OFF;
}
}
break;
case CIFX_DMA_STATE_GETSTATE:
break;
default:
/* Unknown command */
lRet = CIFX_INVALID_COMMAND;
break;
}
return lRet;
}
/*****************************************************************************/
/*! Get actual DMA input buffer
* !!!! This function will be needed if "Buffer switch" is supported !!!
* !!!! Currently we only using "One Buffer" operation in the Toolkit!!!
* \param ptChannel Channel instance
* \param ulDirection Direction value
* \return actual DMA buffer number */
/*****************************************************************************/
uint32_t GetActualDMABuffer( PCHANNELINSTANCE ptChannel, uint32_t ulDirection)
{
uint32_t ulTemp = 0;
uint32_t ulDMAChIdx = (ptChannel->ulChannelNumber * 2) + ulDirection; /* This is the input buffer */
PDEVICEINSTANCE ptDevInstance = (PDEVICEINSTANCE)ptChannel->pvDeviceInstance;
/* Setup pointer to global netX register block */
NETX_DMA_CHANNEL_CONFIG* pDMACtrl = &ptDevInstance->ptGlobalRegisters->atDmaCtrl[ulDMAChIdx];
/* Acknowledge the buffer */
pDMACtrl->ulBufCtrl |= HOST_TO_LE32((1 << 19));
ulTemp = (LE32_TO_HOST(pDMACtrl->ulBufCtrl)) & (7 << 16);
ulTemp = (ulTemp >> 17) & 0x00000003;
return ulTemp;
}
#endif
#ifdef CIFX_TOOLKIT_HWIF
/*****************************************************************************/
/*! Wrapper function to read byte from DPM
* \param ptDev Device instance
* \param pvSrc DPM address to read from
* \return Byte read from DPM */
/*****************************************************************************/
uint8_t HwIfRead8(PDEVICEINSTANCE ptDev, void* pvSrc)
{
uint8_t bData = 0;
(void)ptDev->pfnHwIfRead(1, ptDev, pvSrc, &bData, sizeof(bData));
return bData;
}
/*****************************************************************************/
/*! Wrapper function to read word from DPM
* \param ptDev Device instance
* \param pvSrc DPM address to read from
* \return Word read from DPM */
/*****************************************************************************/
uint16_t HwIfRead16(PDEVICEINSTANCE ptDev, void* pvSrc)
{
uint16_t usData = 0;
(void)ptDev->pfnHwIfRead(1, ptDev, pvSrc, &usData, sizeof(usData));
return usData;
}
/*****************************************************************************/
/*! Wrapper function to read double word from DPM
* \param ptDev Device instance
* \param pvSrc DPM address to read from
* \return Double word read from DPM */
/*****************************************************************************/
uint32_t HwIfRead32(PDEVICEINSTANCE ptDev, void* pvSrc)
{
uint32_t ulData = 0;
(void)ptDev->pfnHwIfRead(1, ptDev, pvSrc, &ulData, sizeof(ulData));
return ulData;
}
#endif /* CIFX_TOOLKIT_HWIF */
/*****************************************************************************/
/*! \} */
/*****************************************************************************/