eepromtool.c
Go to the documentation of this file.
00001 
00017 #include <stdio.h>
00018 #include <stdlib.h>
00019 #include <string.h>
00020 #include <sys/time.h>
00021 #include <unistd.h>
00022 #include <time.h>
00023 
00024 #include "ethercat_soem/ethercattype.h"
00025 #include "ethercat_soem/nicdrv.h"
00026 #include "ethercat_soem/ethercatbase.h"
00027 #include "ethercat_soem/ethercatmain.h"
00028 #include "ethercat_soem/ethercatcoe.h"
00029 //#include "ethercat_soem/ethercatfoe.h"
00030 //#include "ethercat_soem/ethercatconfig.h"
00031 //#include "ethercat_soem/ethercatprint.h"
00032 
00033 #define MAXBUF 32768
00034 #define STDBUF 2048
00035 #define MINBUF 128
00036 #define CRCBUF 14
00037 
00038 #define MODE_NONE         0
00039 #define MODE_READBIN      1
00040 #define MODE_READINTEL    2
00041 #define MODE_WRITEBIN     3
00042 #define MODE_WRITEINTEL   4
00043 #define MODE_WRITEALIAS   5
00044 #define MODE_INFO         6
00045 
00046 #define MAXSLENGTH        256
00047 
00048 uint8 ebuf[MAXBUF];
00049 uint8 ob;
00050 uint16 ow;
00051 int os;
00052 int slave;
00053 int alias;
00054 struct timeval tstart,tend, tdif;
00055 int wkc;
00056 int mode;
00057 char sline[MAXSLENGTH];
00058 
00059 #define IHEXLENGTH 0x20
00060 
00061 void calc_crc(uint8 *crc, uint8 b)
00062 {
00063    int j;
00064    *crc ^= b;
00065    for(j = 0; j <= 7 ; j++ )
00066    {
00067      if(*crc & 0x80)
00068         *crc = (*crc << 1) ^ 0x07;
00069      else
00070         *crc = (*crc << 1);
00071    }  
00072 }
00073 
00074 uint16 SIIcrc(uint8 *buf)
00075 {
00076    int i; 
00077    uint8 crc;
00078     
00079    crc = 0xff; 
00080    for( i = 0 ; i <= 13 ; i++ )
00081    {
00082       calc_crc(&crc , *(buf++));  
00083    } 
00084    return (uint16)crc;
00085 }
00086 
00087 int input_bin(char *fname, int *length)
00088 {
00089    FILE *fp;
00090  
00091    int cc = 0, c;
00092 
00093    fp = fopen(fname, "rb");
00094    if(fp == NULL) 
00095       return 0;
00096    while (((c = fgetc(fp)) != EOF) && (cc < MAXBUF))
00097       ebuf[cc++] = (uint8)c;
00098    *length = cc;
00099    fclose(fp);
00100    
00101    return 1;
00102 }
00103 
00104 int input_intelhex(char *fname, int *start, int *length)
00105 {
00106    FILE *fp;
00107  
00108    int c, sc, retval = 1;
00109    int ll, ladr, lt, sn, i, lval;
00110    int hstart, hlength, sum;
00111 
00112    fp = fopen(fname, "r");
00113    if(fp == NULL) 
00114       return 0;
00115    hstart = MAXBUF;
00116    hlength = 0;
00117    sum = 0;
00118    do
00119    {
00120       memset(sline, 0x00, MAXSLENGTH);
00121       sc = 0;
00122       while (((c = fgetc(fp)) != EOF) && (c != 0x0A) && (sc < (MAXSLENGTH -1)))
00123          sline[sc++] = (uint8)c;
00124       if ((c != EOF) && ((sc < 11) || (sline[0] != ':')))
00125       {
00126          c = EOF;
00127          retval = 0;
00128          printf("Invalid Intel Hex format.\n");
00129       }
00130       if (c != EOF)
00131       {
00132          sn = sscanf(sline , ":%2x%4x%2x", &ll, &ladr, &lt);
00133          if ((sn == 3) && ((ladr + ll) <= MAXBUF) && (lt == 0))
00134          {
00135             sum = ll + (ladr >> 8) + (ladr & 0xff) + lt;
00136             if(ladr < hstart) hstart = ladr;
00137             for(i = 0; i < ll ; i++)
00138             {
00139                sn = sscanf(&sline[9 + (i << 1)], "%2x", &lval);
00140                ebuf[ladr + i] = (uint8)lval;
00141                sum += (uint8)lval;
00142             }
00143             if(((ladr + ll) - hstart) > hlength)
00144                hlength = (ladr + ll) - hstart;
00145             sum = (0x100 - sum) & 0xff;
00146             sn = sscanf(&sline[9 + (i << 1)], "%2x", &lval);
00147             if (!sn || ((sum - lval) != 0))
00148             {
00149                c = EOF;
00150                retval = 0;
00151                printf("Invalid checksum.\n");
00152             }
00153          }
00154       }      
00155    }
00156    while (c != EOF);
00157    if (retval)
00158    {
00159       *length = hlength;
00160       *start = hstart;
00161    }
00162    fclose(fp);
00163    
00164    return retval;
00165 }
00166 
00167 int output_bin(char *fname, int length)
00168 {
00169    FILE *fp;
00170  
00171    int cc;
00172 
00173    fp = fopen(fname, "wb");
00174    if(fp == NULL) 
00175       return 0;
00176    for (cc = 0 ; cc < length ; cc++)
00177       fputc( ebuf[cc], fp);
00178    fclose(fp);
00179    
00180    return 1;
00181 }
00182 
00183 int output_intelhex(char *fname, int length)
00184 {
00185    FILE *fp;
00186  
00187    int cc = 0, ll, sum, i;
00188 
00189    fp = fopen(fname, "w");
00190    if(fp == NULL) 
00191       return 0;
00192    while (cc < length)
00193    {
00194       ll = length - cc;
00195       if (ll > IHEXLENGTH) ll = IHEXLENGTH;
00196       sum = ll + (cc >> 8) + (cc & 0xff);
00197       fprintf(fp, ":%2.2X%4.4X00", ll, cc);
00198       for (i = 0; i < ll; i++)
00199       {
00200          fprintf(fp, "%2.2X", ebuf[cc + i]);
00201          sum += ebuf[cc + i];
00202       }
00203       fprintf(fp, "%2.2X\n", (0x100 - sum) & 0xff);
00204       cc += ll;
00205    }
00206    fprintf(fp, ":00000001FF\n");   
00207    fclose(fp);
00208    
00209    return 1;
00210 }
00211 
00212 int eeprom_read(int slave, int start, int length)
00213 {
00214    int i, wkc, ainc = 4;
00215    uint16 estat, aiadr;
00216    uint32 b4;
00217    uint64 b8;
00218    uint8 eepctl;
00219    
00220    if((ec_slavecount >= slave) && (slave > 0) && ((start + length) <= MAXBUF))
00221    {
00222       aiadr = 1 - slave;
00223       eepctl = 2;
00224       wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET); /* force Eeprom from PDI */
00225       eepctl = 0;
00226       wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET); /* set Eeprom to master */
00227 
00228       estat = 0x0000;
00229       aiadr = 1 - slave;
00230       wkc=ec_APRD(aiadr, ECT_REG_EEPSTAT, sizeof(estat), &estat, EC_TIMEOUTRET); /* read eeprom status */
00231       estat = etohs(estat);
00232       if (estat & EC_ESTAT_R64)
00233       {
00234          ainc = 8;
00235          for (i = start ; i < (start + length) ; i+=ainc)
00236          {
00237             b8 = ec_readeepromAP(aiadr, i >> 1 , EC_TIMEOUTEEP);
00238             ebuf[i] = b8;
00239             ebuf[i+1] = b8 >> 8;
00240             ebuf[i+2] = b8 >> 16;
00241             ebuf[i+3] = b8 >> 24;
00242             ebuf[i+4] = b8 >> 32;
00243             ebuf[i+5] = b8 >> 40;
00244             ebuf[i+6] = b8 >> 48;
00245             ebuf[i+7] = b8 >> 56;
00246          }
00247       }
00248       else
00249       {
00250          for (i = start ; i < (start + length) ; i+=ainc)
00251          {
00252             b4 = ec_readeepromAP(aiadr, i >> 1 , EC_TIMEOUTEEP);
00253             ebuf[i] = b4;
00254             ebuf[i+1] = b4 >> 8;
00255             ebuf[i+2] = b4 >> 16;
00256             ebuf[i+3] = b4 >> 24;
00257          }
00258       }
00259       
00260       return 1;
00261    }
00262    
00263    return 0;
00264 }
00265 
00266 int eeprom_write(int slave, int start, int length)
00267 {
00268    int i, wkc, dc = 0;
00269    uint16 aiadr, *wbuf;
00270    uint8 eepctl;
00271    int ret;
00272    
00273    if((ec_slavecount >= slave) && (slave > 0) && ((start + length) <= MAXBUF))
00274    {
00275       aiadr = 1 - slave;
00276       eepctl = 2;
00277       wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET); /* force Eeprom from PDI */
00278       eepctl = 0;
00279       wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET); /* set Eeprom to master */
00280 
00281       aiadr = 1 - slave;
00282       wbuf = (uint16 *)&ebuf[0];
00283       for (i = start ; i < (start + length) ; i+=2)
00284       {
00285          ret = ec_writeeepromAP(aiadr, i >> 1 , *(wbuf + (i >> 1)), EC_TIMEOUTEEP);
00286          if (++dc >= 100)
00287          {
00288             dc = 0;
00289             printf(".");
00290             fflush(stdout);
00291          }
00292       }
00293       
00294       return 1;
00295    }
00296    
00297    return 0;
00298 }
00299 
00300 int eeprom_writealias(int slave, int alias, uint16 crc)
00301 {
00302    int wkc;
00303    uint16 aiadr;
00304    uint8 eepctl;
00305    int ret;
00306    
00307    if((ec_slavecount >= slave) && (slave > 0) && (alias <= 0xffff))
00308    {
00309       aiadr = 1 - slave;
00310       eepctl = 2;
00311       wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET); /* force Eeprom from PDI */
00312       eepctl = 0;
00313       wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET); /* set Eeprom to master */
00314 
00315       ret = ec_writeeepromAP(aiadr, 0x04 , alias, EC_TIMEOUTEEP);
00316       if (ret)
00317         ret = ec_writeeepromAP(aiadr, 0x07 , crc, EC_TIMEOUTEEP);
00318         
00319       return ret;
00320    }
00321    
00322    return 0;
00323 }
00324 
00325 void eepromtool(char *ifname, int slave, int mode, char *fname)
00326 {
00327    int w, rc = 0, estart, esize;
00328    uint16 *wbuf;
00329    
00330    /* initialise SOEM, bind socket to ifname */
00331    if (ec_init(ifname))
00332    {   
00333       printf("ec_init on %s succeeded.\n",ifname);
00334 
00335       w = 0x0000;
00336        wkc = ec_BRD(0x0000, ECT_REG_TYPE, sizeof(w), &w, EC_TIMEOUTSAFE);      /* detect number of slaves */
00337        if (wkc > 0)
00338        {
00339          ec_slavecount = wkc;
00340 
00341          printf("%d slaves found.\n",ec_slavecount);
00342          if((ec_slavecount >= slave) && (slave > 0))
00343          {
00344             if ((mode == MODE_INFO) || (mode == MODE_READBIN) || (mode == MODE_READINTEL))
00345             {
00346                rc =  gettimeofday(&tstart, NULL);
00347                eeprom_read(slave, 0x0000, MINBUF); // read first 128 bytes
00348 
00349                wbuf = (uint16 *)&ebuf[0];
00350                printf("Slave %d data\n", slave);
00351                printf(" PDI Control      : %4.4X\n",*(wbuf + 0x00));
00352                printf(" PDI Config       : %4.4X\n",*(wbuf + 0x01));
00353                printf(" Config Alias     : %4.4X\n",*(wbuf + 0x04));
00354                printf(" Checksum         : %4.4X\n",*(wbuf + 0x07));
00355                printf("   calculated     : %4.4X\n",SIIcrc(&ebuf[0])); 
00356                printf(" Vendor ID        : %8.8X\n",*(uint32 *)(wbuf + 0x08));
00357                printf(" Product Code     : %8.8X\n",*(uint32 *)(wbuf + 0x0A));
00358                printf(" Revision Number  : %8.8X\n",*(uint32 *)(wbuf + 0x0C));
00359                printf(" Serial Number    : %8.8X\n",*(uint32 *)(wbuf + 0x0E));
00360                printf(" Mailbox Protocol : %4.4X\n",*(wbuf + 0x1C));
00361                esize = (*(wbuf + 0x3E) + 1) * 128;
00362                if (esize > MAXBUF) esize = MAXBUF;
00363                printf(" Size             : %4.4X = %d bytes\n",*(wbuf + 0x3E), esize);
00364                printf(" Version          : %4.4X\n",*(wbuf + 0x3F));
00365             }
00366             if ((mode == MODE_READBIN) || (mode == MODE_READINTEL))
00367             {
00368                if (esize > MINBUF)
00369                   eeprom_read(slave, MINBUF, esize - MINBUF); // read reminder
00370 
00371                rc =  gettimeofday(&tend, NULL);
00372                timersub(&tend, &tstart, &tdif);
00373                if (mode == MODE_READINTEL) output_intelhex(fname, esize);
00374                if (mode == MODE_READBIN)   output_bin(fname, esize);
00375 
00376                printf("\nTotal EEPROM read time :%ldms\n", (tdif.tv_usec+(tdif.tv_sec*1000000L)) / 1000);
00377             }
00378             if ((mode == MODE_WRITEBIN) || (mode == MODE_WRITEINTEL))
00379             {
00380                estart = 0;
00381                if (mode == MODE_WRITEINTEL) rc = input_intelhex(fname, &estart, &esize);
00382                if (mode == MODE_WRITEBIN)   rc = input_bin(fname, &esize);
00383 
00384                if (rc > 0)
00385                {               
00386                   wbuf = (uint16 *)&ebuf[0];
00387                   printf("Slave %d\n", slave);
00388                   printf(" Vendor ID        : %8.8X\n",*(uint32 *)(wbuf + 0x08));
00389                   printf(" Product Code     : %8.8X\n",*(uint32 *)(wbuf + 0x0A));
00390                   printf(" Revision Number  : %8.8X\n",*(uint32 *)(wbuf + 0x0C));
00391                   printf(" Serial Number    : %8.8X\n",*(uint32 *)(wbuf + 0x0E));
00392 
00393                   printf("Busy");
00394                   fflush(stdout);
00395                   rc =  gettimeofday(&tstart, NULL);
00396                   eeprom_write(slave, estart, esize);
00397                   rc =  gettimeofday(&tend, NULL);               
00398                   timersub(&tend, &tstart, &tdif);
00399 
00400                   printf("\nTotal EEPROM write time :%ldms\n", (tdif.tv_usec+(tdif.tv_sec*1000000L)) / 1000);
00401                }
00402                else
00403                   printf("Error reading file, abort.\n"); 
00404             }
00405             if (mode == MODE_WRITEALIAS)
00406             {
00407                if( eeprom_read(slave, 0x0000, CRCBUF) ) // read first 14 bytes
00408                {
00409                   wbuf = (uint16 *)&ebuf[0];
00410                   *(wbuf + 0x04) = alias;  
00411                   if(eeprom_writealias(slave, alias, SIIcrc(&ebuf[0])))
00412                   {
00413                      printf("Alias %4.4X written successfully to slave %d\n", alias, slave);
00414                   } 
00415                   else
00416                   {
00417                      printf("Alias not written\n");
00418                   }
00419                }  
00420                else
00421                {
00422                   printf("Could not read slave EEPROM");    
00423                }
00424             }
00425          }
00426          else
00427          {
00428             printf("Slave number outside range.\n");
00429          }
00430       }
00431       else
00432       {
00433          printf("No slaves found!\n");
00434       }
00435       printf("End, close socket\n");
00436       /* stop SOEM, close socket */
00437       ec_close();
00438    }
00439    else
00440    {
00441       printf("No socket connection on %s\nExcecute as root\n",ifname);
00442    }
00443 }   
00444 
00445 int main(int argc, char *argv[])
00446 {
00447    printf("SOEM (Simple Open EtherCAT Master)\nEEPROM tool\n");
00448 
00449    mode = MODE_NONE;
00450    if (argc > 3)
00451    {      
00452       slave = atoi(argv[2]);
00453       if ((strncmp(argv[3], "-i", sizeof("-i")) == 0))   mode = MODE_INFO;
00454       if (argc > 4)
00455       {
00456          if ((strncmp(argv[3], "-r", sizeof("-r")) == 0))   mode = MODE_READBIN;
00457          if ((strncmp(argv[3], "-ri", sizeof("-ri")) == 0)) mode = MODE_READINTEL;
00458          if ((strncmp(argv[3], "-w", sizeof("-w")) == 0))   mode = MODE_WRITEBIN;
00459          if ((strncmp(argv[3], "-wi", sizeof("-wi")) == 0)) mode = MODE_WRITEINTEL;
00460          if ((strncmp(argv[3], "-walias", sizeof("-walias")) == 0))
00461          {
00462             mode = MODE_WRITEALIAS;
00463             alias = atoi(argv[4]);
00464          }
00465       }
00466       /* start tool */
00467       eepromtool(argv[1],slave,mode,argv[4]);
00468    }
00469    else
00470    {
00471       printf("Usage: eepromtool ifname slave OPTION fname|alias\n");
00472       printf("ifname = eth0 for example\n");
00473       printf("slave = slave number in EtherCAT order 1..n\n");
00474       printf("    -i      display EEPROM information\n");
00475       printf("    -walias write slave alias\n");
00476       printf("    -r      read EEPROM, output binary format\n");
00477       printf("    -ri     read EEPROM, output Intel Hex format\n");
00478       printf("    -w      write EEPROM, input binary format\n");
00479       printf("    -wi     write EEPROM, input Intel Hex format\n");
00480    }   
00481    
00482    printf("End program\n");
00483    
00484    return (0);
00485 }


ethercat_soem
Author(s): Arthur Ketels, M.J.G. van de Molengraft
autogenerated on Wed Aug 26 2015 11:32:40