# ADS over EtherCAT® (AoE) To handle AoE object transfers within the application, the callbacks pfnAoeRead, pfnAoeWrite and/or pfnAoeReadWrite can be registered using [`esSetSlaveAoeObjectTransferCallbacks()`](#_CPPv436esSetSlaveAoeObjectTransferCallbacks10EC_T_DWORD9EC_T_WORD19EC_T_PF_AOE_READ_CB20EC_T_PF_AOE_WRITE_CB24EC_T_PF_AOE_READWRITE_CBP9EC_T_VOID) or [`esSetSlaveSscApplication()`](api_general.html.md#_CPPv424esSetSlaveSscApplication10EC_T_DWORD9EC_T_WORDP24EC_T_SLAVE_SSC_APPL_DESC), e.g. in `myAppPrepare()` of EcSimulatorHilDemo / EcSimulatorSilDemo. See also [AoE Simulator and MainDevice Example](#aoe-simulator-and-maindevice-example) ## esAoeGetSlaveNetId ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esAoeGetSlaveNetId([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceID, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwSlaveId, EC_T_AOE_NETID \*poAoeNetId) Retrieve the NetID of a specific EtherCAT device. * **Parameters:** * **dwInstanceID** – [in] Instance ID (Multiple EtherCAT Network Support) * **dwSlaveId** – [in] Slave ID * **poAoeNetId** – [out] AoE NetID of the corresponding slave * **Returns:** * [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) if successful * [EC_E_INVALIDSTATE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga2a6310e052fca1b94797e8e26f031739) if EtherCAT stack isn’t initialized * [EC_E_INVALIDPARM](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga1e10d9022db11a708658c71b0dead2fe) if dwInstanceID is out of range, the input pointer is EC_NULL or contains EC_NULL pointer, or dwTimeout is EC_NOWAIT * [EC_E_SLAVE_NOT_PRESENT](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga45555d5de25571188a82d2d76c02dd81) if slave not present * [EC_E_NOTFOUND](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga3113f3b6f82bb50e6ab3cde40268730a) if no slave matching dwSlaveId can be found * [EC_E_NO_MBX_SUPPORT](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga461eba97c1aa71d0d6bc72202035ad98) if slave has no mailbox support * [EC_E_ADS_IS_RUNNING](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1gac053cb32c9b2bee0305b0644ef76e933) if ADS server is running ## esAoeRead ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esAoeRead([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceID, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwSlaveId, EC_T_AOE_NETID \*poTargetNetId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wTargetPort, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwIndexGroup, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwIndexOffset, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwDataLen, [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) \*pbyData, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) \*pdwDataOutLen, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) \*pdwErrorCode, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) \*pdwCmdResult, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwTimeout) Execute an AoE mailbox read request to an EtherCAT slave device. This function may not be called from within the JobTask’s context. * **Parameters:** * **dwInstanceID** – [in] Instance ID (Multiple EtherCAT Network Support) * **dwSlaveId** – [in] Slave ID * **poTargetNetId** – [in] Target NetID * **wTargetPort** – [in] Target port * **dwIndexGroup** – [in] AoE read command index group * **dwIndexOffset** – [in] AoE read command index offset * **dwDataLen** – [in] Buffer length [bytes] * **pbyData** – [out] Buffer receiving transferred data * **pdwDataOutLen** – [out] Number of bytes read from the target device * **pdwErrorCode** – [out] AoE response error code * **pdwCmdResult** – [out] AoE read command result code * **dwTimeout** – [in] Timeout [ms]. The function will block at most for this time. * **Returns:** * [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) on success * [EC_E_AOE_VENDOR_SPECIFIC](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga1b4e331b053ac416172151c2d402d9f6) if the AoE device has responded with a user defined error code * [EC_E_MASTER_RED_STATE_INACTIVE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1gae2870f20d370920995e27b2a78171a5e) if Master Redundancy is configured and master is inactive ## esAoeWrite ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esAoeWrite([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceID, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwSlaveId, EC_T_AOE_NETID \*poTargetNetId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wTargetPort, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwIndexGroup, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwIndexOffset, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwDataLen, [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) \*pbyData, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) \*pdwErrorCode, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) \*pdwCmdResult, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwTimeout) Execute an AoE mailbox write request to an EtherCAT slave device. This function may not be called from within the JobTask’s context. * **Parameters:** * **dwInstanceID** – [in] Instance ID (Multiple EtherCAT Network Support) * **dwSlaveId** – [in] Slave ID * **poTargetNetId** – [in] Target NetID * **wTargetPort** – [in] Target port * **dwIndexGroup** – [in] AoE write command index group * **dwIndexOffset** – [in] AoE write command index offset * **dwDataLen** – [in] Buffer length [bytes] * **pbyData** – [in] Buffer containing transfered data * **pdwErrorCode** – [out] Pointer to AoE response error code * **pdwCmdResult** – [out] Pointer to AoE write command result code * **dwTimeout** – [in] Timeout [ms]. The function will block at most for this time. * **Returns:** * [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) on success * [EC_E_AOE_VENDOR_SPECIFIC](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga1b4e331b053ac416172151c2d402d9f6) if the AoE device has responded with a user defined error code * [EC_E_MASTER_RED_STATE_INACTIVE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1gae2870f20d370920995e27b2a78171a5e) if Master Redundancy is configured and master is inactive ## esAoeReadWrite ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esAoeReadWrite([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceID, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwSlaveId, EC_T_AOE_NETID \*poTargetNetId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wTargetPort, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwIndexGroup, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwIndexOffset, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwReadDataLen, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwWriteDataLen, [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) \*pbyData, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) \*pdwDataOutLen, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) \*pdwErrorCode, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) \*pdwCmdResult, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwTimeout) Execute an AoE mailbox read/write request to an EtherCAT slave device. * **Parameters:** * **dwInstanceID** – [in] Instance ID (Multiple EtherCAT Network Support) * **dwSlaveId** – [in] Slave ID * **poTargetNetId** – [in] Target NetID * **wTargetPort** – [in] Target port * **dwIndexGroup** – [in] AoE read/write command index group * **dwIndexOffset** – [in] AoE read/write command index offset * **dwReadDataLen** – [in] Number of bytes to read from the target device * **dwWriteDataLen** – [in] Number of bytes to write to the target device * **pbyData** – [in, out] Buffer containing and receiving transfered data * **pdwDataOutLen** – [out] Number of bytes read from the target device * **pdwErrorCode** – [out] Pointer to AoE response error code * **pdwCmdResult** – [out] Pointer to AoE write command result code * **dwTimeout** – [in] Timeout [ms]. The function will block at most for this time. EC_NOWAIT is not valid. * **Returns:** * [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) on success * [EC_E_AOE_VENDOR_SPECIFIC](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga1b4e331b053ac416172151c2d402d9f6) if the AoE device has responded with a user defined error code * [EC_E_MASTER_RED_STATE_INACTIVE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1gae2870f20d370920995e27b2a78171a5e) if Master Redundancy is configured and master is inactive ## esSetSlaveAoeObjectTransferCallbacks ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esSetSlaveAoeObjectTransferCallbacks([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wCfgFixedAddress, EC_T_PF_AOE_READ_CB pfRead, EC_T_PF_AOE_WRITE_CB pfWrite, EC_T_PF_AOE_READWRITE_CB pfReadWrite, EC_T_VOID \*pvContext) Set AoE read/write callbacks. \_ * **Parameters:** * **dwInstanceId** – [in] Simulator Instance ID * **wCfgFixedAddress** – [in] Slave’s station address. 0: all slaves. * **pfRead** – [in] Read callback function * **pfWrite** – [in] Write callback function * **pfReadWrite** – [in] ReadWrite callback function * **pvContext** – [in] Pointer to context passed as first parameters to callback functions * **Returns:** [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) or error code ## AoE Simulator and MainDevice Example The following example demonstrates how to handle AoE object transfers within the simulator application: ### **AoE Simulator and MainDevice Example** The following example handlers can be registered at the EC-Simulator: ```cpp /* EC_T_PF_AOE_READ_CB */ EC_T_DWORD EC_FNCALL myAppAoeReadObjectCallback( EC_T_VOID* /* pvContext */, EC_T_DWORD dwSimulatorId, EC_T_WORD wCfgFixedAddress, EC_T_AOE_NETID* /* poSenderNetId */, EC_T_WORD /* wSenderPort */, EC_T_AOE_NETID* /* poTargetNetId */, EC_T_WORD wTargetPort, EC_T_DWORD dwIndexGroup, EC_T_DWORD dwIndexOffset, EC_T_BYTE* pbyReadData, EC_T_DWORD* pdwReadDataLen, EC_T_DWORD* pdwErrorCode, EC_T_DWORD* pdwCmdResult) { if (65535 != wTargetPort) { EC_SETDWORD(pdwErrorCode, EC_E_AOE_TARGET_PORT_NOT_FOUND); goto Exit; } if (0xF302 /* ADSIGRP_CANOPEN_SDO */ != dwIndexGroup) { EC_SETDWORD(pdwErrorCode, EC_E_AOE_INVALIDGRP); goto Exit; } /* check for object 0x2003, subindex 0, no complete access */ if (0x20030000 != dwIndexOffset /* example value */) { EC_SETDWORD(pdwErrorCode, EC_E_AOE_NOTFOUND); goto Exit; } /* check for size of object 0x2003, subindex 0 */ if (4 != EC_GETDWORD(pdwReadDataLen) /* UDINT: sizeof(EC_T_DWORD) */) { EC_SETDWORD(pdwErrorCode, EC_E_AOE_INVALIDSIZE); goto Exit; } /* all checks passed, return data and set success */ EC_SET_FRM_DWORD(pbyReadData, 0x12345678); EC_SETDWORD(pdwErrorCode, EC_E_NOERROR); Exit: EcLogMsg(EC_LOG_LEVEL_VERBOSE, (pEcLogContext, EC_LOG_LEVEL_VERBOSE, "myAppAoeReadObjectCallback(%d, %d, %d, 0x%04X, 0x%04X, %d bytes, 0x%08X, 0x%08X): %s (0x%08X)\n", dwSimulatorId, wCfgFixedAddress, wTargetPort, dwIndexGroup, dwIndexOffset, EC_GETDWORD(pdwReadDataLen), EC_GETDWORD(pdwErrorCode), EC_GETDWORD(pdwCmdResult), esGetText(dwSimulatorId, EC_GETDWORD(pdwErrorCode)), EC_GETDWORD(pdwErrorCode))); return EC_GETDWORD(pdwErrorCode); } /* EC_T_PF_AOE_WRITE_CB */ EC_T_DWORD EC_FNCALL myAppAoeWriteObjectCallback( EC_T_VOID* /* pvContext */, EC_T_DWORD dwSimulatorId, EC_T_WORD wCfgFixedAddress, EC_T_AOE_NETID* /* poSenderNetId */, EC_T_WORD /* wSenderPort */, EC_T_AOE_NETID* /* poTargetNetId */, EC_T_WORD wTargetPort, EC_T_DWORD dwIndexGroup, EC_T_DWORD dwIndexOffset, EC_T_BYTE* pbyWriteData, EC_T_DWORD dwWriteDataLen, EC_T_DWORD* pdwErrorCode, EC_T_DWORD* pdwCmdResult) { EC_T_DWORD dwVal = 0; if (65535 != wTargetPort) { EC_SETDWORD(pdwErrorCode, EC_E_AOE_TARGET_PORT_NOT_FOUND); goto Exit; } if (0xF302 /* ADSIGRP_CANOPEN_SDO */ != dwIndexGroup) { EC_SETDWORD(pdwErrorCode, EC_E_AOE_INVALIDGRP); goto Exit; } /* check for object 0x2003, subindex 0, no complete access */ if (0x20030000 != dwIndexOffset /* example value */) { EC_SETDWORD(pdwErrorCode, EC_E_AOE_NOTFOUND); goto Exit; } /* check for size of object 0x2003, subindex 0 */ if (4 != dwWriteDataLen /* UDINT: sizeof(EC_T_DWORD) */) { EC_SETDWORD(pdwErrorCode, EC_E_AOE_INVALIDSIZE); goto Exit; } /* all checks passed, get data and set success */ dwVal = EC_GET_FRM_DWORD(pbyWriteData); EC_SETDWORD(pdwErrorCode, EC_E_NOERROR); Exit: EcLogMsg(EC_LOG_LEVEL_VERBOSE, (pEcLogContext, EC_LOG_LEVEL_VERBOSE, "myAppAoeWriteObjectCallback(%d, %d, %d, 0x%04X, 0x%04X, %d bytes, 0x%08X, 0x%08X) = %d (0x%08X): %s (0x%08X)\n", dwSimulatorId, wCfgFixedAddress, wTargetPort, dwIndexGroup, dwIndexOffset, dwWriteDataLen, EC_GETDWORD(pdwErrorCode), EC_GETDWORD(pdwCmdResult), dwVal, dwVal, esGetText(dwSimulatorId, EC_GETDWORD(pdwErrorCode)), EC_GETDWORD(pdwErrorCode))); return EC_GETDWORD(pdwErrorCode); } /* EC_T_PF_AOE_READWRITE_CB */ EC_T_DWORD EC_FNCALL myAppAoeReadWriteObjectCallback( EC_T_VOID* /* pvContext */, EC_T_DWORD dwSimulatorId, EC_T_WORD wCfgFixedAddress, EC_T_AOE_NETID* /* poSenderNetId */, EC_T_WORD /* wSenderPort */, EC_T_AOE_NETID* /* poTargetNetId */, EC_T_WORD wTargetPort, EC_T_DWORD dwIndexGroup, EC_T_DWORD dwIndexOffset, EC_T_BYTE* pbyReadData, EC_T_DWORD* pdwReadDataLen, EC_T_BYTE* pbyWriteData, EC_T_DWORD dwWriteDataLen, EC_T_DWORD* pdwErrorCode, EC_T_DWORD* pdwCmdResult) { EC_T_DWORD dwVal = 0; if (65535 != wTargetPort) { EC_SETDWORD(pdwErrorCode, EC_E_AOE_TARGET_PORT_NOT_FOUND); goto Exit; } if (0xF302 /* ADSIGRP_CANOPEN_SDO */ != dwIndexGroup) { EC_SETDWORD(pdwErrorCode, EC_E_AOE_INVALIDGRP); goto Exit; } /* check for object 0x2003, subindex 0, no complete access */ if (0x20030000 != dwIndexOffset /* example value */) { EC_SETDWORD(pdwErrorCode, EC_E_AOE_NOTFOUND); goto Exit; } /* check for size of object 0x2003, subindex 0 */ if ((4 != EC_GETDWORD(pdwReadDataLen) /* UDINT: sizeof(EC_T_DWORD) */) || (4 != dwWriteDataLen /* UDINT: sizeof(EC_T_DWORD) */)) { EC_SETDWORD(pdwErrorCode, EC_E_AOE_INVALIDSIZE); goto Exit; } /* all checks passed, set and get data and set success */ EC_SET_FRM_DWORD(pbyReadData, 0x12345678); dwVal = EC_GET_FRM_DWORD(pbyWriteData); EC_SETDWORD(pdwErrorCode, EC_E_NOERROR); Exit: EcLogMsg(EC_LOG_LEVEL_VERBOSE, (pEcLogContext, EC_LOG_LEVEL_VERBOSE, "myAppAoeReadWriteObjectCallback(%d, %d, %d, 0x%04X, 0x%04X, read %d bytes, write %d bytes, 0x%08X, 0x%08X) = %d (0x%08X): %s (0x%08X)\n", dwSimulatorId, wCfgFixedAddress, wTargetPort, dwIndexGroup, dwIndexOffset, EC_GETDWORD(pdwReadDataLen), dwWriteDataLen, EC_GETDWORD(pdwErrorCode), EC_GETDWORD(pdwCmdResult), dwVal, dwVal, esGetText(dwSimulatorId, EC_GETDWORD(pdwErrorCode)), EC_GETDWORD(pdwErrorCode))); return EC_GETDWORD(pdwErrorCode); } ``` The following example demonstrates object transfers between MainDevice and Simulator: ```cpp EC_T_DWORD dwRes = EC_E_ERROR; EC_T_DWORD dwRetVal = EC_E_ERROR; EC_T_BYTE abyWriteData[sizeof(EC_T_DWORD)]; EC_T_BYTE abyReadData[sizeof(EC_T_DWORD)]; EC_T_BYTE abyReadWriteData[sizeof(EC_T_DWORD)]; EC_T_DWORD dwDataOutLen = 0; EC_T_AOE_NETID oAoeNetId; EC_T_DWORD dwSlaveId = emGetSlaveId(dwMasterId, wSlaveAddress); EC_T_DWORD dwErrorCode = EC_E_ERROR; EC_T_DWORD dwCmdResult = EC_E_ERROR; OsMemset(abyWriteData, 0, sizeof(abyWriteData)); OsMemset(abyReadData, 0, sizeof(abyReadData)); OsMemset(abyReadWriteData, 0, sizeof(abyReadWriteData)); /* EC-Master: get configured AoE net ID */ dwRes = emAoeGetSlaveNetId(dwMasterId, dwSlaveId, &oAoeNetId); if (dwRes != EC_E_NOERROR) { EcLogMsg(EC_LOG_LEVEL_ERROR, (pEcLogContext, EC_LOG_LEVEL_ERROR, "emAoeGetSlaveNetId failed: %s (0x%lx))\n", ecatGetText(dwRes), dwRes)); dwRetVal = dwRes; goto Exit; } /* EC-Simulator: register AoE handlers */ dwRes = esSetSlaveAoeObjectTransferCallbacks(dwSimulatorId, wSlaveAddress, myAppAoeReadObjectCallback, myAppAoeWriteObjectCallback, myAppAoeReadWriteObjectCallback, pAppContext); if (dwRes != EC_E_NOERROR) { EcLogMsg(EC_LOG_LEVEL_ERROR, (pEcLogContext, EC_LOG_LEVEL_ERROR, "esSetSlaveAoeObjectTransferCallbacks failed: %s (0x%lx))\n", esGetText(dwSimulatorId, dwRes), dwRes)); dwRetVal = dwRes; goto Exit; } /* EC-Master: set PREOP state */ dwRes = emSetMasterState(dwMasterId, 30000, eEcatState_PREOP); if (dwRes != EC_E_NOERROR) { EcLogMsg(EC_LOG_LEVEL_ERROR, (pEcLogContext, EC_LOG_LEVEL_ERROR, "emSetMasterState failed: %s (0x%lx))\n", ecatGetText(dwRes), dwRes)); dwRetVal = dwRes; goto Exit; } #define AOE_TARGET_PORT 65535 #define AOE_INDEX_GROUP 0xF302 /* ADSIGRP_CANOPEN_SDO */ /* CoE objects to access via AoE */ #define AOE_COE_OBJ_IDX 0x2003 #define AOE_COE_OBJ_SUBINDEX 0 #define AOE_COE_OBJ_COMPLETEACCESS EC_FALSE /* Bit 16-31: index, Bit 8: complete access, Bit 0-7: subindex */ #define AOE_INDEX_OFFSET ((AOE_COE_OBJ_IDX << 16) | (AOE_COE_OBJ_COMPLETEACCESS << 8) | AOE_COE_OBJ_SUBINDEX) /* EC-Master: write AoE to slave */ EC_SET_FRM_DWORD(abyWriteData, 0x11223344 /* example value */); dwRes = emAoeWrite(dwMasterId, dwSlaveId, &oAoeNetId, AOE_TARGET_PORT, AOE_INDEX_GROUP, AOE_INDEX_OFFSET, sizeof(EC_T_DWORD), abyWriteData, &dwErrorCode, &dwCmdResult, MBX_TIMEOUT); if (dwRes != EC_E_NOERROR) { EcLogMsg(EC_LOG_LEVEL_ERROR, (pEcLogContext, EC_LOG_LEVEL_ERROR, "emAoeWrite failed: %s (0x%lx))\n", ecatGetText(dwRes), dwRes)); dwRetVal = dwRes; goto Exit; } /* EC-Master: read AoE from slave */ EC_SET_FRM_DWORD(abyReadData, 0); dwRes = emAoeRead(dwMasterId, dwSlaveId, &oAoeNetId, AOE_TARGET_PORT, AOE_INDEX_GROUP, AOE_INDEX_OFFSET, sizeof(EC_T_DWORD), abyReadData, &dwDataOutLen, &dwErrorCode, &dwCmdResult, MBX_TIMEOUT); if (dwRes != EC_E_NOERROR) { EcLogMsg(EC_LOG_LEVEL_ERROR, (pEcLogContext, EC_LOG_LEVEL_ERROR, "emAoeRead failed: %s (0x%lx))\n", ecatGetText(dwRes), dwRes)); dwRetVal = dwRes; goto Exit; } /* EC-Master: read + write AoE from/to slave */ EC_SET_FRM_DWORD(abyReadWriteData, 0x11223344 /* example value */); dwRes = emAoeReadWrite(dwMasterId, dwSlaveId, &oAoeNetId, AOE_TARGET_PORT, AOE_INDEX_GROUP, AOE_INDEX_OFFSET, sizeof(EC_T_DWORD), sizeof(EC_T_DWORD), abyReadWriteData, &dwDataOutLen, &dwErrorCode, &dwCmdResult, MBX_TIMEOUT); if (dwRes != EC_E_NOERROR) { EcLogMsg(EC_LOG_LEVEL_ERROR, (pEcLogContext, EC_LOG_LEVEL_ERROR, "emAoeReadWrite failed: %s (0x%lx))\n", ecatGetText(dwRes), dwRes)); dwRetVal = dwRes; goto Exit; } /* EC-Simulator: write AoE to slave */ EC_SET_FRM_DWORD(abyWriteData, 0x11223344 /* example value */); dwRes = esAoeWrite(dwSimulatorId, dwSlaveId, &oAoeNetId, AOE_TARGET_PORT, AOE_INDEX_GROUP, AOE_INDEX_OFFSET, sizeof(EC_T_DWORD), abyWriteData, &dwErrorCode, &dwCmdResult, MBX_TIMEOUT); if (dwRes != EC_E_NOERROR) { EcLogMsg(EC_LOG_LEVEL_ERROR, (pEcLogContext, EC_LOG_LEVEL_ERROR, "emAoeWrite failed: %s (0x%lx))\n", ecatGetText(dwRes), dwRes)); dwRetVal = dwRes; goto Exit; } /* EC-Simulator: read AoE from slave */ EC_SET_FRM_DWORD(abyReadData, 0); dwRes = esAoeRead(dwSimulatorId, dwSlaveId, &oAoeNetId, AOE_TARGET_PORT, AOE_INDEX_GROUP, AOE_INDEX_OFFSET, sizeof(EC_T_DWORD), abyReadData, &dwDataOutLen, &dwErrorCode, &dwCmdResult, MBX_TIMEOUT); if (dwRes != EC_E_NOERROR) { EcLogMsg(EC_LOG_LEVEL_ERROR, (pEcLogContext, EC_LOG_LEVEL_ERROR, "emAoeRead failed: %s (0x%lx))\n", ecatGetText(dwRes), dwRes)); dwRetVal = dwRes; goto Exit; } /* EC-Simulator: read + write AoE from/to slave */ EC_SET_FRM_DWORD(abyReadWriteData, 0x11223344 /* example value */); dwRes = esAoeReadWrite(dwSimulatorId, dwSlaveId, &oAoeNetId, AOE_TARGET_PORT, AOE_INDEX_GROUP, AOE_INDEX_OFFSET, sizeof(EC_T_DWORD), sizeof(EC_T_DWORD), abyReadWriteData, &dwDataOutLen, &dwErrorCode, &dwCmdResult, MBX_TIMEOUT); if (dwRes != EC_E_NOERROR) { EcLogMsg(EC_LOG_LEVEL_ERROR, (pEcLogContext, EC_LOG_LEVEL_ERROR, "emAoeReadWrite failed: %s (0x%lx))\n", ecatGetText(dwRes), dwRes)); dwRetVal = dwRes; goto Exit; } ``` # CAN application protocol over EtherCAT® (CoE) To handle CoE object transfers within the application, the callbacks pfnCoeRead and/or pfnCoeWrite can be registered using [`esSetSlaveCoeObjectTransferCallbacks()`](#_CPPv436esSetSlaveCoeObjectTransferCallbacks10EC_T_DWORD9EC_T_WORD9EC_T_WORD19EC_T_PF_COE_READ_CB20EC_T_PF_COE_WRITE_CBP9EC_T_VOID) or [`esSetSlaveSscApplication()`](api_general.html.md#_CPPv424esSetSlaveSscApplication10EC_T_DWORD9EC_T_WORDP24EC_T_SLAVE_SSC_APPL_DESC), e.g. in `myAppPrepare()` of EcSimulatorHilDemo / EcSimulatorSilDemo. See also [CoE transfer Simulator and MainDevice Example](#coe-transfer-simulator-and-maindevice-example) ## esExtendSlaveCoeObjectDictionary ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esExtendSlaveCoeObjectDictionary([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wCfgFixedAddress, EC_T_COE_DICTIONARY_DESC \*pDict) Add data types and / or objects to slave’s CoE object dictionary. \_ * **Parameters:** * **dwInstanceId** – [in] Simulator Instance ID * **wCfgFixedAddress** – [in] Slave’s station address * **pDict** – [in] Pointer to dictionary descriptor * **Returns:** [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) or error code ## esDeleteSlaveCoeObject ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esDeleteSlaveCoeObject([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wCfgFixedAddress, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wObjectIndex) Delete object from slave’s CoE object dictionary. \_ * **Parameters:** * **dwInstanceId** – [in] Simulator Instance ID * **wCfgFixedAddress** – [in] Slave’s station address * **wObjectIndex** – [in] Object index * **Returns:** [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) or error code ## esClearSlaveCoeObjectDictionary ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esClearSlaveCoeObjectDictionary([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wCfgFixedAddress) Delete all objects from slave’s CoE object dictionary. \_ * **Parameters:** * **dwInstanceId** – [in] Simulator Instance ID * **wCfgFixedAddress** – [in] Slave’s station address * **Returns:** [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) or error code ## esResetSlaveCoeObjectDictionary ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esResetSlaveCoeObjectDictionary([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wCfgFixedAddress) Reset all objects from slave’s CoE object dictionary to default. \_ * **Parameters:** * **dwInstanceId** – [in] Simulator Instance ID * **wCfgFixedAddress** – [in] Slave’s station address * **Returns:** [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) or error code ## esSetSlaveCoeObjectTransferCallbacks ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esSetSlaveCoeObjectTransferCallbacks([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wCfgFixedAddress, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wObjectIndex, [EC_T_PF_COE_READ_CB](#_CPPv419EC_T_PF_COE_READ_CB) pfRead, [EC_T_PF_COE_WRITE_CB](#_CPPv420EC_T_PF_COE_WRITE_CB) pfWrite, EC_T_VOID \*pvContext) Set SDO upload / download transfer callbacks. #### NOTE pfRead / pfWrite can also be registered if object dictionary unavailable at EC-Simulator. [esClearSlaveCoeObjectDictionary()](#da/dca/_ec_simulator_api_8cpp_1a2100ae59345a76d35218bd66d6d754cf) has to be called first. See [esClearSlaveCoeObjectDictionary()](#da/dca/_ec_simulator_api_8cpp_1a2100ae59345a76d35218bd66d6d754cf). In case of using an ENI and the simulator’s default dictionary wObjectIndex must be set to 0xFFFF. * **Parameters:** * **dwInstanceId** – [in] Simulator Instance ID * **wCfgFixedAddress** – [in] Slave’s station address. 0: all slaves. * **wObjectIndex** – [in] Object index. 0xffff: all objects * **pfRead** – [in] Upload callback function * **pfWrite** – [in] Download callback function * **pvContext** – [in] Pointer to context passed as first parameters to callback functions * **dwInstanceId** – **[in]** Simulator Instance ID * **wCfgFixedAddress** – **[in]** Slave’s station address. 0: All slaves. * **wObjectIndex** – **[in]** Object index. 0xFFFF: all objects. * **pfRead** – **[in]** Upload callback function. EC_NULL: clears callback if already registered. * **pfWrite** – **[in]** Download callback function. EC_NULL: clears callback if already registered. * **pvContext** – **[in]** Arbitrarily application-defined parameter passed to transfer callback functions * **Returns:** * [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116): Success * [EC_E_INVALIDPARM](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga1e10d9022db11a708658c71b0dead2fe): if dwInstanceId is out of range * [EC_E_INVALIDSTATE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga2a6310e052fca1b94797e8e26f031739): if simulator instance (dwInstanceId) not initialized, see [esInitSimulator()](api_general.html.md#da/dca/_ec_simulator_api_8cpp_1a9abcdec979e4ebcde0ddc9fd83da2948) * [EC_E_NOTFOUND](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga3113f3b6f82bb50e6ab3cde40268730a): if slave not found in ENI/EXI (wCfgFixedAddress) * [EC_E_NO_MBX_SUPPORT](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga461eba97c1aa71d0d6bc72202035ad98): if slave without Mailbox support * [EC_E_SDO_ABORTCODE_INDEX](error-codes_coe.html.md#df/d91/group___e_c___e_r_r_o_r___c_o_d_e_s___c_o_e_1ga38c3c5e62e8523dd5a294cb58803d804): if nonexistent object (wObjectIndex) #### SEE ALSO - [`esSetSlaveSscApplication()`](api_general.html.md#_CPPv424esSetSlaveSscApplication10EC_T_DWORD9EC_T_WORDP24EC_T_SLAVE_SSC_APPL_DESC) - [`esClearSlaveCoeObjectDictionary()`](#_CPPv431esClearSlaveCoeObjectDictionary10EC_T_DWORD9EC_T_WORD) ### typedef EC_T_VOID (\*EC_T_PF_COE_READ_CB)(EC_T_VOID \*pvContext, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwSimulatorId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wCfgFixedAddress, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wIndex, [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) bySubindex, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwSize, [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) \*pbyData, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) \*pdwOutDataLen, [EC_T_BOOL](api.html.md#_CPPv49EC_T_BOOL) bCompleteAccess, [EC_T_BOOL](api.html.md#_CPPv49EC_T_BOOL) bCheckReadAccess, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) \*pdwErrorCode) CoE Read Object Callback: Handle read requests from the master in the simulator application. The simulator has pre-handled the request and sets pdwErrorCode accordingly. * **Param pvContext:** **[in]** Arbitrarily application-defined parameter passed to callback * **Param dwSimulatorId:** **[in]** Simulator Instance ID * **Param wCfgFixedAddress:** **[in]** Slave fixed address from master request * **Param wIndex:** **[in]** Object Index from master request, e.g. 0x1018 * **Param bySubindex:** **[in]** Object SubIndex from master request * **Param dwSize:** **[in]** Read buffer size according to MbxIn Sync Manager size * **Param pbyData:** **[inout]** Read data buffer: pre-filled by the simulator if the object exists in the simulated slave’s object dictionary and is read-able in the current EtherCAT state * **Param pdwOutDataLen:** **[inout]** Read data length: pre-filled by the simulator if the object exists in the simulated slave’s object dictionary and is read-able in the current EtherCAT state, else the simulator application shall set the value accordingly * **Param bCompleteAccess:** **[in]** EC_TRUE: CoE SDO Upload with Complete Access. See also EC_MAILBOX_FLAG_SDO_COMPLETE. * **Param bCheckReadAccess:** **[in]** EC_TRUE: The simulator application should check the read access, e.g. if the object does not exist in the simulated slave’s object dictionary * **Param pdwErrorCode:** **[inout]** Current transfer error code pre-filled by the simulator. The simulator application shall set the current transfer error accordingly within the callback. * [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116): if object exists in the simulated slave’s object dictionary and is read-able in the current EtherCAT state * [EC_E_SDO_ABORTCODE_INDEX](error-codes_coe.html.md#df/d91/group___e_c___e_r_r_o_r___c_o_d_e_s___c_o_e_1ga38c3c5e62e8523dd5a294cb58803d804): if object does not exist in the simulated slave’s object dictionary and is read-able in the current EtherCAT state * [EC_E_SDO_ABORTCODE_OFFSET](error-codes_coe.html.md#df/d91/group___e_c___e_r_r_o_r___c_o_d_e_s___c_o_e_1gadd3c76fd45406e3cce1cfd0bac5b1210): if object SubIndex does not exist in the accessed object in the simulated slave’s object dictionary * [EC_E_SDO_ABORTCODE_DATA_LENGTH_NOT_MATCH](error-codes_coe.html.md#df/d91/group___e_c___e_r_r_o_r___c_o_d_e_s___c_o_e_1ga81a7871a5686e30272ee67ad08194b90): if the read data length does not match the accessed object length * [EC_E_SDO_ABORTCODE_ACCESS](error-codes_coe.html.md#df/d91/group___e_c___e_r_r_o_r___c_o_d_e_s___c_o_e_1ga69f15f48a4f39407a59175f4ecaa810b): if accessed Entry does not support commanded accesstype e.g. complete access is not supported on simple objects or ENUM descriptions * [EC_E_SDO_ABORTCODE_WRITEONLY](error-codes_coe.html.md#df/d91/group___e_c___e_r_r_o_r___c_o_d_e_s___c_o_e_1ga1df1d4ad8037a803e458faf3f5898cd3): if accessed Entry does not support read operation * [EC_E_SDO_ABORTCODE_TRANSFER_DEVICE_STATE](error-codes_coe.html.md#df/d91/group___e_c___e_r_r_o_r___c_o_d_e_s___c_o_e_1ga389c6c5de9cd017c1ea5feb3468c4e5e): if entry cannot be read in the current EtherCAT state * EC_E_… ### typedef EC_T_VOID (\*EC_T_PF_COE_WRITE_CB)(EC_T_VOID \*pvContext, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwSimulatorId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wCfgFixedAddress, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wIndex, [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) bySubindex, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwSize, [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) \*pbyData, [EC_T_BOOL](api.html.md#_CPPv49EC_T_BOOL) bCompleteAccess, [EC_T_BOOL](api.html.md#_CPPv49EC_T_BOOL) bCheckWriteAccess, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) \*pdwErrorCode) CoE Write Object Callback: Handle write requests from the master in the simulator application. The simulator has pre-handled the request and sets pdwErrorCode accordingly. * **Param pvContext:** **[in]** Arbitrarily application-defined parameter passed to callback * **Param dwSimulatorId:** **[in]** Simulator Instance ID * **Param wCfgFixedAddress:** **[in]** Slave fixed address from master request * **Param wIndex:** **[in]** Object Index from master request, e.g. 0x40A2 * **Param bySubindex:** **[in]** Object SubIndex from master request * **Param dwSize:** **[in]** Write data length * **Param pbyData:** **[inout]** Write data buffer: pre-filled by the simulator if the object exists in the simulated slave’s object dictionary and is write-able in the current EtherCAT state * **Param bCompleteAccess:** **[in]** EC_TRUE: CoE SDO Download with Complete Access. See also EC_MAILBOX_FLAG_SDO_COMPLETE. * **Param bCheckWriteAccess:** **[in]** EC_TRUE: The simulator application should check the write access, e.g. if the object does not exist in the simulated slave’s object dictionary * **Param pdwErrorCode:** **[inout]** Current transfer error code pre-filled by the simulator. The simulator application shall set the current transfer error accordingly within the callback. * [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116): if object exists in the simulated slave’s object dictionary and is write-able in the current EtherCAT state * [EC_E_SDO_ABORTCODE_INDEX](error-codes_coe.html.md#df/d91/group___e_c___e_r_r_o_r___c_o_d_e_s___c_o_e_1ga38c3c5e62e8523dd5a294cb58803d804): if object does not exist in the simulated slave’s object dictionary and is write-able in the current EtherCAT state * [EC_E_SDO_ABORTCODE_OFFSET](error-codes_coe.html.md#df/d91/group___e_c___e_r_r_o_r___c_o_d_e_s___c_o_e_1gadd3c76fd45406e3cce1cfd0bac5b1210): if object SubIndex does not exist in the accessed object in the simulated slave’s object dictionary * [EC_E_SDO_ABORTCODE_DATA_LENGTH_NOT_MATCH](error-codes_coe.html.md#df/d91/group___e_c___e_r_r_o_r___c_o_d_e_s___c_o_e_1ga81a7871a5686e30272ee67ad08194b90): if the write data length does not match the accessed object length * [EC_E_SDO_ABORTCODE_ACCESS](error-codes_coe.html.md#df/d91/group___e_c___e_r_r_o_r___c_o_d_e_s___c_o_e_1ga69f15f48a4f39407a59175f4ecaa810b): if accessed Entry does not support commanded accesstype e.g. complete access is not supported on simple objects or ENUM descriptions * [EC_E_SDO_ABORTCODE_READONLY](error-codes_coe.html.md#df/d91/group___e_c___e_r_r_o_r___c_o_d_e_s___c_o_e_1ga01af93e2a2d8a86de098c70057a1ccac): if accessed Entry does not support write operation * [EC_E_SDO_ABORTCODE_TRANSFER_DEVICE_STATE](error-codes_coe.html.md#df/d91/group___e_c___e_r_r_o_r___c_o_d_e_s___c_o_e_1ga389c6c5de9cd017c1ea5feb3468c4e5e): if entry cannot be write in the current EtherCAT state * EC_E_… ## esCoeSdoDownload ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esCoeSdoDownload([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceID, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwSlaveId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wObIndex, [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) byObSubIndex, const [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) \*pbyData, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwDataLen, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwTimeout, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwFlags) Execute a CoE SDO download to an EtherCAT slave device. This function may not be called from within the JobTask’s context. * **Parameters:** * **dwInstanceID** – [in] Instance ID (Multiple EtherCAT Network Support) * **dwSlaveId** – [in] Slave ID * **wObIndex** – [in] Object Index * **byObSubIndex** – [in] Object SubIndex. If Complete Access only 0 or 1 allowed. * **pbyData** – [in] Buffer containing transferred data. Must not be EC_NULL if dwDataLen > 0. * **dwDataLen** – [in] Buffer length [bytes]. Can be 0 for example for array. * **dwTimeout** – [in] Timeout [ms] * **dwFlags** – [in] Mailbox Flags. Bit 0: set if Complete Access (EC_MAILBOX_FLAG_SDO_COMPLETE). * **Returns:** * [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) if successful * [EC_E_INVALIDSTATE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga2a6310e052fca1b94797e8e26f031739) if EtherCAT stack isn’t initialized * [EC_E_INVALIDPARM](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga1e10d9022db11a708658c71b0dead2fe) if dwInstanceID is out of range, pbyData is EC_NULL and dwDataLen > 0, or dwTimeout is EC_NOWAIT * [EC_E_NOMEMORY](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga48c2a7b288dc6922a8c0eb116495e1fd) if the mailbox protocol queue of the slave is full * [EC_E_SLAVE_NOT_PRESENT](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga45555d5de25571188a82d2d76c02dd81) if slave not present * [EC_E_NOTFOUND](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga3113f3b6f82bb50e6ab3cde40268730a) if no slave matching dwSlaveId can be found * [EC_E_NO_MBX_SUPPORT](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga461eba97c1aa71d0d6bc72202035ad98) if slave has no mailbox support * [EC_E_INVALID_SLAVE_STATE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga9a3a38c9d24ba99a15c7fc3c953e1ff2) if slave is in an invalid state for mailbox transfer * [EC_E_MASTER_RED_STATE_INACTIVE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1gae2870f20d370920995e27b2a78171a5e) if Master Redundancy is configured and master is inactive * [EC_E_ADS_IS_RUNNING](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1gac053cb32c9b2bee0305b0644ef76e933) if ADS server is running * [CoE SDO error code](error-codes_coe.html.md#df-d91-group-e-c-e-r-r-o-r-c-o-d-e-s-c-o-e) ## esCoeSdoUpload ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esCoeSdoUpload([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceID, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwSlaveId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wObIndex, [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) byObSubIndex, [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) \*pbyData, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwDataLen, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) \*pdwOutDataLen, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwTimeout, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwFlags) Execute a CoE SDO upload from an EtherCAT slave device to the master. This function may not be called from within the JobTask’s context. * **Parameters:** * **dwInstanceID** – [in] Instance ID (Multiple EtherCAT Network Support) * **dwSlaveId** – [in] Slave ID * **wObIndex** – [in] Object index * **byObSubIndex** – [in] Object sub index. If Complete Access only 0 or 1 allowed. * **pbyData** – [out] Buffer receiving transferred data * **dwDataLen** – [in] Buffer length [bytes] * **pdwOutDataLen** – [out] Length of received data [byte] * **dwTimeout** – [in] Timeout [ms] * **dwFlags** – [in] Mailbox Flags. Bit 0: set if Complete Access (EC_MAILBOX_FLAG_SDO_COMPLETE). * **Returns:** * [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) if successful * [EC_E_INVALIDSTATE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga2a6310e052fca1b94797e8e26f031739) if EtherCAT stack isn’t initialized * [EC_E_INVALIDPARM](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga1e10d9022db11a708658c71b0dead2fe) if dwInstanceID is out of range, the input pointer is EC_NULL or contains EC_NULL pointer, or dwTimeout is EC_NOWAIT * [EC_E_NOMEMORY](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga48c2a7b288dc6922a8c0eb116495e1fd) if the mailbox protocol queue of the slave is full * [EC_E_SLAVE_NOT_PRESENT](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga45555d5de25571188a82d2d76c02dd81) if slave not present * [EC_E_NOTFOUND](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga3113f3b6f82bb50e6ab3cde40268730a) if no slave matching dwSlaveId can be found * [EC_E_NO_MBX_SUPPORT](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga461eba97c1aa71d0d6bc72202035ad98) if slave has no mailbox support * [EC_E_INVALID_SLAVE_STATE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga9a3a38c9d24ba99a15c7fc3c953e1ff2) if slave is in an invalid state for mailbox transfer * [EC_E_MASTER_RED_STATE_INACTIVE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1gae2870f20d370920995e27b2a78171a5e) if Master Redundancy is configured and master is inactive * [EC_E_ADS_IS_RUNNING](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1gac053cb32c9b2bee0305b0644ef76e933) if ADS server is running * [CoE SDO error code](error-codes_coe.html.md#df-d91-group-e-c-e-r-r-o-r-c-o-d-e-s-c-o-e) ## esCoeGetODList ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esCoeGetODList([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceID, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwSlaveId, EC_T_COE_ODLIST_TYPE eListType, [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) \*pbyData, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwDataLen, EC_T_COE_ODLIST \*poOdList, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwTimeout) Gets a list of object IDs that are available in a slave. This function may not be called from within the JobTask’s context. #### NOTE The data buffer will receive the slave response containing the list type followed by the list itself. Therefore the buffer must be 2 bytes bigger than the expected list size. * **Parameters:** * **dwInstanceID** – [in] Instance ID (Multiple EtherCAT Network Support) * **dwSlaveId** – [in] Slave ID * **eListType** – [in] Which object types shall be transferred * **pbyData** – [out] Buffer receiving transferred data * **dwDataLen** – [in] Buffer length in bytes * **poOdList** – [out] Received OD list object * **dwTimeout** – [in] Timeout [ms] * **Returns:** * [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) if successful * [EC_E_INVALIDSTATE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga2a6310e052fca1b94797e8e26f031739) if master isn’t initialized * [EC_E_INVALIDPARM](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga1e10d9022db11a708658c71b0dead2fe) if dwInstanceID is out of range, the input pointer is EC_NULL or contains EC_NULL pointer, or dwTimeout is EC_NOWAIT * [EC_E_NOMEMORY](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga48c2a7b288dc6922a8c0eb116495e1fd) if the mailbox protocol queue of the slave is full * [EC_E_SLAVE_NOT_PRESENT](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga45555d5de25571188a82d2d76c02dd81) if slave not present * [EC_E_NOTFOUND](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga3113f3b6f82bb50e6ab3cde40268730a) if no slave matching dwSlaveId can be found * [EC_E_NO_MBX_SUPPORT](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga461eba97c1aa71d0d6bc72202035ad98) if slave has no mailbox support * [EC_E_INVALID_SLAVE_STATE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga9a3a38c9d24ba99a15c7fc3c953e1ff2) if slave is in an invalid state for mailbox transfer * [EC_E_MASTER_RED_STATE_INACTIVE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1gae2870f20d370920995e27b2a78171a5e) if Master Redundancy is configured and master is inactive * [EC_E_ADS_IS_RUNNING](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1gac053cb32c9b2bee0305b0644ef76e933) if ADS server is running * [CoE SDO error code](error-codes_coe.html.md#df-d91-group-e-c-e-r-r-o-r-c-o-d-e-s-c-o-e) ## esCoeGetODListReq ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esCoeGetODListReq([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceID, EC_T_MBXTFER \*pMbxTfer, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwSlaveId, EC_T_COE_ODLIST_TYPE eListType, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwTimeout) Initiates retrieval of a list of object IDs that are available in a slave and returns immediately. A unique transfer ID must be written into EC_T_MBXTFER.dwTferId. EC_NOTIFY_MBOXRCV is given on completion. #### NOTE The mailbox transfer object will receive the slave response containing the list type followed by the list itself. Therefore the buffer must be 2 bytes bigger than the expected list size. * **Parameters:** * **dwInstanceID** – [in] Instance ID (Multiple EtherCAT Network Support) * **pMbxTfer** – [in] Mailbox transfer * **dwSlaveId** – [in] Slave ID * **eListType** – [in] Which object types shall be transferred * **dwTimeout** – [in] Timeout [ms] * **Returns:** * [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) if successful * [EC_E_INVALIDSTATE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga2a6310e052fca1b94797e8e26f031739) if EtherCAT stack isn’t initialized * [EC_E_INVALIDPARM](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga1e10d9022db11a708658c71b0dead2fe) if dwInstanceID is out of range, the input pointer is EC_NULL or contains EC_NULL pointer, or dwTimeout is EC_NOWAIT * [EC_E_NOMEMORY](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga48c2a7b288dc6922a8c0eb116495e1fd) if the mailbox protocol queue of the slave is full * [EC_E_SLAVE_NOT_PRESENT](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga45555d5de25571188a82d2d76c02dd81) if slave not present * [EC_E_NOTFOUND](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga3113f3b6f82bb50e6ab3cde40268730a) if no slave matching dwSlaveId can be found * [EC_E_NO_MBX_SUPPORT](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga461eba97c1aa71d0d6bc72202035ad98) if slave has no mailbox support * [EC_E_INVALID_SLAVE_STATE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga9a3a38c9d24ba99a15c7fc3c953e1ff2) if slave is in an invalid state for mailbox transfer * [EC_E_MASTER_RED_STATE_INACTIVE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1gae2870f20d370920995e27b2a78171a5e) if Master Redundancy is configured and master is inactive * [EC_E_ADS_IS_RUNNING](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1gac053cb32c9b2bee0305b0644ef76e933) if ADS server is running * [CoE SDO error code](error-codes_coe.html.md#df-d91-group-e-c-e-r-r-o-r-c-o-d-e-s-c-o-e) ## esCoeGetObjectDesc ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esCoeGetObjectDesc([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceID, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwSlaveId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wObIndex, [EC_T_CHAR](api.html.md#_CPPv49EC_T_CHAR) \*pchObName, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wObNameLen, [EC_T_COE_OBDESC](#_CPPv415EC_T_COE_OBDESC) \*poObDesc, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwTimeout) Determines the description of a specific object. This function may not be called from within the JobTask’s context. * **Parameters:** * **dwInstanceID** – [in] Instance ID (Multiple EtherCAT Network Support) * **dwSlaveId** – [in] Slave ID * **wObIndex** – [in] Object index * **pchObName** – [out] Buffer receiving object name * **wObNameLen** – [in] Buffer length * **poObDesc** – [out] Received object description object * **dwTimeout** – [in] Timeout [ms] * **Returns:** * [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) if successful * [EC_E_INVALIDSTATE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga2a6310e052fca1b94797e8e26f031739) if master isn’t initialized * [EC_E_INVALIDPARM](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga1e10d9022db11a708658c71b0dead2fe) if dwInstanceID is out of range, the input pointer is EC_NULL or contains EC_NULL pointer, or dwTimeout is EC_NOWAIT * [EC_E_NOMEMORY](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga48c2a7b288dc6922a8c0eb116495e1fd) if the mailbox protocol queue of the slave is full * [EC_E_SLAVE_NOT_PRESENT](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga45555d5de25571188a82d2d76c02dd81) if slave not present * [EC_E_NOTFOUND](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga3113f3b6f82bb50e6ab3cde40268730a) if no slave matching dwSlaveId can be found * [EC_E_NO_MBX_SUPPORT](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga461eba97c1aa71d0d6bc72202035ad98) if slave has no mailbox support * [EC_E_INVALID_SLAVE_STATE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga9a3a38c9d24ba99a15c7fc3c953e1ff2) if slave is in an invalid state for mailbox transfer * [EC_E_MASTER_RED_STATE_INACTIVE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1gae2870f20d370920995e27b2a78171a5e) if Master Redundancy is configured and master is inactive * [EC_E_ADS_IS_RUNNING](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1gac053cb32c9b2bee0305b0644ef76e933) if ADS server is running * [CoE SDO error code](error-codes_coe.html.md#df-d91-group-e-c-e-r-r-o-r-c-o-d-e-s-c-o-e) ### struct EC_T_COE_OBDESC ### Public Members ### [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wObIndex Index in the object dictionary ### [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wDataType Data type of the object ### [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) byObjCode Object code, see Table 62, ETG.1000 section 6 ### [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) byObjCategory Object category ### [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) byMaxNumSubIndex Maximum sub index number ### [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wObNameLen Length of the object name ### [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wStationAddress Station address of the slave ### [EC_T_CHAR](api.html.md#_CPPv49EC_T_CHAR) \*pchObName Object name (not NULL terminated!) ## esCoeGetObjectDescReq ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esCoeGetObjectDescReq([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceID, EC_T_MBXTFER \*pMbxTfer, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwSlaveId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wObIndex, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwTimeout) Initiates retrieval of the description of a specific object and returns immediately. A unique transfer ID must be written into EC_T_MBXTFER.dwTferId. EC_NOTIFY_MBOXRCV is given on completion. * **Parameters:** * **dwInstanceID** – [in] Instance ID (Multiple EtherCAT Network Support) * **pMbxTfer** – [in] Mailbox transfer object * **dwSlaveId** – [in] Slave ID * **wObIndex** – [in] Object index * **dwTimeout** – [in] Timeout [ms] * **Returns:** * [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) if successful * [EC_E_INVALIDSTATE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga2a6310e052fca1b94797e8e26f031739) if EtherCAT stack isn’t initialized * [EC_E_INVALIDPARM](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga1e10d9022db11a708658c71b0dead2fe) if dwInstanceID is out of range, the input pointer is EC_NULL or contains EC_NULL pointer, or dwTimeout is EC_NOWAIT * [EC_E_NOMEMORY](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga48c2a7b288dc6922a8c0eb116495e1fd) if the mailbox protocol queue of the slave is full * [EC_E_SLAVE_NOT_PRESENT](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga45555d5de25571188a82d2d76c02dd81) if slave not present * [EC_E_NOTFOUND](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga3113f3b6f82bb50e6ab3cde40268730a) if no slave matching dwSlaveId can be found * [EC_E_NO_MBX_SUPPORT](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga461eba97c1aa71d0d6bc72202035ad98) if slave has no mailbox support * [EC_E_INVALID_SLAVE_STATE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga9a3a38c9d24ba99a15c7fc3c953e1ff2) if slave is in an invalid state for mailbox transfer * [EC_E_MASTER_RED_STATE_INACTIVE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1gae2870f20d370920995e27b2a78171a5e) if Master Redundancy is configured and master is inactive * [EC_E_ADS_IS_RUNNING](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1gac053cb32c9b2bee0305b0644ef76e933) if ADS server is running * [CoE SDO error code](error-codes_coe.html.md#df-d91-group-e-c-e-r-r-o-r-c-o-d-e-s-c-o-e) ## esCoeGetEntryDesc ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esCoeGetEntryDesc([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceID, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwSlaveId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wObIndex, [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) byObSubIndex, [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) byValueInfo, [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) \*pbyData, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wDataLen, [EC_T_COE_ENTRYDESC](#_CPPv418EC_T_COE_ENTRYDESC) \*poEntryDesc, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwTimeout) Determines the description of a specific object entry. This function may not be called from within the JobTask’s context. * **Parameters:** * **dwInstanceID** – [in] Instance ID (Multiple EtherCAT Network Support) * **dwSlaveId** – [in] Slave ID * **wObIndex** – [in] Object index * **byObSubIndex** – [in] Object sub-index * **byValueInfo** – [in] The value info bit mask includes which elements shall be in the response. See Value info flags for available values. * **pbyData** – [out] Buffer receiving additional entry desc data * **wDataLen** – [in] Buffer length in bytes * **poEntryDesc** – [out] Received entry desc object * **dwTimeout** – [in] Timeout [ms] * **Returns:** * [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) if successful * [EC_E_INVALIDSTATE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga2a6310e052fca1b94797e8e26f031739) if master isn’t initialized * [EC_E_INVALIDPARM](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga1e10d9022db11a708658c71b0dead2fe) if dwInstanceID is out of range, the input pointer is EC_NULL or contains EC_NULL pointer, or dwTimeout is EC_NOWAIT * [EC_E_NOMEMORY](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga48c2a7b288dc6922a8c0eb116495e1fd) if the mailbox protocol queue of the slave is full * [EC_E_SLAVE_NOT_PRESENT](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga45555d5de25571188a82d2d76c02dd81) if slave not present * [EC_E_NOTFOUND](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga3113f3b6f82bb50e6ab3cde40268730a) if no slave matching dwSlaveId can be found * [EC_E_NO_MBX_SUPPORT](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga461eba97c1aa71d0d6bc72202035ad98) if slave has no mailbox support * [EC_E_INVALID_SLAVE_STATE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga9a3a38c9d24ba99a15c7fc3c953e1ff2) if slave is in an invalid state for mailbox transfer * [EC_E_MASTER_RED_STATE_INACTIVE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1gae2870f20d370920995e27b2a78171a5e) if Master Redundancy is configured and master is inactive * [EC_E_ADS_IS_RUNNING](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1gac053cb32c9b2bee0305b0644ef76e933) if ADS server is running * [CoE SDO error code](error-codes_coe.html.md#df-d91-group-e-c-e-r-r-o-r-c-o-d-e-s-c-o-e) ### struct EC_T_COE_ENTRYDESC ### Public Members ### [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wObIndex Index in the object dictionary ### [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) byObSubIndex Sub index in the object dictionary ### [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) byValueInfo Bit mask which information is included in pbyData. See Value info flags. ### [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wDataType Object data type according to ETG.1000 ### [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wBitLen Object size (number of bits) ### [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) byObAccess Access rights. See Object access flags. ### [EC_T_BOOL](api.html.md#_CPPv49EC_T_BOOL) bRxPdoMapping Object is mappable in a RxPDO ### [EC_T_BOOL](api.html.md#_CPPv49EC_T_BOOL) bTxPdoMapping Object is mappable in a TxPDO ### [EC_T_BOOL](api.html.md#_CPPv49EC_T_BOOL) bObCanBeUsedForBackup Object can be used for backup ### [EC_T_BOOL](api.html.md#_CPPv49EC_T_BOOL) bObCanBeUsedForSettings Object can be used for settings ### [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wStationAddress Station address of the slave ### [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wDataLen Size of the remaining object data ### [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) \*pbyData Remaining object data: dwUnitType, pbyDefaultValue, pbyMinValue, pbyMaxValue, pbyDescription (see ETG.1000.5 and ETG.1000.6) See szUnitType, szDefaultValue, szMinValue, szMaxValue, szDescription in CoeReadObjectDictionary() in EcSdoServices.cpp as an example for evaluating EC_T_COE_ENTRYDESC.pbyData. ## esCoeGetEntryDescReq ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esCoeGetEntryDescReq([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceID, EC_T_MBXTFER \*pMbxTfer, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwSlaveId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wObIndex, [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) byObSubIndex, [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) byValueInfo, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwTimeout) Initiates retrieval of the description of a specific object entry and returns immediately. A unique transfer ID must be written into EC_T_MBXTFER.dwTferId. EC_NOTIFY_MBOXRCV is given on completion. * **Parameters:** * **dwInstanceID** – [in] Instance ID (Multiple EtherCAT Network Support) * **pMbxTfer** – [in] Mailbox transfer object * **dwSlaveId** – [in] Slave ID * **wObIndex** – [in] Object index * **byObSubIndex** – [in] Object sub-index * **byValueInfo** – [in] The value info bit mask includes which elements shall be in the response. See Value info flags for available values. * **dwTimeout** – [in] Timeout [ms] * **Returns:** * [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) if successful * [EC_E_INVALIDSTATE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga2a6310e052fca1b94797e8e26f031739) if EtherCAT stack isn’t initialized * [EC_E_INVALIDPARM](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga1e10d9022db11a708658c71b0dead2fe) if dwInstanceID is out of range, the input pointer is EC_NULL or contains EC_NULL pointer, or dwTimeout is EC_NOWAIT * [EC_E_NOMEMORY](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga48c2a7b288dc6922a8c0eb116495e1fd) if the mailbox protocol queue of the slave is full * [EC_E_SLAVE_NOT_PRESENT](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga45555d5de25571188a82d2d76c02dd81) if slave not present * [EC_E_NOTFOUND](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga3113f3b6f82bb50e6ab3cde40268730a) if no slave matching dwSlaveId can be found * [EC_E_NO_MBX_SUPPORT](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga461eba97c1aa71d0d6bc72202035ad98) if slave has no mailbox support * [EC_E_INVALID_SLAVE_STATE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga9a3a38c9d24ba99a15c7fc3c953e1ff2) if slave is in an invalid state for mailbox transfer * [EC_E_MASTER_RED_STATE_INACTIVE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1gae2870f20d370920995e27b2a78171a5e) if Master Redundancy is configured and master is inactive * [EC_E_ADS_IS_RUNNING](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1gac053cb32c9b2bee0305b0644ef76e933) if ADS server is running * [CoE SDO error code](error-codes_coe.html.md#df-d91-group-e-c-e-r-r-o-r-c-o-d-e-s-c-o-e) ## CoE transfer Simulator and MainDevice Example The following example demonstrates how to handle CoE object transfers within the simulator application: ### **CoE transfer Simulator and MainDevice Example** The following example handlers can be registered at the EC-Simulator: ```cpp /* Length check in application if Object Dictionary unavailable at EC-Simulator */ static EC_T_DWORD myAppCoeObjectGetDataLen( EC_T_VOID* /* pvContext */, EC_T_WORD /* wCfgFixedAddress */, EC_T_WORD wObjectIndex, EC_T_BYTE bySubindex, EC_T_BOOL /* bCompleteAccess */, EC_T_DWORD* pdwDataLen) { EC_T_DWORD dwRetVal = EC_E_SDO_ABORTCODE_INDEX; /* example for 0x1018 Identity Object, SubIndex 1 Vendor ID */ if ((0x1018 == wObjectIndex) && (1 == bySubindex)) { *pdwDataLen = 4; dwRetVal = EC_E_NOERROR; } return dwRetVal; } /* EC_T_PF_COE_READ_CB */ static EC_T_VOID EC_FNCALL myAppCoeReadObjectCallback( EC_T_VOID* pvContext, EC_T_DWORD /* dwSimulatorId */, EC_T_WORD wCfgFixedAddress, EC_T_WORD wObjectIndex, EC_T_BYTE bySubindex, EC_T_DWORD dwBufSize, EC_T_BYTE* pbyData, EC_T_DWORD* pdwOutDataLen, EC_T_BOOL bCompleteAccess, EC_T_BOOL bCheckReadAccess /* EC_TRUE: Object Dictionary unavailable at EC-Simulator */, EC_T_DWORD* pdwErrorCode /* see EC_E_SDO_ABORTCODE_... */) { EC_T_DWORD dwDataLen = *pdwOutDataLen; /* check transfer parameters in application if Object Dictionary unavailable at EC-Simulator */ if (bCheckReadAccess) { *pdwErrorCode = myAppCoeObjectGetDataLen(pvContext, wCfgFixedAddress, wObjectIndex, bySubindex, bCompleteAccess, &dwDataLen); if ((EC_E_NOERROR == *pdwErrorCode) && (dwBufSize < dwDataLen)) { *pdwErrorCode = EC_E_SDO_ABORTCODE_DATA_LENGTH_TOO_LOW; } } if (EC_E_NOERROR == *pdwErrorCode) { /* provide data. example for 0x1018 Identity Object, SubIndex 1 Vendor ID */ if ((0x1018 == wObjectIndex) && (1 == bySubindex)) { OsDbgAssert(4 == dwDataLen); EC_SET_FRM_DWORD((EC_T_DWORD*)pbyData, 0x12345678); } } else { dwDataLen = 0; } *pdwOutDataLen = dwDataLen; return; } /* EC_T_PF_COE_WRITE_CB */ static EC_T_VOID EC_FNCALL myAppCoeWriteObjectCallback( EC_T_VOID* /* pvContext */, EC_T_DWORD /* dwSimulatorId */, EC_T_WORD /* wCfgFixedAddress */, EC_T_WORD wObjectIndex, EC_T_BYTE bySubindex, EC_T_DWORD dwSize, EC_T_BYTE* pbyData, EC_T_BOOL /* bCompleteAccess */, EC_T_BOOL bCheckWriteAccess /* EC_TRUE if Object Dictionary unavailable at EC-Simulator */, EC_T_DWORD* pdwErrorCode) { OsDbgAssert(!bCheckWriteAccess /* Object Dictionary available */ || (EC_E_SDO_ABORTCODE_INDEX == *pdwErrorCode)); if ((0x2000 == wObjectIndex) && (0 == bySubindex)) { /* check write access if Object Dictionary unavailable at EC-Simulator */ if (bCheckWriteAccess && (2 != dwSize)) { if (dwSize > 2) { *pdwErrorCode = EC_E_SDO_ABORTCODE_DATA_LENGTH_TOO_HIGH; } else { *pdwErrorCode = EC_E_SDO_ABORTCODE_DATA_LENGTH_TOO_LOW; } return; } /* handle data, e.g. myCoeSdoWrite(wObjectIndex, bySubindex, pbyData); */ EcLogMsg(EC_LOG_LEVEL_INFO, (pEcLogContext, EC_LOG_LEVEL_INFO, "myAppCoeWriteObjectCallback: 0x%04X, %d: 0x%04X)\n", wObjectIndex, bySubindex, EC_GET_FRM_WORD(pbyData))); *pdwErrorCode = EC_E_NOERROR; return; } } ``` The following example demonstrates objects transfers between MainDevice and Simulator: ```cpp EC_T_DWORD dwRes = EC_E_ERROR; EC_T_DWORD dwRetVal = EC_E_ERROR; EC_T_BYTE abyWriteData[sizeof(EC_T_WORD)]; EC_T_BYTE abyReadData[sizeof(EC_T_DWORD)]; EC_T_DWORD dwDataOutLen = 0; OsMemset(abyWriteData, 0, sizeof(abyWriteData)); OsMemset(abyReadData, 0, sizeof(abyReadData)); /* EC-Simulator: clear Object Dictionary */ dwRes = esClearSlaveCoeObjectDictionary(dwSimulatorId, wSlaveAddress); if (dwRes != EC_E_NOERROR) { EcLogMsg(EC_LOG_LEVEL_ERROR, (pEcLogContext, EC_LOG_LEVEL_ERROR, "esClearSlaveCoeObjectDictionary failed: %s (0x%lx))\n", esGetText(dwSimulatorId, dwRes), dwRes)); dwRetVal = dwRes; goto Exit; } /* EC-Simulator: register CoE handlers */ dwRes = esSetSlaveCoeObjectTransferCallbacks(dwSimulatorId, wSlaveAddress, 0xFFFF /* all objects */, myAppCoeReadObjectCallback, myAppCoeWriteObjectCallback, pAppContext); if (dwRes != EC_E_NOERROR) { EcLogMsg(EC_LOG_LEVEL_ERROR, (pEcLogContext, EC_LOG_LEVEL_ERROR, "esSetSlaveCoeObjectTransferCallbacks failed: %s (0x%lx))\n", esGetText(dwSimulatorId, dwRes), dwRes)); dwRetVal = dwRes; goto Exit; } /* EC-Master: set PREOP state */ dwRes = emSetMasterState(dwMasterId, 30000, eEcatState_PREOP); if (dwRes != EC_E_NOERROR) { EcLogMsg(EC_LOG_LEVEL_ERROR, (pEcLogContext, EC_LOG_LEVEL_ERROR, "emSetMasterState failed: %s (0x%lx))\n", ecatGetText(dwRes), dwRes)); dwRetVal = dwRes; goto Exit; } /* EC-Master: write CoE to slave */ EC_SET_FRM_WORD(abyWriteData, 0x1234 /* example value */); dwRes = emCoeSdoDownload(dwMasterId, emGetSlaveId(dwMasterId, wSlaveAddress), 0x2000, 0, abyWriteData, sizeof(EC_T_WORD), 5000 /* timeout */, 0); if (dwRes != EC_E_NOERROR) { EcLogMsg(EC_LOG_LEVEL_ERROR, (pEcLogContext, EC_LOG_LEVEL_ERROR, "emCoeSdoDownload failed: %s (0x%lx))\n", ecatGetText(dwRes), dwRes)); dwRetVal = dwRes; goto Exit; } /* EC-Master: read CoE from slave */ EC_SET_FRM_DWORD(abyReadData, 0); dwRes = emCoeSdoUpload(dwMasterId, emGetSlaveId(dwMasterId, wSlaveAddress), 0x1018, 1 /* vendor id */, abyReadData, sizeof(EC_T_DWORD), &dwDataOutLen, 5000 /* timeout */, 0); if (dwRes != EC_E_NOERROR) { EcLogMsg(EC_LOG_LEVEL_ERROR, (pEcLogContext, EC_LOG_LEVEL_ERROR, "emCoeSdoUpload failed: %s (0x%lx))\n", ecatGetText(dwRes), dwRes)); dwRetVal = dwRes; goto Exit; } /* EC-Simulator: write CoE to slave */ EC_SET_FRM_WORD(abyWriteData, 0x1234 /* example value */); dwRes = esCoeSdoDownload(dwSimulatorId, esGetSlaveId(dwSimulatorId, wSlaveAddress), 0x2000, 0, abyWriteData, sizeof(EC_T_WORD), 5000 /* timeout */, 0); if (dwRes != EC_E_NOERROR) { EcLogMsg(EC_LOG_LEVEL_ERROR, (pEcLogContext, EC_LOG_LEVEL_ERROR, "esCoeSdoDownload failed: %s (0x%lx))\n", ecatGetText(dwRes), dwRes)); dwRetVal = dwRes; goto Exit; } /* EC-Simulator: read CoE from slave */ EC_SET_FRM_DWORD(abyReadData, 0); dwRes = esCoeSdoUpload(dwSimulatorId, esGetSlaveId(dwSimulatorId, wSlaveAddress), 0x1018, 1 /* vendor id */, abyReadData, sizeof(EC_T_DWORD), &dwDataOutLen, 5000 /* timeout */, 0); if (dwRes != EC_E_NOERROR) { EcLogMsg(EC_LOG_LEVEL_ERROR, (pEcLogContext, EC_LOG_LEVEL_ERROR, "emCoeSdoUpload failed: %s (0x%lx))\n", ecatGetText(dwRes), dwRes)); dwRetVal = dwRes; goto Exit; } ``` # Ethernet over EtherCAT® (EoE) To handle EoE frames within the application, the callback pfnEoeReceive must be registered using [`esSetSlaveSscApplication()`](api_general.html.md#_CPPv424esSetSlaveSscApplication10EC_T_DWORD9EC_T_WORDP24EC_T_SLAVE_SSC_APPL_DESC), e.g. in `myAppPrepare()` of EcSimulatorHilDemo / EcSimulatorSilDemo. See also [EoE Ping Example](#eoe-ping-example) ## esEoeSendFrame ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esEoeSendFrame([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wCfgFixedAddress, [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) \*pbyFrame, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwFrameLen) Send EoE frame (queued) \_ * **Returns:** [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) or error code ## esGetCfgSlaveEoeInfo ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esGetCfgSlaveEoeInfo([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceID, [EC_T_BOOL](api.html.md#_CPPv49EC_T_BOOL) bFixedAddressing, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wSlaveAddress, [EC_T_CFG_SLAVE_EOE_INFO](#_CPPv423EC_T_CFG_SLAVE_EOE_INFO) \*pSlaveEoeInfo) Return EoE information about a configured slave from the ENI file. * **Parameters:** * **dwInstanceID** – [in] Instance ID (Multiple EtherCAT Network Support) * **bFixedAddressing** – [in] EC_TRUE: use station address, EC_FALSE: use AutoInc address * **wSlaveAddress** – [in] Slave address according bFixedAddressing * **pSlaveEoeInfo** – [out] Information about the slave * **Returns:** * [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) if successful * [EC_E_INVALIDSTATE](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga2a6310e052fca1b94797e8e26f031739) if EtherCAT stack isn’t initialized * [EC_E_INVALIDPARM](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga1e10d9022db11a708658c71b0dead2fe) if dwInstanceID is out of range * [EC_E_NOTFOUND](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga3113f3b6f82bb50e6ab3cde40268730a) if no slave matching bFixedAddressing / wSlaveAddress can be found * [EC_E_NO_MBX_SUPPORT](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga461eba97c1aa71d0d6bc72202035ad98) if the slave does not support mailbox communication * [EC_E_NO_EOE_SUPPORT](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1gae1e7c653cdf6275070be88c546b34ce1) if the slave supports mailbox communication, but not EoE \\newpage Content of [`EC_T_CFG_SLAVE_EOE_INFO`](#_CPPv423EC_T_CFG_SLAVE_EOE_INFO) is subject to be extended. ### struct EC_T_CFG_SLAVE_EOE_INFO ### Public Members ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwSlaveId [out] Slave ID ### [EC_T_BOOL](api.html.md#_CPPv49EC_T_BOOL) bMacAddr [out] Indicates whether the MAC address could be read and is valid ### [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) abyMacAddr[6] [out] MAC address ### [EC_T_BOOL](api.html.md#_CPPv49EC_T_BOOL) bIpAddr [out] Indicates whether the IP address could be read and is valid ### [EC_T_IPADDR](software-integration_ras-server.html.md#_CPPv411EC_T_IPADDR) oIpAddr [out] IP address ### [EC_T_BOOL](api.html.md#_CPPv49EC_T_BOOL) bSubnetMask [out] Indicates whether the subnet mask could be read and is valid ### [EC_T_IPADDR](software-integration_ras-server.html.md#_CPPv411EC_T_IPADDR) oSubnetMask [out] Subnet mask ### [EC_T_BOOL](api.html.md#_CPPv49EC_T_BOOL) bDefaultGateway [out] Indicates whether the default gateway could be read and is valid ### [EC_T_IPADDR](software-integration_ras-server.html.md#_CPPv411EC_T_IPADDR) oDefaultGateway [out] Default gateway ### [EC_T_BOOL](api.html.md#_CPPv49EC_T_BOOL) bDnsServer [out] Indicates whether the DNS server could be read and is valid ### [EC_T_IPADDR](software-integration_ras-server.html.md#_CPPv411EC_T_IPADDR) oDnsServer [out] DNS server ### [EC_T_BOOL](api.html.md#_CPPv49EC_T_BOOL) bDnsName [out] Indicates whether the DNS name could be read and is valid ### [EC_T_CHAR](api.html.md#_CPPv49EC_T_CHAR) szDnsName[32] [out] DNS name ### [EC_T_BOOL](api.html.md#_CPPv49EC_T_BOOL) bDisableEoe [out] Indicates whether the EoE is Disabled or not \\newpage ### **esGetCfgSlaveEoeInfo() Example** ```cpp EC_T_CFG_SLAVE_EOE_INFO oInfo; OsMemset(&oInfo, 0, sizeof(EC_T_CFG_SLAVE_EOE_INFO)); dwRes = esGetCfgSlaveEoeInfo(pAppContext->dwInstanceId, EC_TRUE, wSlaveAddress, &oInfo); if (dwRes != EC_E_NOERROR) { EcLogMsg(EC_LOG_LEVEL_ERROR, (pEcLogContext, EC_LOG_LEVEL_ERROR, "esGetCfgSlaveEoeInfo failed: %s (0x%lx))\n", esGetText(pAppContext->dwInstanceId, dwRes), dwRes)); dwRetVal = dwRes; goto Exit; } EcLogMsg(EC_LOG_LEVEL_INFO, (pEcLogContext, EC_LOG_LEVEL_INFO, "esGetCfgSlaveEoeInfo(%d): " "MAC address: %02X:%02X:%02X:%02X:%02X:%02X, IP address: %d.%d.%d.%d, subnet mask: %d.%d.%d.%d, " "default gateway: %d.%d.%d.%d, DNS server: %d.%d.%d.%d, DNS name: %s\n", wSlaveAddress, oInfo.abyMacAddr[0], oInfo.abyMacAddr[1], oInfo.abyMacAddr[2], oInfo.abyMacAddr[3], oInfo.abyMacAddr[4], oInfo.abyMacAddr[5], oInfo.oIpAddr.sAddr.by[0], oInfo.oIpAddr.sAddr.by[1], oInfo.oIpAddr.sAddr.by[2], oInfo.oIpAddr.sAddr.by[3], oInfo.oSubnetMask.sAddr.by[0], oInfo.oSubnetMask.sAddr.by[1], oInfo.oSubnetMask.sAddr.by[2], oInfo.oSubnetMask.sAddr.by[3], oInfo.oDefaultGateway.sAddr.by[0], oInfo.oDefaultGateway.sAddr.by[1], oInfo.oDefaultGateway.sAddr.by[2], oInfo.oDefaultGateway.sAddr.by[3], oInfo.oDnsServer.sAddr.by[0], oInfo.oDnsServer.sAddr.by[1], oInfo.oDnsServer.sAddr.by[2], oInfo.oDnsServer.sAddr.by[3], oInfo.szDnsName)); ``` \\newpage ## EoE Ping Example The following example demonstrates how to customize EoE simulation using [`esSetSlaveSscApplication()`](api_general.html.md#_CPPv424esSetSlaveSscApplication10EC_T_DWORD9EC_T_WORDP24EC_T_SLAVE_SSC_APPL_DESC) and [`esEoeSendFrame()`](#_CPPv414esEoeSendFrame10EC_T_DWORD9EC_T_WORDP9EC_T_BYTE10EC_T_DWORD). ### **EoE Ping Example** The following code demonstrates how to receive EoE frames from the MainDevice and send answers back. ```cpp /********************************************************************************/ /** \brief EoE ARP request and PING request context structure */ typedef struct _T_MY_EOE_CONTEXT { T_EC_DEMO_APP_CONTEXT* pAppContext; EC_T_WORD wSlaveAddress; ETHERNET_ADDRESS oMacAddress; EC_T_IPADDR oIpV4Address; EC_T_LINK_FRAMEDESC oSendFrame; } T_MY_EOE_CONTEXT; /********************************************************************************/ /** \brief EoE ARP request and PING request handler * * \return pReplyFrameDesc->dwSize > 0 if handled with reply */ static EC_T_VOID myAppProcessEoeFrameArpAndPing(EC_T_LINK_FRAMEDESC* pRequestFrameDesc, EC_T_LINK_FRAMEDESC* pReplyFrameDesc, ETHERNET_ADDRESS MacAddress, EC_T_IPADDR IpV4Address) { ETHERNET_FRAME* pRequest = (ETHERNET_FRAME*)pRequestFrameDesc->pbyFrame; ETHERNET_FRAME* pReply = (ETHERNET_FRAME*)pReplyFrameDesc->pbyFrame; /* prepare reply */ OsMemcpy(pReply, pRequest, pRequestFrameDesc->dwSize); pReply->Destination = pRequest->Source; pReply->Source = MacAddress; pReplyFrameDesc->dwSize = 0; /* handle ARP / ping */ switch (EC_ETHFRM_GET_FRAMETYPE(pRequest)) { case ETHERNET_FRAME_TYPE_ARP: { EC_ARP_IP_HEADER* pArpRequest = (EC_ARP_IP_HEADER*)EC_ENDOF(pRequest); /* skip ETHERNET_FRAME header */ EC_ARP_IP_HEADER* pArpReply = (EC_ARP_IP_HEADER*)EC_ENDOF(pReply); /* skip ETHERNET_FRAME header */ /* only Ethernet MAC and IPv4 ARP requests supported */ if ((EC_NTOHS(pArpRequest->wHwAddressType) == EC_ARP_HW_TYPE_ETHERNET) && (EC_NTOHS(pArpRequest->wProtocolType) == ETHERNET_FRAME_TYPE_IP) && (pArpRequest->byHwAddressLength == ETHERNET_ADDRESS_LEN) && (pArpRequest->byProtocolAddressLength == EC_IPv4_ADDRESS_LEN) && (EC_NTOHS(pArpRequest->wOpCode) == EC_ARP_OPCODE_REQUEST)) { /* only answer ARP request if IP address matches */ if ((BroadcastEthernetAddress == pRequest->Destination) && (pArpRequest->Address.IpV4.DestinationIp == IpV4Address)) { pArpReply->Address.IpV4.DestinationMac = pArpRequest->Address.IpV4.SourceMac; pArpReply->Address.IpV4.SourceMac = MacAddress; pArpReply->Address.IpV4.DestinationIp = pArpRequest->Address.IpV4.SourceIp; pArpReply->Address.IpV4.SourceIp = IpV4Address; pArpReply->wOpCode = EC_HTONS(EC_ARP_OPCODE_REPLY); /* reply valid */ pReplyFrameDesc->dwSize = ETHERNET_FRAME_LEN + EC_ARP_IPv4_HEADER_LEN; } } } break; case ETHERNET_FRAME_TYPE_IP: { if (((EC_IP_HEADER*)EC_ENDOF(pRequest))->byProtocol == EC_IP_PROTOCOL_ICMP) { EC_ICMP_HEADER* pIcmpRequest = (EC_ICMP_HEADER*)EC_ENDOF(pRequest); /* skip ETHERNET_FRAME header */ EC_ICMP_HEADER* pIcmpReply = (EC_ICMP_HEADER*)EC_ENDOF(pReply); /* skip ETHERNET_FRAME header */ /* only answer PING request if MAC address and IP address match */ if ((pIcmpRequest->byType == EC_ICMP_TYPE_ECHO) && (pRequest->Destination == MacAddress) && (pIcmpRequest->IpHdr.dwDstAddr == IpV4Address)) { EC_T_WORD wLen = EC_NTOHS(pIcmpRequest->IpHdr.wTotalLength); /* swap src and dest ip address */ pIcmpReply->IpHdr.dwSrcAddr = pIcmpRequest->IpHdr.dwDstAddr; pIcmpReply->IpHdr.dwDstAddr = pIcmpRequest->IpHdr.dwSrcAddr; pIcmpReply->byType = EC_ICMP_TYPE_ECHO_REPLY; pIcmpReply->IpHdr.wCheckSum = 0; #if __GNUC__ >= 9 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Waddress-of-packed-member" #endif pIcmpReply->IpHdr.wCheckSum = EC_HTONS(EcCalculateCrcRfc1071((EC_T_WORD*)&pIcmpReply->IpHdr, EC_IP_HEADER_MINIMUM_LEN)); #if __GNUC__ >= 9 #pragma GCC diagnostic pop #endif pIcmpRequest->wCheckSum = 0; pIcmpRequest->wCheckSum = EC_HTONS(EcCalculateCrcRfc1071((EC_T_WORD*)&pIcmpReply->byType /* skip IpHdr */, (EC_T_WORD)(wLen - EC_IP_HEADER_MINIMUM_LEN))); /* reply valid */ pReplyFrameDesc->dwSize = (EC_T_WORD)(ETHERNET_FRAME_LEN + wLen); } } } break; } } static EC_T_VOID myAppEoe_APPL_EoeReceive(EC_T_VOID* pvContext, EC_T_DWORD dwSimulatorId, EC_T_WORD wCfgFixedAddress, EC_T_WORD* pwFrame, EC_T_WORD wFrameSize) { T_MY_EOE_CONTEXT* poContext = (T_MY_EOE_CONTEXT*)pvContext; EC_T_LINK_FRAMEDESC oReceiveFrame; oReceiveFrame.pbyFrame = (EC_T_BYTE*)pwFrame; oReceiveFrame.dwSize = wFrameSize; /* call ARP request and ping request handler and send reply if filled by handler */ myAppProcessEoeFrameArpAndPing(&oReceiveFrame, &poContext->oSendFrame, poContext->oMacAddress, poContext->oIpV4Address); if (poContext->oSendFrame.dwSize > 0) { esEoeSendFrame(dwSimulatorId, wCfgFixedAddress, poContext->oSendFrame.pbyFrame, poContext->oSendFrame.dwSize); } } static EC_T_VOID myAppEoe_APPL_EoeSettingInd(EC_T_VOID* pvContext, EC_T_DWORD /* dwSimulatorId */, EC_T_WORD /* wCfgFixedAddress */, EC_T_WORD* pwMacAddress, EC_T_WORD* pwIpV4Address, EC_T_WORD* /* pwIpV4SubNetMask */, EC_T_WORD* /* pwIpV4DefaultGateway */, EC_T_WORD* /* pwDnsIpV4Address */) { T_MY_EOE_CONTEXT* poContext = (T_MY_EOE_CONTEXT*)pvContext; poContext->oMacAddress = *((ETHERNET_ADDRESS*)pwMacAddress); poContext->oIpV4Address.dwAddr = EC_GETDWORD(pwIpV4Address); } static EC_INLINESTART EC_T_DWORD myAppEoeInit(T_EC_DEMO_APP_CONTEXT* pAppContext, T_MY_EOE_CONTEXT* poContext, EC_T_WORD wSlaveAddress) { EC_T_DWORD dwRetVal = EC_E_ERROR; EC_T_DWORD dwRes = EC_E_ERROR; poContext->pAppContext = pAppContext; poContext->wSlaveAddress = wSlaveAddress; poContext->oSendFrame.pbyFrame = (EC_T_BYTE*)OsMalloc(ETHERNET_MAX_FRAMEBUF_LEN /* 1536 */); if (EC_NULL == poContext->oSendFrame.pbyFrame) { dwRetVal = EC_E_NOMEMORY; goto Exit; } { struct _EC_T_SLAVE_SSC_APPL_DESC oSlaveApplDesc; OsMemset(&oSlaveApplDesc, 0, sizeof(struct _EC_T_SLAVE_SSC_APPL_DESC)); oSlaveApplDesc.dwSignature = SIMULATOR_SIGNATURE; oSlaveApplDesc.dwSize = sizeof(struct _EC_T_SLAVE_SSC_APPL_DESC); oSlaveApplDesc.szName = (EC_T_CHAR*)"MyAppEoeSlaveAppl"; oSlaveApplDesc.pvContext = poContext; /* first parameter of static wrapper functions */ oSlaveApplDesc.pfnEoeReceive = myAppEoe_APPL_EoeReceive; oSlaveApplDesc.pfnEoeSettingInd = myAppEoe_APPL_EoeSettingInd; /* register callbacks at slave */ dwRes = esSetSlaveSscApplication(pAppContext->dwInstanceId, wSlaveAddress, &oSlaveApplDesc); if (EC_E_NOERROR != dwRes) { dwRetVal = dwRes; goto Exit; } } dwRetVal = EC_E_NOERROR; Exit: if (EC_E_NOERROR != dwRetVal) { OsSafeFree(poContext->oSendFrame.pbyFrame); } return dwRetVal; } EC_INLINESTOP ``` The callbacks need a context. Each SubDevice needs its individual context. If there is only one SubDevice to be registered, a global context can be declared and used: ```cpp T_MY_EOE_CONTEXT G_oContext; ``` The callbacks must be registered using [`esSetSlaveSscApplication()`](api_general.html.md#_CPPv424esSetSlaveSscApplication10EC_T_DWORD9EC_T_WORDP24EC_T_SLAVE_SSC_APPL_DESC), e.g. in `myAppPrepare()` of EcSimulatorHilDemo / EcSimulatorSilDemo: ```cpp OsMemset(&G_oContext, 0, sizeof(G_oContext)); dwRes = myAppEoeInit(pAppContext, &G_oContext, wSlaveAddress); if (EC_E_NOERROR != dwRes) { dwRetVal = dwRes; goto Exit; } ``` \\newpage # File access over EtherCAT® (FoE) The following examples demonstrate how to customize FoE simulation using [`esSetSlaveSscApplication()`](api_general.html.md#_CPPv424esSetSlaveSscApplication10EC_T_DWORD9EC_T_WORDP24EC_T_SLAVE_SSC_APPL_DESC). ### **FoE Download Example** The following code demonstrates how to receive FoE from the MainDevice and store it in a buffer. The data received in this example is stored in `T_MY_CONTEXT::abyFileBuf` : ```cpp #define MYAPP_FOE_BUFFER_SIZE (35264) typedef struct { EC_T_BYTE abyFileBuf[MYAPP_FOE_BUFFER_SIZE]; EC_T_WORD wFileBufLen; /* ... */ } T_MY_CONTEXT; ``` The callback `myAppFoeWrite()` handles download requests from the MainDevice, `myAppFoeWriteData()` copies the FoE payload from the mailbox to `T_MY_CONTEXT::abyFileBuf` : ```cpp extern "C" EC_T_WORD EC_FNCALL myAppFoeWrite( EC_T_VOID* pvContext, EC_T_DWORD /* dwSimulatorId */, EC_T_WORD /* wCfgFixedAddress */, EC_T_WORD*, EC_T_WORD, EC_T_DWORD) { T_MY_CONTEXT* poContext = (T_MY_CONTEXT*)pvContext; poContext->wFileBufLen = 0; return 0; /* accept file download (ECAT_FOE_ERRCODE_... denies download) */ } extern "C" EC_T_WORD EC_FNCALL myAppFoeWriteData( EC_T_VOID* pvContext, EC_T_DWORD /* dwSimulatorId */, EC_T_WORD /* wCfgFixedAddress */, EC_T_WORD* pData, EC_T_WORD wSize, EC_T_BYTE bDataFollowing) { T_MY_CONTEXT* poContext = (T_MY_CONTEXT*)pvContext; if (poContext->wFileBufLen + wSize > sizeof(poContext->abyFileBuf)) { return ECAT_FOE_ERRCODE_DISKFULL; /* abort transfer */ } OsMemcpy(&poContext->abyFileBuf[poContext->wFileBufLen], pData, wSize); poContext->wFileBufLen = poContext->wFileBufLen + wSize; /* FoE ACK segment at Master (more segments follow / download finished) */ return bDataFollowing ? SSC_FOE_ACK : SSC_FOE_ACKFINISHED; } ``` See type `EC_PF_SSC_APPL_FOE_WRITE` . The callbacks must be registered using [`esSetSlaveSscApplication()`](api_general.html.md#_CPPv424esSetSlaveSscApplication10EC_T_DWORD9EC_T_WORDP24EC_T_SLAVE_SSC_APPL_DESC), e.g. in `myAppPrepare()` of EcSimulatorHilDemo / EcSimulatorSilDemo: ```cpp struct _EC_T_SLAVE_SSC_APPL_DESC oSlaveApp; OsMemset(&oSlaveApp, 0, sizeof(struct _EC_T_SLAVE_SSC_APPL_DESC)); T_MY_CONTEXT* poSlaveApplContext = &G_oSlaveApplContext; OsMemset(poSlaveApplContext, 0, sizeof(G_oSlaveApplContext)); oSlaveApp.dwSignature = SIMULATOR_SIGNATURE; oSlaveApp.dwSize = sizeof(struct _EC_T_SLAVE_SSC_APPL_DESC); oSlaveApp.szName = (EC_T_CHAR*)"mySlaveAppl"; oSlaveApp.pvContext = poSlaveApplContext; /* pvContext of callbacks */ oSlaveApp.pfnFoeWrite = myAppFoeWrite; oSlaveApp.pfnFoeWriteData = myAppFoeWriteData; /* register SlaveSscApplication call-backs (Master in INIT) */ dwRes = esSetSlaveSscApplication(dwSimulatorId, wSlaveAddress, &oSlaveApp); if (dwRes != EC_E_NOERROR) { goto Exit; } ``` The following code at MainDevice downloads the file to the SubDevice: ```cpp /* set Master PREOP */ dwRes = emSetMasterState(dwMasterId, 30000 /* dwTimeout */, eEcatState_PREOP); if (dwRes != EC_E_NOERROR) { goto Exit; } /* download file */ dwRes = emFoeFileDownload(dwMasterId, emGetSlaveId(dwMasterId, wSlaveAddress), (EC_T_CHAR*)"foe.dat", (EC_T_DWORD)OsStrlen((EC_T_CHAR*)"foe.dat"), G_abyFileBuf, MYAPP_FOE_BUFFER_SIZE, 0 /* dwPassword */, 30000 /* dwTimeout */); if (dwRes != EC_E_NOERROR) { goto Exit; } ``` \\newpage ### **FoE Upload Example** The following code demonstrates how to send FoE data from a local buffer to the MainDevice. The data sent in this example is stored in `T_MY_CONTEXT::abyFileBuf` : ```cpp #define MYAPP_FOE_BUFFER_SIZE (35264) typedef struct { EC_T_BYTE abyFileBuf[MYAPP_FOE_BUFFER_SIZE]; EC_T_WORD wFileBufLen; /* ... */ } T_MY_CONTEXT; ``` `myAppFoeRead()` handles upload requests from the MainDevice, `myAppFoeReadData()` copies the FoE payload from `T_MY_CONTEXT::abyFileBuf` to the mailbox: ```cpp extern "C" EC_T_WORD EC_FNCALL myAppFoeReadData( EC_T_VOID* pvContext, EC_T_DWORD /* dwSimulatorId */, EC_T_WORD /* wCfgFixedAddress */, EC_T_DWORD dwOffset, EC_T_WORD wMaxBlockSize, EC_T_WORD* pData) { T_MY_CONTEXT* poContext = (T_MY_CONTEXT*)pvContext; if (dwOffset > poContext->wFileBufLen) { return 0; } if (dwOffset + wMaxBlockSize > poContext->wFileBufLen) { wMaxBlockSize = EC_LOWORD(poContext->wFileBufLen - dwOffset); } if (wMaxBlockSize > 0) { OsMemcpy(pData, &poContext->abyFileBuf[dwOffset], wMaxBlockSize); } return wMaxBlockSize; /* amount of data read */ } extern "C" EC_T_WORD EC_FNCALL myAppFoeRead( EC_T_VOID* pvContext, EC_T_DWORD dwSimulatorId, EC_T_WORD wCfgFixedAddress, EC_T_WORD*, EC_T_WORD, EC_T_DWORD, EC_T_WORD wMaxBlockSize, EC_T_WORD* pData) { /* APPL_FoeRead contains returning first data */ return myAppFoeReadData(pvContext, dwSimulatorId, wCfgFixedAddress, 0, wMaxBlockSize, pData); } ``` The callbacks must be registered using [`esSetSlaveSscApplication()`](api_general.html.md#_CPPv424esSetSlaveSscApplication10EC_T_DWORD9EC_T_WORDP24EC_T_SLAVE_SSC_APPL_DESC), e.g. in `myAppPrepare()` of EcSimulatorHilDemo / EcSimulatorSilDemo: ```cpp struct _EC_T_SLAVE_SSC_APPL_DESC oSlaveApp; OsMemset(&oSlaveApp, 0, sizeof(struct _EC_T_SLAVE_SSC_APPL_DESC)); T_MY_CONTEXT* poSlaveApplContext = &G_oSlaveApplContext; OsMemset(poSlaveApplContext, 0, sizeof(G_oSlaveApplContext)); /* pattern for file content */ OsMemset(poSlaveApplContext->abyFileBuf, 0xAA, MYAPP_FOE_BUFFER_SIZE); poSlaveApplContext->wFileBufLen = MYAPP_FOE_BUFFER_SIZE; oSlaveApp.dwSignature = SIMULATOR_SIGNATURE; oSlaveApp.dwSize = sizeof(struct _EC_T_SLAVE_SSC_APPL_DESC); oSlaveApp.szName = (EC_T_CHAR*)"mySlaveAppl"; oSlaveApp.pvContext = poSlaveApplContext; /* pvContext of callbacks */ oSlaveApp.pfnFoeRead = myAppFoeRead; oSlaveApp.pfnFoeReadData = myAppFoeReadData; /* register SlaveSscApplication callbacks (Master in INIT) */ dwRes = esSetSlaveSscApplication(dwSimulatorId, wSlaveAddress, &oSlaveApp); if (dwRes != EC_E_NOERROR) { goto Exit; } ``` The following code at MainDevice uploads the file from the SubDevice: ```cpp /* set Master PREOP */ dwRes = emSetMasterState(dwMasterId, 30000 /* dwTimeout */, eEcatState_PREOP); if (dwRes != EC_E_NOERROR) { goto Exit; } /* upload file */ dwRes = emFoeFileUpload(dwMasterId, emGetSlaveId(dwMasterId, wSlaveAddress), (EC_T_CHAR*)"foe.dat", (EC_T_DWORD)OsStrlen((EC_T_CHAR*)"foe.dat"), G_abyFileBuf, MYAPP_FOE_BUFFER_SIZE, &dwOutDataLen, 0 /* dwPassword */, 30000 /* dwTimeout */); if (dwRes != EC_E_NOERROR) { goto Exit; } ``` #### SEE ALSO - [`esInitSimulator()`](api_general.html.md#_CPPv415esInitSimulator10EC_T_DWORDPK25EC_T_SIMULATOR_INIT_PARMS) - [`esConfigureNetwork()`](api_general.html.md#_CPPv418esConfigureNetwork10EC_T_DWORD13EC_T_CNF_TYPE10EC_T_PBYTE10EC_T_DWORD) \\newpage # Vendor specific access over EtherCAT® (VoE) See also [VoE Receive Example](#voe-receive-example) ## esVoeSend ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esVoeSend([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wCfgFixedAddress, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wDstFixedAddress, const [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) \*pbyData, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwDataLen) Fill “Mailbox In” (SM1) with VoE data to be polled by Master. The slave must have VoE enabled, see ESI: /EtherCATInfo/Descriptions/Devices/Device/Mailbox/VoE, ENI/EXI: /EtherCATConfig/Config/Slave/Mailbox/Protocol/VoE. \_ * **Parameters:** * **dwInstanceId** – [in] Simulator Instance ID * **wCfgFixedAddress** – [in] Slave’s station address * **wDstFixedAddress** – [in] Destination address * **pbyData** – [in] Data * **dwDataLen** – [in] Data length * **Returns:** [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) or error code ## esSetVoeReceiveCallback ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esSetVoeReceiveCallback([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wCfgFixedAddress, EC_T_PF_VOE_RECEIVE_CB pfVoeReceive, EC_T_VOID \*pvContext) Set VoE data received callback for “Mailbox Out” (SM0). Within the callback, no EC-Simulator API may be called. The slave must have VoE enabled, see ESI: /EtherCATInfo/Descriptions/Devices/Device/Mailbox/VoE, ENI/EXI: /EtherCATConfig/Config/Slave/Mailbox/Protocol/VoE. * **Parameters:** * **dwInstanceId** – [in] Simulator Instance ID * **wCfgFixedAddress** – [in] Slave’s station address * **pfVoeReceive** – [in] Receive callback function * **pvContext** – [in] Receive callback function context * **Returns:** * [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116): on success * [EC_E_NOTFOUND](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga3113f3b6f82bb50e6ab3cde40268730a): if slave not found in ENI/EXI (wCfgFixedAddress) * [EC_E_NO_MBX_SUPPORT](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga461eba97c1aa71d0d6bc72202035ad98): if slave without Mailbox support ## VoE Receive Example The following examples demonstrate how to register a handler for VoE writes from the MainDevice or from other SubDevices. ### **VoE Receive Example** The following code demonstrates how to send VoE from the MainDevice to the SubDevice and store it in a buffer at the Simulator. The data received in this example is stored in `T_MY_CONTEXT::abyVoeBuf` : ```cpp #define MYAPP_VOE_BUFFER_SIZE (512) typedef struct { EC_T_BYTE abyVoeBuf[MYAPP_VOE_BUFFER_SIZE]; EC_T_DWORD dwVoeBufLen; EC_T_VOID* pvEvent; /* ... */ } T_MY_CONTEXT; ``` `myAppVoeReceiveCallback()` handles write requests from the MainDevice and copies the received VoE payload from the mailbox to `T_MY_CONTEXT::abyVoeBuf` : ```cpp EC_T_BYTE EC_FNCALL myAppVoeReceiveCallback( EC_T_VOID* pvContext, EC_T_DWORD /* dwSimulatorId */, EC_T_WORD /* wCfgFixedAddress VoE receiver address, e.g. 1001 */, EC_T_WORD /* wSrcFixedAddress VoE sender address, 0: Master */, const EC_T_BYTE* pbyData, EC_T_DWORD dwDataLen) { T_MY_CONTEXT* poContext = (T_MY_CONTEXT*)pvContext; OsMemcpy(poContext->abyVoeBuf, pbyData, EC_AT_MOST(MYAPP_VOE_BUFFER_SIZE, dwDataLen)); poContext->dwVoeBufLen = dwDataLen; /* No EC-Simulator APIs may be issued from within the callback context. Signalize VoE data received for deferred processing in other thread. */ OsSetEvent(poContext->pvEvent); return 0; } ``` The following code shows how to register `myAppVoeReceiveCallback()` and send VoE from the MainDevice to the simulated SubDevice: ```cpp EC_T_DWORD dwRes = EC_E_ERROR; EC_T_DWORD dwRetVal = EC_E_ERROR; #define MYAPP_VOE_SEND_BUF_LEN sizeof(EC_T_DWORD) EC_T_BYTE abyVoeSendBuf[MYAPP_VOE_SEND_BUF_LEN]; OsMemset(abyVoeSendBuf, 0, MYAPP_VOE_SEND_BUF_LEN); T_MY_CONTEXT oContext; OsMemset(&oContext, 0, sizeof(T_MY_CONTEXT)); oContext.pvEvent = OsCreateEvent(); if (EC_NULL == oContext.pvEvent) { EcLogMsg(EC_LOG_LEVEL_ERROR, (pEcLogContext, EC_LOG_LEVEL_ERROR, "OsCreateEvent failed\n")); dwRetVal = EC_E_NOMEMORY; goto Exit; } /* EC-Simulator: register VoE handler */ dwRes = esSetVoeReceiveCallback(dwSimulatorId, 1001, myAppVoeReceiveCallback, &oContext); if (dwRes != EC_E_NOERROR) { EcLogMsg(EC_LOG_LEVEL_ERROR, (pEcLogContext, EC_LOG_LEVEL_ERROR, "esSetVoeReceiveCallback failed: %s (0x%lx))\n", esGetText(dwSimulatorId, dwRes), dwRes)); dwRetVal = dwRes; goto Exit; } /* EC-Master: set PREOP state */ dwRes = emSetMasterState(dwMasterId, 30000, eEcatState_PREOP); if (dwRes != EC_E_NOERROR) { EcLogMsg(EC_LOG_LEVEL_ERROR, (pEcLogContext, EC_LOG_LEVEL_ERROR, "emSetMasterState failed: %s (0x%lx))\n", ecatGetText(dwRes), dwRes)); dwRetVal = dwRes; goto Exit; } /* send VoE to slave */ EC_SET_FRM_DWORD(abyVoeSendBuf, 0x12345678); dwRes = emVoeWrite(dwMasterId, emGetSlaveId(dwMasterId, 1001), abyVoeSendBuf, MYAPP_VOE_SEND_BUF_LEN, 5000); if (dwRes != EC_E_NOERROR) { EcLogMsg(EC_LOG_LEVEL_ERROR, (pEcLogContext, EC_LOG_LEVEL_ERROR, "emVoeWrite failed: %s (0x%lx))\n", ecatGetText(dwRes), dwRes)); dwRetVal = dwRes; goto Exit; } /* wait for slave received data in callback */ dwRes = OsWaitForEvent(oContext.pvEvent, 5000); if (dwRes != EC_E_NOERROR) { EcLogMsg(EC_LOG_LEVEL_ERROR, (pEcLogContext, EC_LOG_LEVEL_ERROR, "OsWaitForEvent failed: %s (0x%lx))\n", esGetText(dwSimulatorId, dwRes), dwRes)); dwRetVal = dwRes; goto Exit; } dwRetVal = EC_E_NOERROR; Exit: OsSafeDeleteEvent(oContext.pvEvent); ```