win32/eepromtool/eepromtool.c
Go to the documentation of this file.
1 
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 
19 #include "ethercat.h"
20 
21 #define MAXBUF 32768
22 #define STDBUF 2048
23 #define MINBUF 128
24 
25 #define MODE_NONE 0
26 #define MODE_READBIN 1
27 #define MODE_READINTEL 2
28 #define MODE_WRITEBIN 3
29 #define MODE_WRITEINTEL 4
30 
31 #define MAXSLENGTH 256
32 
36 int os;
37 int slave;
39 int wkc;
40 int mode;
42 
43 #define IHEXLENGTH 0x20
44 
45 int input_bin(char *fname, int *length)
46 {
47  FILE *fp;
48 
49  int cc = 0, c;
50 
51  fp = fopen(fname, "rb");
52  if(fp == NULL)
53  return 0;
54  while (((c = fgetc(fp)) != EOF) && (cc < MAXBUF))
55  ebuf[cc++] = (uint8)c;
56  *length = cc;
57  fclose(fp);
58 
59  return 1;
60 }
61 
62 int input_intelhex(char *fname, int *start, int *length)
63 {
64  FILE *fp;
65 
66  int c, sc, retval = 1;
67  int ll, ladr, lt, sn, i, lval;
68  int hstart, hlength, sum;
69 
70  fp = fopen(fname, "r");
71  if(fp == NULL)
72  return 0;
73  hstart = MAXBUF;
74  hlength = 0;
75  sum = 0;
76  do
77  {
78  memset(sline, 0x00, MAXSLENGTH);
79  sc = 0;
80  while (((c = fgetc(fp)) != EOF) && (c != 0x0A) && (sc < (MAXSLENGTH -1)))
81  sline[sc++] = (uint8)c;
82  if ((c != EOF) && ((sc < 11) || (sline[0] != ':')))
83  {
84  c = EOF;
85  retval = 0;
86  printf("Invalid Intel Hex format.\n");
87  }
88  if (c != EOF)
89  {
90  sn = sscanf(sline , ":%2x%4x%2x", &ll, &ladr, &lt);
91  if ((sn == 3) && ((ladr + ll) <= MAXBUF) && (lt == 0))
92  {
93  sum = ll + (ladr >> 8) + (ladr & 0xff) + lt;
94  if(ladr < hstart) hstart = ladr;
95  for(i = 0; i < ll ; i++)
96  {
97  sn = sscanf(&sline[9 + (i << 1)], "%2x", &lval);
98  ebuf[ladr + i] = (uint8)lval;
99  sum += (uint8)lval;
100  }
101  if(((ladr + ll) - hstart) > hlength)
102  hlength = (ladr + ll) - hstart;
103  sum = (0x100 - sum) & 0xff;
104  sn = sscanf(&sline[9 + (i << 1)], "%2x", &lval);
105  if (!sn || ((sum - lval) != 0))
106  {
107  c = EOF;
108  retval = 0;
109  printf("Invalid checksum.\n");
110  }
111  }
112  }
113  }
114  while (c != EOF);
115  if (retval)
116  {
117  *length = hlength;
118  *start = hstart;
119  }
120  fclose(fp);
121 
122  return retval;
123 }
124 
125 int output_bin(char *fname, int length)
126 {
127  FILE *fp;
128 
129  int cc;
130 
131  fp = fopen(fname, "wb");
132  if(fp == NULL)
133  return 0;
134  for (cc = 0 ; cc < length ; cc++)
135  fputc( ebuf[cc], fp);
136  fclose(fp);
137 
138  return 1;
139 }
140 
141 int output_intelhex(char *fname, int length)
142 {
143  FILE *fp;
144 
145  int cc = 0, ll, sum, i;
146 
147  fp = fopen(fname, "w");
148  if(fp == NULL)
149  return 0;
150  while (cc < length)
151  {
152  ll = length - cc;
153  if (ll > IHEXLENGTH) ll = IHEXLENGTH;
154  sum = ll + (cc >> 8) + (cc & 0xff);
155  fprintf(fp, ":%2.2X%4.4X00", ll, cc);
156  for (i = 0; i < ll; i++)
157  {
158  fprintf(fp, "%2.2X", ebuf[cc + i]);
159  sum += ebuf[cc + i];
160  }
161  fprintf(fp, "%2.2X\n", (0x100 - sum) & 0xff);
162  cc += ll;
163  }
164  fprintf(fp, ":00000001FF\n");
165  fclose(fp);
166 
167  return 1;
168 }
169 
170 int eeprom_read(int slave, int start, int length)
171 {
172  int i, wkc, ainc = 4;
173  uint16 estat, aiadr;
174  uint32 b4;
175  uint64 b8;
176  uint8 eepctl;
177 
178  if((ec_slavecount >= slave) && (slave > 0) && ((start + length) <= MAXBUF))
179  {
180  aiadr = 1 - slave;
181  eepctl = 2;
182  wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET3); /* force Eeprom from PDI */
183  eepctl = 0;
184  wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET3); /* set Eeprom to master */
185 
186  estat = 0x0000;
187  aiadr = 1 - slave;
188  wkc=ec_APRD(aiadr, ECT_REG_EEPSTAT, sizeof(estat), &estat, EC_TIMEOUTRET3); /* read eeprom status */
189  estat = etohs(estat);
190  if (estat & EC_ESTAT_R64)
191  {
192  ainc = 8;
193  for (i = start ; i < (start + length) ; i+=ainc)
194  {
195  b8 = ec_readeepromAP(aiadr, i >> 1 , EC_TIMEOUTEEP);
196  ebuf[i] = (uint8) b8;
197  ebuf[i+1] = (uint8) (b8 >> 8);
198  ebuf[i+2] = (uint8) (b8 >> 16);
199  ebuf[i+3] = (uint8) (b8 >> 24);
200  ebuf[i+4] = (uint8) (b8 >> 32);
201  ebuf[i+5] = (uint8) (b8 >> 40);
202  ebuf[i+6] = (uint8) (b8 >> 48);
203  ebuf[i+7] = (uint8) (b8 >> 56);
204  }
205  }
206  else
207  {
208  for (i = start ; i < (start + length) ; i+=ainc)
209  {
210  b4 = (uint32)ec_readeepromAP(aiadr, i >> 1 , EC_TIMEOUTEEP);
211  ebuf[i] = (uint8) b4;
212  ebuf[i+1] = (uint8) (b4 >> 8);
213  ebuf[i+2] = (uint8) (b4 >> 16);
214  ebuf[i+3] = (uint8) (b4 >> 24);
215  }
216  }
217 
218  return 1;
219  }
220 
221  return 0;
222 }
223 
224 int eeprom_write(int slave, int start, int length)
225 {
226  int i, wkc, dc = 0;
227  uint16 aiadr, *wbuf;
228  uint8 eepctl;
229  int ret;
230 
231  if((ec_slavecount >= slave) && (slave > 0) && ((start + length) <= MAXBUF))
232  {
233  aiadr = 1 - slave;
234  eepctl = 2;
235  wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET3); /* force Eeprom from PDI */
236  eepctl = 0;
237  wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET3); /* set Eeprom to master */
238 
239  aiadr = 1 - slave;
240  wbuf = (uint16 *)&ebuf[0];
241  for (i = start ; i < (start + length) ; i+=2)
242  {
243  ret = ec_writeeepromAP(aiadr, i >> 1 , *(wbuf + (i >> 1)), EC_TIMEOUTEEP);
244  if (++dc >= 100)
245  {
246  dc = 0;
247  printf(".");
248  fflush(stdout);
249  }
250  }
251 
252  return 1;
253  }
254 
255  return 0;
256 }
257 
258 void eepromtool(char *ifname, int slave, int mode, char *fname)
259 {
260  int w, rc = 0, estart, esize;
261  uint16 *wbuf;
262 
263  /* initialise SOEM, bind socket to ifname */
264  if (ec_init(ifname))
265  {
266  printf("ec_init on %s succeeded.\n",ifname);
267 
268  w = 0x0000;
269  wkc = ec_BRD(0x0000, ECT_REG_TYPE, sizeof(w), &w, EC_TIMEOUTSAFE); /* detect number of slaves */
270  if (wkc > 0)
271  {
272  ec_slavecount = wkc;
273 
274  printf("%d slaves found.\n",ec_slavecount);
275  if((ec_slavecount >= slave) && (slave > 0))
276  {
277  if ((mode == MODE_READBIN) || (mode == MODE_READINTEL))
278  {
279  tstart = osal_current_time();
280  eeprom_read(slave, 0x0000, MINBUF); // read first 128 bytes
281 
282  wbuf = (uint16 *)&ebuf[0];
283  printf("Slave %d data\n", slave);
284  printf(" PDI Control : %4.4X\n",*(wbuf + 0x00));
285  printf(" PDI Config : %4.4X\n",*(wbuf + 0x01));
286  printf(" Config Alias : %4.4X\n",*(wbuf + 0x04));
287  printf(" Checksum : %4.4X\n",*(wbuf + 0x07));
288  printf(" Vendor ID : %8.8X\n",*(uint32 *)(wbuf + 0x08));
289  printf(" Product Code : %8.8X\n",*(uint32 *)(wbuf + 0x0A));
290  printf(" Revision Number : %8.8X\n",*(uint32 *)(wbuf + 0x0C));
291  printf(" Serial Number : %8.8X\n",*(uint32 *)(wbuf + 0x0E));
292  printf(" Mailbox Protocol : %4.4X\n",*(wbuf + 0x1C));
293  esize = (*(wbuf + 0x3E) + 1) * 128;
294  if (esize > MAXBUF) esize = MAXBUF;
295  printf(" Size : %4.4X = %d bytes\n",*(wbuf + 0x3E), esize);
296  printf(" Version : %4.4X\n",*(wbuf + 0x3F));
297 
298  if (esize > MINBUF)
299  eeprom_read(slave, MINBUF, esize - MINBUF); // read reminder
300 
301  tend = osal_current_time();
302  osal_time_diff(&tstart, &tend, &tdif);
303  if (mode == MODE_READINTEL) output_intelhex(fname, esize);
304  if (mode == MODE_READBIN) output_bin(fname, esize);
305 
306  printf("\nTotal EEPROM read time :%ldms\n", (tdif.usec+(tdif.sec*1000000L)) / 1000);
307  }
308  if ((mode == MODE_WRITEBIN) || (mode == MODE_WRITEINTEL))
309  {
310  estart = 0;
311  if (mode == MODE_WRITEINTEL) rc = input_intelhex(fname, &estart, &esize);
312  if (mode == MODE_WRITEBIN) rc = input_bin(fname, &esize);
313 
314  if (rc > 0)
315  {
316  wbuf = (uint16 *)&ebuf[0];
317  printf("Slave %d\n", slave);
318  printf(" Vendor ID : %8.8X\n",*(uint32 *)(wbuf + 0x08));
319  printf(" Product Code : %8.8X\n",*(uint32 *)(wbuf + 0x0A));
320  printf(" Revision Number : %8.8X\n",*(uint32 *)(wbuf + 0x0C));
321  printf(" Serial Number : %8.8X\n",*(uint32 *)(wbuf + 0x0E));
322 
323  printf("Busy");
324  fflush(stdout);
325  tstart = osal_current_time();
326  eeprom_write(slave, estart, esize);
327  tend = osal_current_time();
328  osal_time_diff(&tstart, &tend, &tdif);
329 
330  printf("\nTotal EEPROM write time :%ldms\n", (tdif.usec+(tdif.sec*1000000L)) / 1000);
331  }
332  else
333  printf("Error reading file, abort.\n");
334  }
335  }
336  else
337  printf("Slave number outside range.\n");
338  }
339  else
340  printf("No slaves found!\n");
341  printf("End, close socket\n");
342  /* stop SOEM, close socket */
343  ec_close();
344  }
345  else
346  printf("No socket connection on %s\nExcecute as root\n",ifname);
347 }
348 
349 int main(int argc, char *argv[])
350 {
351  ec_adaptert * adapter = NULL;
352  printf("SOEM (Simple Open EtherCAT Master)\nEEPROM tool\n");
353 
354  if (argc > 4)
355  {
356  slave = atoi(argv[2]);
357  mode = MODE_NONE;
358  if ((strncmp(argv[3], "-r", sizeof("-r")) == 0)) mode = MODE_READBIN;
359  if ((strncmp(argv[3], "-ri", sizeof("-ri")) == 0)) mode = MODE_READINTEL;
360  if ((strncmp(argv[3], "-w", sizeof("-w")) == 0)) mode = MODE_WRITEBIN;
361  if ((strncmp(argv[3], "-wi", sizeof("-wi")) == 0)) mode = MODE_WRITEINTEL;
362 
363  /* start tool */
364  eepromtool(argv[1],slave,mode,argv[4]);
365  }
366  else
367  {
368  printf("Usage: eepromtool ifname slave OPTION fname\n");
369  printf("ifname = adapter name\n");
370  printf("slave = slave number in EtherCAT order 1..n\n");
371  printf(" -r read EEPROM, output binary format\n");
372  printf(" -ri read EEPROM, output Intel Hex format\n");
373  printf(" -w write EEPROM, input binary format\n");
374  printf(" -wi write EEPROM, input Intel Hex format\n");
375  /* Print the list */
376  printf ("Available adapters\n");
377  adapter = ec_find_adapters ();
378  while (adapter != NULL)
379  {
380  printf ("Description : %s, Device to use for wpcap: %s\n", adapter->desc,adapter->name);
381  adapter = adapter->next;
382  }
383  }
384 
385  printf("End program\n");
386 
387  return (0);
388 }
int eeprom_write(int slave, int start, int length)
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:598
int ec_APRD(uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout)
Definition: ethercatbase.c:559
#define IHEXLENGTH
#define MODE_READINTEL
char name[EC_MAXLEN_ADAPTERNAME]
Definition: ethercatmain.h:46
#define EC_TIMEOUTSAFE
Definition: ethercattype.h:68
int main(int argc, char *argv[])
uint8_t uint8
Definition: osal.h:28
uint32 usec
Definition: osal.h:39
#define MODE_NONE
Headerfile for all ethercat headers.
ec_adaptert * next
Definition: ethercatmain.h:48
#define MODE_WRITEINTEL
int ec_init(const char *ifname)
uint16_t uint16
Definition: osal.h:29
#define etohs(A)
Definition: ethercattype.h:536
ec_timet tdif
int output_intelhex(char *fname, int length)
char desc[EC_MAXLEN_ADAPTERNAME]
Definition: ethercatmain.h:47
void eepromtool(char *ifname, int slave, int mode, char *fname)
ec_timet osal_current_time(void)
Definition: erika/osal.c:37
Definition: osal.h:36
int ec_BRD(uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout)
Definition: ethercatbase.c:554
int ec_slavecount
Definition: ethercatmain.c:69
void osal_time_diff(ec_timet *start, ec_timet *end, ec_timet *diff)
Definition: erika/osal.c:48
int eeprom_read(int slave, int start, int length)
#define EC_TIMEOUTEEP
Definition: ethercattype.h:70
#define MAXSLENGTH
int input_bin(char *fname, int *length)
uint64_t uint64
Definition: osal.h:32
#define MODE_READBIN
int input_intelhex(char *fname, int *start, int *length)
#define MINBUF
uint8 ebuf[MAXBUF]
#define MODE_WRITEBIN
uint64 ec_readeepromAP(uint16 aiadr, uint16 eeproma, int timeout)
uint32 sec
Definition: osal.h:38
uint32_t uint32
Definition: osal.h:30
#define EC_TIMEOUTRET3
Definition: ethercattype.h:66
ec_adaptert * ec_find_adapters(void)
Definition: ethercatmain.c:131
ec_timet tstart
void ec_close(void)
char sline[MAXSLENGTH]
int ainc
ec_timet tend
#define EC_ESTAT_R64
Definition: ethercattype.h:271
#define MAXBUF
int output_bin(char *fname, int length)


soem
Author(s): Arthur Ketels and M.J.G. van den Molengraft
autogenerated on Mon Feb 28 2022 23:46:57