EasyCAT LAB - EtherCAT master legacy example
Dependencies: SOEM SPI_STMPE610 SPI_TFT_ILI9341 TFT_fonts
The EasyCAT LAB is a complete educational and experimental EtherCAT® system, composed of one master and two slaves .
- It 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.
- This repository contains a demo software for the EtherCAT® master, that runs on the Nucleo STM32F767ZI board.
- It uses the SOEM (Simple Open EtherCAT® Master) library by rt-labs, that has been ported in the ecosystem by AB&T Tecnologie Informatiche.
- The slaves are based on the EasyCAT SHIELD and the Arduino UNO.
Diff: soem_start.cpp
- Revision:
- 0:7077d8f28b3e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/soem_start.cpp Tue Jun 11 10:19:08 2019 +0000 @@ -0,0 +1,705 @@ + +#include "soem_start.h" +#include "ethercat.h" +#include "string.h" +#include "oshw.h" + +#include "mbed.h" + +#include <inttypes.h> + +#include "SPI_TFT_ILI9341.h" + +extern SPI_TFT_ILI9341 TFT; + +boolean printSDO = TRUE; +boolean printMAP = TRUE; + +ec_ODlistt ODlist; +ec_OElistt OElist; +char usdo[128]; +char hstr[1024]; + +char extern IOmap[]; + +uint32_t error_counter = 0; + + +char* dtype2string(uint16 dtype); +char* SDO2string(uint16 slave, uint16 index, uint8 subidx, uint16 dtype); +int si_PDOassign(uint16 slave, uint16 PDOassign, int mapoffset, int bitoffset); +void si_sdo(int cnt); +int si_map_sdo(int slave); +int si_siiPDO(uint16 slave, uint8 t, int mapoffset, int bitoffset); +bool network_scanning(void); + + + +//---- convert Ethercat types to string ---------------------------------------- + + +char* dtype2string(uint16 dtype) +{ + switch(dtype) + { + case ECT_BOOLEAN: + sprintf(hstr, "BOOLEAN"); + break; + case ECT_INTEGER8: + sprintf(hstr, "INTEGER8"); + break; + case ECT_INTEGER16: + sprintf(hstr, "INTEGER16"); + break; + case ECT_INTEGER32: + sprintf(hstr, "INTEGER32"); + break; + case ECT_INTEGER24: + sprintf(hstr, "INTEGER24"); + break; + case ECT_INTEGER64: + sprintf(hstr, "INTEGER64"); + break; + case ECT_UNSIGNED8: + sprintf(hstr, "UNSIGNED8"); + break; + case ECT_UNSIGNED16: + sprintf(hstr, "UNSIGNED16"); + break; + case ECT_UNSIGNED32: + sprintf(hstr, "UNSIGNED32"); + break; + case ECT_UNSIGNED24: + sprintf(hstr, "UNSIGNED24"); + break; + case ECT_UNSIGNED64: + sprintf(hstr, "UNSIGNED64"); + break; + case ECT_REAL32: + sprintf(hstr, "REAL32"); + break; + case ECT_REAL64: + sprintf(hstr, "REAL64"); + break; + case ECT_BIT1: + sprintf(hstr, "BIT1"); + break; + case ECT_BIT2: + sprintf(hstr, "BIT2"); + break; + case ECT_BIT3: + sprintf(hstr, "BIT3"); + break; + case ECT_BIT4: + sprintf(hstr, "BIT4"); + break; + case ECT_BIT5: + sprintf(hstr, "BIT5"); + break; + case ECT_BIT6: + sprintf(hstr, "BIT6"); + break; + case ECT_BIT7: + sprintf(hstr, "BIT7"); + break; + case ECT_BIT8: + sprintf(hstr, "BIT8"); + break; + case ECT_VISIBLE_STRING: + sprintf(hstr, "VISIBLE_STRING"); + break; + case ECT_OCTET_STRING: + sprintf(hstr, "OCTET_STRING"); + break; + default: + sprintf(hstr, "Type 0x%4.4X", dtype); + } + return hstr; +} + + +//------------------------------------------------------------------------------ + +char* SDO2string(uint16 slave, uint16 index, uint8 subidx, uint16 dtype) +{ + int l = sizeof(usdo) - 1, i; + uint8 *u8; + int8 *i8; + uint16 *u16; + int16 *i16; + uint32 *u32; + int32 *i32; + uint64 *u64; + int64 *i64; + float *sr; + double *dr; + char es[32]; + + memset(&usdo, 0, 128); + ec_SDOread(slave, index, subidx, FALSE, &l, &usdo, EC_TIMEOUTRXM); + if (EcatError) + { + return ec_elist2string(); + } + else + { + switch(dtype) + { + case ECT_BOOLEAN: + u8 = (uint8*) &usdo[0]; + if (*u8) sprintf(hstr, "TRUE"); + else sprintf(hstr, "FALSE"); + break; + case ECT_INTEGER8: + i8 = (int8*) &usdo[0]; + sprintf(hstr, "0x%2.2x %d", *i8, *i8); + break; + case ECT_INTEGER16: + i16 = (int16*) &usdo[0]; + sprintf(hstr, "0x%4.4x %d", *i16, *i16); + break; + case ECT_INTEGER32: + case ECT_INTEGER24: + i32 = (int32*) &usdo[0]; + sprintf(hstr, "0x%8.8x %d", *i32, *i32); + break; + case ECT_INTEGER64: + i64 = (int64*) &usdo[0]; + sprintf(hstr, "0x%16.16"PRIx64" %"PRId64, *i64, *i64); + break; + case ECT_UNSIGNED8: + u8 = (uint8*) &usdo[0]; + sprintf(hstr, "0x%2.2x %u", *u8, *u8); + break; + case ECT_UNSIGNED16: + u16 = (uint16*) &usdo[0]; + sprintf(hstr, "0x%4.4x %u", *u16, *u16); + break; + case ECT_UNSIGNED32: + case ECT_UNSIGNED24: + u32 = (uint32*) &usdo[0]; + sprintf(hstr, "0x%8.8x %u", *u32, *u32); + break; + case ECT_UNSIGNED64: + u64 = (uint64*) &usdo[0]; + sprintf(hstr, "0x%16.16"PRIx64" %"PRIu64, *u64, *u64); + break; + case ECT_REAL32: + sr = (float*) &usdo[0]; + sprintf(hstr, "%f", *sr); + break; + case ECT_REAL64: + dr = (double*) &usdo[0]; + sprintf(hstr, "%f", *dr); + break; + case ECT_BIT1: + case ECT_BIT2: + case ECT_BIT3: + case ECT_BIT4: + case ECT_BIT5: + case ECT_BIT6: + case ECT_BIT7: + case ECT_BIT8: + u8 = (uint8*) &usdo[0]; + sprintf(hstr, "0x%x", *u8); + break; + case ECT_VISIBLE_STRING: + strcpy(hstr, usdo); + break; + case ECT_OCTET_STRING: + hstr[0] = 0x00; + for (i = 0 ; i < l ; i++) + { + sprintf(es, "0x%2.2x ", usdo[i]); + strcat( hstr, es); + } + break; + default: + sprintf(hstr, "Unknown type"); + } + return hstr; + } +} + + +//----- read PDO assign structure ---------------------------------------------- + +int si_PDOassign(uint16 slave, uint16 PDOassign, int mapoffset, int bitoffset) +{ + uint16 idxloop, nidx, subidxloop, rdat, idx, subidx; + uint8 subcnt; + int wkc, bsize = 0, rdl; + int32 rdat2; + uint8 bitlen, obj_subidx; + uint16 obj_idx; + int abs_offset, abs_bit; + + rdl = sizeof(rdat); rdat = 0; + // read PDO assign subindex 0 (= number of PDO's) + wkc = ec_SDOread(slave, PDOassign, 0x00, FALSE, &rdl, &rdat, EC_TIMEOUTRXM); + rdat = etohs(rdat); + + if ((wkc > 0) && (rdat > 0)) // positive result from slave? + { + nidx = rdat; // number of available sub indexes + bsize = 0; + + for (idxloop = 1; idxloop <= nidx; idxloop++) // read all PDO's + { + rdl = sizeof(rdat); rdat = 0; + // read PDO assign + wkc = ec_SDOread(slave, PDOassign, (uint8)idxloop, FALSE, &rdl, &rdat, EC_TIMEOUTRXM); + + idx = etohl(rdat); // result is index of PDO + if (idx > 0) + { + rdl = sizeof(subcnt); subcnt = 0; + // read number of subindexes of PDO + wkc = ec_SDOread(slave,idx, 0x00, FALSE, &rdl, &subcnt, EC_TIMEOUTRXM); + subidx = subcnt; + // for each subindex + for (subidxloop = 1; subidxloop <= subidx; subidxloop++) + { + rdl = sizeof(rdat2); rdat2 = 0; + // read SDO that is mapped in PDO + wkc = ec_SDOread(slave, idx, (uint8)subidxloop, FALSE, &rdl, &rdat2, EC_TIMEOUTRXM); + rdat2 = etohl(rdat2); + + bitlen = LO_BYTE(rdat2); // extract bitlength of SDO + bsize += bitlen; + obj_idx = (uint16)(rdat2 >> 16); + obj_subidx = (uint8)((rdat2 >> 8) & 0x000000ff); + abs_offset = mapoffset + (bitoffset / 8); + abs_bit = bitoffset % 8; + ODlist.Slave = slave; + ODlist.Index[0] = obj_idx; + OElist.Entries = 0; + wkc = 0; + + if(obj_idx || obj_subidx) // read object entry from dictionary if not a filler (0x0000:0x00) + wkc = ec_readOEsingle(0, obj_subidx, &ODlist, &OElist); + printf(" [0x%4.4X.%1d] 0x%4.4X:0x%2.2X 0x%2.2X", abs_offset, abs_bit, obj_idx, obj_subidx, bitlen); + + if((wkc > 0) && OElist.Entries) + { + printf(" %-12s %s\n", dtype2string(OElist.DataType[obj_subidx]), OElist.Name[obj_subidx]); + } + else + printf("\n"); + bitoffset += bitlen; + }; + }; + }; + }; + + return bsize; // return total found bitlength (PDO) +} + + +//---- PDO mapping according to CoE -------------------------------------------- + +int si_map_sdo(int slave) +{ + int wkc, rdl; + int retVal = 0; + uint8 nSM, iSM, tSM; + int Tsize, outputs_bo, inputs_bo; + uint8 SMt_bug_add; + + printf("PDO mapping according to CoE :\n\n"); + SMt_bug_add = 0; + outputs_bo = 0; + inputs_bo = 0; + rdl = sizeof(nSM); nSM = 0; + // read SyncManager Communication Type object count + wkc = ec_SDOread(slave, ECT_SDO_SMCOMMTYPE, 0x00, FALSE, &rdl, &nSM, EC_TIMEOUTRXM); + + if ((wkc > 0) && (nSM > 2)) // positive result from slave ? + { + nSM--; // make nSM equal to number of defined SM + + if (nSM > EC_MAXSM) // limit to maximum number of SM defined, + nSM = EC_MAXSM; // if true the slave can't be configured + + for (iSM = 2 ; iSM <= nSM ; iSM++) // iterate for every SM type defined + { + rdl = sizeof(tSM); tSM = 0; + // read SyncManager Communication Type + wkc = ec_SDOread(slave, ECT_SDO_SMCOMMTYPE, iSM + 1, FALSE, &rdl, &tSM, EC_TIMEOUTRXM); + if (wkc > 0) + { + if((iSM == 2) && (tSM == 2)) // SM2 has type 2 == mailbox out, this is a bug in the slave! + { + SMt_bug_add = 1; // try to correct, this works if the types are 0 1 2 3 and should be 1 2 3 4 + printf("Activated SM type workaround, possible incorrect mapping.\n"); + } + + if(tSM) // only add if SMt > 0 + tSM += SMt_bug_add; + + if (tSM == 3) // outputs + { // read the assign RXPDO + + printf(" SM%1d outputs\n addr b index: sub bitl data_type name\n", iSM); + Tsize = si_PDOassign(slave, ECT_SDO_PDOASSIGN + iSM, (int)(ec_slave[slave].outputs - (uint8 *)&IOmap[0]), outputs_bo ); + outputs_bo += Tsize; + } + + if (tSM == 4) // inputs + { // read the assign TXPDO + + printf(" SM%1d inputs\n addr b index: sub bitl data_type name\n", iSM); + Tsize = si_PDOassign(slave, ECT_SDO_PDOASSIGN + iSM, (int)(ec_slave[slave].inputs - (uint8 *)&IOmap[0]), inputs_bo ); + inputs_bo += Tsize; + } + } + } + } + + if ((outputs_bo > 0) || (inputs_bo > 0)) // found some I/O bits? + retVal = 1; + return retVal; +} + + +//---- CoE objects description ------------------------------------------------- + +void si_sdo(int cnt) +{ + int i, j; + + ODlist.Entries = 0; + memset(&ODlist, 0, sizeof(ODlist)); + if( ec_readODlist(cnt, &ODlist)) + { + printf(" CoE Object Description found, %d entries.\n",ODlist.Entries); + for( i = 0 ; i < ODlist.Entries ; i++) + { + ec_readODdescription(i, &ODlist); + while(EcatError) printf("%s", ec_elist2string()); + printf(" Index: %4.4x Datatype: %4.4x Objectcode: %2.2x Name: %s\n", + ODlist.Index[i], ODlist.DataType[i], ODlist.ObjectCode[i], ODlist.Name[i]); + memset(&OElist, 0, sizeof(OElist)); + ec_readOE(i, &ODlist, &OElist); + while(EcatError) printf("%s", ec_elist2string()); + for( j = 0 ; j < ODlist.MaxSub[i]+1 ; j++) + { + if ((OElist.DataType[j] > 0) && (OElist.BitLength[j] > 0)) + { + printf(" Sub: %2.2x Datatype: %4.4x Bitlength: %4.4x Obj.access: %4.4x Name: %s\n", + j, OElist.DataType[j], OElist.BitLength[j], OElist.ObjAccess[j], OElist.Name[j]); + if ((OElist.ObjAccess[j] & 0x0007)) + { + printf(" Value :%s\n", SDO2string(cnt, ODlist.Index[i], j, OElist.DataType[j])); + } + } + } + } + } + else + { + while(EcatError) printf("%s", ec_elist2string()); + } +} + + +//---- PDO mapping according to SII -------------------------------------------- + +int si_map_sii(int slave) +{ + int retVal = 0; + int Tsize, outputs_bo, inputs_bo; + + printf("\nPDO mapping according to SII :\n\n"); + + outputs_bo = 0; + inputs_bo = 0; + // read the assign RXPDOs + Tsize = si_siiPDO(slave, 1, (int)(ec_slave[slave].outputs - (uint8*)&IOmap), outputs_bo ); + outputs_bo += Tsize; + // read the assign TXPDOs + Tsize = si_siiPDO(slave, 0, (int)(ec_slave[slave].inputs - (uint8*)&IOmap), inputs_bo ); + inputs_bo += Tsize; + + if ((outputs_bo > 0) || (inputs_bo > 0)) // found some I/O bits ? + retVal = 1; + return retVal; +} + + +//------------------------------------------------------------------------------ + +int si_siiPDO(uint16 slave, uint8 t, int mapoffset, int bitoffset) +{ + uint16 a , w, c, e, er, Size; + uint8 eectl; + uint16 obj_idx; + uint8 obj_subidx; + uint8 obj_name; + uint8 obj_datatype; + uint8 bitlen; + int totalsize; + ec_eepromPDOt eepPDO; + ec_eepromPDOt *PDO; + int abs_offset, abs_bit; + char str_name[EC_MAXNAME + 1]; + + eectl = ec_slave[slave].eep_pdi; + Size = 0; + totalsize = 0; + PDO = &eepPDO; + PDO->nPDO = 0; + PDO->Length = 0; + PDO->Index[1] = 0; + + for (c = 0 ; c < EC_MAXSM ; c++) + PDO->SMbitsize[c] = 0; + + if (t > 1) + t = 1; + + PDO->Startpos = ec_siifind(slave, ECT_SII_PDO + t); + + if (PDO->Startpos > 0) + { + a = PDO->Startpos; + w = ec_siigetbyte(slave, a++); + w += (ec_siigetbyte(slave, a++) << 8); + PDO->Length = w; + c = 1; + + do // traverse through all PDOs + { + PDO->nPDO++; + PDO->Index[PDO->nPDO] = ec_siigetbyte(slave, a++); + PDO->Index[PDO->nPDO] += (ec_siigetbyte(slave, a++) << 8); + PDO->BitSize[PDO->nPDO] = 0; + c++; + + e = ec_siigetbyte(slave, a++); // number of entries in PDO + PDO->SyncM[PDO->nPDO] = ec_siigetbyte(slave, a++); + a++; + obj_name = ec_siigetbyte(slave, a++); + a += 2; + c += 2; + + if (PDO->SyncM[PDO->nPDO] < EC_MAXSM) // active and in range SM? + { + str_name[0] = 0; + if(obj_name) + ec_siistring(str_name, slave, obj_name); + + if (t) + printf(" SM%1d RXPDO 0x%4.4X %s\n", PDO->SyncM[PDO->nPDO], PDO->Index[PDO->nPDO], str_name); + else + printf(" SM%1d TXPDO 0x%4.4X %s\n", PDO->SyncM[PDO->nPDO], PDO->Index[PDO->nPDO], str_name); + + printf(" addr b index: sub bitl data_type name\n"); + + for (er = 1; er <= e; er++) // read all entries defined in PDO + { + c += 4; + obj_idx = ec_siigetbyte(slave, a++); + obj_idx += (ec_siigetbyte(slave, a++) << 8); + obj_subidx = ec_siigetbyte(slave, a++); + obj_name = ec_siigetbyte(slave, a++); + obj_datatype = ec_siigetbyte(slave, a++); + bitlen = ec_siigetbyte(slave, a++); + abs_offset = mapoffset + (bitoffset / 8); + abs_bit = bitoffset % 8; + + PDO->BitSize[PDO->nPDO] += bitlen; + a += 2; + + if(obj_idx || obj_subidx) // skip entry if filler (0x0000:0x00) + { + str_name[0] = 0; + if(obj_name) + ec_siistring(str_name, slave, obj_name); + + printf(" [0x%4.4X.%1d] 0x%4.4X:0x%2.2X 0x%2.2X", abs_offset, abs_bit, obj_idx, obj_subidx, bitlen); + printf(" %-12s %s\n", dtype2string(obj_datatype), str_name); + } + bitoffset += bitlen; + totalsize += bitlen; + } + PDO->SMbitsize[ PDO->SyncM[PDO->nPDO] ] += PDO->BitSize[PDO->nPDO]; + Size += PDO->BitSize[PDO->nPDO]; + c++; + } + + else // PDO deactivated because SM is 0xff or > EC_MAXSM + { + c += 4 * e; + a += 8 * e; + c++; + } + // limit number of PDO entries in buffer + if (PDO->nPDO >= (EC_MAXEEPDO - 1)) c = PDO->Length; + } + while (c < PDO->Length); + } + + if (eectl) + ec_eeprom2pdi(slave); // if eeprom control was previously pdi then restore + + return totalsize; +} + + +//------------------------------------------------------------------------------ + +bool network_scanning(void) + +{ + int expectedWKC; + int cnt, i, j, nSM; + uint16 ssigen; + + if ( ec_config(FALSE, &IOmap) > 0 ) // find and configure the slaves + { + ec_configdc(); + while(EcatError) printf("%s", ec_elist2string()); + + printf("%d slaves found and configured.\n",ec_slavecount); + TFT.printf("%d slaves found and configured.\n\n",ec_slavecount); + + expectedWKC = (ec_group[0].outputsWKC * 2) + ec_group[0].inputsWKC; + printf("Calculated workcounter %d\n", expectedWKC); + // wait for all slaves to reach SAFE_OP state + ec_statecheck(0, EC_STATE_SAFE_OP, EC_TIMEOUTSTATE * 3); + + if (ec_slave[0].state != EC_STATE_SAFE_OP ) + { + printf("Not all slaves reached safe operational state.\n"); + ec_readstate(); + for(i = 1; i<=ec_slavecount ; i++) + { + if(ec_slave[i].state != EC_STATE_SAFE_OP) + { + printf("Slave %d State=%2x StatusCode=%4x : %s\n", + i, ec_slave[i].state, ec_slave[i].ALstatuscode, ec_ALstatuscode2string(ec_slave[i].ALstatuscode)); + } + } + } + + ec_readstate(); + + for( cnt = 1 ; cnt <= ec_slavecount ; cnt++) + { + printf("\nSlave:%d -------------------------------------------------\nName:%s\n Output size: %dbits\n Input size: %dbits\n State: %d\n Delay: %d[ns]\n Has DC: %d\n", + cnt, ec_slave[cnt].name, ec_slave[cnt].Obits, ec_slave[cnt].Ibits, + ec_slave[cnt].state, ec_slave[cnt].pdelay, ec_slave[cnt].hasdc); + + int Line = cnt-1; + + TFT.foreground(Green); // print Name, Manufacturer, ID and Revision + TFT.locate(0, 12*(((Line % 6)*3)+3)); // of the slaves found on the TFT + TFT.printf("Slave %d ", cnt); // + TFT.foreground(Yellow); // + // + TFT.foreground(Magenta); // + TFT.locate(60, 12*(((Line % 6)*3)+3)); // + TFT.printf("Name"); // + TFT.foreground(Yellow); // + TFT.locate(104, 12*(((Line % 6)*3)+3)); // + TFT.printf("%.14s", ec_slave[cnt].name); // + // + TFT.foreground(Magenta); // + TFT.locate(220, 12*(((Line % 6)*3)+3)); // + TFT.printf("Man"); // + TFT.foreground(Yellow); // + TFT.locate(250, 12*(((Line % 6)*3)+3)); // + TFT.printf("%8.8X", (int)ec_slave[cnt].eep_man);// + // + TFT.foreground(Magenta); // + TFT.locate(60, 12*(((Line % 6)*3)+4)); // + TFT.printf("ID"); // + TFT.foreground(Yellow); // + TFT.locate(104, 12*(((Line % 6)*3)+4)); // + TFT.printf("%8.8X", (int)ec_slave[cnt].eep_id); // + // + TFT.foreground(Magenta); // + TFT.locate(220, 12*(((Line % 6)*3)+4)); // + TFT.printf("Rev "); // + TFT.foreground(Yellow); // + TFT.locate(250, 12*(((Line % 6)*3)+4)); // + TFT.printf("%8.8X", (int)ec_slave[cnt].eep_rev);// + + + if (ec_slave[cnt].hasdc) printf(" DCParentport:%d\n", ec_slave[cnt].parentport); + printf(" Activeports:%d.%d.%d.%d\n", (ec_slave[cnt].activeports & 0x01) > 0 , + (ec_slave[cnt].activeports & 0x02) > 0 , + (ec_slave[cnt].activeports & 0x04) > 0 , + (ec_slave[cnt].activeports & 0x08) > 0 ); + + printf(" Configured address: %4.4X\n", ec_slave[cnt].configadr); + printf(" Outputs address: %X\n", ec_slave[cnt].outputs); + printf(" Inputs address: %X\n", ec_slave[cnt].inputs); + + printf(" Man: %8.8x ID: %8.8x Rev: %8.8x\n", (int)ec_slave[cnt].eep_man, (int)ec_slave[cnt].eep_id, (int)ec_slave[cnt].eep_rev); + for(nSM = 0 ; nSM < EC_MAXSM ; nSM++) + { + if(ec_slave[cnt].SM[nSM].StartAddr > 0) + printf(" SM%1d A:%4.4x L:%4d F:%8.8x Type:%d\n",nSM, ec_slave[cnt].SM[nSM].StartAddr, ec_slave[cnt].SM[nSM].SMlength, + (int)ec_slave[cnt].SM[nSM].SMflags, ec_slave[cnt].SMtype[nSM]); + } + for(j = 0 ; j < ec_slave[cnt].FMMUunused ; j++) + { + printf(" FMMU%1d Ls:%8.8x Ll:%4d Lsb:%d Leb:%d Ps:%4.4x Psb:%d Ty:%2.2x Act:%2.2x\n", j, + (int)ec_slave[cnt].FMMU[j].LogStart, ec_slave[cnt].FMMU[j].LogLength, ec_slave[cnt].FMMU[j].LogStartbit, + ec_slave[cnt].FMMU[j].LogEndbit, ec_slave[cnt].FMMU[j].PhysStart, ec_slave[cnt].FMMU[j].PhysStartBit, + ec_slave[cnt].FMMU[j].FMMUtype, ec_slave[cnt].FMMU[j].FMMUactive); + } + printf(" FMMUfunc 0:%d 1:%d 2:%d 3:%d\n", + ec_slave[cnt].FMMU0func, ec_slave[cnt].FMMU1func, ec_slave[cnt].FMMU2func, ec_slave[cnt].FMMU3func); + printf(" MBX length wr: %d rd: %d MBX protocols : %2.2x\n", ec_slave[cnt].mbx_l, ec_slave[cnt].mbx_rl, ec_slave[cnt].mbx_proto); + ssigen = ec_siifind(cnt, ECT_SII_GENERAL); + + if (ssigen) // SII general section + { + ec_slave[cnt].CoEdetails = ec_siigetbyte(cnt, ssigen + 0x07); + ec_slave[cnt].FoEdetails = ec_siigetbyte(cnt, ssigen + 0x08); + ec_slave[cnt].EoEdetails = ec_siigetbyte(cnt, ssigen + 0x09); + ec_slave[cnt].SoEdetails = ec_siigetbyte(cnt, ssigen + 0x0a); + if((ec_siigetbyte(cnt, ssigen + 0x0d) & 0x02) > 0) + { + ec_slave[cnt].blockLRW = 1; + ec_slave[0].blockLRW++; + } + ec_slave[cnt].Ebuscurrent = ec_siigetbyte(cnt, ssigen + 0x0e); + ec_slave[cnt].Ebuscurrent += ec_siigetbyte(cnt, ssigen + 0x0f) << 8; + ec_slave[0].Ebuscurrent += ec_slave[cnt].Ebuscurrent; + } + printf(" CoE details: %2.2x FoE details: %2.2x EoE details: %2.2x SoE details: %2.2x\n", + ec_slave[cnt].CoEdetails, ec_slave[cnt].FoEdetails, ec_slave[cnt].EoEdetails, ec_slave[cnt].SoEdetails); + printf(" Ebus current: %d[mA]\n only LRD/LWR:%d\n", + ec_slave[cnt].Ebuscurrent, ec_slave[cnt].blockLRW); + + if ((ec_slave[cnt].mbx_proto & ECT_MBXPROT_COE) && printSDO) + si_sdo(cnt); + + if(printMAP) + { + if (ec_slave[cnt].mbx_proto & ECT_MBXPROT_COE) + si_map_sdo(cnt); + else + si_map_sii(cnt); + } + } + return 1; + } + + else + { + // ec_close(); //******// + + return 0; // no slaves found + } +} + + + + + +