/* * Licensed under the GNU General Public License version 2 with exceptions. See * LICENSE file in the project root for full license information */ /** \file * \brief * Headerfile for ethercatmain.c */ #ifndef _ethercatmain_ #define _ethercatmain_ #ifdef __cplusplus extern "C" { #endif /** max. entries in EtherCAT error list */ #define EC_MAXELIST 64 /** max. length of readable name in slavelist and Object Description List */ #define EC_MAXNAME 40 /** max. number of slaves in array */ #define EC_MAXSLAVE 200 /** max. number of groups */ #define EC_MAXGROUP 2 /** max. number of IO segments per group */ #define EC_MAXIOSEGMENTS 64 /** max. mailbox size */ #define EC_MAXMBX 1486 /** max. eeprom PDO entries */ #define EC_MAXEEPDO 0x200 /** max. SM used */ #define EC_MAXSM 8 /** max. FMMU used */ #define EC_MAXFMMU 4 /** max. Adapter */ #define EC_MAXLEN_ADAPTERNAME 128 /** define maximum number of concurrent threads in mapping */ #define EC_MAX_MAPT 1 typedef struct ec_adapter ec_adaptert; struct ec_adapter { char name[EC_MAXLEN_ADAPTERNAME]; char desc[EC_MAXLEN_ADAPTERNAME]; ec_adaptert *next; }; /** record for FMMU */ PACKED_BEGIN typedef struct PACKED ec_fmmu { uint32 LogStart; uint16 LogLength; uint8 LogStartbit; uint8 LogEndbit; uint16 PhysStart; uint8 PhysStartBit; uint8 FMMUtype; uint8 FMMUactive; uint8 unused1; uint16 unused2; } ec_fmmut; PACKED_END /** record for sync manager */ PACKED_BEGIN typedef struct PACKED ec_sm { uint16 StartAddr; uint16 SMlength; uint32 SMflags; } ec_smt; PACKED_END PACKED_BEGIN typedef struct PACKED ec_state_status { uint16 State; uint16 Unused; uint16 ALstatuscode; } ec_state_status; PACKED_END #define ECT_MBXPROT_AOE 0x0001 #define ECT_MBXPROT_EOE 0x0002 #define ECT_MBXPROT_COE 0x0004 #define ECT_MBXPROT_FOE 0x0008 #define ECT_MBXPROT_SOE 0x0010 #define ECT_MBXPROT_VOE 0x0020 #define ECT_COEDET_SDO 0x01 #define ECT_COEDET_SDOINFO 0x02 #define ECT_COEDET_PDOASSIGN 0x04 #define ECT_COEDET_PDOCONFIG 0x08 #define ECT_COEDET_UPLOAD 0x10 #define ECT_COEDET_SDOCA 0x20 #define EC_SMENABLEMASK 0xfffeffff typedef struct ecx_context ecx_contextt; /** for list of ethercat slaves detected */ typedef struct ec_slave { /** state of slave */ uint16 state; /** AL status code */ uint16 ALstatuscode; /** Configured address */ uint16 configadr; /** Alias address */ uint16 aliasadr; /** Manufacturer from EEprom */ uint32 eep_man; /** ID from EEprom */ uint32 eep_id; /** revision from EEprom */ uint32 eep_rev; /** Interface type */ uint16 Itype; /** Device type */ uint16 Dtype; /** output bits */ uint16 Obits; /** output bytes, if Obits < 8 then Obytes = 0 */ uint32 Obytes; /** output pointer in IOmap buffer */ uint8 *outputs; /** startbit in first output byte */ uint8 Ostartbit; /** input bits */ uint16 Ibits; /** input bytes, if Ibits < 8 then Ibytes = 0 */ uint32 Ibytes; /** input pointer in IOmap buffer */ uint8 *inputs; /** startbit in first input byte */ uint8 Istartbit; /** SM structure */ ec_smt SM[EC_MAXSM]; /** SM type 0=unused 1=MbxWr 2=MbxRd 3=Outputs 4=Inputs */ uint8 SMtype[EC_MAXSM]; /** FMMU structure */ ec_fmmut FMMU[EC_MAXFMMU]; /** FMMU0 function */ uint8 FMMU0func; /** FMMU1 function */ uint8 FMMU1func; /** FMMU2 function */ uint8 FMMU2func; /** FMMU3 function */ uint8 FMMU3func; /** length of write mailbox in bytes, if no mailbox then 0 */ uint16 mbx_l; /** mailbox write offset */ uint16 mbx_wo; /** length of read mailbox in bytes */ uint16 mbx_rl; /** mailbox read offset */ uint16 mbx_ro; /** mailbox supported protocols */ uint16 mbx_proto; /** Counter value of mailbox link layer protocol 1..7 */ uint8 mbx_cnt; /** has DC capability */ boolean hasdc; /** Physical type; Ebus, EtherNet combinations */ uint8 ptype; /** topology: 1 to 3 links */ uint8 topology; /** active ports bitmap : ....3210 , set if respective port is active **/ uint8 activeports; /** consumed ports bitmap : ....3210, used for internal delay measurement **/ uint8 consumedports; /** slave number for parent, 0=master */ uint16 parent; /** port number on parent this slave is connected to **/ uint8 parentport; /** port number on this slave the parent is connected to **/ uint8 entryport; /** DC receivetimes on port A */ int32 DCrtA; /** DC receivetimes on port B */ int32 DCrtB; /** DC receivetimes on port C */ int32 DCrtC; /** DC receivetimes on port D */ int32 DCrtD; /** propagation delay */ int32 pdelay; /** next DC slave */ uint16 DCnext; /** previous DC slave */ uint16 DCprevious; /** DC cycle time in ns */ int32 DCcycle; /** DC shift from clock modulus boundary */ int32 DCshift; /** DC sync activation, 0=off, 1=on */ uint8 DCactive; /** link to config table */ uint16 configindex; /** link to SII config */ uint16 SIIindex; /** 1 = 8 bytes per read, 0 = 4 bytes per read */ uint8 eep_8byte; /** 0 = eeprom to master , 1 = eeprom to PDI */ uint8 eep_pdi; /** CoE details */ uint8 CoEdetails; /** FoE details */ uint8 FoEdetails; /** EoE details */ uint8 EoEdetails; /** SoE details */ uint8 SoEdetails; /** E-bus current */ int16 Ebuscurrent; /** if >0 block use of LRW in processdata */ uint8 blockLRW; /** group */ uint8 group; /** first unused FMMU */ uint8 FMMUunused; /** Boolean for tracking whether the slave is (not) responding, not used/set by the SOEM library */ boolean islost; /** registered configuration function PO->SO, (DEPRECATED)*/ int (*PO2SOconfig)(uint16 slave); /** registered configuration function PO->SO */ int (*PO2SOconfigx)(ecx_contextt * context, uint16 slave); /** readable name */ char name[EC_MAXNAME + 1]; } ec_slavet; /** for list of ethercat slave groups */ typedef struct ec_group { /** logical start address for this group */ uint32 logstartaddr; /** output bytes, if Obits < 8 then Obytes = 0 */ uint32 Obytes; /** output pointer in IOmap buffer */ uint8 *outputs; /** input bytes, if Ibits < 8 then Ibytes = 0 */ uint32 Ibytes; /** input pointer in IOmap buffer */ uint8 *inputs; /** has DC capabillity */ boolean hasdc; /** next DC slave */ uint16 DCnext; /** E-bus current */ int16 Ebuscurrent; /** if >0 block use of LRW in processdata */ uint8 blockLRW; /** IO segments used */ uint16 nsegments; /** 1st input segment */ uint16 Isegment; /** Offset in input segment */ uint16 Ioffset; /** Expected workcounter outputs */ uint16 outputsWKC; /** Expected workcounter inputs */ uint16 inputsWKC; /** check slave states */ boolean docheckstate; /** IO segmentation list. Datagrams must not break SM in two. */ uint32 IOsegment[EC_MAXIOSEGMENTS]; } ec_groupt; /** SII FMMU structure */ typedef struct ec_eepromFMMU { uint16 Startpos; uint8 nFMMU; uint8 FMMU0; uint8 FMMU1; uint8 FMMU2; uint8 FMMU3; } ec_eepromFMMUt; /** SII SM structure */ typedef struct ec_eepromSM { uint16 Startpos; uint8 nSM; uint16 PhStart; uint16 Plength; uint8 Creg; uint8 Sreg; /* don't care */ uint8 Activate; uint8 PDIctrl; /* don't care */ } ec_eepromSMt; /** record to store rxPDO and txPDO table from eeprom */ typedef struct ec_eepromPDO { uint16 Startpos; uint16 Length; uint16 nPDO; uint16 Index[EC_MAXEEPDO]; uint16 SyncM[EC_MAXEEPDO]; uint16 BitSize[EC_MAXEEPDO]; uint16 SMbitsize[EC_MAXSM]; } ec_eepromPDOt; /** mailbox buffer array */ typedef uint8 ec_mbxbuft[EC_MAXMBX + 1]; /** standard ethercat mailbox header */ PACKED_BEGIN typedef struct PACKED ec_mbxheader { uint16 length; uint16 address; uint8 priority; uint8 mbxtype; } ec_mbxheadert; PACKED_END /** ALstatus and ALstatus code */ PACKED_BEGIN typedef struct PACKED ec_alstatus { uint16 alstatus; uint16 unused; uint16 alstatuscode; } ec_alstatust; PACKED_END /** stack structure to store segmented LRD/LWR/LRW constructs */ typedef struct ec_idxstack { uint8 pushed; uint8 pulled; uint8 idx[EC_MAXBUF]; void *data[EC_MAXBUF]; uint16 length[EC_MAXBUF]; uint16 dcoffset[EC_MAXBUF]; } ec_idxstackT; /** ringbuf for error storage */ typedef struct ec_ering { int16 head; int16 tail; ec_errort Error[EC_MAXELIST + 1]; } ec_eringt; /** SyncManager Communication Type structure for CA */ PACKED_BEGIN typedef struct PACKED ec_SMcommtype { uint8 n; uint8 nu1; uint8 SMtype[EC_MAXSM]; } ec_SMcommtypet; PACKED_END /** SDO assign structure for CA */ PACKED_BEGIN typedef struct PACKED ec_PDOassign { uint8 n; uint8 nu1; uint16 index[256]; } ec_PDOassignt; PACKED_END /** SDO description structure for CA */ PACKED_BEGIN typedef struct PACKED ec_PDOdesc { uint8 n; uint8 nu1; uint32 PDO[256]; } ec_PDOdesct; PACKED_END /** Context structure , referenced by all ecx functions*/ struct ecx_context { /** port reference, may include red_port */ ecx_portt *port; /** slavelist reference */ ec_slavet *slavelist; /** number of slaves found in configuration */ int *slavecount; /** maximum number of slaves allowed in slavelist */ int maxslave; /** grouplist reference */ ec_groupt *grouplist; /** maximum number of groups allowed in grouplist */ int maxgroup; /** internal, reference to eeprom cache buffer */ uint8 *esibuf; /** internal, reference to eeprom cache map */ uint32 *esimap; /** internal, current slave for eeprom cache */ uint16 esislave; /** internal, reference to error list */ ec_eringt *elist; /** internal, reference to processdata stack buffer info */ ec_idxstackT *idxstack; /** reference to ecaterror state */ boolean *ecaterror; /** reference to last DC time from slaves */ int64 *DCtime; /** internal, SM buffer */ ec_SMcommtypet *SMcommtype; /** internal, PDO assign list */ ec_PDOassignt *PDOassign; /** internal, PDO description list */ ec_PDOdesct *PDOdesc; /** internal, SM list from eeprom */ ec_eepromSMt *eepSM; /** internal, FMMU list from eeprom */ ec_eepromFMMUt *eepFMMU; /** registered FoE hook */ int (*FOEhook)(uint16 slave, int packetnumber, int datasize); /** registered EoE hook */ int (*EOEhook)(ecx_contextt * context, uint16 slave, void * eoembx); /** flag to control legacy automatic state change or manual state change */ int manualstatechange; }; #ifdef EC_VER1 /** global struct to hold default master context */ extern ecx_contextt ecx_context; /** main slave data structure array */ extern ec_slavet ec_slave[EC_MAXSLAVE]; /** number of slaves found by configuration function */ extern int ec_slavecount; /** slave group structure */ extern ec_groupt ec_group[EC_MAXGROUP]; extern boolean EcatError; extern int64 ec_DCtime; void ec_pusherror(const ec_errort *Ec); boolean ec_poperror(ec_errort *Ec); boolean ec_iserror(void); void ec_packeterror(uint16 Slave, uint16 Index, uint8 SubIdx, uint16 ErrorCode); int ec_init(const char * ifname); int ec_init_redundant(const char *ifname, char *if2name); void ec_close(void); uint8 ec_siigetbyte(uint16 slave, uint16 address); int16 ec_siifind(uint16 slave, uint16 cat); void ec_siistring(char *str, uint16 slave, uint16 Sn); uint16 ec_siiFMMU(uint16 slave, ec_eepromFMMUt* FMMU); uint16 ec_siiSM(uint16 slave, ec_eepromSMt* SM); uint16 ec_siiSMnext(uint16 slave, ec_eepromSMt* SM, uint16 n); uint32 ec_siiPDO(uint16 slave, ec_eepromPDOt* PDO, uint8 t); int ec_readstate(void); int ec_writestate(uint16 slave); uint16 ec_statecheck(uint16 slave, uint16 reqstate, int timeout); int ec_mbxempty(uint16 slave, int timeout); int ec_mbxsend(uint16 slave,ec_mbxbuft *mbx, int timeout); int ec_mbxreceive(uint16 slave, ec_mbxbuft *mbx, int timeout); void ec_esidump(uint16 slave, uint8 *esibuf); uint32 ec_readeeprom(uint16 slave, uint16 eeproma, int timeout); int ec_writeeeprom(uint16 slave, uint16 eeproma, uint16 data, int timeout); int ec_eeprom2master(uint16 slave); int ec_eeprom2pdi(uint16 slave); uint64 ec_readeepromAP(uint16 aiadr, uint16 eeproma, int timeout); int ec_writeeepromAP(uint16 aiadr, uint16 eeproma, uint16 data, int timeout); uint64 ec_readeepromFP(uint16 configadr, uint16 eeproma, int timeout); int ec_writeeepromFP(uint16 configadr, uint16 eeproma, uint16 data, int timeout); void ec_readeeprom1(uint16 slave, uint16 eeproma); uint32 ec_readeeprom2(uint16 slave, int timeout); int ec_send_processdata_group(uint8 group); int ec_send_overlap_processdata_group(uint8 group); int ec_receive_processdata_group(uint8 group, int timeout); int ec_send_processdata(void); int ec_send_overlap_processdata(void); int ec_receive_processdata(int timeout); #endif ec_adaptert * ec_find_adapters(void); void ec_free_adapters(ec_adaptert * adapter); uint8 ec_nextmbxcnt(uint8 cnt); void ec_clearmbx(ec_mbxbuft *Mbx); void ecx_pusherror(ecx_contextt *context, const ec_errort *Ec); boolean ecx_poperror(ecx_contextt *context, ec_errort *Ec); boolean ecx_iserror(ecx_contextt *context); void ecx_packeterror(ecx_contextt *context, uint16 Slave, uint16 Index, uint8 SubIdx, uint16 ErrorCode); int ecx_init(ecx_contextt *context, const char * ifname); int ecx_init_redundant(ecx_contextt *context, ecx_redportt *redport, const char *ifname, char *if2name); void ecx_close(ecx_contextt *context); uint8 ecx_siigetbyte(ecx_contextt *context, uint16 slave, uint16 address); int16 ecx_siifind(ecx_contextt *context, uint16 slave, uint16 cat); void ecx_siistring(ecx_contextt *context, char *str, uint16 slave, uint16 Sn); uint16 ecx_siiFMMU(ecx_contextt *context, uint16 slave, ec_eepromFMMUt* FMMU); uint16 ecx_siiSM(ecx_contextt *context, uint16 slave, ec_eepromSMt* SM); uint16 ecx_siiSMnext(ecx_contextt *context, uint16 slave, ec_eepromSMt* SM, uint16 n); uint32 ecx_siiPDO(ecx_contextt *context, uint16 slave, ec_eepromPDOt* PDO, uint8 t); int ecx_readstate(ecx_contextt *context); int ecx_writestate(ecx_contextt *context, uint16 slave); uint16 ecx_statecheck(ecx_contextt *context, uint16 slave, uint16 reqstate, int timeout); int ecx_mbxempty(ecx_contextt *context, uint16 slave, int timeout); int ecx_mbxsend(ecx_contextt *context, uint16 slave,ec_mbxbuft *mbx, int timeout); int ecx_mbxreceive(ecx_contextt *context, uint16 slave, ec_mbxbuft *mbx, int timeout); void ecx_esidump(ecx_contextt *context, uint16 slave, uint8 *esibuf); uint32 ecx_readeeprom(ecx_contextt *context, uint16 slave, uint16 eeproma, int timeout); int ecx_writeeeprom(ecx_contextt *context, uint16 slave, uint16 eeproma, uint16 data, int timeout); int ecx_eeprom2master(ecx_contextt *context, uint16 slave); int ecx_eeprom2pdi(ecx_contextt *context, uint16 slave); uint64 ecx_readeepromAP(ecx_contextt *context, uint16 aiadr, uint16 eeproma, int timeout); int ecx_writeeepromAP(ecx_contextt *context, uint16 aiadr, uint16 eeproma, uint16 data, int timeout); uint64 ecx_readeepromFP(ecx_contextt *context, uint16 configadr, uint16 eeproma, int timeout); int ecx_writeeepromFP(ecx_contextt *context, uint16 configadr, uint16 eeproma, uint16 data, int timeout); void ecx_readeeprom1(ecx_contextt *context, uint16 slave, uint16 eeproma); uint32 ecx_readeeprom2(ecx_contextt *context, uint16 slave, int timeout); int ecx_send_overlap_processdata_group(ecx_contextt *context, uint8 group); int ecx_receive_processdata_group(ecx_contextt *context, uint8 group, int timeout); int ecx_send_processdata(ecx_contextt *context); int ecx_send_overlap_processdata(ecx_contextt *context); int ecx_receive_processdata(ecx_contextt *context, int timeout); int ecx_send_processdata_group(ecx_contextt *context, uint8 group); #ifdef __cplusplus } #endif #endif