INLINE_FUNCTION void PUBLIC AmiSetTimeOfDay (void FAR* pAddr_p, tTimeOfDay FAR* pTimeOfDay_p) { AmiSetDwordToLe (((BYTE FAR*) pAddr_p), pTimeOfDay_p->m_dwMs & 0x0FFFFFFF); AmiSetWordToLe (((BYTE FAR*) pAddr_p) + 4, pTimeOfDay_p->m_wDays); }
static tEplKernel EplPdokPdoEncode(tEplFrame* pFrame_p, unsigned int uiFrameSize_p, BOOL fReadyFlag_p) { tEplKernel Ret = kEplSuccessful; BYTE bFlag1; unsigned int uiNodeId; tEplMsgType MsgType; tEplPdoChannel* pPdoChannel; unsigned int uiChannelId; tEplPdoMappObject* pMappObject; unsigned int uiMappObjectCount; // set TPDO invalid, so that only fully processed TPDOs are sent as valid bFlag1 = AmiGetByteFromLe(&pFrame_p->m_Data.m_Pres.m_le_bFlag1); AmiSetByteToLe(&pFrame_p->m_Data.m_Pres.m_le_bFlag1, (bFlag1 & ~EPL_FRAME_FLAG1_RD)); // retrieve EPL message type MsgType = AmiGetByteFromLe(&pFrame_p->m_le_bMessageType); if (MsgType == kEplMsgTypePres) { // TPDO is PRes frame uiNodeId = EPL_PDO_PRES_NODE_ID; // 0x00 } else { // TPDO is PReq frame // retrieve node ID uiNodeId = AmiGetByteFromLe(&pFrame_p->m_le_bDstNodeId); } // search for appropriate valid TPDO for (uiChannelId = 0, pPdoChannel = &EplPdokInstance_g.m_pTxPdoChannel[0]; uiChannelId < EplPdokInstance_g.m_Allocation.m_uiTxPdoChannelCount; uiChannelId++, pPdoChannel++) { if (pPdoChannel->m_uiNodeId != uiNodeId) { continue; } // valid TPDO found if ((unsigned int)(pPdoChannel->m_wPdoSize + 24) > uiFrameSize_p) { // TPDO is too short // $$$ raise PDO error, set Ret break; } // set PDO version in frame AmiSetByteToLe(&pFrame_p->m_Data.m_Pres.m_le_bPdoVersion, pPdoChannel->m_bMappingVersion); // call data copy callback function right before TPDO access if ((EplPdokInstance_g.m_pfnCbTpdoPreCopy != NULL) && (pPdoChannel->m_uiMappObjectCount != 0)) { EplPdokInstance_g.m_pfnCbTpdoPreCopy((BYTE) uiChannelId); } // process mapping for (uiMappObjectCount = pPdoChannel->m_uiMappObjectCount, pMappObject = EplPdokInstance_g.m_paTxObject[uiChannelId]; uiMappObjectCount > 0; uiMappObjectCount--, pMappObject++) { BENCHMARK_MOD_08_TOGGLE(7); // copy object from process/OD variable to TPDO Ret = EplPdokCopyVarToPdo(&pFrame_p->m_Data.m_Pres.m_le_abPayload[0], pMappObject); if (Ret != kEplSuccessful) { // other fatal error occurred goto Exit; } } // set PDO size in frame AmiSetWordToLe(&pFrame_p->m_Data.m_Pres.m_le_wSize, pPdoChannel->m_wPdoSize); if (fReadyFlag_p != FALSE) { // set TPDO valid AmiSetByteToLe(&pFrame_p->m_Data.m_Pres.m_le_bFlag1, (bFlag1 | EPL_FRAME_FLAG1_RD)); } // processing finished successfully goto Exit; } // set PDO size in frame to zero, because no TPDO mapped AmiSetWordToLe(&pFrame_p->m_Data.m_Pres.m_le_wSize, 0); if (fReadyFlag_p != FALSE) { // set TPDO valid even if TPDO size is 0 AmiSetByteToLe(&pFrame_p->m_Data.m_Pres.m_le_bFlag1, (bFlag1 | EPL_FRAME_FLAG1_RD)); } Exit: return Ret; }
//--------------------------------------------------------------------------- // // Function: EplErrorHandlerkProcess // // Description: processes error events from DLL // // Parameters: pEvent_p = pointer to event-structure from buffer // // Returns: tEpKernel = errorcode // // State: // //--------------------------------------------------------------------------- tEplKernel PUBLIC EplErrorHandlerkProcess(tEplEvent* pEvent_p) { tEplKernel Ret; unsigned long ulDllErrorEvents; tEplEvent Event; tEplNmtEvent NmtEvent; Ret = kEplSuccessful; // check m_EventType switch(pEvent_p->m_EventType) { case kEplEventTypeDllError: { tEplErrorHandlerkEvent* pErrHandlerEvent = (tEplErrorHandlerkEvent*)pEvent_p->m_pArg; tEplErrHistoryEntry HistoryEntry = {0}; ulDllErrorEvents = pErrHandlerEvent->m_ulDllErrorEvents; HistoryEntry.m_wEntryType = EPL_ERR_ENTRYTYPE_MODE_OCCURRED | EPL_ERR_ENTRYTYPE_PROF_EPL | EPL_ERR_ENTRYTYPE_HISTORY; // check the several error events if ((ulDllErrorEvents & EPL_DLL_ERR_CN_LOSS_SOC) != 0) { // loss of SoC event occured // increment cumulative counter by 1 EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwCumulativeCnt++; if (EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThreshold > 0) { // increment threshold counter by 8 EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThresholdCnt += 8; if (EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThreshold) { // threshold is reached // generate error history entry E_DLL_LOSS_SOC_TH HistoryEntry.m_wErrorCode = EPL_E_DLL_LOSS_SOC_TH; HistoryEntry.m_TimeStamp = pEvent_p->m_NetTime; Ret = EplErrorHandlerkPostHistoryEntry(&HistoryEntry); if (Ret != kEplSuccessful) { goto Exit; } BENCHMARK_MOD_02_TOGGLE(7); // post event to NMT state machine NmtEvent = kEplNmtEventNmtCycleError; Event.m_EventSink = kEplEventSinkNmtk; Event.m_EventType = kEplEventTypeNmtEvent; Event.m_pArg = &NmtEvent; Event.m_uiSize = sizeof (NmtEvent); Ret = EplEventkPost(&Event); } EplErrorHandlerkInstance_g.m_ulDllErrorEvents |= EPL_DLL_ERR_CN_LOSS_SOC; } } if ((ulDllErrorEvents & EPL_DLL_ERR_CN_LOSS_PREQ) != 0) { // loss of PReq event occured // increment cumulative counter by 1 EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwCumulativeCnt++; if (EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThreshold > 0) { // increment threshold counter by 8 EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThresholdCnt += 8; if (EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThreshold) { // threshold is reached // generate error history entry E_DLL_LOSS_PREQ_TH HistoryEntry.m_wErrorCode = EPL_E_DLL_LOSS_PREQ_TH; HistoryEntry.m_TimeStamp = pEvent_p->m_NetTime; Ret = EplErrorHandlerkPostHistoryEntry(&HistoryEntry); if (Ret != kEplSuccessful) { goto Exit; } BENCHMARK_MOD_02_TOGGLE(7); // post event to NMT state machine NmtEvent = kEplNmtEventNmtCycleError; Event.m_EventSink = kEplEventSinkNmtk; Event.m_EventType = kEplEventTypeNmtEvent; Event.m_pArg = &NmtEvent; Event.m_uiSize = sizeof (NmtEvent); Ret = EplEventkPost(&Event); } } } if ((EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThresholdCnt > 0) && ((ulDllErrorEvents & EPL_DLL_ERR_CN_RECVD_PREQ) != 0)) { // PReq correctly received // decrement threshold counter by 1 EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThresholdCnt--; } if ((ulDllErrorEvents & EPL_DLL_ERR_CN_CRC) != 0) { // CRC error event occured // increment cumulative counter by 1 EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwCumulativeCnt++; if (EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThreshold > 0) { // increment threshold counter by 8 EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThresholdCnt += 8; if (EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThreshold) { // threshold is reached // generate error history entry E_DLL_CRC_TH HistoryEntry.m_wErrorCode = EPL_E_DLL_CRC_TH; HistoryEntry.m_TimeStamp = pEvent_p->m_NetTime; Ret = EplErrorHandlerkPostHistoryEntry(&HistoryEntry); if (Ret != kEplSuccessful) { goto Exit; } BENCHMARK_MOD_02_TOGGLE(7); // post event to NMT state machine NmtEvent = kEplNmtEventNmtCycleError; Event.m_EventSink = kEplEventSinkNmtk; Event.m_EventType = kEplEventTypeNmtEvent; Event.m_pArg = &NmtEvent; Event.m_uiSize = sizeof (NmtEvent); Ret = EplEventkPost(&Event); } EplErrorHandlerkInstance_g.m_ulDllErrorEvents |= EPL_DLL_ERR_CN_CRC; } } if ((ulDllErrorEvents & EPL_DLL_ERR_INVALID_FORMAT) != 0) { // invalid format error occured (only direct reaction) // generate error history entry E_DLL_INVALID_FORMAT HistoryEntry.m_wErrorCode = EPL_E_DLL_INVALID_FORMAT; HistoryEntry.m_TimeStamp = pEvent_p->m_NetTime; AmiSetByteToLe(&HistoryEntry.m_abAddInfo[0], (BYTE) pErrHandlerEvent->m_uiNodeId); Ret = EplErrorHandlerkPostHistoryEntry(&HistoryEntry); if (Ret != kEplSuccessful) { goto Exit; } BENCHMARK_MOD_02_TOGGLE(7); #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) if (pErrHandlerEvent->m_NmtState >= kEplNmtMsNotActive) { // MN is active if (pErrHandlerEvent->m_uiNodeId != 0) { tEplHeartbeatEvent HeartbeatEvent; tEplDllNodeOpParam NodeOpParam; NodeOpParam.m_OpNodeType = kEplDllNodeOpTypeIsochronous; NodeOpParam.m_uiNodeId = pErrHandlerEvent->m_uiNodeId; // remove node from isochronous phase Ret = EplDllkDeleteNode(&NodeOpParam); // inform NmtMnu module about state change, which shall send NMT command ResetNode to this CN HeartbeatEvent.m_uiNodeId = pErrHandlerEvent->m_uiNodeId; HeartbeatEvent.m_NmtState = kEplNmtCsNotActive; HeartbeatEvent.m_wErrorCode = EPL_E_DLL_INVALID_FORMAT; Event.m_EventSink = kEplEventSinkNmtMnu; Event.m_EventType = kEplEventTypeHeartbeat; Event.m_uiSize = sizeof (HeartbeatEvent); Event.m_pArg = &HeartbeatEvent; Ret = EplEventkPost(&Event); } // $$$ and else should lead to InternComError } else #endif { // CN is active // post event to NMT state machine NmtEvent = kEplNmtEventInternComError; Event.m_EventSink = kEplEventSinkNmtk; Event.m_EventType = kEplEventTypeNmtEvent; Event.m_pArg = &NmtEvent; Event.m_uiSize = sizeof (NmtEvent); Ret = EplEventkPost(&Event); } } #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) if ((ulDllErrorEvents & EPL_DLL_ERR_MN_CRC) != 0) { // CRC error event occured // increment cumulative counter by 1 EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwCumulativeCnt++; if (EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThreshold > 0) { // increment threshold counter by 8 EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThresholdCnt += 8; if (EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThreshold) { // threshold is reached // generate error history entry E_DLL_CRC_TH HistoryEntry.m_wErrorCode = EPL_E_DLL_CRC_TH; HistoryEntry.m_TimeStamp = pEvent_p->m_NetTime; Ret = EplErrorHandlerkPostHistoryEntry(&HistoryEntry); if (Ret != kEplSuccessful) { goto Exit; } // post event to NMT state machine NmtEvent = kEplNmtEventNmtCycleError; Event.m_EventSink = kEplEventSinkNmtk; Event.m_EventType = kEplEventTypeNmtEvent; Event.m_pArg = &NmtEvent; Event.m_uiSize = sizeof (NmtEvent); Ret = EplEventkPost(&Event); } EplErrorHandlerkInstance_g.m_ulDllErrorEvents |= EPL_DLL_ERR_MN_CRC; } } if ((ulDllErrorEvents & EPL_DLL_ERR_MN_CYCTIMEEXCEED) != 0) { // cycle time exceeded event occured // increment cumulative counter by 1 EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwCumulativeCnt++; if (EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThreshold > 0) { // increment threshold counter by 8 EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThresholdCnt += 8; if (EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThreshold) { // threshold is reached // generate error history entry E_DLL_CYCLE_EXCEED_TH HistoryEntry.m_wErrorCode = EPL_E_DLL_CYCLE_EXCEED_TH; HistoryEntry.m_TimeStamp = pEvent_p->m_NetTime; AmiSetWordToLe(&HistoryEntry.m_abAddInfo[0], (WORD) pErrHandlerEvent->m_EplError); Ret = EplErrorHandlerkPostHistoryEntry(&HistoryEntry); if (Ret != kEplSuccessful) { goto Exit; } // post event to NMT state machine NmtEvent = kEplNmtEventNmtCycleError; Event.m_EventSink = kEplEventSinkNmtk; Event.m_EventType = kEplEventTypeNmtEvent; Event.m_pArg = &NmtEvent; Event.m_uiSize = sizeof (NmtEvent); Ret = EplEventkPost(&Event); } else { // generate error history entry E_DLL_CYCLE_EXCEED HistoryEntry.m_wErrorCode = EPL_E_DLL_CYCLE_EXCEED; HistoryEntry.m_TimeStamp = pEvent_p->m_NetTime; AmiSetWordToLe(&HistoryEntry.m_abAddInfo[0], (WORD) pErrHandlerEvent->m_EplError); Ret = EplErrorHandlerkPostHistoryEntry(&HistoryEntry); if (Ret != kEplSuccessful) { goto Exit; } } EplErrorHandlerkInstance_g.m_ulDllErrorEvents |= EPL_DLL_ERR_MN_CYCTIMEEXCEED; } } if ((ulDllErrorEvents & EPL_DLL_ERR_MN_CN_LOSS_PRES) != 0) { // CN loss PRes event occured unsigned int uiNodeId; uiNodeId = pErrHandlerEvent->m_uiNodeId - 1; if (uiNodeId < tabentries(EplErrorHandlerkInstance_g.m_adwMnCnLossPresCumCnt)) { if (EplErrorHandlerkInstance_g.m_abMnCnLossPresEvent[uiNodeId] == EPL_ERRORHANDLERK_CN_LOSS_PRES_EVENT_NONE) { // increment cumulative counter by 1 EplErrorHandlerkInstance_g.m_adwMnCnLossPresCumCnt[uiNodeId]++; if (EplErrorHandlerkInstance_g.m_adwMnCnLossPresThreshold[uiNodeId] > 0) { // increment threshold counter by 8 EplErrorHandlerkInstance_g.m_adwMnCnLossPresThrCnt[uiNodeId] += 8; if (EplErrorHandlerkInstance_g.m_adwMnCnLossPresThrCnt[uiNodeId] >= EplErrorHandlerkInstance_g.m_adwMnCnLossPresThreshold[uiNodeId]) { // threshold is reached tEplHeartbeatEvent HeartbeatEvent; tEplDllNodeOpParam NodeOpParam; EplErrorHandlerkInstance_g.m_abMnCnLossPresEvent[uiNodeId] = EPL_ERRORHANDLERK_CN_LOSS_PRES_EVENT_THR; NodeOpParam.m_OpNodeType = kEplDllNodeOpTypeIsochronous; NodeOpParam.m_uiNodeId = pErrHandlerEvent->m_uiNodeId; // generate error history entry E_DLL_LOSS_PRES_TH HistoryEntry.m_wErrorCode = EPL_E_DLL_LOSS_PRES_TH; HistoryEntry.m_TimeStamp = pEvent_p->m_NetTime; AmiSetByteToLe(&HistoryEntry.m_abAddInfo[0], (BYTE) pErrHandlerEvent->m_uiNodeId); Ret = EplErrorHandlerkPostHistoryEntry(&HistoryEntry); if (Ret != kEplSuccessful) { goto Exit; } // remove node from isochronous phase Ret = EplDllkDeleteNode(&NodeOpParam); // inform NmtMnu module about state change, which shall send NMT command ResetNode to this CN HeartbeatEvent.m_uiNodeId = pErrHandlerEvent->m_uiNodeId; HeartbeatEvent.m_NmtState = kEplNmtCsNotActive; HeartbeatEvent.m_wErrorCode = EPL_E_DLL_LOSS_PRES_TH; Event.m_EventSink = kEplEventSinkNmtMnu; Event.m_EventType = kEplEventTypeHeartbeat; Event.m_uiSize = sizeof (HeartbeatEvent); Event.m_pArg = &HeartbeatEvent; Ret = EplEventkPost(&Event); } else { EplErrorHandlerkInstance_g.m_abMnCnLossPresEvent[uiNodeId] = EPL_ERRORHANDLERK_CN_LOSS_PRES_EVENT_OCC; } } } } } #endif break; } // unknown type default: { Ret = kEplInvalidEvent; break; } } // end of switch(pEvent_p->m_EventType) Exit: return Ret; }