EasyCAT LAB - EtherCAT master legacy example

Dependencies:   SOEM SPI_STMPE610 SPI_TFT_ILI9341 TFT_fonts

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers soem_start.cpp Source File

soem_start.cpp

00001 
00002 #include "soem_start.h"
00003 #include "ethercat.h"
00004 #include "string.h"
00005 #include "oshw.h"
00006 
00007 #include "mbed.h"
00008 
00009 #include <inttypes.h>
00010 
00011 #include "SPI_TFT_ILI9341.h"
00012 
00013 extern SPI_TFT_ILI9341 TFT;
00014 
00015 boolean printSDO = TRUE;            
00016 boolean printMAP = TRUE;            
00017 
00018 ec_ODlistt ODlist;
00019 ec_OElistt OElist;
00020 char usdo[128];
00021 char hstr[1024];
00022 
00023 char extern IOmap[];
00024 
00025 uint32_t error_counter = 0;
00026 
00027 
00028 char* dtype2string(uint16 dtype);
00029 char* SDO2string(uint16 slave, uint16 index, uint8 subidx, uint16 dtype);
00030 int si_PDOassign(uint16 slave, uint16 PDOassign, int mapoffset, int bitoffset);
00031 void si_sdo(int cnt);
00032 int si_map_sdo(int slave);
00033 int si_siiPDO(uint16 slave, uint8 t, int mapoffset, int bitoffset);
00034 bool network_scanning(void);
00035 
00036 
00037 
00038 //---- convert Ethercat types to string ----------------------------------------
00039 
00040 
00041 char* dtype2string(uint16 dtype)
00042 {
00043     switch(dtype)
00044     {
00045         case ECT_BOOLEAN:
00046             sprintf(hstr, "BOOLEAN");
00047             break;
00048         case ECT_INTEGER8:
00049             sprintf(hstr, "INTEGER8");
00050             break;
00051         case ECT_INTEGER16:
00052             sprintf(hstr, "INTEGER16");
00053             break;
00054         case ECT_INTEGER32:
00055             sprintf(hstr, "INTEGER32");
00056             break;
00057         case ECT_INTEGER24:
00058             sprintf(hstr, "INTEGER24");
00059             break;
00060         case ECT_INTEGER64:
00061             sprintf(hstr, "INTEGER64");
00062             break;
00063         case ECT_UNSIGNED8:
00064             sprintf(hstr, "UNSIGNED8");
00065             break;
00066         case ECT_UNSIGNED16:
00067             sprintf(hstr, "UNSIGNED16");
00068             break;
00069         case ECT_UNSIGNED32:
00070             sprintf(hstr, "UNSIGNED32");
00071             break;
00072         case ECT_UNSIGNED24:
00073             sprintf(hstr, "UNSIGNED24");
00074             break;
00075         case ECT_UNSIGNED64:
00076             sprintf(hstr, "UNSIGNED64");
00077             break;
00078         case ECT_REAL32:
00079             sprintf(hstr, "REAL32");
00080             break;
00081         case ECT_REAL64:
00082             sprintf(hstr, "REAL64");
00083             break;
00084         case ECT_BIT1:
00085             sprintf(hstr, "BIT1");
00086             break;
00087         case ECT_BIT2:
00088             sprintf(hstr, "BIT2");
00089             break;
00090         case ECT_BIT3:
00091             sprintf(hstr, "BIT3");
00092             break;
00093         case ECT_BIT4:
00094             sprintf(hstr, "BIT4");
00095             break;
00096         case ECT_BIT5:
00097             sprintf(hstr, "BIT5");
00098             break;
00099         case ECT_BIT6:
00100             sprintf(hstr, "BIT6");
00101             break;
00102         case ECT_BIT7:
00103             sprintf(hstr, "BIT7");
00104             break;
00105         case ECT_BIT8:
00106             sprintf(hstr, "BIT8");
00107             break;
00108         case ECT_VISIBLE_STRING:
00109             sprintf(hstr, "VISIBLE_STRING");
00110             break;
00111         case ECT_OCTET_STRING:
00112             sprintf(hstr, "OCTET_STRING");
00113             break;
00114         default:
00115             sprintf(hstr, "Type 0x%4.4X", dtype);
00116     }
00117     return hstr;
00118 }
00119 
00120 
00121 //------------------------------------------------------------------------------
00122 
00123 char* SDO2string(uint16 slave, uint16 index, uint8 subidx, uint16 dtype)
00124 {
00125    int l = sizeof(usdo) - 1, i;
00126    uint8 *u8;
00127    int8 *i8;
00128    uint16 *u16;
00129    int16 *i16;
00130    uint32 *u32;
00131    int32 *i32;
00132    uint64 *u64;
00133    int64 *i64;
00134    float *sr;
00135    double *dr;
00136    char es[32];
00137 
00138    memset(&usdo, 0, 128);
00139    ec_SDOread(slave, index, subidx, FALSE, &l, &usdo, EC_TIMEOUTRXM);
00140    if (EcatError)
00141    {
00142       return ec_elist2string();
00143    }
00144    else
00145    {
00146       switch(dtype)
00147       {
00148          case ECT_BOOLEAN:
00149             u8 = (uint8*) &usdo[0];
00150             if (*u8) sprintf(hstr, "TRUE");
00151              else sprintf(hstr, "FALSE");
00152             break;
00153          case ECT_INTEGER8:
00154             i8 = (int8*) &usdo[0];
00155             sprintf(hstr, "0x%2.2x %d", *i8, *i8);
00156             break;
00157          case ECT_INTEGER16:
00158             i16 = (int16*) &usdo[0];
00159             sprintf(hstr, "0x%4.4x %d", *i16, *i16);
00160             break;
00161          case ECT_INTEGER32:
00162          case ECT_INTEGER24:
00163             i32 = (int32*) &usdo[0];
00164             sprintf(hstr, "0x%8.8x %d", *i32, *i32);
00165             break;
00166          case ECT_INTEGER64:
00167             i64 = (int64*) &usdo[0];
00168             sprintf(hstr, "0x%16.16"PRIx64" %"PRId64, *i64, *i64);
00169             break;
00170          case ECT_UNSIGNED8:
00171             u8 = (uint8*) &usdo[0];
00172             sprintf(hstr, "0x%2.2x %u", *u8, *u8);
00173             break;
00174          case ECT_UNSIGNED16:
00175             u16 = (uint16*) &usdo[0];
00176             sprintf(hstr, "0x%4.4x %u", *u16, *u16);
00177             break;
00178          case ECT_UNSIGNED32:
00179          case ECT_UNSIGNED24:
00180             u32 = (uint32*) &usdo[0];
00181             sprintf(hstr, "0x%8.8x %u", *u32, *u32);
00182             break;
00183          case ECT_UNSIGNED64:
00184             u64 = (uint64*) &usdo[0];
00185             sprintf(hstr, "0x%16.16"PRIx64" %"PRIu64, *u64, *u64);
00186             break;
00187          case ECT_REAL32:
00188             sr = (float*) &usdo[0];
00189             sprintf(hstr, "%f", *sr);
00190             break;
00191          case ECT_REAL64:
00192             dr = (double*) &usdo[0];
00193             sprintf(hstr, "%f", *dr);
00194             break;
00195          case ECT_BIT1:
00196          case ECT_BIT2:
00197          case ECT_BIT3:
00198          case ECT_BIT4:
00199          case ECT_BIT5:
00200          case ECT_BIT6:
00201          case ECT_BIT7:
00202          case ECT_BIT8:
00203             u8 = (uint8*) &usdo[0];
00204             sprintf(hstr, "0x%x", *u8);
00205             break;
00206          case ECT_VISIBLE_STRING:
00207             strcpy(hstr, usdo);
00208             break;
00209          case ECT_OCTET_STRING:
00210             hstr[0] = 0x00;
00211             for (i = 0 ; i < l ; i++)
00212             {
00213                sprintf(es, "0x%2.2x ", usdo[i]);
00214                strcat( hstr, es);
00215             }
00216             break;
00217          default:
00218             sprintf(hstr, "Unknown type");
00219       }
00220       return hstr;
00221    }
00222 }
00223 
00224 
00225 //----- read PDO assign structure ----------------------------------------------
00226 
00227 int si_PDOassign(uint16 slave, uint16 PDOassign, int mapoffset, int bitoffset)
00228 {
00229     uint16 idxloop, nidx, subidxloop, rdat, idx, subidx;
00230     uint8 subcnt;
00231     int wkc, bsize = 0, rdl;
00232     int32 rdat2;
00233     uint8 bitlen, obj_subidx;
00234     uint16 obj_idx;
00235     int abs_offset, abs_bit;
00236 
00237     rdl = sizeof(rdat); rdat = 0;
00238                                                                 // read PDO assign subindex 0 (= number of PDO's)
00239     wkc = ec_SDOread(slave, PDOassign, 0x00, FALSE, &rdl, &rdat, EC_TIMEOUTRXM);
00240     rdat = etohs(rdat);
00241 
00242     if ((wkc > 0) && (rdat > 0))                                // positive result from slave?
00243     {
00244         nidx = rdat;                                            // number of available sub indexes 
00245         bsize = 0;
00246         
00247         for (idxloop = 1; idxloop <= nidx; idxloop++)           // read all PDO's 
00248         {
00249             rdl = sizeof(rdat); rdat = 0;
00250                                                                 // read PDO assign 
00251             wkc = ec_SDOread(slave, PDOassign, (uint8)idxloop, FALSE, &rdl, &rdat, EC_TIMEOUTRXM);
00252                                                     
00253             idx = etohl(rdat);                                  // result is index of PDO
00254             if (idx > 0)
00255             {
00256                 rdl = sizeof(subcnt); subcnt = 0;
00257                                                                 // read number of subindexes of PDO
00258                 wkc = ec_SDOread(slave,idx, 0x00, FALSE, &rdl, &subcnt, EC_TIMEOUTRXM);
00259                 subidx = subcnt;
00260                                                                 // for each subindex 
00261                 for (subidxloop = 1; subidxloop <= subidx; subidxloop++)
00262                 {
00263                     rdl = sizeof(rdat2); rdat2 = 0;
00264                                                                 // read SDO that is mapped in PDO
00265                     wkc = ec_SDOread(slave, idx, (uint8)subidxloop, FALSE, &rdl, &rdat2, EC_TIMEOUTRXM);
00266                     rdat2 = etohl(rdat2);
00267                     
00268                     bitlen = LO_BYTE(rdat2);                    // extract bitlength of SDO
00269                     bsize += bitlen;
00270                     obj_idx = (uint16)(rdat2 >> 16);
00271                     obj_subidx = (uint8)((rdat2 >> 8) & 0x000000ff);
00272                     abs_offset = mapoffset + (bitoffset / 8);
00273                     abs_bit = bitoffset % 8;
00274                     ODlist.Slave = slave;
00275                     ODlist.Index[0] = obj_idx;
00276                     OElist.Entries = 0;
00277                     wkc = 0;
00278                                                                 
00279                     if(obj_idx || obj_subidx)                   // read object entry from dictionary if not a filler (0x0000:0x00)
00280                         wkc = ec_readOEsingle(0, obj_subidx, &ODlist, &OElist);
00281                     printf("  [0x%4.4X.%1d] 0x%4.4X:0x%2.2X 0x%2.2X", abs_offset, abs_bit, obj_idx, obj_subidx, bitlen);
00282                     
00283                     if((wkc > 0) && OElist.Entries)
00284                     {
00285                         printf(" %-12s %s\n", dtype2string(OElist.DataType[obj_subidx]), OElist.Name[obj_subidx]);
00286                     }
00287                     else
00288                         printf("\n");
00289                     bitoffset += bitlen;
00290                 };
00291             };
00292         };
00293     };
00294 
00295     return bsize;                                               // return total found bitlength (PDO)
00296 }
00297 
00298 
00299 //---- PDO mapping according to CoE --------------------------------------------
00300 
00301 int si_map_sdo(int slave)
00302 {
00303     int wkc, rdl;
00304     int retVal = 0;
00305     uint8 nSM, iSM, tSM;
00306     int Tsize, outputs_bo, inputs_bo;
00307     uint8 SMt_bug_add;
00308 
00309     printf("PDO mapping according to CoE :\n\n");
00310     SMt_bug_add = 0;
00311     outputs_bo = 0;
00312     inputs_bo = 0;
00313     rdl = sizeof(nSM); nSM = 0;
00314                                                             // read SyncManager Communication Type object count
00315     wkc = ec_SDOread(slave, ECT_SDO_SMCOMMTYPE, 0x00, FALSE, &rdl, &nSM, EC_TIMEOUTRXM);
00316                                                             
00317     if ((wkc > 0) && (nSM > 2))                             // positive result from slave ? 
00318     {   
00319         nSM--;                                              // make nSM equal to number of defined SM 
00320         
00321         if (nSM > EC_MAXSM)                                 // limit to maximum number of SM defined,
00322             nSM = EC_MAXSM;                                 // if true the slave can't be configured 
00323         
00324         for (iSM = 2 ; iSM <= nSM ; iSM++)                  // iterate for every SM type defined        
00325         {
00326             rdl = sizeof(tSM); tSM = 0;
00327                                                             // read SyncManager Communication Type 
00328             wkc = ec_SDOread(slave, ECT_SDO_SMCOMMTYPE, iSM + 1, FALSE, &rdl, &tSM, EC_TIMEOUTRXM);
00329             if (wkc > 0)
00330             {
00331                 if((iSM == 2) && (tSM == 2))                // SM2 has type 2 == mailbox out, this is a bug in the slave!
00332                 {
00333                     SMt_bug_add = 1;                        // try to correct, this works if the types are 0 1 2 3 and should be 1 2 3 4
00334                     printf("Activated SM type workaround, possible incorrect mapping.\n");
00335                 }
00336                 
00337                 if(tSM)                                     // only add if SMt > 0
00338                     tSM += SMt_bug_add;                     
00339 
00340                 if (tSM == 3)                               // outputs
00341                 {                                           // read the assign RXPDO
00342                  
00343                     printf("  SM%1d outputs\n        addr b   index: sub bitl data_type    name\n", iSM);
00344                     Tsize = si_PDOassign(slave, ECT_SDO_PDOASSIGN + iSM, (int)(ec_slave[slave].outputs - (uint8 *)&IOmap[0]), outputs_bo );
00345                     outputs_bo += Tsize;
00346                 }
00347                 
00348                 if (tSM == 4)                               // inputs
00349                 {                                           // read the assign TXPDO 
00350                     
00351                     printf("  SM%1d inputs\n     addr b   index: sub bitl data_type    name\n", iSM);
00352                     Tsize = si_PDOassign(slave, ECT_SDO_PDOASSIGN + iSM, (int)(ec_slave[slave].inputs - (uint8 *)&IOmap[0]), inputs_bo );
00353                     inputs_bo += Tsize;
00354                 }
00355             }
00356         }
00357     }
00358 
00359     if ((outputs_bo > 0) || (inputs_bo > 0))                // found some I/O bits? 
00360         retVal = 1;
00361     return retVal;
00362 }
00363 
00364 
00365 //---- CoE objects description -------------------------------------------------
00366 
00367 void si_sdo(int cnt)
00368 {
00369     int i, j;
00370 
00371     ODlist.Entries = 0;
00372     memset(&ODlist, 0, sizeof(ODlist));
00373     if( ec_readODlist(cnt, &ODlist))
00374     {
00375         printf(" CoE Object Description found, %d entries.\n",ODlist.Entries);
00376         for( i = 0 ; i < ODlist.Entries ; i++)
00377         {
00378             ec_readODdescription(i, &ODlist);
00379             while(EcatError) printf("%s", ec_elist2string());
00380             printf(" Index: %4.4x Datatype: %4.4x Objectcode: %2.2x Name: %s\n",
00381                 ODlist.Index[i], ODlist.DataType[i], ODlist.ObjectCode[i], ODlist.Name[i]);
00382             memset(&OElist, 0, sizeof(OElist));
00383             ec_readOE(i, &ODlist, &OElist);
00384             while(EcatError) printf("%s", ec_elist2string());
00385             for( j = 0 ; j < ODlist.MaxSub[i]+1 ; j++)
00386             {
00387                 if ((OElist.DataType[j] > 0) && (OElist.BitLength[j] > 0))
00388                 {
00389                     printf("  Sub: %2.2x Datatype: %4.4x Bitlength: %4.4x Obj.access: %4.4x Name: %s\n",
00390                         j, OElist.DataType[j], OElist.BitLength[j], OElist.ObjAccess[j], OElist.Name[j]);
00391                     if ((OElist.ObjAccess[j] & 0x0007))
00392                     {
00393                         printf("          Value :%s\n", SDO2string(cnt, ODlist.Index[i], j, OElist.DataType[j]));
00394                     }
00395                 }
00396             }
00397         }
00398     }
00399     else
00400     {
00401         while(EcatError) printf("%s", ec_elist2string());
00402     }
00403 }
00404 
00405 
00406 //---- PDO mapping according to SII --------------------------------------------
00407 
00408 int si_map_sii(int slave)
00409 {
00410     int retVal = 0;
00411     int Tsize, outputs_bo, inputs_bo;
00412 
00413     printf("\nPDO mapping according to SII :\n\n");
00414 
00415     outputs_bo = 0;
00416     inputs_bo = 0;
00417                                                             // read the assign RXPDOs 
00418     Tsize = si_siiPDO(slave, 1, (int)(ec_slave[slave].outputs - (uint8*)&IOmap), outputs_bo );
00419     outputs_bo += Tsize;
00420                                                             // read the assign TXPDOs 
00421     Tsize = si_siiPDO(slave, 0, (int)(ec_slave[slave].inputs - (uint8*)&IOmap), inputs_bo );
00422     inputs_bo += Tsize;
00423     
00424     if ((outputs_bo > 0) || (inputs_bo > 0))                // found some I/O bits ? 
00425         retVal = 1;
00426     return retVal;
00427 }
00428 
00429 
00430 //------------------------------------------------------------------------------
00431 
00432 int si_siiPDO(uint16 slave, uint8 t, int mapoffset, int bitoffset)
00433 {
00434     uint16 a , w, c, e, er, Size;
00435     uint8 eectl;
00436     uint16 obj_idx;
00437     uint8 obj_subidx;
00438     uint8 obj_name;
00439     uint8 obj_datatype;
00440     uint8 bitlen;
00441     int totalsize;
00442     ec_eepromPDOt eepPDO;
00443     ec_eepromPDOt *PDO;
00444     int abs_offset, abs_bit;
00445     char str_name[EC_MAXNAME + 1];
00446 
00447     eectl = ec_slave[slave].eep_pdi;
00448     Size = 0;
00449     totalsize = 0;
00450     PDO = &eepPDO;
00451     PDO->nPDO = 0;
00452     PDO->Length = 0;
00453     PDO->Index[1] = 0;
00454   
00455     for (c = 0 ; c < EC_MAXSM ; c++)
00456         PDO->SMbitsize[c] = 0;
00457   
00458     if (t > 1)
00459         t = 1;
00460   
00461     PDO->Startpos = ec_siifind(slave, ECT_SII_PDO + t);
00462   
00463     if (PDO->Startpos > 0)
00464     {
00465         a = PDO->Startpos;
00466         w = ec_siigetbyte(slave, a++);
00467         w += (ec_siigetbyte(slave, a++) << 8);
00468         PDO->Length = w;
00469         c = 1;
00470         
00471         do                                                  // traverse through all PDOs            
00472         {
00473             PDO->nPDO++;
00474             PDO->Index[PDO->nPDO] = ec_siigetbyte(slave, a++);
00475             PDO->Index[PDO->nPDO] += (ec_siigetbyte(slave, a++) << 8);
00476             PDO->BitSize[PDO->nPDO] = 0;
00477             c++;
00478             
00479             e = ec_siigetbyte(slave, a++);                  // number of entries in PDO 
00480             PDO->SyncM[PDO->nPDO] = ec_siigetbyte(slave, a++);
00481             a++;
00482             obj_name = ec_siigetbyte(slave, a++);
00483             a += 2;
00484             c += 2;
00485             
00486             if (PDO->SyncM[PDO->nPDO] < EC_MAXSM)           // active and in range SM? 
00487             {
00488                 str_name[0] = 0;
00489                 if(obj_name)
00490                     ec_siistring(str_name, slave, obj_name);
00491                     
00492                 if (t)
00493                     printf("  SM%1d RXPDO 0x%4.4X %s\n", PDO->SyncM[PDO->nPDO], PDO->Index[PDO->nPDO], str_name);
00494                 else
00495                     printf("  SM%1d TXPDO 0x%4.4X %s\n", PDO->SyncM[PDO->nPDO], PDO->Index[PDO->nPDO], str_name);
00496                 
00497                 printf("     addr b   index: sub  bitl data_type    name\n");
00498                 
00499                 for (er = 1; er <= e; er++)                 // read all entries defined in PDO 
00500                 {
00501                     c += 4;
00502                     obj_idx = ec_siigetbyte(slave, a++);
00503                     obj_idx += (ec_siigetbyte(slave, a++) << 8);
00504                     obj_subidx = ec_siigetbyte(slave, a++);
00505                     obj_name = ec_siigetbyte(slave, a++);
00506                     obj_datatype = ec_siigetbyte(slave, a++);
00507                     bitlen = ec_siigetbyte(slave, a++);
00508                     abs_offset = mapoffset + (bitoffset / 8);
00509                     abs_bit = bitoffset % 8;
00510 
00511                     PDO->BitSize[PDO->nPDO] += bitlen;
00512                     a += 2;
00513 
00514                     if(obj_idx || obj_subidx)               // skip entry if filler (0x0000:0x00)
00515                     {
00516                        str_name[0] = 0;
00517                        if(obj_name)
00518                           ec_siistring(str_name, slave, obj_name);
00519 
00520                        printf("  [0x%4.4X.%1d] 0x%4.4X:0x%2.2X 0x%2.2X", abs_offset, abs_bit, obj_idx, obj_subidx, bitlen);
00521                        printf(" %-12s %s\n", dtype2string(obj_datatype), str_name);
00522                     }
00523                     bitoffset += bitlen;
00524                     totalsize += bitlen;
00525                 }
00526                 PDO->SMbitsize[ PDO->SyncM[PDO->nPDO] ] += PDO->BitSize[PDO->nPDO];
00527                 Size += PDO->BitSize[PDO->nPDO];
00528                 c++;
00529             }
00530             
00531             else                                            // PDO deactivated because SM is 0xff or > EC_MAXSM 
00532             {
00533                 c += 4 * e;
00534                 a += 8 * e;
00535                 c++;
00536             }
00537                                                             // limit number of PDO entries in buffer 
00538             if (PDO->nPDO >= (EC_MAXEEPDO - 1)) c = PDO->Length; 
00539         }
00540         while (c < PDO->Length);
00541     }
00542                                         
00543     if (eectl) 
00544         ec_eeprom2pdi(slave);                               // if eeprom control was previously pdi then restore 
00545     
00546     return totalsize;
00547 }
00548 
00549 
00550 //------------------------------------------------------------------------------
00551 
00552 bool network_scanning(void)
00553 
00554 {
00555     int expectedWKC;
00556     int cnt, i, j, nSM;
00557     uint16 ssigen;          
00558 
00559     if ( ec_config(FALSE, &IOmap) > 0 )                     // find and configure the slaves    
00560     {
00561         ec_configdc();
00562         while(EcatError) printf("%s", ec_elist2string());
00563         
00564         printf("%d slaves found and configured.\n",ec_slavecount);
00565         TFT.printf("%d slaves found and configured.\n\n",ec_slavecount);            
00566         
00567         expectedWKC = (ec_group[0].outputsWKC * 2) + ec_group[0].inputsWKC;
00568         printf("Calculated workcounter %d\n", expectedWKC);
00569                                                             // wait for all slaves to reach SAFE_OP state 
00570         ec_statecheck(0, EC_STATE_SAFE_OP,  EC_TIMEOUTSTATE * 3);
00571         
00572         if (ec_slave[0].state != EC_STATE_SAFE_OP )
00573         {
00574             printf("Not all slaves reached safe operational state.\n");
00575             ec_readstate();
00576             for(i = 1; i<=ec_slavecount ; i++)
00577             {
00578                 if(ec_slave[i].state != EC_STATE_SAFE_OP)
00579                 {
00580                     printf("Slave %d State=%2x StatusCode=%4x : %s\n",
00581                     i, ec_slave[i].state, ec_slave[i].ALstatuscode, ec_ALstatuscode2string(ec_slave[i].ALstatuscode));
00582                 }
00583             }       
00584         }
00585 
00586         ec_readstate();         
00587                                                 
00588         for( cnt = 1 ; cnt <= ec_slavecount ; cnt++)
00589         {  
00590             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",
00591                     cnt, ec_slave[cnt].name, ec_slave[cnt].Obits, ec_slave[cnt].Ibits,
00592                     ec_slave[cnt].state, ec_slave[cnt].pdelay, ec_slave[cnt].hasdc);         
00593 
00594             int Line = cnt-1; 
00595 
00596             TFT.foreground(Green);                          // print Name, Manufacturer, ID and Revision
00597             TFT.locate(0, 12*(((Line % 6)*3)+3));           // of the slaves found on the TFT
00598             TFT.printf("Slave %d ", cnt);                   //
00599             TFT.foreground(Yellow);                         //  
00600                                                             //
00601             TFT.foreground(Magenta);                        //
00602             TFT.locate(60, 12*(((Line % 6)*3)+3));          //  
00603             TFT.printf("Name");                             //
00604             TFT.foreground(Yellow);                         //
00605             TFT.locate(104, 12*(((Line % 6)*3)+3));         //       
00606             TFT.printf("%.14s", ec_slave[cnt].name);        //               
00607                                                             //
00608             TFT.foreground(Magenta);                        //
00609             TFT.locate(220, 12*(((Line % 6)*3)+3));         //                          
00610             TFT.printf("Man");                              //
00611             TFT.foreground(Yellow);                         //
00612             TFT.locate(250, 12*(((Line % 6)*3)+3));         //      
00613             TFT.printf("%8.8X", (int)ec_slave[cnt].eep_man);//
00614                                                             //      
00615             TFT.foreground(Magenta);                        //
00616             TFT.locate(60, 12*(((Line % 6)*3)+4));          //                    
00617             TFT.printf("ID");                               //
00618             TFT.foreground(Yellow);                         //
00619             TFT.locate(104, 12*(((Line % 6)*3)+4));         //                 
00620             TFT.printf("%8.8X", (int)ec_slave[cnt].eep_id); //       
00621                                                             //
00622             TFT.foreground(Magenta);                        //
00623             TFT.locate(220, 12*(((Line % 6)*3)+4));         //                    
00624             TFT.printf("Rev ");                             //
00625             TFT.foreground(Yellow);                         //
00626             TFT.locate(250,  12*(((Line % 6)*3)+4));        //                 
00627             TFT.printf("%8.8X", (int)ec_slave[cnt].eep_rev);//    
00628                                                              
00629                           
00630             if (ec_slave[cnt].hasdc) printf(" DCParentport:%d\n", ec_slave[cnt].parentport);
00631             printf(" Activeports:%d.%d.%d.%d\n", (ec_slave[cnt].activeports & 0x01) > 0 ,
00632                                          (ec_slave[cnt].activeports & 0x02) > 0 ,
00633                                          (ec_slave[cnt].activeports & 0x04) > 0 ,
00634                                          (ec_slave[cnt].activeports & 0x08) > 0 );
00635                                          
00636             printf(" Configured address: %4.4X\n", ec_slave[cnt].configadr);
00637             printf(" Outputs address: %X\n", ec_slave[cnt].outputs);
00638             printf(" Inputs address: %X\n", ec_slave[cnt].inputs);            
00639             
00640             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);
00641             for(nSM = 0 ; nSM < EC_MAXSM ; nSM++)
00642             {
00643                if(ec_slave[cnt].SM[nSM].StartAddr > 0)
00644                   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,
00645                          (int)ec_slave[cnt].SM[nSM].SMflags, ec_slave[cnt].SMtype[nSM]);
00646             }
00647             for(j = 0 ; j < ec_slave[cnt].FMMUunused ; j++)
00648             {
00649                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,
00650                        (int)ec_slave[cnt].FMMU[j].LogStart, ec_slave[cnt].FMMU[j].LogLength, ec_slave[cnt].FMMU[j].LogStartbit,
00651                        ec_slave[cnt].FMMU[j].LogEndbit, ec_slave[cnt].FMMU[j].PhysStart, ec_slave[cnt].FMMU[j].PhysStartBit,
00652                        ec_slave[cnt].FMMU[j].FMMUtype, ec_slave[cnt].FMMU[j].FMMUactive);
00653             }
00654             printf(" FMMUfunc 0:%d 1:%d 2:%d 3:%d\n",
00655                      ec_slave[cnt].FMMU0func, ec_slave[cnt].FMMU1func, ec_slave[cnt].FMMU2func, ec_slave[cnt].FMMU3func);
00656             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);
00657             ssigen = ec_siifind(cnt, ECT_SII_GENERAL);
00658                 
00659             if (ssigen)                                      // SII general section 
00660             {
00661                ec_slave[cnt].CoEdetails = ec_siigetbyte(cnt, ssigen + 0x07);
00662                ec_slave[cnt].FoEdetails = ec_siigetbyte(cnt, ssigen + 0x08);
00663                ec_slave[cnt].EoEdetails = ec_siigetbyte(cnt, ssigen + 0x09);
00664                ec_slave[cnt].SoEdetails = ec_siigetbyte(cnt, ssigen + 0x0a);
00665                if((ec_siigetbyte(cnt, ssigen + 0x0d) & 0x02) > 0)
00666                {
00667                   ec_slave[cnt].blockLRW = 1;
00668                   ec_slave[0].blockLRW++;
00669                }
00670                ec_slave[cnt].Ebuscurrent = ec_siigetbyte(cnt, ssigen + 0x0e);
00671                ec_slave[cnt].Ebuscurrent += ec_siigetbyte(cnt, ssigen + 0x0f) << 8;
00672                ec_slave[0].Ebuscurrent += ec_slave[cnt].Ebuscurrent;
00673             }
00674             printf(" CoE details: %2.2x FoE details: %2.2x EoE details: %2.2x SoE details: %2.2x\n",
00675                     ec_slave[cnt].CoEdetails, ec_slave[cnt].FoEdetails, ec_slave[cnt].EoEdetails, ec_slave[cnt].SoEdetails);
00676             printf(" Ebus current: %d[mA]\n only LRD/LWR:%d\n",
00677                     ec_slave[cnt].Ebuscurrent, ec_slave[cnt].blockLRW);
00678                     
00679             if ((ec_slave[cnt].mbx_proto & ECT_MBXPROT_COE) && printSDO)
00680                 si_sdo(cnt);
00681                     
00682             if(printMAP)
00683             {
00684                 if (ec_slave[cnt].mbx_proto & ECT_MBXPROT_COE)   
00685                     si_map_sdo(cnt);
00686                 else
00687                     si_map_sii(cnt);
00688             }
00689         }       
00690         return 1;
00691     }
00692     
00693     else
00694     {   
00695     //  ec_close();     //******// 
00696         
00697         return 0;                                           // no slaves found
00698     }   
00699 }
00700 
00701 
00702 
00703 
00704 
00705