diff options
Diffstat (limited to 'drivers/staging/epl/EplDllk.c')
-rw-r--r-- | drivers/staging/epl/EplDllk.c | 4052 |
1 files changed, 0 insertions, 4052 deletions
diff --git a/drivers/staging/epl/EplDllk.c b/drivers/staging/epl/EplDllk.c deleted file mode 100644 index 25d2c34..0000000 --- a/drivers/staging/epl/EplDllk.c +++ /dev/null @@ -1,4052 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for kernel DLL module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplDllk.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.21 $ $Date: 2008/11/13 17:13:09 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/12 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#include "kernel/EplDllk.h" -#include "kernel/EplDllkCal.h" -#include "kernel/EplEventk.h" -#include "kernel/EplNmtk.h" -#include "edrv.h" -#include "Benchmark.h" - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) -#include "kernel/EplPdok.h" -#endif - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0) -#include "kernel/VirtualEthernet.h" -#endif - -//#if EPL_TIMER_USE_HIGHRES != FALSE -#include "kernel/EplTimerHighResk.h" -//#endif - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) == 0) -#error "EPL module DLLK needs EPL module NMTK!" -#endif - -#if (EPL_DLL_PRES_READY_AFTER_SOA != FALSE) && (EPL_DLL_PRES_READY_AFTER_SOC != FALSE) -#error "EPL module DLLK: select only one of EPL_DLL_PRES_READY_AFTER_SOA and EPL_DLL_PRES_READY_AFTER_SOC." -#endif - -#if ((EPL_DLL_PRES_READY_AFTER_SOA != FALSE) || (EPL_DLL_PRES_READY_AFTER_SOC != FALSE)) \ - && (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) == 0) -#error "EPL module DLLK: currently, EPL_DLL_PRES_READY_AFTER_* is not supported if EPL_MODULE_NMT_MN is enabled." -#endif - -#if (EDRV_FAST_TXFRAMES == FALSE) && \ - ((EPL_DLL_PRES_READY_AFTER_SOA != FALSE) || (EPL_DLL_PRES_READY_AFTER_SOC != FALSE)) -#error "EPL module DLLK: EPL_DLL_PRES_READY_AFTER_* is enabled, but not EDRV_FAST_TXFRAMES." -#endif - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -// TracePoint support for realtime-debugging -#ifdef _DBG_TRACE_POINTS_ -void TgtDbgSignalTracePoint(u8 bTracePointNumber_p); -void TgtDbgPostTraceValue(u32 dwTraceValue_p); -#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p) -#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v) -#else -#define TGT_DBG_SIGNAL_TRACE_POINT(p) -#define TGT_DBG_POST_TRACE_VALUE(v) -#endif -#define EPL_DLLK_DBG_POST_TRACE_VALUE(Event_p, uiNodeId_p, wErrorCode_p) \ - TGT_DBG_POST_TRACE_VALUE((kEplEventSinkDllk << 28) | (Event_p << 24) \ - | (uiNodeId_p << 16) | wErrorCode_p) - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S EplDllk */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: -// -// -/***************************************************************************/ - -//=========================================================================// -// // -// P R I V A T E D E F I N I T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -// defines for indexes of tEplDllInstance.m_pTxFrameInfo -#define EPL_DLLK_TXFRAME_IDENTRES 0 // IdentResponse on CN / MN -#define EPL_DLLK_TXFRAME_STATUSRES 1 // StatusResponse on CN / MN -#define EPL_DLLK_TXFRAME_NMTREQ 2 // NMT Request from FIFO on CN / MN -#define EPL_DLLK_TXFRAME_NONEPL 3 // non-EPL frame from FIFO on CN / MN -#define EPL_DLLK_TXFRAME_PRES 4 // PRes on CN / MN -#define EPL_DLLK_TXFRAME_SOC 5 // SoC on MN -#define EPL_DLLK_TXFRAME_SOA 6 // SoA on MN -#define EPL_DLLK_TXFRAME_PREQ 7 // PReq on MN -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) -#define EPL_DLLK_TXFRAME_COUNT (7 + EPL_D_NMT_MaxCNNumber_U8 + 2) // on MN: 7 + MaxPReq of regular CNs + 1 Diag + 1 Router -#else -#define EPL_DLLK_TXFRAME_COUNT 5 // on CN: 5 -#endif - -#define EPL_DLLK_BUFLEN_EMPTY 0 // buffer is empty -#define EPL_DLLK_BUFLEN_FILLING 1 // just the buffer is being filled -#define EPL_DLLK_BUFLEN_MIN 60 // minimum ethernet frame length - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -typedef enum { - kEplDllGsInit = 0x00, // MN/CN: initialisation (< PreOp2) - kEplDllCsWaitPreq = 0x01, // CN: wait for PReq frame - kEplDllCsWaitSoc = 0x02, // CN: wait for SoC frame - kEplDllCsWaitSoa = 0x03, // CN: wait for SoA frame - kEplDllMsNonCyclic = 0x04, // MN: reduced EPL cycle (PreOp1) - kEplDllMsWaitSocTrig = 0x05, // MN: wait for SoC trigger (cycle timer) - kEplDllMsWaitPreqTrig = 0x06, // MN: wait for (first) PReq trigger (WaitSoCPReq_U32) - kEplDllMsWaitPres = 0x07, // MN: wait for PRes frame from CN - kEplDllMsWaitSoaTrig = 0x08, // MN: wait for SoA trigger (PRes transmitted) - kEplDllMsWaitAsndTrig = 0x09, // MN: wait for ASnd trigger (SoA transmitted) - kEplDllMsWaitAsnd = 0x0A, // MN: wait for ASnd frame if SoA contained invitation - -} tEplDllState; - -typedef struct { - u8 m_be_abSrcMac[6]; - tEdrvTxBuffer *m_pTxBuffer; // Buffers for Tx-Frames - unsigned int m_uiMaxTxFrames; - u8 m_bFlag1; // Flag 1 with EN, EC for PRes, StatusRes - u8 m_bMnFlag1; // Flag 1 with EA, ER from PReq, SoA of MN - u8 m_bFlag2; // Flag 2 with PR and RS for PRes, StatusRes, IdentRes - tEplDllConfigParam m_DllConfigParam; - tEplDllIdentParam m_DllIdentParam; - tEplDllState m_DllState; - tEplDllkCbAsync m_pfnCbAsync; - tEplDllAsndFilter m_aAsndFilter[EPL_DLL_MAX_ASND_SERVICE_ID]; - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - tEplDllkNodeInfo *m_pFirstNodeInfo; - tEplDllkNodeInfo *m_pCurNodeInfo; - tEplDllkNodeInfo m_aNodeInfo[EPL_NMT_MAX_NODE_ID]; - tEplDllReqServiceId m_LastReqServiceId; - unsigned int m_uiLastTargetNodeId; -#endif - -#if EPL_TIMER_USE_HIGHRES != FALSE - tEplTimerHdl m_TimerHdlCycle; // used for EPL cycle monitoring on CN and generation on MN -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - tEplTimerHdl m_TimerHdlResponse; // used for CN response monitoring -#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) -#endif - - unsigned int m_uiCycleCount; // cycle counter (needed for multiplexed cycle support) - unsigned long long m_ullFrameTimeout; // frame timeout (cycle length + loss of frame tolerance) - -} tEplDllkInstance; - -//--------------------------------------------------------------------------- -// local vars -//--------------------------------------------------------------------------- - -// if no dynamic memory allocation shall be used -// define structures statically -static tEplDllkInstance EplDllkInstance_g; - -static tEdrvTxBuffer aEplDllkTxBuffer_l[EPL_DLLK_TXFRAME_COUNT]; - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -// change DLL state on event -static tEplKernel EplDllkChangeState(tEplNmtEvent NmtEvent_p, - tEplNmtState NmtState_p); - -// called from EdrvInterruptHandler() -static void EplDllkCbFrameReceived(tEdrvRxBuffer * pRxBuffer_p); - -// called from EdrvInterruptHandler() -static void EplDllkCbFrameTransmitted(tEdrvTxBuffer * pTxBuffer_p); - -// check frame and set missing information -static tEplKernel EplDllkCheckFrame(tEplFrame * pFrame_p, - unsigned int uiFrameSize_p); - -// called by high resolution timer module to monitor EPL cycle as CN -#if EPL_TIMER_USE_HIGHRES != FALSE -static tEplKernel EplDllkCbCnTimer(tEplTimerEventArg *pEventArg_p); -#endif - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) -// MN: returns internal node info structure -static tEplDllkNodeInfo *EplDllkGetNodeInfo(unsigned int uiNodeId_p); - -// transmit SoA -static tEplKernel EplDllkMnSendSoa(tEplNmtState NmtState_p, - tEplDllState * pDllStateProposed_p, - BOOL fEnableInvitation_p); - -static tEplKernel EplDllkMnSendSoc(void); - -static tEplKernel EplDllkMnSendPreq(tEplNmtState NmtState_p, - tEplDllState * pDllStateProposed_p); - -static tEplKernel EplDllkAsyncFrameNotReceived(tEplDllReqServiceId - ReqServiceId_p, - unsigned int uiNodeId_p); - -static tEplKernel EplDllkCbMnTimerCycle(tEplTimerEventArg *pEventArg_p); - -static tEplKernel EplDllkCbMnTimerResponse(tEplTimerEventArg *pEventArg_p); - -#endif - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplDllkAddInstance() -// -// Description: add and initialize new instance of EPL stack -// -// Parameters: pInitParam_p = initialisation parameters like MAC address -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkAddInstance(tEplDllkInitParam * pInitParam_p) -{ - tEplKernel Ret = kEplSuccessful; - unsigned int uiIndex; - tEdrvInitParam EdrvInitParam; - - // reset instance structure - EPL_MEMSET(&EplDllkInstance_g, 0, sizeof(EplDllkInstance_g)); - -#if EPL_TIMER_USE_HIGHRES != FALSE - Ret = EplTimerHighReskInit(); - if (Ret != kEplSuccessful) { // error occured while initializing high resolution timer module - goto Exit; - } -#endif - - // if dynamic memory allocation available - // allocate instance structure - // allocate TPDO and RPDO table with default size - - // initialize and link pointers in instance structure to frame tables - EplDllkInstance_g.m_pTxBuffer = aEplDllkTxBuffer_l; - EplDllkInstance_g.m_uiMaxTxFrames = - sizeof(aEplDllkTxBuffer_l) / sizeof(tEdrvTxBuffer); - - // initialize state - EplDllkInstance_g.m_DllState = kEplDllGsInit; - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - // set up node info structure - for (uiIndex = 0; uiIndex < tabentries(EplDllkInstance_g.m_aNodeInfo); - uiIndex++) { - EplDllkInstance_g.m_aNodeInfo[uiIndex].m_uiNodeId = uiIndex + 1; - EplDllkInstance_g.m_aNodeInfo[uiIndex].m_wPresPayloadLimit = - 0xFFFF; - } -#endif - - // initialize Edrv - EPL_MEMCPY(EdrvInitParam.m_abMyMacAddr, pInitParam_p->m_be_abSrcMac, 6); - EdrvInitParam.m_pfnRxHandler = EplDllkCbFrameReceived; - EdrvInitParam.m_pfnTxHandler = EplDllkCbFrameTransmitted; - Ret = EdrvInit(&EdrvInitParam); - if (Ret != kEplSuccessful) { // error occured while initializing ethernet driver - goto Exit; - } - // copy local MAC address from Ethernet driver back to local instance structure - // because Ethernet driver may have read it from controller EEPROM - EPL_MEMCPY(EplDllkInstance_g.m_be_abSrcMac, EdrvInitParam.m_abMyMacAddr, - 6); - EPL_MEMCPY(pInitParam_p->m_be_abSrcMac, EdrvInitParam.m_abMyMacAddr, 6); - - // initialize TxBuffer array - for (uiIndex = 0; uiIndex < EplDllkInstance_g.m_uiMaxTxFrames; - uiIndex++) { - EplDllkInstance_g.m_pTxBuffer[uiIndex].m_pbBuffer = NULL; - } - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0) - Ret = VEthAddInstance(pInitParam_p); -#endif - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkDelInstance() -// -// Description: deletes an instance of EPL stack -// -// Parameters: (none) -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkDelInstance(void) -{ - tEplKernel Ret = kEplSuccessful; - - // reset state - EplDllkInstance_g.m_DllState = kEplDllGsInit; - -#if EPL_TIMER_USE_HIGHRES != FALSE - Ret = EplTimerHighReskDelInstance(); -#endif - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0) - Ret = VEthDelInstance(); -#endif - - Ret = EdrvShutdown(); - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCreateTxFrame -// -// Description: creates the buffer for a Tx frame and registers it to the -// ethernet driver -// -// Parameters: puiHandle_p = OUT: handle to frame buffer -// ppFrame_p = OUT: pointer to pointer of EPL frame -// puiFrameSize_p = IN/OUT: pointer to size of frame -// returned size is always equal or larger than -// requested size, if that is not possible -// an error will be returned -// MsgType_p = EPL message type -// ServiceId_p = Service ID in case of ASnd frame, otherwise -// kEplDllAsndNotDefined -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkCreateTxFrame(unsigned int *puiHandle_p, - tEplFrame ** ppFrame_p, - unsigned int *puiFrameSize_p, - tEplMsgType MsgType_p, - tEplDllAsndServiceId ServiceId_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplFrame *pTxFrame; - unsigned int uiHandle = EplDllkInstance_g.m_uiMaxTxFrames; - tEdrvTxBuffer *pTxBuffer = NULL; - - if (MsgType_p == kEplMsgTypeAsnd) { - // search for fixed Tx buffers - if (ServiceId_p == kEplDllAsndIdentResponse) { - uiHandle = EPL_DLLK_TXFRAME_IDENTRES; - } else if (ServiceId_p == kEplDllAsndStatusResponse) { - uiHandle = EPL_DLLK_TXFRAME_STATUSRES; - } else if ((ServiceId_p == kEplDllAsndNmtRequest) - || (ServiceId_p == kEplDllAsndNmtCommand)) { - uiHandle = EPL_DLLK_TXFRAME_NMTREQ; - } - - if (uiHandle >= EplDllkInstance_g.m_uiMaxTxFrames) { // look for free entry - uiHandle = EPL_DLLK_TXFRAME_PREQ; - pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[uiHandle]; - for (; uiHandle < EplDllkInstance_g.m_uiMaxTxFrames; - uiHandle++, pTxBuffer++) { - if (pTxBuffer->m_pbBuffer == NULL) { // free entry found - break; - } - } - } - } else if (MsgType_p == kEplMsgTypeNonEpl) { - uiHandle = EPL_DLLK_TXFRAME_NONEPL; - } else if (MsgType_p == kEplMsgTypePres) { - uiHandle = EPL_DLLK_TXFRAME_PRES; - } else if (MsgType_p == kEplMsgTypeSoc) { - uiHandle = EPL_DLLK_TXFRAME_SOC; - } else if (MsgType_p == kEplMsgTypeSoa) { - uiHandle = EPL_DLLK_TXFRAME_SOA; - } else { // look for free entry - uiHandle = EPL_DLLK_TXFRAME_PREQ; - pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[uiHandle]; - for (; uiHandle < EplDllkInstance_g.m_uiMaxTxFrames; - uiHandle++, pTxBuffer++) { - if (pTxBuffer->m_pbBuffer == NULL) { // free entry found - break; - } - } - if (pTxBuffer->m_pbBuffer != NULL) { - Ret = kEplEdrvNoFreeBufEntry; - goto Exit; - } - } - - // test if requested entry is free - pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[uiHandle]; - if (pTxBuffer->m_pbBuffer != NULL) { // entry is not free - Ret = kEplEdrvNoFreeBufEntry; - goto Exit; - } - // setup Tx buffer - pTxBuffer->m_EplMsgType = MsgType_p; - pTxBuffer->m_uiMaxBufferLen = *puiFrameSize_p; - - Ret = EdrvAllocTxMsgBuffer(pTxBuffer); - if (Ret != kEplSuccessful) { // error occured while registering Tx frame - goto Exit; - } - // because buffer size may be larger than requested - // memorize real length of frame - pTxBuffer->m_uiTxMsgLen = *puiFrameSize_p; - - // fill whole frame with 0 - EPL_MEMSET(pTxBuffer->m_pbBuffer, 0, pTxBuffer->m_uiMaxBufferLen); - - pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer; - - if (MsgType_p != kEplMsgTypeNonEpl) { // fill out Frame only if it is an EPL frame - // ethertype - AmiSetWordToBe(&pTxFrame->m_be_wEtherType, - EPL_C_DLL_ETHERTYPE_EPL); - // source node ID - AmiSetByteToLe(&pTxFrame->m_le_bSrcNodeId, - (u8) EplDllkInstance_g.m_DllConfigParam. - m_uiNodeId); - // source MAC address - EPL_MEMCPY(&pTxFrame->m_be_abSrcMac[0], - &EplDllkInstance_g.m_be_abSrcMac[0], 6); - switch (MsgType_p) { - case kEplMsgTypeAsnd: - // destination MAC address - AmiSetQword48ToBe(&pTxFrame->m_be_abDstMac[0], - EPL_C_DLL_MULTICAST_ASND); - // destination node ID - switch (ServiceId_p) { - case kEplDllAsndIdentResponse: - case kEplDllAsndStatusResponse: - { // IdentResponses and StatusResponses are Broadcast - AmiSetByteToLe(&pTxFrame-> - m_le_bDstNodeId, - (u8) - EPL_C_ADR_BROADCAST); - break; - } - - default: - break; - } - // ASnd Service ID - AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.m_le_bServiceId, - ServiceId_p); - break; - - case kEplMsgTypeSoc: - // destination MAC address - AmiSetQword48ToBe(&pTxFrame->m_be_abDstMac[0], - EPL_C_DLL_MULTICAST_SOC); - // destination node ID - AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId, - (u8) EPL_C_ADR_BROADCAST); - // reset Flags - //AmiSetByteToLe(&pTxFrame->m_Data.m_Soc.m_le_bFlag1, (u8) 0); - //AmiSetByteToLe(&pTxFrame->m_Data.m_Soc.m_le_bFlag2, (u8) 0); - break; - - case kEplMsgTypeSoa: - // destination MAC address - AmiSetQword48ToBe(&pTxFrame->m_be_abDstMac[0], - EPL_C_DLL_MULTICAST_SOA); - // destination node ID - AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId, - (u8) EPL_C_ADR_BROADCAST); - // reset Flags - //AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bFlag1, (u8) 0); - //AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bFlag2, (u8) 0); - // EPL profile version - AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bEplVersion, - (u8) EPL_SPEC_VERSION); - break; - - case kEplMsgTypePres: - // destination MAC address - AmiSetQword48ToBe(&pTxFrame->m_be_abDstMac[0], - EPL_C_DLL_MULTICAST_PRES); - // destination node ID - AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId, - (u8) EPL_C_ADR_BROADCAST); - // reset Flags - //AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag1, (u8) 0); - //AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag2, (u8) 0); - // PDO size - //AmiSetWordToLe(&pTxFrame->m_Data.m_Pres.m_le_wSize, 0); - break; - - case kEplMsgTypePreq: - // reset Flags - //AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag1, (u8) 0); - //AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag2, (u8) 0); - // PDO size - //AmiSetWordToLe(&pTxFrame->m_Data.m_Preq.m_le_wSize, 0); - break; - - default: - break; - } - // EPL message type - AmiSetByteToLe(&pTxFrame->m_le_bMessageType, (u8) MsgType_p); - } - - *ppFrame_p = pTxFrame; - *puiFrameSize_p = pTxBuffer->m_uiMaxBufferLen; - *puiHandle_p = uiHandle; - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkDeleteTxFrame -// -// Description: deletes the buffer for a Tx frame and frees it in the -// ethernet driver -// -// Parameters: uiHandle_p = IN: handle to frame buffer -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkDeleteTxFrame(unsigned int uiHandle_p) -{ - tEplKernel Ret = kEplSuccessful; - tEdrvTxBuffer *pTxBuffer = NULL; - - if (uiHandle_p >= EplDllkInstance_g.m_uiMaxTxFrames) { // handle is not valid - Ret = kEplDllIllegalHdl; - goto Exit; - } - - pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[uiHandle_p]; - - // mark buffer as free so that frame will not be send in future anymore - // $$$ d.k. What's up with running transmissions? - pTxBuffer->m_uiTxMsgLen = EPL_DLLK_BUFLEN_EMPTY; - pTxBuffer->m_pbBuffer = NULL; - - // delete Tx buffer - Ret = EdrvReleaseTxMsgBuffer(pTxBuffer); - if (Ret != kEplSuccessful) { // error occured while releasing Tx frame - goto Exit; - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkProcess -// -// Description: process the passed event -// -// Parameters: pEvent_p = event to be processed -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkProcess(tEplEvent * pEvent_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplFrame *pTxFrame; - tEdrvTxBuffer *pTxBuffer; - unsigned int uiHandle; - unsigned int uiFrameSize; - u8 abMulticastMac[6]; - tEplDllAsyncReqPriority AsyncReqPriority; - unsigned int uiFrameCount; - tEplNmtState NmtState; -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) - tEplFrameInfo FrameInfo; -#endif - - switch (pEvent_p->m_EventType) { - case kEplEventTypeDllkCreate: - { - // $$$ reset ethernet driver - - NmtState = *((tEplNmtState *) pEvent_p->m_pArg); - - // initialize flags for PRes and StatusRes - EplDllkInstance_g.m_bFlag1 = EPL_FRAME_FLAG1_EC; - EplDllkInstance_g.m_bMnFlag1 = 0; - EplDllkInstance_g.m_bFlag2 = 0; - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - // initialize linked node list - EplDllkInstance_g.m_pFirstNodeInfo = NULL; -#endif - - // register TxFrames in Edrv - - // IdentResponse - uiFrameSize = EPL_C_DLL_MINSIZE_IDENTRES; - Ret = - EplDllkCreateTxFrame(&uiHandle, &pTxFrame, - &uiFrameSize, kEplMsgTypeAsnd, - kEplDllAsndIdentResponse); - if (Ret != kEplSuccessful) { // error occured while registering Tx frame - goto Exit; - } - // EPL profile version - AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_bEplProfileVersion, - (u8) EPL_SPEC_VERSION); - // FeatureFlags - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_dwFeatureFlags, - EplDllkInstance_g.m_DllConfigParam. - m_dwFeatureFlags); - // MTU - AmiSetWordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_wMtu, - (u16) EplDllkInstance_g. - m_DllConfigParam.m_uiAsyncMtu); - // PollInSize - AmiSetWordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_wPollInSize, - (u16) EplDllkInstance_g. - m_DllConfigParam. - m_uiPreqActPayloadLimit); - // PollOutSize - AmiSetWordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_wPollOutSize, - (u16) EplDllkInstance_g. - m_DllConfigParam. - m_uiPresActPayloadLimit); - // ResponseTime / PresMaxLatency - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_dwResponseTime, - EplDllkInstance_g.m_DllConfigParam. - m_dwPresMaxLatency); - // DeviceType - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_dwDeviceType, - EplDllkInstance_g.m_DllIdentParam. - m_dwDeviceType); - // VendorId - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_dwVendorId, - EplDllkInstance_g.m_DllIdentParam. - m_dwVendorId); - // ProductCode - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_dwProductCode, - EplDllkInstance_g.m_DllIdentParam. - m_dwProductCode); - // RevisionNumber - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_dwRevisionNumber, - EplDllkInstance_g.m_DllIdentParam. - m_dwRevisionNumber); - // SerialNumber - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_dwSerialNumber, - EplDllkInstance_g.m_DllIdentParam. - m_dwSerialNumber); - // VendorSpecificExt1 - AmiSetQword64ToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse. - m_le_qwVendorSpecificExt1, - EplDllkInstance_g.m_DllIdentParam. - m_qwVendorSpecificExt1); - // VerifyConfigurationDate - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse. - m_le_dwVerifyConfigurationDate, - EplDllkInstance_g.m_DllIdentParam. - m_dwVerifyConfigurationDate); - // VerifyConfigurationTime - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse. - m_le_dwVerifyConfigurationTime, - EplDllkInstance_g.m_DllIdentParam. - m_dwVerifyConfigurationTime); - // ApplicationSwDate - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse. - m_le_dwApplicationSwDate, - EplDllkInstance_g.m_DllIdentParam. - m_dwApplicationSwDate); - // ApplicationSwTime - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse. - m_le_dwApplicationSwTime, - EplDllkInstance_g.m_DllIdentParam. - m_dwApplicationSwTime); - // IPAddress - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_dwIpAddress, - EplDllkInstance_g.m_DllIdentParam. - m_dwIpAddress); - // SubnetMask - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_dwSubnetMask, - EplDllkInstance_g.m_DllIdentParam. - m_dwSubnetMask); - // DefaultGateway - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_dwDefaultGateway, - EplDllkInstance_g.m_DllIdentParam. - m_dwDefaultGateway); - // HostName - EPL_MEMCPY(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_sHostname[0], - &EplDllkInstance_g.m_DllIdentParam. - m_sHostname[0], - sizeof(EplDllkInstance_g.m_DllIdentParam. - m_sHostname)); - // VendorSpecificExt2 - EPL_MEMCPY(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_abVendorSpecificExt2[0], - &EplDllkInstance_g.m_DllIdentParam. - m_abVendorSpecificExt2[0], - sizeof(EplDllkInstance_g.m_DllIdentParam. - m_abVendorSpecificExt2)); - - // StatusResponse - uiFrameSize = EPL_C_DLL_MINSIZE_STATUSRES; - Ret = - EplDllkCreateTxFrame(&uiHandle, &pTxFrame, - &uiFrameSize, kEplMsgTypeAsnd, - kEplDllAsndStatusResponse); - if (Ret != kEplSuccessful) { // error occured while registering Tx frame - goto Exit; - } - // PRes $$$ maybe move this to PDO module - if ((EplDllkInstance_g.m_DllConfigParam.m_fAsyncOnly == - FALSE) - && (EplDllkInstance_g.m_DllConfigParam.m_uiPresActPayloadLimit >= 36)) { // it is not configured as async-only CN, - // so take part in isochronous phase and register PRes frame - uiFrameSize = - EplDllkInstance_g.m_DllConfigParam. - m_uiPresActPayloadLimit + 24; - Ret = - EplDllkCreateTxFrame(&uiHandle, &pTxFrame, - &uiFrameSize, - kEplMsgTypePres, - kEplDllAsndNotDefined); - if (Ret != kEplSuccessful) { // error occured while registering Tx frame - goto Exit; - } -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) - // initially encode TPDO -> inform PDO module - FrameInfo.m_pFrame = pTxFrame; - FrameInfo.m_uiFrameSize = uiFrameSize; - Ret = EplPdokCbPdoTransmitted(&FrameInfo); -#endif - // reset cycle counter - EplDllkInstance_g.m_uiCycleCount = 0; - } else { // it is an async-only CN - // fool EplDllkChangeState() to think that PRes was not expected - EplDllkInstance_g.m_uiCycleCount = 1; - } - - // NMT request - uiFrameSize = EPL_C_IP_MAX_MTU; - Ret = - EplDllkCreateTxFrame(&uiHandle, &pTxFrame, - &uiFrameSize, kEplMsgTypeAsnd, - kEplDllAsndNmtRequest); - if (Ret != kEplSuccessful) { // error occured while registering Tx frame - goto Exit; - } - // mark Tx buffer as empty - EplDllkInstance_g.m_pTxBuffer[uiHandle].m_uiTxMsgLen = - EPL_DLLK_BUFLEN_EMPTY; - - // non-EPL frame - uiFrameSize = EPL_C_IP_MAX_MTU; - Ret = - EplDllkCreateTxFrame(&uiHandle, &pTxFrame, - &uiFrameSize, - kEplMsgTypeNonEpl, - kEplDllAsndNotDefined); - if (Ret != kEplSuccessful) { // error occured while registering Tx frame - goto Exit; - } - // mark Tx buffer as empty - EplDllkInstance_g.m_pTxBuffer[uiHandle].m_uiTxMsgLen = - EPL_DLLK_BUFLEN_EMPTY; - - // register multicast MACs in ethernet driver - AmiSetQword48ToBe(&abMulticastMac[0], - EPL_C_DLL_MULTICAST_SOC); - Ret = EdrvDefineRxMacAddrEntry(abMulticastMac); - AmiSetQword48ToBe(&abMulticastMac[0], - EPL_C_DLL_MULTICAST_SOA); - Ret = EdrvDefineRxMacAddrEntry(abMulticastMac); - AmiSetQword48ToBe(&abMulticastMac[0], - EPL_C_DLL_MULTICAST_PRES); - Ret = EdrvDefineRxMacAddrEntry(abMulticastMac); - AmiSetQword48ToBe(&abMulticastMac[0], - EPL_C_DLL_MULTICAST_ASND); - Ret = EdrvDefineRxMacAddrEntry(abMulticastMac); - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - if (NmtState >= kEplNmtMsNotActive) { // local node is MN - unsigned int uiIndex; - - // SoC - uiFrameSize = EPL_C_DLL_MINSIZE_SOC; - Ret = - EplDllkCreateTxFrame(&uiHandle, &pTxFrame, - &uiFrameSize, - kEplMsgTypeSoc, - kEplDllAsndNotDefined); - if (Ret != kEplSuccessful) { // error occured while registering Tx frame - goto Exit; - } - // SoA - uiFrameSize = EPL_C_DLL_MINSIZE_SOA; - Ret = - EplDllkCreateTxFrame(&uiHandle, &pTxFrame, - &uiFrameSize, - kEplMsgTypeSoa, - kEplDllAsndNotDefined); - if (Ret != kEplSuccessful) { // error occured while registering Tx frame - goto Exit; - } - - for (uiIndex = 0; - uiIndex < - tabentries(EplDllkInstance_g.m_aNodeInfo); - uiIndex++) { -// EplDllkInstance_g.m_aNodeInfo[uiIndex].m_uiNodeId = uiIndex + 1; - EplDllkInstance_g.m_aNodeInfo[uiIndex]. - m_wPresPayloadLimit = - (u16) EplDllkInstance_g. - m_DllConfigParam. - m_uiIsochrRxMaxPayload; - } - - // calculate cycle length - EplDllkInstance_g.m_ullFrameTimeout = 1000LL - * - ((unsigned long long)EplDllkInstance_g. - m_DllConfigParam.m_dwCycleLen); - } -#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - - Ret = EplDllkCalAsyncClearBuffer(); - - break; - } - - case kEplEventTypeDllkDestroy: - { - // destroy all data structures - - NmtState = *((tEplNmtState *) pEvent_p->m_pArg); - - // delete Tx frames - Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_IDENTRES); - if (Ret != kEplSuccessful) { // error occured while deregistering Tx frame - goto Exit; - } - - Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_STATUSRES); - if (Ret != kEplSuccessful) { // error occured while deregistering Tx frame - goto Exit; - } - - Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_PRES); - if (Ret != kEplSuccessful) { // error occured while deregistering Tx frame - goto Exit; - } - - Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_NMTREQ); - if (Ret != kEplSuccessful) { // error occured while deregistering Tx frame - goto Exit; - } - - Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_NONEPL); - if (Ret != kEplSuccessful) { // error occured while deregistering Tx frame - goto Exit; - } -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - if (NmtState >= kEplNmtMsNotActive) { // local node was MN - unsigned int uiIndex; - - Ret = - EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_SOC); - if (Ret != kEplSuccessful) { // error occured while deregistering Tx frame - goto Exit; - } - - Ret = - EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_SOA); - if (Ret != kEplSuccessful) { // error occured while deregistering Tx frame - goto Exit; - } - - for (uiIndex = 0; - uiIndex < - tabentries(EplDllkInstance_g.m_aNodeInfo); - uiIndex++) { - if (EplDllkInstance_g. - m_aNodeInfo[uiIndex]. - m_pPreqTxBuffer != NULL) { - uiHandle = - EplDllkInstance_g. - m_aNodeInfo[uiIndex]. - m_pPreqTxBuffer - - EplDllkInstance_g. - m_pTxBuffer; - EplDllkInstance_g. - m_aNodeInfo[uiIndex]. - m_pPreqTxBuffer = NULL; - Ret = - EplDllkDeleteTxFrame - (uiHandle); - if (Ret != kEplSuccessful) { // error occured while deregistering Tx frame - goto Exit; - } - - } - EplDllkInstance_g.m_aNodeInfo[uiIndex]. - m_wPresPayloadLimit = 0xFFFF; - } - } -#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - - // deregister multicast MACs in ethernet driver - AmiSetQword48ToBe(&abMulticastMac[0], - EPL_C_DLL_MULTICAST_SOC); - Ret = EdrvUndefineRxMacAddrEntry(abMulticastMac); - AmiSetQword48ToBe(&abMulticastMac[0], - EPL_C_DLL_MULTICAST_SOA); - Ret = EdrvUndefineRxMacAddrEntry(abMulticastMac); - AmiSetQword48ToBe(&abMulticastMac[0], - EPL_C_DLL_MULTICAST_PRES); - Ret = EdrvUndefineRxMacAddrEntry(abMulticastMac); - AmiSetQword48ToBe(&abMulticastMac[0], - EPL_C_DLL_MULTICAST_ASND); - Ret = EdrvUndefineRxMacAddrEntry(abMulticastMac); - - // delete timer -#if EPL_TIMER_USE_HIGHRES != FALSE - Ret = - EplTimerHighReskDeleteTimer(&EplDllkInstance_g. - m_TimerHdlCycle); -#endif - - break; - } - - case kEplEventTypeDllkFillTx: - { - // fill TxBuffer of specified priority with new frame if empty - - pTxFrame = NULL; - AsyncReqPriority = - *((tEplDllAsyncReqPriority *) pEvent_p->m_pArg); - switch (AsyncReqPriority) { - case kEplDllAsyncReqPrioNmt: // NMT request priority - { - pTxBuffer = - &EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NMTREQ]; - if (pTxBuffer->m_pbBuffer != NULL) { // NmtRequest does exist - // check if frame is empty and not being filled - if (pTxBuffer->m_uiTxMsgLen == - EPL_DLLK_BUFLEN_EMPTY) { - // mark Tx buffer as filling is in process - pTxBuffer-> - m_uiTxMsgLen = - EPL_DLLK_BUFLEN_FILLING; - // set max buffer size as input parameter - uiFrameSize = - pTxBuffer-> - m_uiMaxBufferLen; - // copy frame from shared loop buffer to Tx buffer - Ret = - EplDllkCalAsyncGetTxFrame - (pTxBuffer-> - m_pbBuffer, - &uiFrameSize, - AsyncReqPriority); - if (Ret == - kEplSuccessful) { - pTxFrame = - (tEplFrame - *) - pTxBuffer-> - m_pbBuffer; - Ret = - EplDllkCheckFrame - (pTxFrame, - uiFrameSize); - - // set buffer valid - pTxBuffer-> - m_uiTxMsgLen - = - uiFrameSize; - } else if (Ret == kEplDllAsyncTxBufferEmpty) { // empty Tx buffer is not a real problem - // so just ignore it - Ret = - kEplSuccessful; - // mark Tx buffer as empty - pTxBuffer-> - m_uiTxMsgLen - = - EPL_DLLK_BUFLEN_EMPTY; - } - } - } - break; - } - - default: // generic priority - { - pTxBuffer = - &EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NONEPL]; - if (pTxBuffer->m_pbBuffer != NULL) { // non-EPL frame does exist - // check if frame is empty and not being filled - if (pTxBuffer->m_uiTxMsgLen == - EPL_DLLK_BUFLEN_EMPTY) { - // mark Tx buffer as filling is in process - pTxBuffer-> - m_uiTxMsgLen = - EPL_DLLK_BUFLEN_FILLING; - // set max buffer size as input parameter - uiFrameSize = - pTxBuffer-> - m_uiMaxBufferLen; - // copy frame from shared loop buffer to Tx buffer - Ret = - EplDllkCalAsyncGetTxFrame - (pTxBuffer-> - m_pbBuffer, - &uiFrameSize, - AsyncReqPriority); - if (Ret == - kEplSuccessful) { - pTxFrame = - (tEplFrame - *) - pTxBuffer-> - m_pbBuffer; - Ret = - EplDllkCheckFrame - (pTxFrame, - uiFrameSize); - - // set buffer valid - pTxBuffer-> - m_uiTxMsgLen - = - uiFrameSize; - } else if (Ret == kEplDllAsyncTxBufferEmpty) { // empty Tx buffer is not a real problem - // so just ignore it - Ret = - kEplSuccessful; - // mark Tx buffer as empty - pTxBuffer-> - m_uiTxMsgLen - = - EPL_DLLK_BUFLEN_EMPTY; - } - } - } - break; - } - } - - NmtState = EplNmtkGetNmtState(); - - if ((NmtState == kEplNmtCsBasicEthernet) || (NmtState == kEplNmtMsBasicEthernet)) { // send frame immediately - if (pTxFrame != NULL) { // frame is present - // padding is done by Edrv or ethernet controller - Ret = EdrvSendTxMsg(pTxBuffer); - } else { // no frame moved to TxBuffer - // check if TxBuffers contain unsent frames - if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY) { // NMT request Tx buffer contains a frame - Ret = - EdrvSendTxMsg - (&EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NMTREQ]); - } else if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY) { // non-EPL Tx buffer contains a frame - Ret = - EdrvSendTxMsg - (&EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NONEPL]); - } - if (Ret == kEplInvalidOperation) { // ignore error if caused by already active transmission - Ret = kEplSuccessful; - } - } - // reset PRes flag 2 - EplDllkInstance_g.m_bFlag2 = 0; - } else { - // update Flag 2 (PR, RS) - Ret = - EplDllkCalAsyncGetTxCount(&AsyncReqPriority, - &uiFrameCount); - if (AsyncReqPriority == kEplDllAsyncReqPrioNmt) { // non-empty FIFO with hightest priority is for NMT requests - if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY) { // NMT request Tx buffer contains a frame - // add one more frame - uiFrameCount++; - } - } else { // non-empty FIFO with highest priority is for generic frames - if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY) { // NMT request Tx buffer contains a frame - // use NMT request FIFO, because of higher priority - uiFrameCount = 1; - AsyncReqPriority = - kEplDllAsyncReqPrioNmt; - } else if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY) { // non-EPL Tx buffer contains a frame - // use NMT request FIFO, because of higher priority - // add one more frame - uiFrameCount++; - } - } - - if (uiFrameCount > 7) { // limit frame request to send counter to 7 - uiFrameCount = 7; - } - if (uiFrameCount > 0) { - EplDllkInstance_g.m_bFlag2 = - (u8) (((AsyncReqPriority << - EPL_FRAME_FLAG2_PR_SHIFT) - & EPL_FRAME_FLAG2_PR) - | (uiFrameCount & - EPL_FRAME_FLAG2_RS)); - } else { - EplDllkInstance_g.m_bFlag2 = 0; - } - } - - break; - } - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - case kEplEventTypeDllkStartReducedCycle: - { - // start the reduced cycle by programming the cycle timer - // it is issued by NMT MN module, when PreOp1 is entered - - // clear the asynchronous queues - Ret = EplDllkCalAsyncClearQueues(); - - // reset cycle counter (everytime a SoA is triggerd in PreOp1 the counter is incremented - // and when it reaches EPL_C_DLL_PREOP1_START_CYCLES the SoA may contain invitations) - EplDllkInstance_g.m_uiCycleCount = 0; - - // remove any CN from isochronous phase - while (EplDllkInstance_g.m_pFirstNodeInfo != NULL) { - EplDllkDeleteNode(EplDllkInstance_g. - m_pFirstNodeInfo->m_uiNodeId); - } - - // change state to NonCyclic, - // hence EplDllkChangeState() will not ignore the next call - EplDllkInstance_g.m_DllState = kEplDllMsNonCyclic; - -#if EPL_TIMER_USE_HIGHRES != FALSE - if (EplDllkInstance_g.m_DllConfigParam. - m_dwAsyncSlotTimeout != 0) { - Ret = - EplTimerHighReskModifyTimerNs - (&EplDllkInstance_g.m_TimerHdlCycle, - EplDllkInstance_g.m_DllConfigParam. - m_dwAsyncSlotTimeout, - EplDllkCbMnTimerCycle, 0L, FALSE); - } -#endif - - break; - } -#endif - -#if EPL_DLL_PRES_READY_AFTER_SOA != FALSE - case kEplEventTypeDllkPresReady: - { - // post PRes to transmit FIFO - - NmtState = EplNmtkGetNmtState(); - - if (NmtState != kEplNmtCsBasicEthernet) { - // Does PRes exist? - if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES].m_pbBuffer != NULL) { // PRes does exist - pTxFrame = - (tEplFrame *) EplDllkInstance_g. - m_pTxBuffer[EPL_DLLK_TXFRAME_PRES]. - m_pbBuffer; - // update frame (NMT state, RD, RS, PR, MS, EN flags) - if (NmtState < kEplNmtCsPreOperational2) { // NMT state is not PreOp2, ReadyToOp or Op - // fake NMT state PreOp2, because PRes will be sent only in PreOp2 or greater - NmtState = - kEplNmtCsPreOperational2; - } - AmiSetByteToLe(&pTxFrame->m_Data.m_Pres. - m_le_bNmtStatus, - (u8) NmtState); - AmiSetByteToLe(&pTxFrame->m_Data.m_Pres. - m_le_bFlag2, - EplDllkInstance_g. - m_bFlag2); - if (NmtState != kEplNmtCsOperational) { // mark PDO as invalid in NMT state Op - // $$$ reset only RD flag; set other flags appropriately - AmiSetByteToLe(&pTxFrame-> - m_Data.m_Pres. - m_le_bFlag1, 0); - } - // $$$ make function that updates Pres, StatusRes - // mark PRes frame as ready for transmission - Ret = - EdrvTxMsgReady(&EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_PRES]); - } - } - - break; - } -#endif - default: - { - ASSERTMSG(FALSE, - "EplDllkProcess(): unhandled event type!\n"); - } - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkConfig -// -// Description: configure parameters of DLL -// -// Parameters: pDllConfigParam_p = configuration parameters -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkConfig(tEplDllConfigParam * pDllConfigParam_p) -{ - tEplKernel Ret = kEplSuccessful; - -// d.k. check of NMT state disabled, because CycleLen is programmed at run time by MN without reset of CN -/*tEplNmtState NmtState; - - NmtState = EplNmtkGetNmtState(); - - if (NmtState > kEplNmtGsResetConfiguration) - { // only allowed in state DLL_GS_INIT - Ret = kEplInvalidOperation; - goto Exit; - } -*/ - EPL_MEMCPY(&EplDllkInstance_g.m_DllConfigParam, pDllConfigParam_p, - (pDllConfigParam_p->m_uiSizeOfStruct < - sizeof(tEplDllConfigParam) ? pDllConfigParam_p-> - m_uiSizeOfStruct : sizeof(tEplDllConfigParam))); - - if ((EplDllkInstance_g.m_DllConfigParam.m_dwCycleLen != 0) - && (EplDllkInstance_g.m_DllConfigParam.m_dwLossOfFrameTolerance != 0)) { // monitor EPL cycle, calculate frame timeout - EplDllkInstance_g.m_ullFrameTimeout = (1000LL - * - ((unsigned long long) - EplDllkInstance_g. - m_DllConfigParam. - m_dwCycleLen)) - + - ((unsigned long long)EplDllkInstance_g.m_DllConfigParam. - m_dwLossOfFrameTolerance); - } else { - EplDllkInstance_g.m_ullFrameTimeout = 0LL; - } - - if (EplDllkInstance_g.m_DllConfigParam.m_fAsyncOnly != FALSE) { // it is configured as async-only CN - // disable multiplexed cycle, that m_uiCycleCount will not be incremented spuriously on SoC - EplDllkInstance_g.m_DllConfigParam.m_uiMultiplCycleCnt = 0; - } -//Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkSetIdentity -// -// Description: configure identity of local node for IdentResponse -// -// Parameters: pDllIdentParam_p = identity -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkSetIdentity(tEplDllIdentParam * pDllIdentParam_p) -{ - tEplKernel Ret = kEplSuccessful; - - EPL_MEMCPY(&EplDllkInstance_g.m_DllIdentParam, pDllIdentParam_p, - (pDllIdentParam_p->m_uiSizeOfStruct < - sizeof(tEplDllIdentParam) ? pDllIdentParam_p-> - m_uiSizeOfStruct : sizeof(tEplDllIdentParam))); - - // $$$ if IdentResponse frame exists update it - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkRegAsyncHandler -// -// Description: registers handler for non-EPL frames -// -// Parameters: pfnDllkCbAsync_p = pointer to callback function -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkRegAsyncHandler(tEplDllkCbAsync pfnDllkCbAsync_p) -{ - tEplKernel Ret = kEplSuccessful; - - if (EplDllkInstance_g.m_pfnCbAsync == NULL) { // no handler registered yet - EplDllkInstance_g.m_pfnCbAsync = pfnDllkCbAsync_p; - } else { // handler already registered - Ret = kEplDllCbAsyncRegistered; - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkDeregAsyncHandler -// -// Description: deregisters handler for non-EPL frames -// -// Parameters: pfnDllkCbAsync_p = pointer to callback function -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkDeregAsyncHandler(tEplDllkCbAsync pfnDllkCbAsync_p) -{ - tEplKernel Ret = kEplSuccessful; - - if (EplDllkInstance_g.m_pfnCbAsync == pfnDllkCbAsync_p) { // same handler is registered - // deregister it - EplDllkInstance_g.m_pfnCbAsync = NULL; - } else { // wrong handler or no handler registered - Ret = kEplDllCbAsyncRegistered; - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkSetAsndServiceIdFilter() -// -// Description: sets the specified node ID filter for the specified -// AsndServiceId. It registers C_DLL_MULTICAST_ASND in ethernet -// driver if any AsndServiceId is open. -// -// Parameters: ServiceId_p = ASnd Service ID -// Filter_p = node ID filter -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkSetAsndServiceIdFilter(tEplDllAsndServiceId ServiceId_p, - tEplDllAsndFilter Filter_p) -{ - tEplKernel Ret = kEplSuccessful; - - if (ServiceId_p < tabentries(EplDllkInstance_g.m_aAsndFilter)) { - EplDllkInstance_g.m_aAsndFilter[ServiceId_p] = Filter_p; - } - - return Ret; -} - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - -//--------------------------------------------------------------------------- -// -// Function: EplDllkSetFlag1OfNode() -// -// Description: sets Flag1 (for PReq and SoA) of the specified node ID. -// -// Parameters: uiNodeId_p = node ID -// bSoaFlag1_p = flag1 -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkSetFlag1OfNode(unsigned int uiNodeId_p, u8 bSoaFlag1_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplDllkNodeInfo *pNodeInfo; - - pNodeInfo = EplDllkGetNodeInfo(uiNodeId_p); - if (pNodeInfo == NULL) { // no node info structure available - Ret = kEplDllNoNodeInfo; - goto Exit; - } - // store flag1 in internal node info structure - pNodeInfo->m_bSoaFlag1 = bSoaFlag1_p; - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkGetFirstNodeInfo() -// -// Description: returns first info structure of first node in isochronous phase. -// It is only useful for ErrorHandlerk module. -// -// Parameters: ppNodeInfo_p = pointer to pointer of internal node info structure -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkGetFirstNodeInfo(tEplDllkNodeInfo ** ppNodeInfo_p) -{ - tEplKernel Ret = kEplSuccessful; - - *ppNodeInfo_p = EplDllkInstance_g.m_pFirstNodeInfo; - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkAddNode() -// -// Description: adds the specified node to the isochronous phase. -// -// Parameters: pNodeInfo_p = pointer of node info structure -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkAddNode(tEplDllNodeInfo * pNodeInfo_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplDllkNodeInfo *pIntNodeInfo; - tEplDllkNodeInfo **ppIntNodeInfo; - unsigned int uiHandle; - tEplFrame *pFrame; - unsigned int uiFrameSize; - - pIntNodeInfo = EplDllkGetNodeInfo(pNodeInfo_p->m_uiNodeId); - if (pIntNodeInfo == NULL) { // no node info structure available - Ret = kEplDllNoNodeInfo; - goto Exit; - } - - EPL_DLLK_DBG_POST_TRACE_VALUE(kEplEventTypeDllkAddNode, - pNodeInfo_p->m_uiNodeId, 0); - - // copy node configuration - pIntNodeInfo->m_dwPresTimeout = pNodeInfo_p->m_dwPresTimeout; - pIntNodeInfo->m_wPresPayloadLimit = pNodeInfo_p->m_wPresPayloadLimit; - - // $$$ d.k.: actually add node only if MN. On CN it is sufficient to update the node configuration - if (pNodeInfo_p->m_uiNodeId == EplDllkInstance_g.m_DllConfigParam.m_uiNodeId) { // we shall send PRes ourself - // insert our node at the end of the list - ppIntNodeInfo = &EplDllkInstance_g.m_pFirstNodeInfo; - while ((*ppIntNodeInfo != NULL) - && ((*ppIntNodeInfo)->m_pNextNodeInfo != NULL)) { - ppIntNodeInfo = &(*ppIntNodeInfo)->m_pNextNodeInfo; - } - if (*ppIntNodeInfo != NULL) { - if ((*ppIntNodeInfo)->m_uiNodeId == pNodeInfo_p->m_uiNodeId) { // node was already added to list - // $$$ d.k. maybe this should be an error - goto Exit; - } else { // add our node at the end of the list - ppIntNodeInfo = - &(*ppIntNodeInfo)->m_pNextNodeInfo; - } - } - // set "PReq"-TxBuffer to PRes-TxBuffer - pIntNodeInfo->m_pPreqTxBuffer = - &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES]; - } else { // normal CN shall be added to isochronous phase - // insert node into list in ascending order - ppIntNodeInfo = &EplDllkInstance_g.m_pFirstNodeInfo; - while ((*ppIntNodeInfo != NULL) - && ((*ppIntNodeInfo)->m_uiNodeId < - pNodeInfo_p->m_uiNodeId) - && ((*ppIntNodeInfo)->m_uiNodeId != - EplDllkInstance_g.m_DllConfigParam.m_uiNodeId)) { - ppIntNodeInfo = &(*ppIntNodeInfo)->m_pNextNodeInfo; - } - if ((*ppIntNodeInfo != NULL) && ((*ppIntNodeInfo)->m_uiNodeId == pNodeInfo_p->m_uiNodeId)) { // node was already added to list - // $$$ d.k. maybe this should be an error - goto Exit; - } - } - - // initialize elements of internal node info structure - pIntNodeInfo->m_bSoaFlag1 = 0; - pIntNodeInfo->m_fSoftDelete = FALSE; - pIntNodeInfo->m_NmtState = kEplNmtCsNotActive; - if (pIntNodeInfo->m_pPreqTxBuffer == NULL) { // create TxBuffer entry - uiFrameSize = pNodeInfo_p->m_wPreqPayloadLimit + 24; - Ret = - EplDllkCreateTxFrame(&uiHandle, &pFrame, &uiFrameSize, - kEplMsgTypePreq, - kEplDllAsndNotDefined); - if (Ret != kEplSuccessful) { - goto Exit; - } - pIntNodeInfo->m_pPreqTxBuffer = - &EplDllkInstance_g.m_pTxBuffer[uiHandle]; - AmiSetByteToLe(&pFrame->m_le_bDstNodeId, - (u8) pNodeInfo_p->m_uiNodeId); - - // set up destination MAC address - EPL_MEMCPY(pFrame->m_be_abDstMac, pIntNodeInfo->m_be_abMacAddr, - 6); - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) - { - tEplFrameInfo FrameInfo; - - // initially encode TPDO -> inform PDO module - FrameInfo.m_pFrame = pFrame; - FrameInfo.m_uiFrameSize = uiFrameSize; - Ret = EplPdokCbPdoTransmitted(&FrameInfo); - } -#endif - } - pIntNodeInfo->m_ulDllErrorEvents = 0L; - // add node to list - pIntNodeInfo->m_pNextNodeInfo = *ppIntNodeInfo; - *ppIntNodeInfo = pIntNodeInfo; - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkDeleteNode() -// -// Description: removes the specified node from the isochronous phase. -// -// Parameters: uiNodeId_p = node ID -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkDeleteNode(unsigned int uiNodeId_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplDllkNodeInfo *pIntNodeInfo; - tEplDllkNodeInfo **ppIntNodeInfo; - unsigned int uiHandle; - - pIntNodeInfo = EplDllkGetNodeInfo(uiNodeId_p); - if (pIntNodeInfo == NULL) { // no node info structure available - Ret = kEplDllNoNodeInfo; - goto Exit; - } - - EPL_DLLK_DBG_POST_TRACE_VALUE(kEplEventTypeDllkDelNode, uiNodeId_p, 0); - - // search node in whole list - ppIntNodeInfo = &EplDllkInstance_g.m_pFirstNodeInfo; - while ((*ppIntNodeInfo != NULL) - && ((*ppIntNodeInfo)->m_uiNodeId != uiNodeId_p)) { - ppIntNodeInfo = &(*ppIntNodeInfo)->m_pNextNodeInfo; - } - if ((*ppIntNodeInfo == NULL) || ((*ppIntNodeInfo)->m_uiNodeId != uiNodeId_p)) { // node was not found in list - // $$$ d.k. maybe this should be an error - goto Exit; - } - // remove node from list - *ppIntNodeInfo = pIntNodeInfo->m_pNextNodeInfo; - - if ((pIntNodeInfo->m_pPreqTxBuffer != NULL) - && (pIntNodeInfo->m_pPreqTxBuffer != &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES])) { // delete TxBuffer entry - uiHandle = - pIntNodeInfo->m_pPreqTxBuffer - - EplDllkInstance_g.m_pTxBuffer; - pIntNodeInfo->m_pPreqTxBuffer = NULL; - Ret = EplDllkDeleteTxFrame(uiHandle); -/* if (Ret != kEplSuccessful) - { - goto Exit; - }*/ - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkSoftDeleteNode() -// -// Description: removes the specified node not immediately from the isochronous phase. -// Instead the will be removed after error (late/loss PRes) without -// charging the error. -// -// Parameters: uiNodeId_p = node ID -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkSoftDeleteNode(unsigned int uiNodeId_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplDllkNodeInfo *pIntNodeInfo; - - pIntNodeInfo = EplDllkGetNodeInfo(uiNodeId_p); - if (pIntNodeInfo == NULL) { // no node info structure available - Ret = kEplDllNoNodeInfo; - goto Exit; - } - - EPL_DLLK_DBG_POST_TRACE_VALUE(kEplEventTypeDllkSoftDelNode, - uiNodeId_p, 0); - - pIntNodeInfo->m_fSoftDelete = TRUE; - - Exit: - return Ret; -} - -#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplDllkChangeState -// -// Description: change DLL state on event and diagnose some communication errors -// -// Parameters: NmtEvent_p = DLL event (wrapped in NMT event) -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplDllkChangeState(tEplNmtEvent NmtEvent_p, - tEplNmtState NmtState_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplEvent Event; - tEplErrorHandlerkEvent DllEvent; - - DllEvent.m_ulDllErrorEvents = 0; - DllEvent.m_uiNodeId = 0; - DllEvent.m_NmtState = NmtState_p; - - switch (NmtState_p) { - case kEplNmtGsOff: - case kEplNmtGsInitialising: - case kEplNmtGsResetApplication: - case kEplNmtGsResetCommunication: - case kEplNmtGsResetConfiguration: - case kEplNmtCsBasicEthernet: - // enter DLL_GS_INIT - EplDllkInstance_g.m_DllState = kEplDllGsInit; - break; - - case kEplNmtCsNotActive: - case kEplNmtCsPreOperational1: - // reduced EPL cycle is active - if (NmtEvent_p == kEplNmtEventDllCeSoc) { // SoC received - // enter DLL_CS_WAIT_PREQ - EplDllkInstance_g.m_DllState = kEplDllCsWaitPreq; - } else { - // enter DLL_GS_INIT - EplDllkInstance_g.m_DllState = kEplDllGsInit; - } - break; - - case kEplNmtCsPreOperational2: - case kEplNmtCsReadyToOperate: - case kEplNmtCsOperational: - // full EPL cycle is active - - switch (EplDllkInstance_g.m_DllState) { - case kEplDllCsWaitPreq: - switch (NmtEvent_p) { - // DLL_CT2 - case kEplNmtEventDllCePreq: - // enter DLL_CS_WAIT_SOA - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_RECVD_PREQ; - EplDllkInstance_g.m_DllState = kEplDllCsWaitSoa; - break; - - // DLL_CT8 - case kEplNmtEventDllCeFrameTimeout: - if (NmtState_p == kEplNmtCsPreOperational2) { // ignore frame timeout in PreOp2, - // because the previously configured cycle len - // may be wrong. - // 2008/10/15 d.k. If it would not be ignored, - // we would go cyclically to PreOp1 and on next - // SoC back to PreOp2. - break; - } - // report DLL_CEV_LOSS_SOC and DLL_CEV_LOSS_SOA - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOA | - EPL_DLL_ERR_CN_LOSS_SOC; - - // enter DLL_CS_WAIT_SOC - EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc; - break; - - case kEplNmtEventDllCeSoa: - // check if multiplexed and PReq should have been received in this cycle - // and if >= NMT_CS_READY_TO_OPERATE - if ((EplDllkInstance_g.m_uiCycleCount == 0) - && (NmtState_p >= kEplNmtCsReadyToOperate)) { // report DLL_CEV_LOSS_OF_PREQ - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_PREQ; - } - // enter DLL_CS_WAIT_SOC - EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc; - break; - - // DLL_CT7 - case kEplNmtEventDllCeSoc: - case kEplNmtEventDllCeAsnd: - // report DLL_CEV_LOSS_SOA - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOA; - - case kEplNmtEventDllCePres: - default: - // remain in this state - break; - } - break; - - case kEplDllCsWaitSoc: - switch (NmtEvent_p) { - // DLL_CT1 - case kEplNmtEventDllCeSoc: - // start of cycle and isochronous phase - // enter DLL_CS_WAIT_PREQ - EplDllkInstance_g.m_DllState = - kEplDllCsWaitPreq; - break; - - // DLL_CT4 -// case kEplNmtEventDllCePres: - case kEplNmtEventDllCeFrameTimeout: - if (NmtState_p == kEplNmtCsPreOperational2) { // ignore frame timeout in PreOp2, - // because the previously configured cycle len - // may be wrong. - // 2008/10/15 d.k. If it would not be ignored, - // we would go cyclically to PreOp1 and on next - // SoC back to PreOp2. - break; - } - // fall through - - case kEplNmtEventDllCePreq: - case kEplNmtEventDllCeSoa: - // report DLL_CEV_LOSS_SOC - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOC; - - case kEplNmtEventDllCeAsnd: - default: - // remain in this state - break; - } - break; - - case kEplDllCsWaitSoa: - switch (NmtEvent_p) { - case kEplNmtEventDllCeFrameTimeout: - // DLL_CT3 - if (NmtState_p == kEplNmtCsPreOperational2) { // ignore frame timeout in PreOp2, - // because the previously configured cycle len - // may be wrong. - // 2008/10/15 d.k. If it would not be ignored, - // we would go cyclically to PreOp1 and on next - // SoC back to PreOp2. - break; - } - // fall through - - case kEplNmtEventDllCePreq: - // report DLL_CEV_LOSS_SOC and DLL_CEV_LOSS_SOA - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOA | - EPL_DLL_ERR_CN_LOSS_SOC; - - case kEplNmtEventDllCeSoa: - // enter DLL_CS_WAIT_SOC - EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc; - break; - - // DLL_CT9 - case kEplNmtEventDllCeSoc: - // report DLL_CEV_LOSS_SOA - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOA; - - // enter DLL_CS_WAIT_PREQ - EplDllkInstance_g.m_DllState = - kEplDllCsWaitPreq; - break; - - // DLL_CT10 - case kEplNmtEventDllCeAsnd: - // report DLL_CEV_LOSS_SOA - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOA; - - case kEplNmtEventDllCePres: - default: - // remain in this state - break; - } - break; - - case kEplDllGsInit: - // enter DLL_CS_WAIT_PREQ - EplDllkInstance_g.m_DllState = kEplDllCsWaitPreq; - break; - - default: - break; - } - break; - - case kEplNmtCsStopped: - // full EPL cycle is active, but without PReq/PRes - - switch (EplDllkInstance_g.m_DllState) { - case kEplDllCsWaitPreq: - switch (NmtEvent_p) { - // DLL_CT2 - case kEplNmtEventDllCePreq: - // enter DLL_CS_WAIT_SOA - EplDllkInstance_g.m_DllState = kEplDllCsWaitSoa; - break; - - // DLL_CT8 - case kEplNmtEventDllCeFrameTimeout: - // report DLL_CEV_LOSS_SOC and DLL_CEV_LOSS_SOA - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOA | - EPL_DLL_ERR_CN_LOSS_SOC; - - case kEplNmtEventDllCeSoa: - // NMT_CS_STOPPED active - // it is Ok if no PReq was received - - // enter DLL_CS_WAIT_SOC - EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc; - break; - - // DLL_CT7 - case kEplNmtEventDllCeSoc: - case kEplNmtEventDllCeAsnd: - // report DLL_CEV_LOSS_SOA - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOA; - - case kEplNmtEventDllCePres: - default: - // remain in this state - break; - } - break; - - case kEplDllCsWaitSoc: - switch (NmtEvent_p) { - // DLL_CT1 - case kEplNmtEventDllCeSoc: - // start of cycle and isochronous phase - // enter DLL_CS_WAIT_SOA - EplDllkInstance_g.m_DllState = kEplDllCsWaitSoa; - break; - - // DLL_CT4 -// case kEplNmtEventDllCePres: - case kEplNmtEventDllCePreq: - case kEplNmtEventDllCeSoa: - case kEplNmtEventDllCeFrameTimeout: - // report DLL_CEV_LOSS_SOC - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOC; - - case kEplNmtEventDllCeAsnd: - default: - // remain in this state - break; - } - break; - - case kEplDllCsWaitSoa: - switch (NmtEvent_p) { - // DLL_CT3 - case kEplNmtEventDllCeFrameTimeout: - // report DLL_CEV_LOSS_SOC and DLL_CEV_LOSS_SOA - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOA | - EPL_DLL_ERR_CN_LOSS_SOC; - - case kEplNmtEventDllCeSoa: - // enter DLL_CS_WAIT_SOC - EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc; - break; - - // DLL_CT9 - case kEplNmtEventDllCeSoc: - // report DLL_CEV_LOSS_SOA - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOA; - // remain in DLL_CS_WAIT_SOA - break; - - // DLL_CT10 - case kEplNmtEventDllCeAsnd: - // report DLL_CEV_LOSS_SOA - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOA; - - case kEplNmtEventDllCePreq: - // NMT_CS_STOPPED active and we do not expect any PReq - // so just ignore it - case kEplNmtEventDllCePres: - default: - // remain in this state - break; - } - break; - - case kEplDllGsInit: - default: - // enter DLL_CS_WAIT_PREQ - EplDllkInstance_g.m_DllState = kEplDllCsWaitSoa; - break; - } - break; - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - case kEplNmtMsNotActive: - case kEplNmtMsBasicEthernet: - break; - - case kEplNmtMsPreOperational1: - // reduced EPL cycle is active - if (EplDllkInstance_g.m_DllState != kEplDllMsNonCyclic) { // stop cycle timer -#if EPL_TIMER_USE_HIGHRES != FALSE - Ret = - EplTimerHighReskDeleteTimer(&EplDllkInstance_g. - m_TimerHdlCycle); -#endif - EplDllkInstance_g.m_DllState = kEplDllMsNonCyclic; - - // stop further processing, - // because it will be restarted by NMT MN module - break; - } - - switch (NmtEvent_p) { - case kEplNmtEventDllMeSocTrig: - case kEplNmtEventDllCeAsnd: - { // because of reduced EPL cycle SoA shall be triggered, not SoC - tEplDllState DummyDllState; - - Ret = - EplDllkAsyncFrameNotReceived - (EplDllkInstance_g.m_LastReqServiceId, - EplDllkInstance_g.m_uiLastTargetNodeId); - - // go ahead and send SoA - Ret = EplDllkMnSendSoa(NmtState_p, - &DummyDllState, - (EplDllkInstance_g. - m_uiCycleCount >= - EPL_C_DLL_PREOP1_START_CYCLES)); - // increment cycle counter to detect if EPL_C_DLL_PREOP1_START_CYCLES empty cycles are elapsed - EplDllkInstance_g.m_uiCycleCount++; - - // reprogram timer -#if EPL_TIMER_USE_HIGHRES != FALSE - if (EplDllkInstance_g.m_DllConfigParam. - m_dwAsyncSlotTimeout != 0) { - Ret = - EplTimerHighReskModifyTimerNs - (&EplDllkInstance_g.m_TimerHdlCycle, - EplDllkInstance_g.m_DllConfigParam. - m_dwAsyncSlotTimeout, - EplDllkCbMnTimerCycle, 0L, FALSE); - } -#endif - break; - } - - default: - break; - } - break; - - case kEplNmtMsPreOperational2: - case kEplNmtMsReadyToOperate: - case kEplNmtMsOperational: - // full EPL cycle is active - switch (NmtEvent_p) { - case kEplNmtEventDllMeSocTrig: - { - // update cycle counter - if (EplDllkInstance_g.m_DllConfigParam.m_uiMultiplCycleCnt > 0) { // multiplexed cycle active - EplDllkInstance_g.m_uiCycleCount = - (EplDllkInstance_g.m_uiCycleCount + - 1) % - EplDllkInstance_g.m_DllConfigParam. - m_uiMultiplCycleCnt; - // $$$ check multiplexed cycle restart - // -> toggle MC flag - // -> change node linked list - } else { // non-multiplexed cycle active - // start with first node in isochronous phase - EplDllkInstance_g.m_pCurNodeInfo = NULL; - } - - switch (EplDllkInstance_g.m_DllState) { - case kEplDllMsNonCyclic: - { // start continuous cycle timer -#if EPL_TIMER_USE_HIGHRES != FALSE - Ret = - EplTimerHighReskModifyTimerNs - (&EplDllkInstance_g. - m_TimerHdlCycle, - EplDllkInstance_g. - m_ullFrameTimeout, - EplDllkCbMnTimerCycle, 0L, - TRUE); -#endif - // continue with sending SoC - } - - case kEplDllMsWaitAsnd: - case kEplDllMsWaitSocTrig: - { // if m_LastReqServiceId is still valid, - // SoA was not correctly answered - // and user part has to be informed - Ret = - EplDllkAsyncFrameNotReceived - (EplDllkInstance_g. - m_LastReqServiceId, - EplDllkInstance_g. - m_uiLastTargetNodeId); - - // send SoC - Ret = EplDllkMnSendSoc(); - - // new DLL state - EplDllkInstance_g.m_DllState = - kEplDllMsWaitPreqTrig; - - // start WaitSoCPReq Timer -#if EPL_TIMER_USE_HIGHRES != FALSE - Ret = - EplTimerHighReskModifyTimerNs - (&EplDllkInstance_g. - m_TimerHdlResponse, - EplDllkInstance_g. - m_DllConfigParam. - m_dwWaitSocPreq, - EplDllkCbMnTimerResponse, - 0L, FALSE); -#endif - break; - } - - default: - { // wrong DLL state / cycle time exceeded - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_MN_CYCTIMEEXCEED; - EplDllkInstance_g.m_DllState = - kEplDllMsWaitSocTrig; - break; - } - } - - break; - } - - case kEplNmtEventDllMePresTimeout: - { - - switch (EplDllkInstance_g.m_DllState) { - case kEplDllMsWaitPres: - { // PRes not received - - if (EplDllkInstance_g.m_pCurNodeInfo->m_fSoftDelete == FALSE) { // normal isochronous CN - DllEvent. - m_ulDllErrorEvents - |= - EPL_DLL_ERR_MN_CN_LOSS_PRES; - DllEvent.m_uiNodeId = - EplDllkInstance_g. - m_pCurNodeInfo-> - m_uiNodeId; - } else { // CN shall be deleted softly - Event.m_EventSink = - kEplEventSinkDllkCal; - Event.m_EventType = - kEplEventTypeDllkSoftDelNode; - // $$$ d.k. set Event.m_NetTime to current time - Event.m_uiSize = - sizeof(unsigned - int); - Event.m_pArg = - &EplDllkInstance_g. - m_pCurNodeInfo-> - m_uiNodeId; - Ret = - EplEventkPost - (&Event); - } - - // continue with sending next PReq - } - - case kEplDllMsWaitPreqTrig: - { - // send next PReq - Ret = - EplDllkMnSendPreq - (NmtState_p, - &EplDllkInstance_g. - m_DllState); - - break; - } - - default: - { // wrong DLL state - break; - } - } - - break; - } - - case kEplNmtEventDllCePres: - { - - switch (EplDllkInstance_g.m_DllState) { - case kEplDllMsWaitPres: - { // PRes received - // send next PReq - Ret = - EplDllkMnSendPreq - (NmtState_p, - &EplDllkInstance_g. - m_DllState); - - break; - } - - default: - { // wrong DLL state - break; - } - } - - break; - } - - case kEplNmtEventDllMeSoaTrig: - { - - switch (EplDllkInstance_g.m_DllState) { - case kEplDllMsWaitSoaTrig: - { // MN PRes sent - // send SoA - Ret = - EplDllkMnSendSoa(NmtState_p, - &EplDllkInstance_g. - m_DllState, - TRUE); - - break; - } - - default: - { // wrong DLL state - break; - } - } - - break; - } - - case kEplNmtEventDllCeAsnd: - { // ASnd has been received, but it may be not the requested one -/* - // report if SoA was correctly answered - Ret = EplDllkAsyncFrameNotReceived(EplDllkInstance_g.m_LastReqServiceId, - EplDllkInstance_g.m_uiLastTargetNodeId); -*/ - if (EplDllkInstance_g.m_DllState == - kEplDllMsWaitAsnd) { - EplDllkInstance_g.m_DllState = - kEplDllMsWaitSocTrig; - } - break; - } - - default: - break; - } - break; -#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - - default: - break; - } - - if (DllEvent.m_ulDllErrorEvents != 0) { // error event set -> post it to error handler - Event.m_EventSink = kEplEventSinkErrk; - Event.m_EventType = kEplEventTypeDllError; - // $$$ d.k. set Event.m_NetTime to current time - Event.m_uiSize = sizeof(DllEvent); - Event.m_pArg = &DllEvent; - Ret = EplEventkPost(&Event); - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCbFrameReceived() -// -// Description: called from EdrvInterruptHandler() -// -// Parameters: pRxBuffer_p = receive buffer structure -// -// Returns: (none) -// -// -// State: -// -//--------------------------------------------------------------------------- - -static void EplDllkCbFrameReceived(tEdrvRxBuffer * pRxBuffer_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplNmtState NmtState; - tEplNmtEvent NmtEvent = kEplNmtEventNoEvent; - tEplEvent Event; - tEplFrame *pFrame; - tEplFrame *pTxFrame; - tEdrvTxBuffer *pTxBuffer = NULL; - tEplFrameInfo FrameInfo; - tEplMsgType MsgType; - tEplDllReqServiceId ReqServiceId; - unsigned int uiAsndServiceId; - unsigned int uiNodeId; - u8 bFlag1; - - BENCHMARK_MOD_02_SET(3); - NmtState = EplNmtkGetNmtState(); - - if (NmtState <= kEplNmtGsResetConfiguration) { - goto Exit; - } - - pFrame = (tEplFrame *) pRxBuffer_p->m_pbBuffer; - -#if EDRV_EARLY_RX_INT != FALSE - switch (pRxBuffer_p->m_BufferInFrame) { - case kEdrvBufferFirstInFrame: - { - MsgType = - (tEplMsgType) AmiGetByteFromLe(&pFrame-> - m_le_bMessageType); - if (MsgType == kEplMsgTypePreq) { - if (EplDllkInstance_g.m_DllState == kEplDllCsWaitPreq) { // PReq expected and actually received - // d.k.: The condition above is sufficent, because EPL cycle is active - // and no non-EPL frame shall be received in isochronous phase. - // start transmission PRes - // $$$ What if Tx buffer is invalid? - pTxBuffer = - &EplDllkInstance_g. - m_pTxBuffer[EPL_DLLK_TXFRAME_PRES]; -#if (EPL_DLL_PRES_READY_AFTER_SOA != FALSE) || (EPL_DLL_PRES_READY_AFTER_SOC != FALSE) - Ret = EdrvTxMsgStart(pTxBuffer); -#else - pTxFrame = - (tEplFrame *) pTxBuffer->m_pbBuffer; - // update frame (NMT state, RD, RS, PR, MS, EN flags) - AmiSetByteToLe(&pTxFrame->m_Data.m_Pres. - m_le_bNmtStatus, - (u8) NmtState); - AmiSetByteToLe(&pTxFrame->m_Data.m_Pres. - m_le_bFlag2, - EplDllkInstance_g. - m_bFlag2); - if (NmtState != kEplNmtCsOperational) { // mark PDO as invalid in NMT state Op - // $$$ reset only RD flag; set other flags appropriately - AmiSetByteToLe(&pTxFrame-> - m_Data.m_Pres. - m_le_bFlag1, 0); - } - // $$$ make function that updates Pres, StatusRes - // send PRes frame - Ret = EdrvSendTxMsg(pTxBuffer); -#endif - } - } - goto Exit; - } - - case kEdrvBufferMiddleInFrame: - { - goto Exit; - } - - case kEdrvBufferLastInFrame: - { - break; - } - } -#endif - - FrameInfo.m_pFrame = pFrame; - FrameInfo.m_uiFrameSize = pRxBuffer_p->m_uiRxMsgLen; - FrameInfo.m_NetTime.m_dwNanoSec = pRxBuffer_p->m_NetTime.m_dwNanoSec; - FrameInfo.m_NetTime.m_dwSec = pRxBuffer_p->m_NetTime.m_dwSec; - - if (AmiGetWordFromBe(&pFrame->m_be_wEtherType) != EPL_C_DLL_ETHERTYPE_EPL) { // non-EPL frame - //TRACE2("EplDllkCbFrameReceived: pfnCbAsync=0x%p SrcMAC=0x%llx\n", EplDllkInstance_g.m_pfnCbAsync, AmiGetQword48FromBe(pFrame->m_be_abSrcMac)); - if (EplDllkInstance_g.m_pfnCbAsync != NULL) { // handler for async frames is registered - EplDllkInstance_g.m_pfnCbAsync(&FrameInfo); - } - - goto Exit; - } - - MsgType = (tEplMsgType) AmiGetByteFromLe(&pFrame->m_le_bMessageType); - switch (MsgType) { - case kEplMsgTypePreq: - { - // PReq frame - // d.k.: (we assume that this PReq frame is intended for us and don't check DstNodeId) - if (AmiGetByteFromLe(&pFrame->m_le_bDstNodeId) != EplDllkInstance_g.m_DllConfigParam.m_uiNodeId) { // this PReq is not intended for us - goto Exit; - } - NmtEvent = kEplNmtEventDllCePreq; - - if (NmtState >= kEplNmtMsNotActive) { // MN is active -> wrong msg type - break; - } -#if EDRV_EARLY_RX_INT == FALSE - if (NmtState >= kEplNmtCsPreOperational2) { // respond to and process PReq frames only in PreOp2, ReadyToOp and Op - // Does PRes exist? - pTxBuffer = - &EplDllkInstance_g. - m_pTxBuffer[EPL_DLLK_TXFRAME_PRES]; - if (pTxBuffer->m_pbBuffer != NULL) { // PRes does exist -#if (EPL_DLL_PRES_READY_AFTER_SOA != FALSE) || (EPL_DLL_PRES_READY_AFTER_SOC != FALSE) - EdrvTxMsgStart(pTxBuffer); -#else - pTxFrame = - (tEplFrame *) pTxBuffer->m_pbBuffer; - // update frame (NMT state, RD, RS, PR, MS, EN flags) - AmiSetByteToLe(&pTxFrame->m_Data.m_Pres. - m_le_bNmtStatus, - (u8) NmtState); - AmiSetByteToLe(&pTxFrame->m_Data.m_Pres. - m_le_bFlag2, - EplDllkInstance_g. - m_bFlag2); - bFlag1 = - AmiGetByteFromLe(&pFrame->m_Data. - m_Preq. - m_le_bFlag1); - // save EA flag - EplDllkInstance_g.m_bMnFlag1 = - (EplDllkInstance_g. - m_bMnFlag1 & ~EPL_FRAME_FLAG1_EA) - | (bFlag1 & EPL_FRAME_FLAG1_EA); - // preserve MS flag - bFlag1 &= EPL_FRAME_FLAG1_MS; - // add EN flag from Error signaling module - bFlag1 |= - EplDllkInstance_g. - m_bFlag1 & EPL_FRAME_FLAG1_EN; - if (NmtState != kEplNmtCsOperational) { // mark PDO as invalid in NMT state Op - // reset only RD flag - AmiSetByteToLe(&pTxFrame-> - m_Data.m_Pres. - m_le_bFlag1, - bFlag1); - } else { // leave RD flag untouched - AmiSetByteToLe(&pTxFrame-> - m_Data.m_Pres. - m_le_bFlag1, - (AmiGetByteFromLe - (&pTxFrame-> - m_Data.m_Pres. - m_le_bFlag1) & - EPL_FRAME_FLAG1_RD) - | bFlag1); - } - // $$$ update EPL_DLL_PRES_READY_AFTER_* code - // send PRes frame - Ret = EdrvSendTxMsg(pTxBuffer); - if (Ret != kEplSuccessful) { - goto Exit; - } -#endif - } -#endif - // inform PDO module -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) - if (NmtState >= kEplNmtCsReadyToOperate) { // inform PDO module only in ReadyToOp and Op - if (NmtState != kEplNmtCsOperational) { - // reset RD flag and all other flags, but that does not matter, because they were processed above - AmiSetByteToLe(&pFrame->m_Data. - m_Preq. - m_le_bFlag1, 0); - } - // compares real frame size and PDO size - if ((unsigned - int)(AmiGetWordFromLe(&pFrame-> - m_Data. - m_Preq. - m_le_wSize) + - 24) - > FrameInfo.m_uiFrameSize) { // format error - tEplErrorHandlerkEvent DllEvent; - - DllEvent.m_ulDllErrorEvents = - EPL_DLL_ERR_INVALID_FORMAT; - DllEvent.m_uiNodeId = - AmiGetByteFromLe(&pFrame-> - m_le_bSrcNodeId); - DllEvent.m_NmtState = NmtState; - Event.m_EventSink = - kEplEventSinkErrk; - Event.m_EventType = - kEplEventTypeDllError; - Event.m_NetTime = - FrameInfo.m_NetTime; - Event.m_uiSize = - sizeof(DllEvent); - Event.m_pArg = &DllEvent; - Ret = EplEventkPost(&Event); - break; - } - // forward PReq frame as RPDO to PDO module - Ret = EplPdokCbPdoReceived(&FrameInfo); - - } -#if (EPL_DLL_PRES_READY_AFTER_SOC != FALSE) - if (pTxBuffer->m_pbBuffer != NULL) { // PRes does exist - // inform PDO module about PRes after PReq - FrameInfo.m_pFrame = - (tEplFrame *) pTxBuffer->m_pbBuffer; - FrameInfo.m_uiFrameSize = - pTxBuffer->m_uiMaxBufferLen; - Ret = - EplPdokCbPdoTransmitted(&FrameInfo); - } -#endif -#endif - -#if EDRV_EARLY_RX_INT == FALSE - // $$$ inform emergency protocol handling (error signaling module) about flags - } -#endif - - // reset cycle counter - EplDllkInstance_g.m_uiCycleCount = 0; - - break; - } - - case kEplMsgTypePres: - { -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - tEplDllkNodeInfo *pIntNodeInfo; - tEplHeartbeatEvent HeartbeatEvent; -#endif - - // PRes frame - NmtEvent = kEplNmtEventDllCePres; - - uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bSrcNodeId); - - if ((NmtState >= kEplNmtCsPreOperational2) - && (NmtState <= kEplNmtCsOperational)) { // process PRes frames only in PreOp2, ReadyToOp and Op of CN - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - pIntNodeInfo = EplDllkGetNodeInfo(uiNodeId); - if (pIntNodeInfo == NULL) { // no node info structure available - Ret = kEplDllNoNodeInfo; - goto Exit; - } - } else if (EplDllkInstance_g.m_DllState == kEplDllMsWaitPres) { // or process PRes frames in MsWaitPres - - pIntNodeInfo = EplDllkInstance_g.m_pCurNodeInfo; - if ((pIntNodeInfo == NULL) || (pIntNodeInfo->m_uiNodeId != uiNodeId)) { // ignore PRes, because it is from wrong CN - // $$$ maybe post event to NmtMn module - goto Exit; - } - // forward Flag2 to asynchronous scheduler - bFlag1 = - AmiGetByteFromLe(&pFrame->m_Data.m_Asnd. - m_Payload.m_StatusResponse. - m_le_bFlag2); - Ret = - EplDllkCalAsyncSetPendingRequests(uiNodeId, - ((tEplDllAsyncReqPriority) ((bFlag1 & EPL_FRAME_FLAG2_PR) >> EPL_FRAME_FLAG2_PR_SHIFT)), (bFlag1 & EPL_FRAME_FLAG2_RS)); - -#endif - } else { // ignore PRes, because it was received in wrong NMT state - // but execute EplDllkChangeState() and post event to NMT module - break; - } - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - { // check NMT state of CN - HeartbeatEvent.m_wErrorCode = EPL_E_NO_ERROR; - HeartbeatEvent.m_NmtState = - (tEplNmtState) (AmiGetByteFromLe - (&pFrame->m_Data.m_Pres. - m_le_bNmtStatus) | - EPL_NMT_TYPE_CS); - if (pIntNodeInfo->m_NmtState != HeartbeatEvent.m_NmtState) { // NMT state of CN has changed -> post event to NmtMnu module - if (pIntNodeInfo->m_fSoftDelete == FALSE) { // normal isochronous CN - HeartbeatEvent.m_uiNodeId = - uiNodeId; - Event.m_EventSink = - kEplEventSinkNmtMnu; - Event.m_EventType = - kEplEventTypeHeartbeat; - Event.m_uiSize = - sizeof(HeartbeatEvent); - Event.m_pArg = &HeartbeatEvent; - } else { // CN shall be deleted softly - Event.m_EventSink = - kEplEventSinkDllkCal; - Event.m_EventType = - kEplEventTypeDllkSoftDelNode; - Event.m_uiSize = - sizeof(unsigned int); - Event.m_pArg = - &pIntNodeInfo->m_uiNodeId; - } - Event.m_NetTime = FrameInfo.m_NetTime; - Ret = EplEventkPost(&Event); - - // save current NMT state of CN in internal node structure - pIntNodeInfo->m_NmtState = - HeartbeatEvent.m_NmtState; - } - } -#endif - - // inform PDO module -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) - if ((NmtState != kEplNmtCsPreOperational2) - && (NmtState != kEplNmtMsPreOperational2)) { // inform PDO module only in ReadyToOp and Op - // compare real frame size and PDO size? - if (((unsigned - int)(AmiGetWordFromLe(&pFrame->m_Data. - m_Pres.m_le_wSize) + - 24) - > FrameInfo.m_uiFrameSize) -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - || - (AmiGetWordFromLe - (&pFrame->m_Data.m_Pres.m_le_wSize) > - pIntNodeInfo->m_wPresPayloadLimit) -#endif - ) { // format error - tEplErrorHandlerkEvent DllEvent; - - DllEvent.m_ulDllErrorEvents = - EPL_DLL_ERR_INVALID_FORMAT; - DllEvent.m_uiNodeId = uiNodeId; - DllEvent.m_NmtState = NmtState; - Event.m_EventSink = kEplEventSinkErrk; - Event.m_EventType = - kEplEventTypeDllError; - Event.m_NetTime = FrameInfo.m_NetTime; - Event.m_uiSize = sizeof(DllEvent); - Event.m_pArg = &DllEvent; - Ret = EplEventkPost(&Event); - break; - } - if ((NmtState != kEplNmtCsOperational) - && (NmtState != kEplNmtMsOperational)) { - // reset RD flag and all other flags, but that does not matter, because they were processed above - AmiSetByteToLe(&pFrame->m_Data.m_Pres. - m_le_bFlag1, 0); - } - Ret = EplPdokCbPdoReceived(&FrameInfo); - } -#endif - - break; - } - - case kEplMsgTypeSoc: - { - // SoC frame - NmtEvent = kEplNmtEventDllCeSoc; - - if (NmtState >= kEplNmtMsNotActive) { // MN is active -> wrong msg type - break; - } -#if EPL_DLL_PRES_READY_AFTER_SOC != FALSE - // post PRes to transmit FIFO of the ethernet controller, but don't start - // transmission over bus - pTxBuffer = - &EplDllkInstance_g. - m_pTxBuffer[EPL_DLLK_TXFRAME_PRES]; - // Does PRes exist? - if (pTxBuffer->m_pbBuffer != NULL) { // PRes does exist - pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer; - // update frame (NMT state, RD, RS, PR, MS, EN flags) - if (NmtState < kEplNmtCsPreOperational2) { // NMT state is not PreOp2, ReadyToOp or Op - // fake NMT state PreOp2, because PRes will be sent only in PreOp2 or greater - NmtState = kEplNmtCsPreOperational2; - } - AmiSetByteToLe(&pTxFrame->m_Data.m_Pres. - m_le_bNmtStatus, - (u8) NmtState); - AmiSetByteToLe(&pTxFrame->m_Data.m_Pres. - m_le_bFlag2, - EplDllkInstance_g.m_bFlag2); - if (NmtState != kEplNmtCsOperational) { // mark PDO as invalid in NMT state Op - // $$$ reset only RD flag; set other flags appropriately - AmiSetByteToLe(&pTxFrame->m_Data.m_Pres. - m_le_bFlag1, 0); - } - // $$$ make function that updates Pres, StatusRes - // mark PRes frame as ready for transmission - Ret = EdrvTxMsgReady(pTxBuffer); - } -#endif - - if (NmtState >= kEplNmtCsPreOperational2) { // SoC frames only in PreOp2, ReadyToOp and Op - // trigger synchronous task - Event.m_EventSink = kEplEventSinkSync; - Event.m_EventType = kEplEventTypeSync; - Event.m_uiSize = 0; - Ret = EplEventkPost(&Event); - - // update cycle counter - if (EplDllkInstance_g.m_DllConfigParam.m_uiMultiplCycleCnt > 0) { // multiplexed cycle active - EplDllkInstance_g.m_uiCycleCount = - (EplDllkInstance_g.m_uiCycleCount + - 1) % - EplDllkInstance_g.m_DllConfigParam. - m_uiMultiplCycleCnt; - } - } - // reprogram timer -#if EPL_TIMER_USE_HIGHRES != FALSE - if (EplDllkInstance_g.m_ullFrameTimeout != 0) { - Ret = - EplTimerHighReskModifyTimerNs - (&EplDllkInstance_g.m_TimerHdlCycle, - EplDllkInstance_g.m_ullFrameTimeout, - EplDllkCbCnTimer, 0L, FALSE); - } -#endif - - break; - } - - case kEplMsgTypeSoa: - { - // SoA frame - NmtEvent = kEplNmtEventDllCeSoa; - - if (NmtState >= kEplNmtMsNotActive) { // MN is active -> wrong msg type - break; - } - - pTxFrame = NULL; - - if ((NmtState & EPL_NMT_SUPERSTATE_MASK) != EPL_NMT_CS_EPLMODE) { // do not respond, if NMT state is < PreOp1 (i.e. not EPL_MODE) - break; - } - // check TargetNodeId - uiNodeId = - AmiGetByteFromLe(&pFrame->m_Data.m_Soa. - m_le_bReqServiceTarget); - if (uiNodeId == EplDllkInstance_g.m_DllConfigParam.m_uiNodeId) { // local node is the target of the current request - - // check ServiceId - ReqServiceId = - (tEplDllReqServiceId) - AmiGetByteFromLe(&pFrame->m_Data.m_Soa. - m_le_bReqServiceId); - if (ReqServiceId == kEplDllReqServiceStatus) { // StatusRequest - if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_STATUSRES].m_pbBuffer != NULL) { // StatusRes does exist - - pTxFrame = - (tEplFrame *) - EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_STATUSRES]. - m_pbBuffer; - // update StatusRes frame (NMT state, EN, EC, RS, PR flags) - AmiSetByteToLe(&pTxFrame-> - m_Data.m_Asnd. - m_Payload. - m_StatusResponse. - m_le_bNmtStatus, - (u8) NmtState); - AmiSetByteToLe(&pTxFrame-> - m_Data.m_Asnd. - m_Payload. - m_StatusResponse. - m_le_bFlag1, - EplDllkInstance_g. - m_bFlag1); - AmiSetByteToLe(&pTxFrame-> - m_Data.m_Asnd. - m_Payload. - m_StatusResponse. - m_le_bFlag2, - EplDllkInstance_g. - m_bFlag2); - // send StatusRes - Ret = - EdrvSendTxMsg - (&EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_STATUSRES]); - if (Ret != kEplSuccessful) { - goto Exit; - } - TGT_DBG_SIGNAL_TRACE_POINT(8); - - // update error signaling - bFlag1 = - AmiGetByteFromLe(&pFrame-> - m_Data. - m_Soa. - m_le_bFlag1); - if (((bFlag1 ^ EplDllkInstance_g.m_bMnFlag1) & EPL_FRAME_FLAG1_ER) != 0) { // exception reset flag was changed by MN - // assume same state for EC in next cycle (clear all other bits) - if ((bFlag1 & - EPL_FRAME_FLAG1_ER) - != 0) { - // set EC and reset rest - EplDllkInstance_g. - m_bFlag1 = - EPL_FRAME_FLAG1_EC; - } else { - // reset complete flag 1 (including EC and EN) - EplDllkInstance_g. - m_bFlag1 = - 0; - } - } - // save flag 1 from MN for Status request response cycle - EplDllkInstance_g.m_bMnFlag1 = - bFlag1; - } - } else if (ReqServiceId == kEplDllReqServiceIdent) { // IdentRequest - if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_IDENTRES].m_pbBuffer != NULL) { // IdentRes does exist - pTxFrame = - (tEplFrame *) - EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_IDENTRES]. - m_pbBuffer; - // update IdentRes frame (NMT state, RS, PR flags) - AmiSetByteToLe(&pTxFrame-> - m_Data.m_Asnd. - m_Payload. - m_IdentResponse. - m_le_bNmtStatus, - (u8) NmtState); - AmiSetByteToLe(&pTxFrame-> - m_Data.m_Asnd. - m_Payload. - m_IdentResponse. - m_le_bFlag2, - EplDllkInstance_g. - m_bFlag2); - // send IdentRes - Ret = - EdrvSendTxMsg - (&EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_IDENTRES]); - if (Ret != kEplSuccessful) { - goto Exit; - } - TGT_DBG_SIGNAL_TRACE_POINT(7); - } - } else if (ReqServiceId == kEplDllReqServiceNmtRequest) { // NmtRequest - if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_pbBuffer != NULL) { // NmtRequest does exist - // check if frame is not empty and not being filled - if (EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NMTREQ]. - m_uiTxMsgLen > - EPL_DLLK_BUFLEN_FILLING) { - /*if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen < EPL_DLLK_BUFLEN_MIN) - { // pad frame - EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen = EPL_DLLK_BUFLEN_MIN; - } */ - // memorize transmission - pTxFrame = - (tEplFrame *) 1; - // send NmtRequest - Ret = - EdrvSendTxMsg - (&EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NMTREQ]); - if (Ret != - kEplSuccessful) { - goto Exit; - } - - } - } - - } else if (ReqServiceId == kEplDllReqServiceUnspecified) { // unspecified invite - if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL].m_pbBuffer != NULL) { // non-EPL frame does exist - // check if frame is not empty and not being filled - if (EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NONEPL]. - m_uiTxMsgLen > - EPL_DLLK_BUFLEN_FILLING) { - /*if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen < EPL_DLLK_BUFLEN_MIN) - { // pad frame - EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen = EPL_DLLK_BUFLEN_MIN; - } */ - // memorize transmission - pTxFrame = - (tEplFrame *) 1; - // send non-EPL frame - Ret = - EdrvSendTxMsg - (&EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NONEPL]); - if (Ret != - kEplSuccessful) { - goto Exit; - } - - } - } - - } else if (ReqServiceId == kEplDllReqServiceNo) { // no async service requested -> do nothing - } - } -#if EPL_DLL_PRES_READY_AFTER_SOA != FALSE - if (pTxFrame == NULL) { // signal process function readiness of PRes frame - Event.m_EventSink = kEplEventSinkDllk; - Event.m_EventType = kEplEventTypeDllkPresReady; - Event.m_uiSize = 0; - Event.m_pArg = NULL; - Ret = EplEventkPost(&Event); - } -#endif - - // inform PDO module -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) -// Ret = EplPdokCbSoa(&FrameInfo); -#endif - - // $$$ put SrcNodeId, NMT state and NetTime as HeartbeatEvent into eventqueue - - // $$$ inform emergency protocol handling about flags - break; - } - - case kEplMsgTypeAsnd: - { - // ASnd frame - NmtEvent = kEplNmtEventDllCeAsnd; - - // ASnd service registered? - uiAsndServiceId = - (unsigned int)AmiGetByteFromLe(&pFrame->m_Data. - m_Asnd. - m_le_bServiceId); - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - if ((EplDllkInstance_g.m_DllState >= kEplDllMsNonCyclic) - && - ((((tEplDllAsndServiceId) uiAsndServiceId) == - kEplDllAsndStatusResponse) - || (((tEplDllAsndServiceId) uiAsndServiceId) == kEplDllAsndIdentResponse))) { // StatusRes or IdentRes received - uiNodeId = - AmiGetByteFromLe(&pFrame->m_le_bSrcNodeId); - if ((EplDllkInstance_g.m_LastReqServiceId == - ((tEplDllReqServiceId) uiAsndServiceId)) - && (uiNodeId == EplDllkInstance_g.m_uiLastTargetNodeId)) { // mark request as responded - EplDllkInstance_g.m_LastReqServiceId = - kEplDllReqServiceNo; - } - if (((tEplDllAsndServiceId) uiAsndServiceId) == kEplDllAsndIdentResponse) { // memorize MAC address of CN for PReq - tEplDllkNodeInfo *pIntNodeInfo; - - pIntNodeInfo = - EplDllkGetNodeInfo(uiNodeId); - if (pIntNodeInfo == NULL) { // no node info structure available - Ret = kEplDllNoNodeInfo; - } else { - EPL_MEMCPY(pIntNodeInfo-> - m_be_abMacAddr, - pFrame-> - m_be_abSrcMac, 6); - } - } - // forward Flag2 to asynchronous scheduler - bFlag1 = - AmiGetByteFromLe(&pFrame->m_Data.m_Asnd. - m_Payload.m_StatusResponse. - m_le_bFlag2); - Ret = - EplDllkCalAsyncSetPendingRequests(uiNodeId, - ((tEplDllAsyncReqPriority) ((bFlag1 & EPL_FRAME_FLAG2_PR) >> EPL_FRAME_FLAG2_PR_SHIFT)), (bFlag1 & EPL_FRAME_FLAG2_RS)); - } -#endif - - if (uiAsndServiceId < EPL_DLL_MAX_ASND_SERVICE_ID) { // ASnd service ID is valid - if (EplDllkInstance_g.m_aAsndFilter[uiAsndServiceId] == kEplDllAsndFilterAny) { // ASnd service ID is registered - // forward frame via async receive FIFO to userspace - Ret = - EplDllkCalAsyncFrameReceived - (&FrameInfo); - } else if (EplDllkInstance_g.m_aAsndFilter[uiAsndServiceId] == kEplDllAsndFilterLocal) { // ASnd service ID is registered, but only local node ID or broadcasts - // shall be forwarded - uiNodeId = - AmiGetByteFromLe(&pFrame-> - m_le_bDstNodeId); - if ((uiNodeId == - EplDllkInstance_g.m_DllConfigParam. - m_uiNodeId) - || (uiNodeId == EPL_C_ADR_BROADCAST)) { // ASnd frame is intended for us - // forward frame via async receive FIFO to userspace - Ret = - EplDllkCalAsyncFrameReceived - (&FrameInfo); - } - } - } - break; - } - - default: - { - break; - } - } - - if (NmtEvent != kEplNmtEventNoEvent) { // event for DLL and NMT state machine generated - Ret = EplDllkChangeState(NmtEvent, NmtState); - if (Ret != kEplSuccessful) { - goto Exit; - } - - if ((NmtEvent != kEplNmtEventDllCeAsnd) - && ((NmtState <= kEplNmtCsPreOperational1) || (NmtEvent != kEplNmtEventDllCePres))) { // NMT state machine is not interested in ASnd frames and PRes frames when not CsNotActive or CsPreOp1 - // inform NMT module - Event.m_EventSink = kEplEventSinkNmtk; - Event.m_EventType = kEplEventTypeNmtEvent; - Event.m_uiSize = sizeof(NmtEvent); - Event.m_pArg = &NmtEvent; - Ret = EplEventkPost(&Event); - } - } - - Exit: - if (Ret != kEplSuccessful) { - u32 dwArg; - - BENCHMARK_MOD_02_TOGGLE(9); - - dwArg = EplDllkInstance_g.m_DllState | (NmtEvent << 8); - - // Error event for API layer - Ret = EplEventkPostError(kEplEventSourceDllk, - Ret, sizeof(dwArg), &dwArg); - } - BENCHMARK_MOD_02_RESET(3); - return; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCbFrameTransmitted() -// -// Description: called from EdrvInterruptHandler(). -// It signals -// -// Parameters: pRxBuffer_p = receive buffer structure -// -// Returns: (none) -// -// -// State: -// -//--------------------------------------------------------------------------- - -static void EplDllkCbFrameTransmitted(tEdrvTxBuffer * pTxBuffer_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplEvent Event; - tEplDllAsyncReqPriority Priority; - tEplNmtState NmtState; - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) \ - && (EPL_DLL_PRES_READY_AFTER_SOC == FALSE) - tEplFrameInfo FrameInfo; -#endif - - NmtState = EplNmtkGetNmtState(); - - if (NmtState <= kEplNmtGsResetConfiguration) { - goto Exit; - } - - if ((pTxBuffer_p - EplDllkInstance_g.m_pTxBuffer) == EPL_DLLK_TXFRAME_NMTREQ) { // frame from NMT request FIFO sent - // mark Tx-buffer as empty - pTxBuffer_p->m_uiTxMsgLen = EPL_DLLK_BUFLEN_EMPTY; - - // post event to DLL - Priority = kEplDllAsyncReqPrioNmt; - Event.m_EventSink = kEplEventSinkDllk; - Event.m_EventType = kEplEventTypeDllkFillTx; - EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime)); - Event.m_pArg = &Priority; - Event.m_uiSize = sizeof(Priority); - Ret = EplEventkPost(&Event); - } else if ((pTxBuffer_p - EplDllkInstance_g.m_pTxBuffer) == EPL_DLLK_TXFRAME_NONEPL) { // frame from generic priority FIFO sent - // mark Tx-buffer as empty - pTxBuffer_p->m_uiTxMsgLen = EPL_DLLK_BUFLEN_EMPTY; - - // post event to DLL - Priority = kEplDllAsyncReqPrioGeneric; - Event.m_EventSink = kEplEventSinkDllk; - Event.m_EventType = kEplEventTypeDllkFillTx; - EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime)); - Event.m_pArg = &Priority; - Event.m_uiSize = sizeof(Priority); - Ret = EplEventkPost(&Event); - } -#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) \ - && (EPL_DLL_PRES_READY_AFTER_SOC == FALSE)) \ - || (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - else if ((pTxBuffer_p->m_EplMsgType == kEplMsgTypePreq) - || (pTxBuffer_p->m_EplMsgType == kEplMsgTypePres)) { // PRes resp. PReq frame sent - -#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) \ - && (EPL_DLL_PRES_READY_AFTER_SOC == FALSE)) - { - // inform PDO module - FrameInfo.m_pFrame = - (tEplFrame *) pTxBuffer_p->m_pbBuffer; - FrameInfo.m_uiFrameSize = pTxBuffer_p->m_uiMaxBufferLen; - Ret = EplPdokCbPdoTransmitted(&FrameInfo); - } -#endif - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - { - // if own Pres on MN, trigger SoA - if ((NmtState >= kEplNmtMsPreOperational2) - && (pTxBuffer_p == - &EplDllkInstance_g. - m_pTxBuffer[EPL_DLLK_TXFRAME_PRES])) { - Ret = - EplDllkChangeState(kEplNmtEventDllMeSoaTrig, - NmtState); - } - } -#endif - -#if EPL_DLL_PRES_READY_AFTER_SOA != FALSE - goto Exit; -#endif - } -#endif -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - else if (pTxBuffer_p->m_EplMsgType == kEplMsgTypeSoa) { // SoA frame sent - tEplNmtEvent NmtEvent = kEplNmtEventDllMeSoaSent; - - // check if we are invited - if (EplDllkInstance_g.m_uiLastTargetNodeId == - EplDllkInstance_g.m_DllConfigParam.m_uiNodeId) { - tEplFrame *pTxFrame; - - if (EplDllkInstance_g.m_LastReqServiceId == kEplDllReqServiceStatus) { // StatusRequest - if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_STATUSRES].m_pbBuffer != NULL) { // StatusRes does exist - - pTxFrame = - (tEplFrame *) EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_STATUSRES]. - m_pbBuffer; - // update StatusRes frame (NMT state, EN, EC, RS, PR flags) - AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd. - m_Payload. - m_StatusResponse. - m_le_bNmtStatus, - (u8) NmtState); - AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd. - m_Payload. - m_StatusResponse. - m_le_bFlag1, - EplDllkInstance_g. - m_bFlag1); - AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd. - m_Payload. - m_StatusResponse. - m_le_bFlag2, - EplDllkInstance_g. - m_bFlag2); - // send StatusRes - Ret = - EdrvSendTxMsg(&EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_STATUSRES]); - if (Ret != kEplSuccessful) { - goto Exit; - } - TGT_DBG_SIGNAL_TRACE_POINT(8); - - } - } else if (EplDllkInstance_g.m_LastReqServiceId == kEplDllReqServiceIdent) { // IdentRequest - if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_IDENTRES].m_pbBuffer != NULL) { // IdentRes does exist - pTxFrame = - (tEplFrame *) EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_IDENTRES]. - m_pbBuffer; - // update IdentRes frame (NMT state, RS, PR flags) - AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd. - m_Payload. - m_IdentResponse. - m_le_bNmtStatus, - (u8) NmtState); - AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd. - m_Payload. - m_IdentResponse. - m_le_bFlag2, - EplDllkInstance_g. - m_bFlag2); - // send IdentRes - Ret = - EdrvSendTxMsg(&EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_IDENTRES]); - if (Ret != kEplSuccessful) { - goto Exit; - } - TGT_DBG_SIGNAL_TRACE_POINT(7); - } - } else if (EplDllkInstance_g.m_LastReqServiceId == kEplDllReqServiceNmtRequest) { // NmtRequest - if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_pbBuffer != NULL) { // NmtRequest does exist - // check if frame is not empty and not being filled - if (EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NMTREQ]. - m_uiTxMsgLen > - EPL_DLLK_BUFLEN_FILLING) { - // check if this frame is a NMT command, - // then forward this frame back to NmtMnu module, - // because it needs the time, when this frame is - // actually sent, to start the timer for monitoring - // the NMT state change. - - pTxFrame = - (tEplFrame *) - EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NMTREQ]. - m_pbBuffer; - if ((AmiGetByteFromLe - (&pTxFrame-> - m_le_bMessageType) - == (u8) kEplMsgTypeAsnd) - && - (AmiGetByteFromLe - (&pTxFrame->m_Data.m_Asnd. - m_le_bServiceId) - == (u8) kEplDllAsndNmtCommand)) { // post event directly to NmtMnu module - Event.m_EventSink = - kEplEventSinkNmtMnu; - Event.m_EventType = - kEplEventTypeNmtMnuNmtCmdSent; - Event.m_uiSize = - EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NMTREQ]. - m_uiTxMsgLen; - Event.m_pArg = pTxFrame; - Ret = - EplEventkPost - (&Event); - - } - // send NmtRequest - Ret = - EdrvSendTxMsg - (&EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NMTREQ]); - if (Ret != kEplSuccessful) { - goto Exit; - } - - } - } - - } else if (EplDllkInstance_g.m_LastReqServiceId == kEplDllReqServiceUnspecified) { // unspecified invite - if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL].m_pbBuffer != NULL) { // non-EPL frame does exist - // check if frame is not empty and not being filled - if (EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NONEPL]. - m_uiTxMsgLen > - EPL_DLLK_BUFLEN_FILLING) { - // send non-EPL frame - Ret = - EdrvSendTxMsg - (&EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NONEPL]); - if (Ret != kEplSuccessful) { - goto Exit; - } - - } - } - } - // ASnd frame was sent, remove the request - EplDllkInstance_g.m_LastReqServiceId = - kEplDllReqServiceNo; - } - // forward event to ErrorHandler and PDO module - Event.m_EventSink = kEplEventSinkNmtk; - Event.m_EventType = kEplEventTypeNmtEvent; - Event.m_uiSize = sizeof(NmtEvent); - Event.m_pArg = &NmtEvent; - Ret = EplEventkPost(&Event); - if (Ret != kEplSuccessful) { - goto Exit; - } - } -#endif - -#if EPL_DLL_PRES_READY_AFTER_SOA != FALSE - else { // d.k.: Why that else? on CN it is entered on IdentRes and StatusRes - goto Exit; - } - - // signal process function readiness of PRes frame - Event.m_EventSink = kEplEventSinkDllk; - Event.m_EventType = kEplEventTypeDllkPresReady; - Event.m_uiSize = 0; - Event.m_pArg = NULL; - Ret = EplEventkPost(&Event); - -#endif - - Exit: - if (Ret != kEplSuccessful) { - u32 dwArg; - - BENCHMARK_MOD_02_TOGGLE(9); - - dwArg = - EplDllkInstance_g.m_DllState | (pTxBuffer_p-> - m_EplMsgType << 16); - - // Error event for API layer - Ret = EplEventkPostError(kEplEventSourceDllk, - Ret, sizeof(dwArg), &dwArg); - } - - return; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCheckFrame() -// -// Description: check frame and set missing information -// -// Parameters: pFrame_p = ethernet frame -// uiFrameSize_p = size of frame -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplDllkCheckFrame(tEplFrame * pFrame_p, - unsigned int uiFrameSize_p) -{ - tEplMsgType MsgType; - u16 wEtherType; - - // check frame - if (pFrame_p != NULL) { - // check SrcMAC - if (AmiGetQword48FromBe(pFrame_p->m_be_abSrcMac) == 0) { - // source MAC address - EPL_MEMCPY(&pFrame_p->m_be_abSrcMac[0], - &EplDllkInstance_g.m_be_abSrcMac[0], 6); - } - // check ethertype - wEtherType = AmiGetWordFromBe(&pFrame_p->m_be_wEtherType); - if (wEtherType == 0) { - // assume EPL frame - wEtherType = EPL_C_DLL_ETHERTYPE_EPL; - AmiSetWordToBe(&pFrame_p->m_be_wEtherType, wEtherType); - } - - if (wEtherType == EPL_C_DLL_ETHERTYPE_EPL) { - // source node ID - AmiSetByteToLe(&pFrame_p->m_le_bSrcNodeId, - (u8) EplDllkInstance_g. - m_DllConfigParam.m_uiNodeId); - - // check message type - MsgType = - AmiGetByteFromLe(&pFrame_p->m_le_bMessageType); - if (MsgType == 0) { - MsgType = kEplMsgTypeAsnd; - AmiSetByteToLe(&pFrame_p->m_le_bMessageType, - (u8) MsgType); - } - - if (MsgType == kEplMsgTypeAsnd) { - // destination MAC address - AmiSetQword48ToBe(&pFrame_p->m_be_abDstMac[0], - EPL_C_DLL_MULTICAST_ASND); - } - - } - } - - return kEplSuccessful; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCbCnTimer() -// -// Description: called by timer module. It monitors the EPL cycle when it is a CN. -// -// Parameters: pEventArg_p = timer event argument -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -#if EPL_TIMER_USE_HIGHRES != FALSE -static tEplKernel EplDllkCbCnTimer(tEplTimerEventArg *pEventArg_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplNmtState NmtState; - -#if EPL_TIMER_USE_HIGHRES != FALSE - if (pEventArg_p->m_TimerHdl != EplDllkInstance_g.m_TimerHdlCycle) { // zombie callback - // just exit - goto Exit; - } -#endif - - NmtState = EplNmtkGetNmtState(); - - if (NmtState <= kEplNmtGsResetConfiguration) { - goto Exit; - } - - Ret = EplDllkChangeState(kEplNmtEventDllCeFrameTimeout, NmtState); - if (Ret != kEplSuccessful) { - goto Exit; - } - // 2008/10/15 d.k. reprogramming of timer not necessary, - // because it will be programmed, when SoC is received. -/* - // reprogram timer -#if EPL_TIMER_USE_HIGHRES != FALSE - if ((NmtState > kEplNmtCsPreOperational1) - && (EplDllkInstance_g.m_ullFrameTimeout != 0)) - { - Ret = EplTimerHighReskModifyTimerNs(&EplDllkInstance_g.m_TimerHdlCycle, EplDllkInstance_g.m_ullFrameTimeout, EplDllkCbCnTimer, 0L, FALSE); - } -#endif -*/ - - Exit: - if (Ret != kEplSuccessful) { - u32 dwArg; - - BENCHMARK_MOD_02_TOGGLE(9); - - dwArg = - EplDllkInstance_g. - m_DllState | (kEplNmtEventDllCeFrameTimeout << 8); - - // Error event for API layer - Ret = EplEventkPostError(kEplEventSourceDllk, - Ret, sizeof(dwArg), &dwArg); - } - - return Ret; -} -#endif - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCbMnTimerCycle() -// -// Description: called by timer module. It triggers the SoC when it is a MN. -// -// Parameters: pEventArg_p = timer event argument -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplDllkCbMnTimerCycle(tEplTimerEventArg *pEventArg_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplNmtState NmtState; - -#if EPL_TIMER_USE_HIGHRES != FALSE - if (pEventArg_p->m_TimerHdl != EplDllkInstance_g.m_TimerHdlCycle) { // zombie callback - // just exit - goto Exit; - } -#endif - - NmtState = EplNmtkGetNmtState(); - - if (NmtState <= kEplNmtGsResetConfiguration) { - goto Exit; - } - - Ret = EplDllkChangeState(kEplNmtEventDllMeSocTrig, NmtState); - - Exit: - if (Ret != kEplSuccessful) { - u32 dwArg; - - BENCHMARK_MOD_02_TOGGLE(9); - - dwArg = - EplDllkInstance_g. - m_DllState | (kEplNmtEventDllMeSocTrig << 8); - - // Error event for API layer - Ret = EplEventkPostError(kEplEventSourceDllk, - Ret, sizeof(dwArg), &dwArg); - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCbMnTimerResponse() -// -// Description: called by timer module. It monitors the PRes timeout. -// -// Parameters: pEventArg_p = timer event argument -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplDllkCbMnTimerResponse(tEplTimerEventArg *pEventArg_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplNmtState NmtState; - -#if EPL_TIMER_USE_HIGHRES != FALSE - if (pEventArg_p->m_TimerHdl != EplDllkInstance_g.m_TimerHdlResponse) { // zombie callback - // just exit - goto Exit; - } -#endif - - NmtState = EplNmtkGetNmtState(); - - if (NmtState <= kEplNmtGsResetConfiguration) { - goto Exit; - } - - Ret = EplDllkChangeState(kEplNmtEventDllMePresTimeout, NmtState); - - Exit: - if (Ret != kEplSuccessful) { - u32 dwArg; - - BENCHMARK_MOD_02_TOGGLE(9); - - dwArg = - EplDllkInstance_g. - m_DllState | (kEplNmtEventDllMePresTimeout << 8); - - // Error event for API layer - Ret = EplEventkPostError(kEplEventSourceDllk, - Ret, sizeof(dwArg), &dwArg); - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkGetNodeInfo() -// -// Description: returns node info structure of the specified node. -// -// Parameters: uiNodeId_p = node ID -// -// Returns: tEplDllkNodeInfo* = pointer to internal node info structure -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplDllkNodeInfo *EplDllkGetNodeInfo(unsigned int uiNodeId_p) -{ - // $$$ d.k.: use hash algorithm to retrieve the appropriate node info structure - // if size of array is less than 254. - uiNodeId_p--; // node ID starts at 1 but array at 0 - if (uiNodeId_p >= tabentries(EplDllkInstance_g.m_aNodeInfo)) { - return NULL; - } else { - return &EplDllkInstance_g.m_aNodeInfo[uiNodeId_p]; - } -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkMnSendSoa() -// -// Description: it updates and transmits the SoA. -// -// Parameters: NmtState_p = current NMT state -// pDllStateProposed_p = proposed DLL state -// fEnableInvitation_p = enable invitation for asynchronous phase -// it will be disabled for EPL_C_DLL_PREOP1_START_CYCLES SoAs -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplDllkMnSendSoa(tEplNmtState NmtState_p, - tEplDllState * pDllStateProposed_p, - BOOL fEnableInvitation_p) -{ - tEplKernel Ret = kEplSuccessful; - tEdrvTxBuffer *pTxBuffer = NULL; - tEplFrame *pTxFrame; - tEplDllkNodeInfo *pNodeInfo; - - *pDllStateProposed_p = kEplDllMsNonCyclic; - - pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_SOA]; - if (pTxBuffer->m_pbBuffer != NULL) { // SoA does exist - pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer; - - if (fEnableInvitation_p != FALSE) { // fetch target of asynchronous phase - if (EplDllkInstance_g.m_bFlag2 == 0) { // own queues are empty - EplDllkInstance_g.m_LastReqServiceId = - kEplDllReqServiceNo; - } else if (((tEplDllAsyncReqPriority) (EplDllkInstance_g.m_bFlag2 >> EPL_FRAME_FLAG2_PR_SHIFT)) == kEplDllAsyncReqPrioNmt) { // frames in own NMT request queue available - EplDllkInstance_g.m_LastReqServiceId = - kEplDllReqServiceNmtRequest; - } else { - EplDllkInstance_g.m_LastReqServiceId = - kEplDllReqServiceUnspecified; - } - Ret = - EplDllkCalAsyncGetSoaRequest(&EplDllkInstance_g. - m_LastReqServiceId, - &EplDllkInstance_g. - m_uiLastTargetNodeId); - if (Ret != kEplSuccessful) { - goto Exit; - } - if (EplDllkInstance_g.m_LastReqServiceId != kEplDllReqServiceNo) { // asynchronous phase will be assigned to one node - if (EplDllkInstance_g.m_uiLastTargetNodeId == EPL_C_ADR_INVALID) { // exchange invalid node ID with local node ID - EplDllkInstance_g.m_uiLastTargetNodeId = - EplDllkInstance_g.m_DllConfigParam. - m_uiNodeId; - // d.k. DLL state WaitAsndTrig is not helpful; - // so just step over to WaitSocTrig, - // because own ASnd is sent automatically in CbFrameTransmitted() after SoA. - //*pDllStateProposed_p = kEplDllMsWaitAsndTrig; - *pDllStateProposed_p = - kEplDllMsWaitSocTrig; - } else { // assignment to CN - *pDllStateProposed_p = - kEplDllMsWaitAsnd; - } - - pNodeInfo = - EplDllkGetNodeInfo(EplDllkInstance_g. - m_uiLastTargetNodeId); - if (pNodeInfo == NULL) { // no node info structure available - Ret = kEplDllNoNodeInfo; - goto Exit; - } - // update frame (EA, ER flags) - AmiSetByteToLe(&pTxFrame->m_Data.m_Soa. - m_le_bFlag1, - pNodeInfo-> - m_bSoaFlag1 & (EPL_FRAME_FLAG1_EA - | - EPL_FRAME_FLAG1_ER)); - } else { // no assignment of asynchronous phase - *pDllStateProposed_p = kEplDllMsWaitSocTrig; - EplDllkInstance_g.m_uiLastTargetNodeId = - EPL_C_ADR_INVALID; - } - - // update frame (target) - AmiSetByteToLe(&pTxFrame->m_Data.m_Soa. - m_le_bReqServiceId, - (u8) EplDllkInstance_g. - m_LastReqServiceId); - AmiSetByteToLe(&pTxFrame->m_Data.m_Soa. - m_le_bReqServiceTarget, - (u8) EplDllkInstance_g. - m_uiLastTargetNodeId); - - } else { // invite nobody - // update frame (target) - AmiSetByteToLe(&pTxFrame->m_Data.m_Soa. - m_le_bReqServiceId, (u8) 0); - AmiSetByteToLe(&pTxFrame->m_Data.m_Soa. - m_le_bReqServiceTarget, (u8) 0); - } - - // update frame (NMT state) - AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bNmtStatus, - (u8) NmtState_p); - - // send SoA frame - Ret = EdrvSendTxMsg(pTxBuffer); - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkMnSendSoc() -// -// Description: it updates and transmits the SoA. -// -// Parameters: (none) -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplDllkMnSendSoc(void) -{ - tEplKernel Ret = kEplSuccessful; - tEdrvTxBuffer *pTxBuffer = NULL; - tEplFrame *pTxFrame; - tEplEvent Event; - - pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_SOC]; - if (pTxBuffer->m_pbBuffer != NULL) { // SoC does exist - pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer; - - // $$$ update NetTime - - // send SoC frame - Ret = EdrvSendTxMsg(pTxBuffer); - if (Ret != kEplSuccessful) { - goto Exit; - } - // trigger synchronous task - Event.m_EventSink = kEplEventSinkSync; - Event.m_EventType = kEplEventTypeSync; - Event.m_uiSize = 0; - Ret = EplEventkPost(&Event); - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkMnSendPreq() -// -// Description: it updates and transmits the PReq for the next isochronous CN -// or own PRes if enabled. -// -// Parameters: NmtState_p = current NMT state -// pDllStateProposed_p = proposed DLL state -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplDllkMnSendPreq(tEplNmtState NmtState_p, - tEplDllState * pDllStateProposed_p) -{ - tEplKernel Ret = kEplSuccessful; - tEdrvTxBuffer *pTxBuffer = NULL; - tEplFrame *pTxFrame; - u8 bFlag1 = 0; - - if (EplDllkInstance_g.m_pCurNodeInfo == NULL) { // start with first isochronous CN - EplDllkInstance_g.m_pCurNodeInfo = - EplDllkInstance_g.m_pFirstNodeInfo; - } else { // iterate to next isochronous CN - EplDllkInstance_g.m_pCurNodeInfo = - EplDllkInstance_g.m_pCurNodeInfo->m_pNextNodeInfo; - } - - if (EplDllkInstance_g.m_pCurNodeInfo == NULL) { // last isochronous CN reached - Ret = EplDllkMnSendSoa(NmtState_p, pDllStateProposed_p, TRUE); - goto Exit; - } else { - pTxBuffer = EplDllkInstance_g.m_pCurNodeInfo->m_pPreqTxBuffer; - bFlag1 = - EplDllkInstance_g.m_pCurNodeInfo-> - m_bSoaFlag1 & EPL_FRAME_FLAG1_EA; - *pDllStateProposed_p = kEplDllMsWaitPres; - - // start PRes Timer - // $$$ d.k.: maybe move this call to CbFrameTransmitted(), because the time should run from there -#if EPL_TIMER_USE_HIGHRES != FALSE - Ret = - EplTimerHighReskModifyTimerNs(&EplDllkInstance_g. - m_TimerHdlResponse, - EplDllkInstance_g. - m_pCurNodeInfo-> - m_dwPresTimeout, - EplDllkCbMnTimerResponse, 0L, - FALSE); -#endif - } - - if (pTxBuffer == NULL) { // PReq does not exist - Ret = kEplDllTxBufNotReady; - goto Exit; - } - - pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer; - - if (pTxFrame != NULL) { // PReq does exist - if (NmtState_p == kEplNmtMsOperational) { // leave RD flag untouched - bFlag1 |= - AmiGetByteFromLe(&pTxFrame->m_Data.m_Preq. - m_le_bFlag1) & EPL_FRAME_FLAG1_RD; - } - - if (pTxBuffer == &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES]) { // PRes of MN will be sent - // update NMT state - AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bNmtStatus, - (u8) NmtState_p); - *pDllStateProposed_p = kEplDllMsWaitSoaTrig; - } - // $$$ d.k. set EPL_FRAME_FLAG1_MS if necessary - // update frame (Flag1) - AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag1, bFlag1); - - // calculate frame size from payload size - pTxBuffer->m_uiTxMsgLen = - AmiGetWordFromLe(&pTxFrame->m_Data.m_Preq.m_le_wSize) + 24; - - // send PReq frame - Ret = EdrvSendTxMsg(pTxBuffer); - } else { - Ret = kEplDllTxFrameInvalid; - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkAsyncFrameNotReceived() -// -// Description: passes empty ASnd frame to receive FIFO. -// It will be called only for frames with registered AsndServiceIds -// (only kEplDllAsndFilterAny). -// -// Parameters: none -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplDllkAsyncFrameNotReceived(tEplDllReqServiceId - ReqServiceId_p, - unsigned int uiNodeId_p) -{ - tEplKernel Ret = kEplSuccessful; - u8 abBuffer[18]; - tEplFrame *pFrame = (tEplFrame *) abBuffer; - tEplFrameInfo FrameInfo; - - // check if previous SoA invitation was not answered - switch (ReqServiceId_p) { - case kEplDllReqServiceIdent: - case kEplDllReqServiceStatus: - // ASnd service registered? - if (EplDllkInstance_g.m_aAsndFilter[ReqServiceId_p] == kEplDllAsndFilterAny) { // ASnd service ID is registered - AmiSetByteToLe(&pFrame->m_le_bSrcNodeId, - (u8) uiNodeId_p); - // EPL MsgType ASnd - AmiSetByteToLe(&pFrame->m_le_bMessageType, - (u8) kEplMsgTypeAsnd); - // ASnd Service ID - AmiSetByteToLe(&pFrame->m_Data.m_Asnd.m_le_bServiceId, - (u8) ReqServiceId_p); - // create frame info structure - FrameInfo.m_pFrame = pFrame; - FrameInfo.m_uiFrameSize = 18; // empty non existing ASnd frame - // forward frame via async receive FIFO to userspace - Ret = EplDllkCalAsyncFrameReceived(&FrameInfo); - } - break; - default: - // no invitation issued or it was successfully answered or it is uninteresting - break; - } - - return Ret; -} - -#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - -#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) -// EOF |