# Programmer’s Guide ## emDcmConfigure ### static EC_T_DWORD ecatDcmConfigure(const [EC_T_DCM_CONFIG](#_CPPv415EC_T_DCM_CONFIG) \*pDcmConfig, EC_T_DWORD dwInSyncTimeout) ### EC_T_DWORD emDcmConfigure(EC_T_DWORD dwInstanceID, const [EC_T_DCM_CONFIG](#_CPPv415EC_T_DCM_CONFIG) \*pDcmConfig, EC_T_DWORD dwInSyncTimeout) Configure DC master synchronization. * **Parameters:** * **dwInstanceID** – [in] Instance ID (Multiple EtherCAT Network Support) * **pDcmConfig** – [in] Configuration information, a pointer to a structure of type [EC_T_DCM_CONFIG](#d1/d72/struct_e_c___t___d_c_m___c_o_n_f_i_g) * **dwInSyncTimeout** – [in] Currently not implemented * **Returns:** EC_E_NOERROR or error code ### struct EC_T_DCM_CONFIG ### Public Members ### [EC_T_DCM_MODE](#_CPPv413EC_T_DCM_MODE) eMode [in] DCM mode ### [EC_T_DCM_CONFIG_BUSSHIFT](#_CPPv424EC_T_DCM_CONFIG_BUSSHIFT) BusShift [in] BusShift configuration. Valid if eMode is set to eDcmMode_BusShift. ### [EC_T_DCM_CONFIG_MASTERSHIFT](#_CPPv427EC_T_DCM_CONFIG_MASTERSHIFT) MasterShift [in] MasterShift configuration. Valid if eMode is set to eDcmMode_MasterShift. ### [EC_T_DCM_CONFIG_LINKLAYERREFCLOCK](#_CPPv433EC_T_DCM_CONFIG_LINKLAYERREFCLOCK) LinkLayerRefClock [in] LinkLayerRefClock configuration. Valid if eMode is set to eDcmMode_LinkLayerRefClock. ### [EC_T_DCM_CONFIG_MASTERREFCLOCK](#_CPPv430EC_T_DCM_CONFIG_MASTERREFCLOCK) MasterRefClock [in] MasterRefClock configuration. Valid if eMode is set to eDcmMode_MasterRefClock. ### [EC_T_DCM_CONFIG_DCX](#_CPPv419EC_T_DCM_CONFIG_DCX) Dcx [in] DCX configuration. Valid if eMode is set to eDcmMode_Dcx. ### enum EC_T_DCM_MODE *Values:* ### enumerator eDcmMode_Off DCM disabled ### enumerator eDcmMode_BusShift DCM BusShift mode ### enumerator eDcmMode_MasterShift DCM MasterShift mode ### enumerator eDcmMode_LinkLayerRefClock DCM LinkLayer Ref Clock mode ### enumerator eDcmMode_MasterRefClock DCM Master Ref Clock mode ### enumerator eDcmMode_Dcx DCM DCX External synchronization mode ### enumerator eDcmMode_MasterShiftByApp DCM MasterShift controlled by application mode ### struct EC_T_DCM_CONFIG_BUSSHIFT ### Public Members ### EC_T_INT nCtlSetVal [in] Controller set value [ns]. This is the time distance between the cyclic frame send time and the DC base on bus (SYNC0 if shift is zero). ### EC_T_INT nCtlGain [in] Proportional gain in ppt (part per thousand). Default is value 2. A value of 0 sets the default value. ### EC_T_INT nCtlDriftErrorGain [in] Multiplier for drift error. Default value is 3. A value of 0 sets the default value. ### EC_T_INT nMaxValidVal [in] Error inputs above this value are considered invalid. If error input prediction is valid then the difference between the error input and the expected value is taken. Default value is 3000. A value of 0 sets the default value. ### EC_T_BOOL bLogEnabled [in] If set to EC_TRUE, logging information are generated and can be got by calling [emDcmGetLog()](#db/d74/_ec_master_api_8cpp_1af51eeb22aae1bd0ceaeb6b764632186d) ### EC_T_DWORD dwInSyncLimit [in] Limit [ns] for InSync monitoring. Default value is 20% of the cycle time. A value of 0 sets the default value. ### EC_T_DWORD dwInSyncSettleTime [in] Settle time [ms] for InSync monitoring. Default value is 1500ms. A value of 0 sets the default value. ### EC_T_BOOL bCtlOff [in] If set to EC_TRUE, control loop is disabled. Combined with bLogEnabled, it makes possible to analyze the natural drift between the stack cycle and the reference clock. ### EC_T_BOOL bUseDcLoopCtlStdValues [in] If set to EC_TRUE, the values of ESC DC time loop control register 0x930 and 0x934 are not changed by master. This could increase the time it takes to get the InSync. Use only if there are problems with the reference clock to get InSync. ### EC_T_DWORD dwInSyncStartDelayCycle [in] Delay time [ms] before InSync monitoring start ### EC_T_VOID \*pGetTimeElapsedSinceCycleStartContext [in] Optional context for the pfnGetTimeElapsedSinceCycleStart function, will be passed as first parameter to this function/static method ### EC_PF_DC_GETTIMEELAPSEDSINCECYCLESTART pfnGetTimeElapsedSinceCycleStart [in] Setting this function enables synchronising the DC SYNC0 to the CycleStart instead of the time frame send. DC SYNC0 is therefore related to the CycleStart instead of the time frame send. Function must return EC_E_NOERROR to work. If 0 (nullptr, EC_NULL) EC_E_NOTSUPPORTED will be returned on attempt to call. ### struct EC_T_DCM_CONFIG_MASTERSHIFT ### Public Members ### EC_T_INT nCtlSetVal [in] Controller set value [ns]. This is the time distance between the cyclic frame send time and the DC base on bus (SYNC0 if shift is zero). ### EC_T_INT nCtlGain [in] Proportional gain in ppt (part per thousand). Default is value 2. A value of 0 sets the default value. ### EC_T_INT nCtlDriftErrorGain [in] Multiplier for drift error. Default value is 3. A value of 0 sets the default value. ### EC_T_INT nMaxValidVal [in] Error inputs above this value are considered invalid. If error input prediction is valid then the difference between the error input and the expected value is taken. Default value is 3000. A value of 0 sets the default value. ### EC_T_BOOL bLogEnabled [in] If set to EC_TRUE, logging information are generated and can be got by calling [emDcmGetLog()](#db/d74/_ec_master_api_8cpp_1af51eeb22aae1bd0ceaeb6b764632186d) ### EC_T_DWORD dwInSyncLimit [in] Limit [ns] for InSync monitoring. Default value is 20% of the cycle time. A value of 0 sets the default value. ### EC_T_DWORD dwInSyncSettleTime [in] Settle time [ms] for InSync monitoring. Default value is 1500ms. A value of 0 sets the default value. ### EC_T_BOOL bCtlOff [in] If set to EC_TRUE, control loop is disabled. Combined with bLogEnabled, it makes possible to analyze the natural drift between the stack cycle and the reference clock. Also it provides reading of current adjustment value using emDcmGetAdjust function. ### EC_T_DWORD dwInSyncStartDelayCycle [in] Delay time [ms] before InSync monitoring start ### [EC_T_DC_STARTTIME_CB_DESC](#_CPPv425EC_T_DC_STARTTIME_CB_DESC) DcStartTimeCallbackDesc [in] If not null, DC start time calculated by application, otherwise by master. See also [EC_T_DC_STARTTIME_CB_DESC](#db/d6b/struct_e_c___t___d_c___s_t_a_r_t_t_i_m_e___c_b___d_e_s_c). Shift value configured in ENI will still be applied. ### EC_T_VOID \*pGetTimeElapsedSinceCycleStartContext [in] Optional context for the pfnGetTimeElapsedSinceCycleStart function, will be passed as first parameter to this function/static method ### EC_PF_DC_GETTIMEELAPSEDSINCECYCLESTART pfnGetTimeElapsedSinceCycleStart [in] Setting this function enables synchronising the DC SYNC0 to the CycleStart instead of the time frame send. DC SYNC0 is therefore related to the CycleStart instead of the time frame send. Function must return EC_E_NOERROR to work. If 0 (nullptr, EC_NULL) EC_E_NOTSUPPORTED will be returned on attempt to call. ### EC_T_VOID \*pAdjustCycleTimeContext [in] Optional context for the pfnAdjustCycleTime function, will be passed as first parameter to this function/static method ### EC_PF_DC_ADJUSTCYCLETIME pfnAdjustCycleTime [in] Mandatory function to adjust the cycle time of the master. The master must adjust its cycle time by the passed amount to be in sync with the slaves. If 0 (nullptr, EC_NULL) MasterShift will not work. ### struct EC_T_DCM_CONFIG_LINKLAYERREFCLOCK ### Public Members ### EC_T_INT nCtlSetVal [in] Controller set value [ns]. This is the time distance between the cyclic frame send time and the DC base on bus (SYNC0 if shift is zero). ### EC_T_BOOL bLogEnabled [in] If set to EC_TRUE, logging information are generated and can be got by calling [emDcmGetLog()](#db/d74/_ec_master_api_8cpp_1af51eeb22aae1bd0ceaeb6b764632186d) ### EC_T_DWORD dwInSyncLimit [in] Limit [ns] for InSync monitoring. Default value is 20% of the cycle time. A value of 0 sets the default value. ### EC_T_DWORD dwInSyncSettleTime [in] Settle time [ms] for InSync monitoring. Default value is 1500ms. A value of 0 sets the default value. ### [EC_T_DC_STARTTIME_CB_DESC](#_CPPv425EC_T_DC_STARTTIME_CB_DESC) DcStartTimeCallbackDesc [in] If not null, DC start time calculated by application, otherwise by master. See also [EC_T_DC_STARTTIME_CB_DESC](#db/d6b/struct_e_c___t___d_c___s_t_a_r_t_t_i_m_e___c_b___d_e_s_c). Shift value configured in ENI will still be applied. ### struct EC_T_DCM_CONFIG_MASTERREFCLOCK ### Public Members ### EC_T_INT nCtlSetVal [in] Controller set value [ns]. This is the time distance between the cyclic frame send time and the DC base on bus (SYNC0 if shift is zero). ### EC_T_BOOL bLogEnabled [in] If set to EC_TRUE, logging information are generated and can be got by calling [emDcmGetLog()](#db/d74/_ec_master_api_8cpp_1af51eeb22aae1bd0ceaeb6b764632186d) ### EC_T_DWORD dwInSyncLimit [in] Limit [ns] for InSync monitoring. Default value is 20% of the cycle time. A value of 0 sets the default value. ### EC_T_DWORD dwInSyncSettleTime [in] Settle time [ms] for InSync monitoring. Default value is 1500ms. A value of 0 sets the default value. ### EC_T_VOID \*pGetHostTimeContext [in] Optional context for the pfnGetHostTime function, will be passed as first parameter to this function/static method ### EC_PF_DC_GETHOSTTIME pfnGetHostTime [in] Mandatory function to offer the host time for the MasterRefClock mode. This time will be distributed to the slaves. If 0 (nullptr, EC_NULL) MasterRefClock mode will not work. ### [EC_T_DC_STARTTIME_CB_DESC](#_CPPv425EC_T_DC_STARTTIME_CB_DESC) DcStartTimeCallbackDesc [in] If not null, DC start time calculated by application, otherwise by master. See also [EC_T_DC_STARTTIME_CB_DESC](#db/d6b/struct_e_c___t___d_c___s_t_a_r_t_t_i_m_e___c_b___d_e_s_c). Shift value configured in ENI will still be applied. ### struct EC_T_DCM_CONFIG_DCX Contains the configuration information for the DCX external synchronization mode. #### SEE ALSO Feature Pack “External Synchronization” for further details. ### struct EC_T_DC_STARTTIME_CB_DESC ### Public Members ### EC_T_VOID \*pvContext [in] Arbitrarily application-defined parameter passed to pfnCallback ### [EC_PF_DC_STARTTIME_CB](#_CPPv421EC_PF_DC_STARTTIME_CB) pfnCallback [in] DC start time callback function pointer. If not EC_NULL, DC start time calculated by application, otherwise by master. ### typedef EC_T_DWORD (\*EC_PF_DC_STARTTIME_CB)(EC_T_VOID \*pvContext, EC_T_WORD wSlaveFixedAddr, EC_T_UINT64 \*pqwDcStartTime) EC-Master requests DC start time for every single slave from a given callback DcStartTimeCallbackDesc with slave station address as input parameter. The slave specific DC start time value will be passed directly to the slave without modifications by master. This means no other values like nCtlSetVal will be added. Shift value configured in ENI will still be applied. * **Param pvContext:** **[in]** Arbitrarily application-defined parameter passed to callback * **Param wSlaveFixedAddr:** **[in]** Slave fixed address * **Param pqwDcStartTime:** **[out]** DC start time for specific slave * **Return:** EC_E_NOERROR or error code ## emDcmGetStatus ### static EC_T_DWORD ecatDcmGetStatus(EC_T_DWORD \*pdwErrorCode, EC_T_INT \*pnDiffCur, EC_T_INT \*pnDiffAvg, EC_T_INT \*pnDiffMax) ### EC_T_DWORD emDcmGetStatus(EC_T_DWORD dwInstanceID, EC_T_DWORD \*pdwErrorCode, EC_T_INT \*pnDiffCur, EC_T_INT \*pnDiffAvg, EC_T_INT \*pnDiffMax) Get DC master synchronization controller status. * **Parameters:** * **dwInstanceID** – [in] Instance ID (Multiple EtherCAT Network Support) * **pdwErrorCode** – [out] Pointer to current error code of the DCM controller. Possible values are: * EC_E_NOTREADY DCM control loop is not running * EC_E_BUSY DCM control loop is running and try to get InSync * [DCM_E_MAX_CTL_ERROR_EXCEED](#d1/d4e/group___e_c___e_r_r_o_r___c_o_d_e_s___d_c_m_1gae592ec678390813a6827181ca605a405) Set if the controller error exceeds the InSyncLimit * [DCM_E_DRIFT_TO_HIGH](#d1/d4e/group___e_c___e_r_r_o_r___c_o_d_e_s___d_c_m_1ga75f02c5a05fd656ae76ecd422dd3168f) DCM control loop not able to compensate drift. Drift above 600ppm * **pnDiffCur** – [out] Pointer to current difference between set value and actual value of controller in nanoseconds * **pnDiffAvg** – [out] Pointer to average difference between set value and actual value of controller in nanoseconds * **pnDiffMax** – [out] Pointer to maximum difference between set value and actual value of controller in nanoseconds * **Returns:** * EC_E_NOERROR if status retrieval was successful * EC_E_NOTSUPPORTED if the DC feature is not supported/switched off. EC-Master stack has to be compiled with DC support see “define INCLUDE_DC_SUPPORT”. * EC_NULL does not appear in normal flow, if EC_NULL is returned we are in a very exceptional case where m_poDcm == NULL (SW error detection) ## emDcmResetStatus ### static EC_T_DWORD ecatDcmResetStatus(EC_T_VOID) ### EC_T_DWORD emDcmResetStatus(EC_T_DWORD dwInstanceID) Reset DC master synchronization controller status, average and maximum difference between set value and actual value. * **Parameters:** **dwInstanceID** – [in] Instance ID (Multiple EtherCAT Network Support) * **Returns:** EC_E_NOERROR or error code ## emDcmGetBusShiftConfigured ### static EC_T_DWORD ecatDcmGetBusShiftConfigured(EC_T_BOOL \*pbBusShiftConfigured) ### EC_T_DWORD emDcmGetBusShiftConfigured(EC_T_DWORD dwInstanceID, EC_T_BOOL \*pbBusShiftConfigured) Determines if DCM Bus Shift is configured/possible in configuration (ENI file). * **Parameters:** * **dwInstanceID** – [in] Instance ID (Multiple EtherCAT Network Support) * **pbBusShiftConfigured** – [out] EC_TRUE if DCM bus shift mode is supported by the current configuration * **Returns:** EC_E_NOERROR or error code ## emDcmGetLog ### static EC_T_DWORD ecatDcmGetLog(EC_T_CHAR \*\*pszLog) ### EC_T_DWORD emDcmGetLog(EC_T_DWORD dwInstanceID, EC_T_CHAR \*\*pszLog) Get logging information from the DCM controller. This function returns non-zero pointer only if bLogEnabled was set to EC_TRUE in [EC_T_DCM_CONFIG](#d1/d72/struct_e_c___t___d_c_m___c_o_n_f_i_g). * **Parameters:** * **dwInstanceID** – [in] Instance ID (Multiple EtherCAT Network Support) * **pszLog** – [out] Pointer to a string containing the current logging information * **Returns:** EC_E_NOERROR or error code #### SEE ALSO [Controller adjustment](dcm_technical_controller-adjustment.html.md#controller-adjustment) for content description of pszLog ## emIoCtl - EC_IOCTL_DCM_GET_LOG ### EC_IOCTL_DCM_GET_LOG Get logging information from the DCM controller. * **Parameters:** * **pbyInBuf** – [in] Should be set to EC_NULL * **dwInBufSize** – [in] Should be set to 0 * **pbyOutBuf** – [out] Pointer to struct [EC_T_DCM_LOG](#dd/d2b/struct_e_c___t___d_c_m___l_o_g) * **dwOutBufSize** – [in] Size of the output buffer in bytes * **pdwNumOutData** – [out] Pointer to EC_T_DWORD. Amount of bytes written to the output buffer pbyOutBuf * **Returns:** EC_E_NOERROR or error code ### struct EC_T_DCM_LOG ### Public Members ### EC_T_DWORD dwMsecCounter [out] Current MsecCounter ### EC_T_INT nCtlSetVal [out] Configured controller set val [ns] ### EC_T_UINT64 qwBusTime [out] Current BusTime ### EC_T_INT nCtlErrorNsec [out] Current controller error [ns] ### EC_T_INT nDrift [out] Current calculated drift [ppm] ### EC_T_DWORD dwErrorCode [out] Last returned error code by controller ### EC_T_BOOL bDcmInSync [out] EC_TRUE if DCM is in sync, EC_FALSE if out of sync ### EC_T_BOOL bDcInSync [out] EC_TRUE if DC is in sync, EC_FALSE if out of sync ### EC_T_UINT64 qwDcStartTime [out] Last used DC StartTime ### EC_T_INT nSystemTimeDifference [out] Last read System Time Difference (ESC register 0x092C) #### SEE ALSO `emIoCtl()` in the [EC-Master Class B](https://developer.acontis.com/ec-master#manuals) documentation ## emDcmShowStatus ### static EC_T_DWORD ecatDcmShowStatus(EC_T_VOID) ### EC_T_DWORD emDcmShowStatus(EC_T_DWORD dwInstanceID) Show DC master synchronization status as DbgMsg (for development purposes only). * **Parameters:** **dwInstanceID** – [in] Instance ID (Multiple EtherCAT Network Support) * **Returns:** EC_E_NOERROR or error code ## emDcmGetAdjust ### static EC_T_DWORD ecatDcmGetAdjust(EC_T_INT \*pnAdjustPermil) ### EC_T_DWORD emDcmGetAdjust(EC_T_DWORD dwInstanceID, EC_T_INT \*pnAdjustPermil) Returns the current adjustment value for the timer. bCtlOff must be set to EC_TRUE in [EC_T_DCM_CONFIG](#d1/d72/struct_e_c___t___d_c_m___c_o_n_f_i_g) to enable external adjustment. * **Parameters:** * **dwInstanceID** – [in] Instance ID (Multiple EtherCAT Network Support) * **pnAdjustPermil** – [out] Current adjustment value of the timer * **Returns:** EC_E_NOERROR or error code ## DCM specific error codes ### DCM_E_ERROR 0x981201C0: Unspecific DCM Error ### DCM_E_NOTINITIALIZED 0x981201C1: Not initialized ### DCM_E_MAX_CTL_ERROR_EXCEED 0x981201C2: DCM controller - synchronization out of limit ### DCM_E_NOMEMORY 0x981201C3: Not enough memory ### DCM_E_INVALID_HWLAYER 0x981201C4: Hardware layer - (BSP) invalid ### DCM_E_TIMER_MODIFY_ERROR 0x981201C5: Hardware layer - error modifying timer ### DCM_E_TIMER_NOT_RUNNING 0x981201C6: Hardware layer - timer not running ### DCM_E_WRONG_CPU 0x981201C7: Hardware layer - function called on wrong CPU ### DCM_E_INVALID_SYNC_PERIOD 0x981201C8: Invalid DC sync period length (invalid clock master?) ### DCM_E_INVALID_SETVAL 0x981201C9: DCM controller SetVal too small ### DCM_E_DRIFT_TO_HIGH 0x981201CA: DCM controller - Drift between local timer and ref clock to high ### DCM_E_BUS_CYCLE_WRONG 0x981201CB: DCM controller - Bus cycle time (dwBusCycleTimeUsec) doesn’t match real cycle ### DCX_E_NO_EXT_CLOCK 0x981201CC: DCX controller - No external synchronization clock found ### DCM_E_INVALID_DATA 0x981201CD: DCM controller - Invalid data ## Notifications At startup the MainDevice raises the notifications [emNotify - EC_NOTIFY_DC_SLV_SYNC](dc_api.html.md#emnotify-ec-notify-dc-slv-sync), [emNotify - EC_NOTIFY_DC_STATUS](dc_api.html.md#emnotify-ec-notify-dc-status) and [emNotify - EC_NOTIFY_DCM_SYNC](#emnotify-ec-notify-dcm-sync) at MainDevice state transition from INIT to PREOP. The order is typically as follows ( [emNotify - EC_NOTIFY_DCM_SYNC](#emnotify-ec-notify-dcm-sync) may be before or after reaching PREOP): EC_NOTIFY_STATECHANGED(INIT)[…] EC_NOTIFY_DC_SLV_SYNC […] EC_NOTIFY_DC_STATUS […] [EC_NOTIFY_DCM_SYNC] […] EC_NOTIFY_STATECHANGED(PREOP) […] [EC_NOTIFY_DCM_SYNC] […] EC_NOTIFY_STATECHANGED(SAFEOP) […] EC_NOTIFY_STATECHANGED(OP) […] ## emNotify - EC_NOTIFY_DCM_SYNC DCM InSync notification. This notification is enabled by default. **emNotify - EC_NOTIFY_DCM_SYNC** : **Parameter** : * `pbyInBuf`: [in] Pointer to notification descriptor EC_T_DCM_SYNC_NTFY_DESC * `dwInBufSize`: [in] sizeof(EC_T_DCM_SYNC_NTFY_DESC) * `pbyOutBuf`: [out] Should be set to EC_NULL * `dwOutBufSize`: [in] Should be set to 0 * `pdwNumOutData`: [out] Should be set to EC_NULL ### struct EC_T_DCM_SYNC_NTFY_DESC ### Public Members ### EC_T_DWORD IsInSync [in] EC_TRUE as long as time of master and reference clock are in sync. False if the InSyncLimit from the bus shift configuration is exceeded. ### EC_T_INT nCtlErrorNsecCur [in] Current difference [ns] between set value and actual value of controller ### EC_T_INT nCtlErrorNsecAvg [in] Average difference [ns] between set value and actual value of controller ### EC_T_INT nCtlErrorNsecMax [in] Maximum difference [ns] between set value and actual value of controller #### SEE ALSO emIoCtl - EC_IOCTL_SET_NOTIFICATION_ENABLED in the [EC-Master Class B](https://developer.acontis.com/ec-master#manuals) documentation for controlling the deactivation