/* * This source file is part of the EtherCAT Slave Stack Code licensed by Beckhoff Automation GmbH & Co KG, 33415 Verl, Germany. * The corresponding license agreement applies. This hint shall not be removed. * https://www.beckhoff.com/media/downloads/slave-stack-code/ethercat_ssc_license.pdf */ /** \addtogroup CoE CAN Application Profile over EtherCAT @{ */ /** \file ecatcoe.c \author EthercatSSC@beckhoff.com \brief Implementation This file contains the CoE mailbox interface \version 5.13
Changes to version V5.11:
V5.13 COE8: handle failure on continue indication
V5.13 TEST4: memory leak on SDO response receive

Changes to version V5.0:
V5.11 COE4: "change prototype of ""COE_ContinueInd()"" return <> 0 if a failure occurred"
V5.11 ECAT10: change PROTO handling to prevent compiler errors
V5.11 TEST6: add test object to trigger Slave-to-Slave communication
V5.11 TEST7: add test behaviour to send an emergency on every SDO request (in SafeOP)

Changes to version V4.40:
V5.0 SDO7: "SDOS_SdoInfoInd()" never return pending SDO Info service. Delete "NOERROR_INWORK" handling.

Changes to version V4.08:
V4.40 SDO1: add initial value for "nSdoInfoFragmentsLeft"
V4.40 MBX6: change return value if no mailbox buffer is available
V4.08 MBX 1: If the switch MAILBOX_QUEUE was set, we have to put all SDO Info Responses in the Send Queue */ /*--------------------------------------------------------------------------------------- ------ ------ Includes ------ ---------------------------------------------------------------------------------------*/ #include "ecat_def.h" #include "sdoserv.h" #define _ECATCOE_ 1 #include "ecatcoe.h" #undef _ECATCOE_ /*remove definition of _ECATCOE_ (#ifdef is used in ecatcoe.h)*/ /*ET9300 Project Handler :(#if TEST_APPLICATION) lines 52 to 60 deleted*/ /*--------------------------------------------------------------------------------------- ------ ------ internal Types and Defines ------ ---------------------------------------------------------------------------------------*/ #define ECATCOE 0x4300 #define ECATCOEMAX 0x02 /*--------------------------------------------------------------------------------------- ------ ------ static variables ------ ---------------------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------------------- ------ ------ static functions ------ ---------------------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------------------- ------ ------ functions ------ ---------------------------------------------------------------------------------------*/ ///////////////////////////////////////////////////////////////////////////////////////// /** \brief This function intialize the CoE Interface. *//////////////////////////////////////////////////////////////////////////////////////// void COE_Init(void) { pCoeSendStored = 0; /*ET9300 Project Handler :(#if SEGMENTED_SDO_SUPPORTED) lines 99 to 101 deleted*/ } ///////////////////////////////////////////////////////////////////////////////////////// /** \param pCoeMbx Pointer to the received mailbox data from the master. \return result of the operation (0 (success) or mailbox error code (MBXERR_.... defined in mailbox.h)) \brief This function is called when a CoE (CAN application layer over EtherCAT) service is received from the master. *//////////////////////////////////////////////////////////////////////////////////////// UINT8 COE_ServiceInd(TCOEMBX MBXMEM *pCoeMbx) { UINT8 result = 0; switch ((pCoeMbx->CoeHeader & COEHEADER_COESERVICEMASK) >> COEHEADER_COESERVICESHIFT) { case COESERVICE_SDOREQUEST: /* SDO-Request received, call SDOS_SdoInd to process the SDO-Request if an existing SDO-Stack shall be used, the corresponding function should be called */ /*ET9300 Project Handler :(#if TEST_APPLICATION && EMERGENCY_SUPPORTED) lines 125 to 152 deleted*/ result = SDOS_SdoInd( (TINITSDOMBX MBXMEM *) pCoeMbx ); break; case COESERVICE_SDOINFO: /* SDO-Information Request received, call SDOS_SdoInfoInd to process the SDO-Request */ result = SDOS_SdoInfoInd( (TSDOINFORMATION MBXMEM *) pCoeMbx ); /*NOERROR_INWORK is never returned by SDOS_SdoInfoInd() => delete return code handling*/ break; case COESERVICE_SDORESPONSE: /*ET9300 Project Handler :(#if TEST_APPLICATION) lines 164 to 178 deleted*/ case COESERVICE_EMERGENCY: case COESERVICE_TXPDO: case COESERVICE_RXPDO: case COESERVICE_TXPDOREMREQ: case COESERVICE_RXPDOREMREQ: /* these CoE services are not supported yet */ result = MBXERR_SERVICENOTSUPPORTED; break; default: result = MBXERR_INVALIDHEADER; break; } return result; } ///////////////////////////////////////////////////////////////////////////////////////// /** \param pMbx Pointer to the free mailbox to sent. \return result of the operation (0 (success) \brief This function is called when a CoE service to be sent is stored and can \brief be put in the send mailbox. *//////////////////////////////////////////////////////////////////////////////////////// UINT8 COE_ContinueInd(TMBX MBXMEM * pMbx) { if (pCoeSendStored) { /* send the stored CoE service which could not be sent before */ /*ECATCHANGE_START(V5.13) COE8*/ if (MBX_MailboxSendReq(pCoeSendStored, COE_SERVICE) == 0) { pCoeSendStored = 0; } /*ECATCHANGE_END(V5.13) COE8*/ } else { /* send the next fragment of the last CoE service (only for SDO-Information possible) */ /* in mailbox queue mode pMbx is always 0, so a mailbox buffer shall be get */ pMbx = (TMBX MBXMEM *) APPL_AllocMailboxBuffer(SIZEOF(TMBX)); /* it shall be checked if a valid pointer was returned */ if (pMbx == NULL) { return MBXERR_NOMOREMEMORY; } else { /* copy the stored SDO-Info-Header in the request */ MBXMEMCPY(pMbx, aSdoInfoHeader, SDO_INFO_HEADER_BYTE_SIZE); /* call SDOS_SdoInfoInd to generate and send the next fragment */ SDOS_SdoInfoInd( (TSDOINFORMATION MBXMEM *) pMbx ); } } return 0; } /** @} */