529 lines
17 KiB
C
529 lines
17 KiB
C
/*
|
|
* 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
|