linux/eepromtool/eepromtool.c
Go to the documentation of this file.
1 
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <sys/time.h>
21 #include <unistd.h>
22 #include <time.h>
23 
24 #include "ethercattype.h"
25 #include "nicdrv.h"
26 #include "ethercatbase.h"
27 #include "ethercatmain.h"
28 #include "ethercatcoe.h"
29 //#include "ethercatfoe.h"
30 //#include "ethercatconfig.h"
31 //#include "ethercatprint.h"
32 
33 #define MAXBUF 32768
34 #define STDBUF 2048
35 #define MINBUF 128
36 #define CRCBUF 14
37 
38 #define MODE_NONE 0
39 #define MODE_READBIN 1
40 #define MODE_READINTEL 2
41 #define MODE_WRITEBIN 3
42 #define MODE_WRITEINTEL 4
43 #define MODE_WRITEALIAS 5
44 #define MODE_INFO 6
45 
46 #define MAXSLENGTH 256
47 
51 int os;
52 int slave;
53 int alias;
54 struct timeval tstart,tend, tdif;
55 int wkc;
56 int mode;
58 
59 #define IHEXLENGTH 0x20
60 
61 void calc_crc(uint8 *crc, uint8 b)
62 {
63  int j;
64  *crc ^= b;
65  for(j = 0; j <= 7 ; j++ )
66  {
67  if(*crc & 0x80)
68  *crc = (*crc << 1) ^ 0x07;
69  else
70  *crc = (*crc << 1);
71  }
72 }
73 
75 {
76  int i;
77  uint8 crc;
78 
79  crc = 0xff;
80  for( i = 0 ; i <= 13 ; i++ )
81  {
82  calc_crc(&crc , *(buf++));
83  }
84  return (uint16)crc;
85 }
86 
87 int input_bin(char *fname, int *length)
88 {
89  FILE *fp;
90 
91  int cc = 0, c;
92 
93  fp = fopen(fname, "rb");
94  if(fp == NULL)
95  return 0;
96  while (((c = fgetc(fp)) != EOF) && (cc < MAXBUF))
97  ebuf[cc++] = (uint8)c;
98  *length = cc;
99  fclose(fp);
100 
101  return 1;
102 }
103 
104 int input_intelhex(char *fname, int *start, int *length)
105 {
106  FILE *fp;
107 
108  int c, sc, retval = 1;
109  int ll, ladr, lt, sn, i, lval;
110  int hstart, hlength, sum;
111 
112  fp = fopen(fname, "r");
113  if(fp == NULL)
114  return 0;
115  hstart = MAXBUF;
116  hlength = 0;
117  sum = 0;
118  do
119  {
120  memset(sline, 0x00, MAXSLENGTH);
121  sc = 0;
122  while (((c = fgetc(fp)) != EOF) && (c != 0x0A) && (sc < (MAXSLENGTH -1)))
123  sline[sc++] = (uint8)c;
124  if ((c != EOF) && ((sc < 11) || (sline[0] != ':')))
125  {
126  c = EOF;
127  retval = 0;
128  printf("Invalid Intel Hex format.\n");
129  }
130  if (c != EOF)
131  {
132  sn = sscanf(sline , ":%2x%4x%2x", &ll, &ladr, &lt);
133  if ((sn == 3) && ((ladr + ll) <= MAXBUF) && (lt == 0))
134  {
135  sum = ll + (ladr >> 8) + (ladr & 0xff) + lt;
136  if(ladr < hstart) hstart = ladr;
137  for(i = 0; i < ll ; i++)
138  {
139  sn = sscanf(&sline[9 + (i << 1)], "%2x", &lval);
140  ebuf[ladr + i] = (uint8)lval;
141  sum += (uint8)lval;
142  }
143  if(((ladr + ll) - hstart) > hlength)
144  hlength = (ladr + ll) - hstart;
145  sum = (0x100 - sum) & 0xff;
146  sn = sscanf(&sline[9 + (i << 1)], "%2x", &lval);
147  if (!sn || ((sum - lval) != 0))
148  {
149  c = EOF;
150  retval = 0;
151  printf("Invalid checksum.\n");
152  }
153  }
154  }
155  }
156  while (c != EOF);
157  if (retval)
158  {
159  *length = hlength;
160  *start = hstart;
161  }
162  fclose(fp);
163 
164  return retval;
165 }
166 
167 int output_bin(char *fname, int length)
168 {
169  FILE *fp;
170 
171  int cc;
172 
173  fp = fopen(fname, "wb");
174  if(fp == NULL)
175  return 0;
176  for (cc = 0 ; cc < length ; cc++)
177  fputc( ebuf[cc], fp);
178  fclose(fp);
179 
180  return 1;
181 }
182 
183 int output_intelhex(char *fname, int length)
184 {
185  FILE *fp;
186 
187  int cc = 0, ll, sum, i;
188 
189  fp = fopen(fname, "w");
190  if(fp == NULL)
191  return 0;
192  while (cc < length)
193  {
194  ll = length - cc;
195  if (ll > IHEXLENGTH) ll = IHEXLENGTH;
196  sum = ll + (cc >> 8) + (cc & 0xff);
197  fprintf(fp, ":%2.2X%4.4X00", ll, cc);
198  for (i = 0; i < ll; i++)
199  {
200  fprintf(fp, "%2.2X", ebuf[cc + i]);
201  sum += ebuf[cc + i];
202  }
203  fprintf(fp, "%2.2X\n", (0x100 - sum) & 0xff);
204  cc += ll;
205  }
206  fprintf(fp, ":00000001FF\n");
207  fclose(fp);
208 
209  return 1;
210 }
211 
212 int eeprom_read(int slave, int start, int length)
213 {
214  int i, wkc, ainc = 4;
215  uint16 estat, aiadr;
216  uint32 b4;
217  uint64 b8;
218  uint8 eepctl;
219 
220  if((ec_slavecount >= slave) && (slave > 0) && ((start + length) <= MAXBUF))
221  {
222  aiadr = 1 - slave;
223  eepctl = 2;
224  wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET); /* force Eeprom from PDI */
225  eepctl = 0;
226  wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET); /* set Eeprom to master */
227 
228  estat = 0x0000;
229  aiadr = 1 - slave;
230  wkc=ec_APRD(aiadr, ECT_REG_EEPSTAT, sizeof(estat), &estat, EC_TIMEOUTRET); /* read eeprom status */
231  estat = etohs(estat);
232  if (estat & EC_ESTAT_R64)
233  {
234  ainc = 8;
235  for (i = start ; i < (start + length) ; i+=ainc)
236  {
237  b8 = ec_readeepromAP(aiadr, i >> 1 , EC_TIMEOUTEEP);
238  ebuf[i] = b8;
239  ebuf[i+1] = b8 >> 8;
240  ebuf[i+2] = b8 >> 16;
241  ebuf[i+3] = b8 >> 24;
242  ebuf[i+4] = b8 >> 32;
243  ebuf[i+5] = b8 >> 40;
244  ebuf[i+6] = b8 >> 48;
245  ebuf[i+7] = b8 >> 56;
246  }
247  }
248  else
249  {
250  for (i = start ; i < (start + length) ; i+=ainc)
251  {
252  b4 = ec_readeepromAP(aiadr, i >> 1 , EC_TIMEOUTEEP);
253  ebuf[i] = b4;
254  ebuf[i+1] = b4 >> 8;
255  ebuf[i+2] = b4 >> 16;
256  ebuf[i+3] = b4 >> 24;
257  }
258  }
259 
260  return 1;
261  }
262 
263  return 0;
264 }
265 
266 int eeprom_write(int slave, int start, int length)
267 {
268  int i, wkc, dc = 0;
269  uint16 aiadr, *wbuf;
270  uint8 eepctl;
271  int ret;
272 
273  if((ec_slavecount >= slave) && (slave > 0) && ((start + length) <= MAXBUF))
274  {
275  aiadr = 1 - slave;
276  eepctl = 2;
277  wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET); /* force Eeprom from PDI */
278  eepctl = 0;
279  wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET); /* set Eeprom to master */
280 
281  aiadr = 1 - slave;
282  wbuf = (uint16 *)&ebuf[0];
283  for (i = start ; i < (start + length) ; i+=2)
284  {
285  ret = ec_writeeepromAP(aiadr, i >> 1 , *(wbuf + (i >> 1)), EC_TIMEOUTEEP);
286  if (++dc >= 100)
287  {
288  dc = 0;
289  printf(".");
290  fflush(stdout);
291  }
292  }
293 
294  return 1;
295  }
296 
297  return 0;
298 }
299 
301 {
302  int wkc;
303  uint16 aiadr;
304  uint8 eepctl;
305  int ret;
306 
307  if((ec_slavecount >= slave) && (slave > 0) && (alias <= 0xffff))
308  {
309  aiadr = 1 - slave;
310  eepctl = 2;
311  wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET); /* force Eeprom from PDI */
312  eepctl = 0;
313  wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET); /* set Eeprom to master */
314 
315  ret = ec_writeeepromAP(aiadr, 0x04 , alias, EC_TIMEOUTEEP);
316  if (ret)
317  ret = ec_writeeepromAP(aiadr, 0x07 , crc, EC_TIMEOUTEEP);
318 
319  return ret;
320  }
321 
322  return 0;
323 }
324 
325 void eepromtool(char *ifname, int slave, int mode, char *fname)
326 {
327  int w, rc = 0, estart, esize;
328  uint16 *wbuf;
329 
330  /* initialise SOEM, bind socket to ifname */
331  if (ec_init(ifname))
332  {
333  printf("ec_init on %s succeeded.\n",ifname);
334 
335  w = 0x0000;
336  wkc = ec_BRD(0x0000, ECT_REG_TYPE, sizeof(w), &w, EC_TIMEOUTSAFE); /* detect number of slaves */
337  if (wkc > 0)
338  {
339  ec_slavecount = wkc;
340 
341  printf("%d slaves found.\n",ec_slavecount);
342  if((ec_slavecount >= slave) && (slave > 0))
343  {
344  if ((mode == MODE_INFO) || (mode == MODE_READBIN) || (mode == MODE_READINTEL))
345  {
346  rc = gettimeofday(&tstart, NULL);
347  eeprom_read(slave, 0x0000, MINBUF); // read first 128 bytes
348 
349  wbuf = (uint16 *)&ebuf[0];
350  printf("Slave %d data\n", slave);
351  printf(" PDI Control : %4.4X\n",*(wbuf + 0x00));
352  printf(" PDI Config : %4.4X\n",*(wbuf + 0x01));
353  printf(" Config Alias : %4.4X\n",*(wbuf + 0x04));
354  printf(" Checksum : %4.4X\n",*(wbuf + 0x07));
355  printf(" calculated : %4.4X\n",SIIcrc(&ebuf[0]));
356  printf(" Vendor ID : %8.8X\n",*(uint32 *)(wbuf + 0x08));
357  printf(" Product Code : %8.8X\n",*(uint32 *)(wbuf + 0x0A));
358  printf(" Revision Number : %8.8X\n",*(uint32 *)(wbuf + 0x0C));
359  printf(" Serial Number : %8.8X\n",*(uint32 *)(wbuf + 0x0E));
360  printf(" Mailbox Protocol : %4.4X\n",*(wbuf + 0x1C));
361  esize = (*(wbuf + 0x3E) + 1) * 128;
362  if (esize > MAXBUF) esize = MAXBUF;
363  printf(" Size : %4.4X = %d bytes\n",*(wbuf + 0x3E), esize);
364  printf(" Version : %4.4X\n",*(wbuf + 0x3F));
365  }
366  if ((mode == MODE_READBIN) || (mode == MODE_READINTEL))
367  {
368  if (esize > MINBUF)
369  eeprom_read(slave, MINBUF, esize - MINBUF); // read reminder
370 
371  rc = gettimeofday(&tend, NULL);
372  timersub(&tend, &tstart, &tdif);
373  if (mode == MODE_READINTEL) output_intelhex(fname, esize);
374  if (mode == MODE_READBIN) output_bin(fname, esize);
375 
376  printf("\nTotal EEPROM read time :%ldms\n", (tdif.tv_usec+(tdif.tv_sec*1000000L)) / 1000);
377  }
378  if ((mode == MODE_WRITEBIN) || (mode == MODE_WRITEINTEL))
379  {
380  estart = 0;
381  if (mode == MODE_WRITEINTEL) rc = input_intelhex(fname, &estart, &esize);
382  if (mode == MODE_WRITEBIN) rc = input_bin(fname, &esize);
383 
384  if (rc > 0)
385  {
386  wbuf = (uint16 *)&ebuf[0];
387  printf("Slave %d\n", slave);
388  printf(" Vendor ID : %8.8X\n",*(uint32 *)(wbuf + 0x08));
389  printf(" Product Code : %8.8X\n",*(uint32 *)(wbuf + 0x0A));
390  printf(" Revision Number : %8.8X\n",*(uint32 *)(wbuf + 0x0C));
391  printf(" Serial Number : %8.8X\n",*(uint32 *)(wbuf + 0x0E));
392 
393  printf("Busy");
394  fflush(stdout);
395  rc = gettimeofday(&tstart, NULL);
396  eeprom_write(slave, estart, esize);
397  rc = gettimeofday(&tend, NULL);
398  timersub(&tend, &tstart, &tdif);
399 
400  printf("\nTotal EEPROM write time :%ldms\n", (tdif.tv_usec+(tdif.tv_sec*1000000L)) / 1000);
401  }
402  else
403  printf("Error reading file, abort.\n");
404  }
405  if (mode == MODE_WRITEALIAS)
406  {
407  if( eeprom_read(slave, 0x0000, CRCBUF) ) // read first 14 bytes
408  {
409  wbuf = (uint16 *)&ebuf[0];
410  *(wbuf + 0x04) = alias;
411  if(eeprom_writealias(slave, alias, SIIcrc(&ebuf[0])))
412  {
413  printf("Alias %4.4X written successfully to slave %d\n", alias, slave);
414  }
415  else
416  {
417  printf("Alias not written\n");
418  }
419  }
420  else
421  {
422  printf("Could not read slave EEPROM");
423  }
424  }
425  }
426  else
427  {
428  printf("Slave number outside range.\n");
429  }
430  }
431  else
432  {
433  printf("No slaves found!\n");
434  }
435  printf("End, close socket\n");
436  /* stop SOEM, close socket */
437  ec_close();
438  }
439  else
440  {
441  printf("No socket connection on %s\nExcecute as root\n",ifname);
442  }
443 }
444 
445 int main(int argc, char *argv[])
446 {
447  printf("SOEM (Simple Open EtherCAT Master)\nEEPROM tool\n");
448 
449  mode = MODE_NONE;
450  if (argc > 3)
451  {
452  slave = atoi(argv[2]);
453  if ((strncmp(argv[3], "-i", sizeof("-i")) == 0)) mode = MODE_INFO;
454  if (argc > 4)
455  {
456  if ((strncmp(argv[3], "-r", sizeof("-r")) == 0)) mode = MODE_READBIN;
457  if ((strncmp(argv[3], "-ri", sizeof("-ri")) == 0)) mode = MODE_READINTEL;
458  if ((strncmp(argv[3], "-w", sizeof("-w")) == 0)) mode = MODE_WRITEBIN;
459  if ((strncmp(argv[3], "-wi", sizeof("-wi")) == 0)) mode = MODE_WRITEINTEL;
460  if ((strncmp(argv[3], "-walias", sizeof("-walias")) == 0))
461  {
463  alias = atoi(argv[4]);
464  }
465  }
466  /* start tool */
467  eepromtool(argv[1],slave,mode,argv[4]);
468  }
469  else
470  {
471  printf("Usage: eepromtool ifname slave OPTION fname|alias\n");
472  printf("ifname = eth0 for example\n");
473  printf("slave = slave number in EtherCAT order 1..n\n");
474  printf(" -i display EEPROM information\n");
475  printf(" -walias write slave alias\n");
476  printf(" -r read EEPROM, output binary format\n");
477  printf(" -ri read EEPROM, output Intel Hex format\n");
478  printf(" -w write EEPROM, input binary format\n");
479  printf(" -wi write EEPROM, input Intel Hex format\n");
480  }
481 
482  printf("End program\n");
483 
484  return (0);
485 }
int eeprom_read(int slave, int start, int length)
uint16 SIIcrc(uint8 *buf)
int eeprom_writealias(int slave, int alias, uint16 crc)
int ec_writeeepromAP(uint16 aiadr, uint16 eeproma, uint16 data, int timeout)
int ec_APWR(uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout)
Definition: ethercatbase.c:608
int ec_APRD(uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout)
Definition: ethercatbase.c:569
#define timersub(a, b, result)
Definition: rtk/osal.c:41
#define EC_TIMEOUTSAFE
Definition: ethercattype.h:94
#define IHEXLENGTH
uint8_t uint8
Definition: osal.h:33
int eeprom_write(int slave, int start, int length)
#define CRCBUF
struct timeval tstart tend tdif
uint16_t uint16
Definition: osal.h:34
#define MODE_INFO
General typedefs and defines for EtherCAT.
#define etohs(A)
Definition: ethercattype.h:550
Headerfile for ethercatcoe.c.
uint8 ebuf[MAXBUF]
#define MAXBUF
int input_intelhex(char *fname, int *start, int *length)
int ec_BRD(uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout)
Definition: ethercatbase.c:564
void eepromtool(char *ifname, int slave, int mode, char *fname)
int ec_init(char *ifname)
#define MODE_WRITEBIN
#define MODE_READINTEL
#define EC_TIMEOUTEEP
Definition: ethercattype.h:96
int output_bin(char *fname, int length)
#define MODE_NONE
uint64_t uint64
Definition: osal.h:37
#define MINBUF
#define MAXSLENGTH
#define EC_TIMEOUTRET
Definition: ethercattype.h:90
void calc_crc(uint8 *crc, uint8 b)
Headerfile for ethercatbase.c.
#define MODE_WRITEINTEL
int output_intelhex(char *fname, int length)
uint64 ec_readeepromAP(uint16 aiadr, uint16 eeproma, int timeout)
Headerfile for ethercatmain.c.
uint32_t uint32
Definition: osal.h:35
int input_bin(char *fname, int *length)
int main(int argc, char *argv[])
#define MODE_READBIN
int gettimeofday(struct timeval *tp, void *tzp)
Definition: rtk/osal.c:65
void ec_close(void)
int ainc
int ec_slavecount
Definition: ethercatmain.c:106
char sline[MAXSLENGTH]
#define EC_ESTAT_R64
Definition: ethercattype.h:293
#define MODE_WRITEALIAS


soem
Author(s): Arthur Ketels and M.J.G. van den Molengraft
autogenerated on Sat Jun 8 2019 18:02:16