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
00030
00031
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, <);
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);
00225 eepctl = 0;
00226 wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET);
00227
00228 estat = 0x0000;
00229 aiadr = 1 - slave;
00230 wkc=ec_APRD(aiadr, ECT_REG_EEPSTAT, sizeof(estat), &estat, EC_TIMEOUTRET);
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);
00278 eepctl = 0;
00279 wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET);
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);
00312 eepctl = 0;
00313 wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET);
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
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);
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);
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);
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) )
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
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
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 }