SOEM EtherCAT Master library for STM Nucleo F767ZI
Dependents: EasyCAT_LAB_simple EasyCAT_LAB_very_simple EasyCAT_LAB
- This repository contains the SOEM (Simple Open EtherCAT® Master) library by rt-labs, that has been ported in the ecosystem by AB&T Tecnologie Informatiche.
- It has been developed for the EasyCAT LAB , a complete educational and experimental EtherCAT® system, composed of one master and two slaves .
- The EasyCAT LAB is provided as a kit by AB&T Tecnologie Informatiche, to allow everybody to have an educational EtherCAT® system up and running in a matter of minutes.
Warning
- Currently only the Nucleo STM32F767ZI board is supported.
Diff: SOEM/ethercatmain.h
- Revision:
- 0:543d6784d4cc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SOEM/ethercatmain.h Tue Jun 11 10:29:09 2019 +0000 @@ -0,0 +1,526 @@ +/* + * 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 + +/** 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 */ + int (*PO2SOconfig)(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]; +} 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*/ +typedef struct ecx_context ecx_contextt; +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; + /** internal, position of DC datagram in process data packet */ + uint16 DCtO; + /** internal, length of DC datagram */ + uint16 DCl; + /** 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); +}; + +#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); +int 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); +int 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