ethercatcoe.c
Go to the documentation of this file.
1 /*
2  * Simple Open EtherCAT Master Library
3  *
4  * File : ethercatcoe.c
5  * Version : 1.3.0
6  * Date : 24-02-2013
7  * Copyright (C) 2005-2013 Speciaal Machinefabriek Ketels v.o.f.
8  * Copyright (C) 2005-2013 Arthur Ketels
9  * Copyright (C) 2008-2009 TU/e Technische Universiteit Eindhoven
10  *
11  * SOEM is free software; you can redistribute it and/or modify it under
12  * the terms of the GNU General Public License version 2 as published by the Free
13  * Software Foundation.
14  *
15  * SOEM is distributed in the hope that it will be useful, but WITHOUT ANY
16  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18  * for more details.
19  *
20  * As a special exception, if other files instantiate templates or use macros
21  * or inline functions from this file, or you compile this file and link it
22  * with other works to produce a work based on this file, this file does not
23  * by itself cause the resulting work to be covered by the GNU General Public
24  * License. However the source code for this file must still be made available
25  * in accordance with section (3) of the GNU General Public License.
26  *
27  * This exception does not invalidate any other reasons why a work based on
28  * this file might be covered by the GNU General Public License.
29  *
30  * The EtherCAT Technology, the trade name and logo “EtherCAT” are the intellectual
31  * property of, and protected by Beckhoff Automation GmbH. You can use SOEM for
32  * the sole purpose of creating, using and/or selling or otherwise distributing
33  * an EtherCAT network master provided that an EtherCAT Master License is obtained
34  * from Beckhoff Automation GmbH.
35  *
36  * In case you did not receive a copy of the EtherCAT Master License along with
37  * SOEM write to Beckhoff Automation GmbH, Eiserstraße 5, D-33415 Verl, Germany
38  * (www.beckhoff.com).
39  */
40 
48 #include <stdio.h>
49 #include <string.h>
50 #include "osal.h"
51 #include "oshw.h"
52 #include "ethercattype.h"
53 #include "ethercatbase.h"
54 #include "ethercatmain.h"
55 #include "ethercatcoe.h"
56 
58 PACKED_BEGIN
59 typedef struct PACKED
60 {
66  union
67  {
68  uint8 bdata[0x200]; /* variants for easy data access */
69  uint16 wdata[0x100];
70  uint32 ldata[0x80];
71  };
72 } ec_SDOt;
73 PACKED_END
74 
76 PACKED_BEGIN
77 typedef struct PACKED
78 {
84  union
85  {
86  uint8 bdata[0x200]; /* variants for easy data access */
87  uint16 wdata[0x100];
88  uint32 ldata[0x80];
89  };
91 PACKED_END
92 
101 void ecx_SDOerror(ecx_contextt *context, uint16 Slave, uint16 Index, uint8 SubIdx, int32 AbortCode)
102 {
103  ec_errort Ec;
104 
105  Ec.Time = osal_current_time();
106  Ec.Slave = Slave;
107  Ec.Index = Index;
108  Ec.SubIdx = SubIdx;
109  *(context->ecaterror) = TRUE;
111  Ec.AbortCode = AbortCode;
112  ecx_pusherror(context, &Ec);
113 }
114 
123 static void ecx_SDOinfoerror(ecx_contextt *context, uint16 Slave, uint16 Index, uint8 SubIdx, int32 AbortCode)
124 {
125  ec_errort Ec;
126 
127  Ec.Slave = Slave;
128  Ec.Index = Index;
129  Ec.SubIdx = SubIdx;
130  *(context->ecaterror) = TRUE;
132  Ec.AbortCode = AbortCode;
133  ecx_pusherror(context, &Ec);
134 }
135 
153 int ecx_SDOread(ecx_contextt *context, uint16 slave, uint16 index, uint8 subindex,
154  boolean CA, int *psize, void *p, int timeout)
155 {
156  ec_SDOt *SDOp, *aSDOp;
157  uint16 bytesize, Framedatasize;
158  int wkc;
159  int32 SDOlen;
160  uint8 *bp;
161  uint8 *hp;
162  ec_mbxbuft MbxIn, MbxOut;
163  uint8 cnt, toggle;
164  boolean NotLast;
165 
166  ec_clearmbx(&MbxIn);
167  /* Empty slave out mailbox if something is in. Timout set to 0 */
168  wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, 0);
169  ec_clearmbx(&MbxOut);
170  aSDOp = (ec_SDOt *)&MbxIn;
171  SDOp = (ec_SDOt *)&MbxOut;
172  SDOp->MbxHeader.length = htoes(0x000a);
173  SDOp->MbxHeader.address = htoes(0x0000);
174  SDOp->MbxHeader.priority = 0x00;
175  /* get new mailbox count value, used as session handle */
176  cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt);
177  context->slavelist[slave].mbx_cnt = cnt;
178  SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
179  SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12)); /* number 9bits service upper 4 bits (SDO request) */
180  if (CA)
181  {
182  SDOp->Command = ECT_SDO_UP_REQ_CA; /* upload request complete access */
183  }
184  else
185  {
186  SDOp->Command = ECT_SDO_UP_REQ; /* upload request normal */
187  }
188  SDOp->Index = htoes(index);
189  if (CA && (subindex > 1))
190  {
191  subindex = 1;
192  }
193  SDOp->SubIndex = subindex;
194  SDOp->ldata[0] = 0;
195  /* send CoE request to slave */
196  wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
197  if (wkc > 0) /* succeeded to place mailbox in slave ? */
198  {
199  /* clean mailboxbuffer */
200  ec_clearmbx(&MbxIn);
201  /* read slave response */
202  wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, timeout);
203  if (wkc > 0) /* succeeded to read slave response ? */
204  {
205  /* slave response should be CoE, SDO response and the correct index */
206  if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
207  ((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_SDORES) &&
208  (aSDOp->Index == SDOp->Index))
209  {
210  if ((aSDOp->Command & 0x02) > 0)
211  {
212  /* expedited frame response */
213  bytesize = 4 - ((aSDOp->Command >> 2) & 0x03);
214  if (*psize >= bytesize) /* parameter buffer big enough ? */
215  {
216  /* copy parameter in parameter buffer */
217  memcpy(p, &aSDOp->ldata[0], bytesize);
218  /* return the real parameter size */
219  *psize = bytesize;
220  }
221  else
222  {
223  wkc = 0;
224  ecx_packeterror(context, slave, index, subindex, 3); /* data container too small for type */
225  }
226  }
227  else
228  { /* normal frame response */
229  SDOlen = etohl(aSDOp->ldata[0]);
230  /* Does parameter fit in parameter buffer ? */
231  if (SDOlen <= *psize)
232  {
233  bp = p;
234  hp = p;
235  /* calculate mailbox transfer size */
236  Framedatasize = (etohs(aSDOp->MbxHeader.length) - 10);
237  if (Framedatasize < SDOlen) /* transfer in segments? */
238  {
239  /* copy parameter data in parameter buffer */
240  memcpy(hp, &aSDOp->ldata[1], Framedatasize);
241  /* increment buffer pointer */
242  hp += Framedatasize;
243  *psize = Framedatasize;
244  NotLast = TRUE;
245  toggle= 0x00;
246  while (NotLast) /* segmented transfer */
247  {
248  SDOp = (ec_SDOt *)&MbxOut;
249  SDOp->MbxHeader.length = htoes(0x000a);
250  SDOp->MbxHeader.address = htoes(0x0000);
251  SDOp->MbxHeader.priority = 0x00;
252  cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt);
253  context->slavelist[slave].mbx_cnt = cnt;
254  SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
255  SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12)); /* number 9bits service upper 4 bits (SDO request) */
256  SDOp->Command = ECT_SDO_SEG_UP_REQ + toggle; /* segment upload request */
257  SDOp->Index = htoes(index);
258  SDOp->SubIndex = subindex;
259  SDOp->ldata[0] = 0;
260  /* send segmented upload request to slave */
261  wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
262  /* is mailbox transfered to slave ? */
263  if (wkc > 0)
264  {
265  ec_clearmbx(&MbxIn);
266  /* read slave response */
267  wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, timeout);
268  /* has slave responded ? */
269  if (wkc > 0)
270  {
271  /* slave response should be CoE, SDO response */
272  if ((((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
273  ((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_SDORES) &&
274  ((aSDOp->Command & 0xe0) == 0x00)))
275  {
276  /* calculate mailbox transfer size */
277  Framedatasize = etohs(aSDOp->MbxHeader.length) - 3;
278  if ((aSDOp->Command & 0x01) > 0)
279  { /* last segment */
280  NotLast = FALSE;
281  if (Framedatasize == 7)
282  /* substract unused bytes from frame */
283  Framedatasize = Framedatasize - ((aSDOp->Command & 0x0e) >> 1);
284  /* copy to parameter buffer */
285  memcpy(hp, &(aSDOp->Index), Framedatasize);
286  }
287  else /* segments follow */
288  {
289  /* copy to parameter buffer */
290  memcpy(hp, &(aSDOp->Index), Framedatasize);
291  /* increment buffer pointer */
292  hp += Framedatasize;
293  }
294  /* update parametersize */
295  *psize += Framedatasize;
296  }
297  /* unexpected frame returned from slave */
298  else
299  {
300  NotLast = FALSE;
301  if ((aSDOp->Command) == ECT_SDO_ABORT) /* SDO abort frame received */
302  ecx_SDOerror(context, slave, index, subindex, etohl(aSDOp->ldata[0]));
303  else
304  ecx_packeterror(context, slave, index, subindex, 1); /* Unexpected frame returned */
305  wkc = 0;
306  }
307  }
308  }
309  toggle = toggle ^ 0x10; /* toggle bit for segment request */
310  }
311  }
312  /* non segmented transfer */
313  else
314  {
315  /* copy to parameter buffer */
316  memcpy(bp, &aSDOp->ldata[1], SDOlen);
317  *psize = SDOlen;
318  }
319  }
320  /* parameter buffer too small */
321  else
322  {
323  wkc = 0;
324  ecx_packeterror(context, slave, index, subindex, 3); /* data container too small for type */
325  }
326  }
327  }
328  /* other slave response */
329  else
330  {
331  if ((aSDOp->Command) == ECT_SDO_ABORT) /* SDO abort frame received */
332  {
333  ecx_SDOerror(context, slave, index, subindex, etohl(aSDOp->ldata[0]));
334  }
335  else
336  {
337  ecx_packeterror(context, slave, index, subindex, 1); /* Unexpected frame returned */
338  }
339  wkc = 0;
340  }
341  }
342  }
343  return wkc;
344 }
345 
364  boolean CA, int psize, void *p, int Timeout)
365 {
366  ec_SDOt *SDOp, *aSDOp;
367  int wkc, maxdata;
368  ec_mbxbuft MbxIn, MbxOut;
369  uint8 cnt, toggle;
370  uint16 framedatasize;
371  boolean NotLast;
372  uint8 *hp;
373 
374  ec_clearmbx(&MbxIn);
375  /* Empty slave out mailbox if something is in. Timout set to 0 */
376  wkc = ecx_mbxreceive(context, Slave, (ec_mbxbuft *)&MbxIn, 0);
377  ec_clearmbx(&MbxOut);
378  aSDOp = (ec_SDOt *)&MbxIn;
379  SDOp = (ec_SDOt *)&MbxOut;
380  maxdata = context->slavelist[Slave].mbx_l - 0x10; /* data section=mailbox size - 6 mbx - 2 CoE - 8 sdo req */
381  /* if small data use expedited transfer */
382  if ((psize <= 4) && !CA)
383  {
384  SDOp->MbxHeader.length = htoes(0x000a);
385  SDOp->MbxHeader.address = htoes(0x0000);
386  SDOp->MbxHeader.priority = 0x00;
387  /* get new mailbox counter, used for session handle */
388  cnt = ec_nextmbxcnt(context->slavelist[Slave].mbx_cnt);
389  context->slavelist[Slave].mbx_cnt = cnt;
390  SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
391  SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12)); /* number 9bits service upper 4 bits */
392  SDOp->Command = ECT_SDO_DOWN_EXP | (((4 - psize) << 2) & 0x0c); /* expedited SDO download transfer */
393  SDOp->Index = htoes(Index);
394  SDOp->SubIndex = SubIndex;
395  hp = p;
396  /* copy parameter data to mailbox */
397  memcpy(&SDOp->ldata[0], hp, psize);
398  /* send mailbox SDO download request to slave */
399  wkc = ecx_mbxsend(context, Slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
400  if (wkc > 0)
401  {
402  ec_clearmbx(&MbxIn);
403  /* read slave response */
404  wkc = ecx_mbxreceive(context, Slave, (ec_mbxbuft *)&MbxIn, Timeout);
405  if (wkc > 0)
406  {
407  /* response should be CoE, SDO response, correct index and subindex */
408  if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
409  ((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_SDORES) &&
410  (aSDOp->Index == SDOp->Index) &&
411  (aSDOp->SubIndex == SDOp->SubIndex))
412  {
413  /* all OK */
414  }
415  /* unexpected response from slave */
416  else
417  {
418  if (aSDOp->Command == ECT_SDO_ABORT) /* SDO abort frame received */
419  {
420  ecx_SDOerror(context, Slave, Index, SubIndex, etohl(aSDOp->ldata[0]));
421  }
422  else
423  {
424  ecx_packeterror(context, Slave, Index, SubIndex, 1); /* Unexpected frame returned */
425  }
426  wkc = 0;
427  }
428  }
429  }
430  }
431  else
432  {
433  framedatasize = psize;
434  NotLast = FALSE;
435  if (framedatasize > maxdata)
436  {
437  framedatasize = maxdata; /* segmented transfer needed */
438  NotLast = TRUE;
439  }
440  SDOp->MbxHeader.length = htoes(0x0a + framedatasize);
441  SDOp->MbxHeader.address = htoes(0x0000);
442  SDOp->MbxHeader.priority = 0x00;
443  /* get new mailbox counter, used for session handle */
444  cnt = ec_nextmbxcnt(context->slavelist[Slave].mbx_cnt);
445  context->slavelist[Slave].mbx_cnt = cnt;
446  SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
447  SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12)); /* number 9bits service upper 4 bits */
448  if (CA)
449  {
450  SDOp->Command = ECT_SDO_DOWN_INIT_CA; /* Complete Access, normal SDO init download transfer */
451  }
452  else
453  {
454  SDOp->Command = ECT_SDO_DOWN_INIT; /* normal SDO init download transfer */
455  }
456  SDOp->Index = htoes(Index);
457  SDOp->SubIndex = SubIndex;
458  if (CA && (SubIndex > 1))
459  {
460  SDOp->SubIndex = 1;
461  }
462  SDOp->ldata[0] = htoel(psize);
463  hp = p;
464  /* copy parameter data to mailbox */
465  memcpy(&SDOp->ldata[1], hp, framedatasize);
466  hp += framedatasize;
467  psize -= framedatasize;
468  /* send mailbox SDO download request to slave */
469  wkc = ecx_mbxsend(context, Slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
470  if (wkc > 0)
471  {
472  ec_clearmbx(&MbxIn);
473  /* read slave response */
474  wkc = ecx_mbxreceive(context, Slave, (ec_mbxbuft *)&MbxIn, Timeout);
475  if (wkc > 0)
476  {
477  /* response should be CoE, SDO response, correct index and subindex */
478  if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
479  ((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_SDORES) &&
480  (aSDOp->Index == SDOp->Index) &&
481  (aSDOp->SubIndex == SDOp->SubIndex))
482  {
483  /* all ok */
484  maxdata += 7;
485  toggle = 0;
486  /* repeat while segments left */
487  while (NotLast)
488  {
489  SDOp = (ec_SDOt *)&MbxOut;
490  framedatasize = psize;
491  NotLast = FALSE;
492  SDOp->Command = 0x01; /* last segment */
493  if (framedatasize > maxdata)
494  {
495  framedatasize = maxdata; /* more segments needed */
496  NotLast = TRUE;
497  SDOp->Command = 0x00; /* segments follow */
498  }
499  if (!NotLast && (framedatasize < 7))
500  {
501  SDOp->MbxHeader.length = htoes(0x0a); /* minimum size */
502  SDOp->Command = 0x01 + ((7 - framedatasize) << 1); /* last segment reduced octets */
503  }
504  else
505  {
506  SDOp->MbxHeader.length = htoes(framedatasize + 3); /* data + 2 CoE + 1 SDO */
507  }
508  SDOp->MbxHeader.address = htoes(0x0000);
509  SDOp->MbxHeader.priority = 0x00;
510  /* get new mailbox counter value */
511  cnt = ec_nextmbxcnt(context->slavelist[Slave].mbx_cnt);
512  context->slavelist[Slave].mbx_cnt = cnt;
513  SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
514  SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12)); /* number 9bits service upper 4 bits (SDO request) */
515  SDOp->Command = SDOp->Command + toggle; /* add toggle bit to command byte */
516  /* copy parameter data to mailbox */
517  memcpy(&SDOp->Index, hp, framedatasize);
518  /* update parameter buffer pointer */
519  hp += framedatasize;
520  psize -= framedatasize;
521  /* send SDO download request */
522  wkc = ecx_mbxsend(context, Slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
523  if (wkc > 0)
524  {
525  ec_clearmbx(&MbxIn);
526  /* read slave response */
527  wkc = ecx_mbxreceive(context, Slave, (ec_mbxbuft *)&MbxIn, Timeout);
528  if (wkc > 0)
529  {
530  if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
531  ((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_SDORES) &&
532  ((aSDOp->Command & 0xe0) == 0x20))
533  {
534  /* all OK, nothing to do */
535  }
536  else
537  {
538  if (aSDOp->Command == ECT_SDO_ABORT) /* SDO abort frame received */
539  {
540  ecx_SDOerror(context, Slave, Index, SubIndex, etohl(aSDOp->ldata[0]));
541  }
542  else
543  {
544  ecx_packeterror(context, Slave, Index, SubIndex, 1); /* Unexpected frame returned */
545  }
546  wkc = 0;
547  NotLast = FALSE;
548  }
549  }
550  }
551  toggle = toggle ^ 0x10; /* toggle bit for segment request */
552  }
553  }
554  /* unexpected response from slave */
555  else
556  {
557  if (aSDOp->Command == ECT_SDO_ABORT) /* SDO abort frame received */
558  {
559  ecx_SDOerror(context, Slave, Index, SubIndex, etohl(aSDOp->ldata[0]));
560  }
561  else
562  {
563  ecx_packeterror(context, Slave, Index, SubIndex, 1); /* Unexpected frame returned */
564  }
565  wkc = 0;
566  }
567  }
568  }
569  }
570 
571  return wkc;
572 }
573 
585 int ecx_RxPDO(ecx_contextt *context, uint16 Slave, uint16 RxPDOnumber, int psize, void *p)
586 {
587  ec_SDOt *SDOp;
588  int wkc, maxdata;
589  ec_mbxbuft MbxIn, MbxOut;
590  uint8 cnt;
591  uint16 framedatasize;
592 
593  ec_clearmbx(&MbxIn);
594  /* Empty slave out mailbox if something is in. Timout set to 0 */
595  wkc = ecx_mbxreceive(context, Slave, (ec_mbxbuft *)&MbxIn, 0);
596  ec_clearmbx(&MbxOut);
597  SDOp = (ec_SDOt *)&MbxOut;
598  maxdata = context->slavelist[Slave].mbx_l - 0x08; /* data section=mailbox size - 6 mbx - 2 CoE */
599  framedatasize = psize;
600  if (framedatasize > maxdata)
601  {
602  framedatasize = maxdata; /* limit transfer */
603  }
604  SDOp->MbxHeader.length = htoes(0x02 + framedatasize);
605  SDOp->MbxHeader.address = htoes(0x0000);
606  SDOp->MbxHeader.priority = 0x00;
607  /* get new mailbox counter, used for session handle */
608  cnt = ec_nextmbxcnt(context->slavelist[Slave].mbx_cnt);
609  context->slavelist[Slave].mbx_cnt = cnt;
610  SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
611  SDOp->CANOpen = htoes((RxPDOnumber & 0x01ff) + (ECT_COES_RXPDO << 12)); /* number 9bits service upper 4 bits */
612  /* copy PDO data to mailbox */
613  memcpy(&SDOp->Command, p, framedatasize);
614  /* send mailbox RxPDO request to slave */
615  wkc = ecx_mbxsend(context, Slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
616 
617  return wkc;
618 }
619 
632 int ecx_TxPDO(ecx_contextt *context, uint16 slave, uint16 TxPDOnumber , int *psize, void *p, int timeout)
633 {
634  ec_SDOt *SDOp, *aSDOp;
635  int wkc;
636  ec_mbxbuft MbxIn, MbxOut;
637  uint8 cnt;
638  uint16 framedatasize;
639 
640  ec_clearmbx(&MbxIn);
641  /* Empty slave out mailbox if something is in. Timout set to 0 */
642  wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, 0);
643  ec_clearmbx(&MbxOut);
644  aSDOp = (ec_SDOt *)&MbxIn;
645  SDOp = (ec_SDOt *)&MbxOut;
646  SDOp->MbxHeader.length = htoes(0x02);
647  SDOp->MbxHeader.address = htoes(0x0000);
648  SDOp->MbxHeader.priority = 0x00;
649  /* get new mailbox counter, used for session handle */
650  cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt);
651  context->slavelist[slave].mbx_cnt = cnt;
652  SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
653  SDOp->CANOpen = htoes((TxPDOnumber & 0x01ff) + (ECT_COES_TXPDO_RR << 12)); /* number 9bits service upper 4 bits */
654  wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
655  if (wkc > 0)
656  {
657  /* clean mailboxbuffer */
658  ec_clearmbx(&MbxIn);
659  /* read slave response */
660  wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, timeout);
661  if (wkc > 0) /* succeeded to read slave response ? */
662  {
663  /* slave response should be CoE, TxPDO */
664  if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
665  ((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_TXPDO))
666  {
667  /* TxPDO response */
668  framedatasize = (aSDOp->MbxHeader.length - 2);
669  if (*psize >= framedatasize) /* parameter buffer big enough ? */
670  {
671  /* copy parameter in parameter buffer */
672  memcpy(p, &aSDOp->Command, framedatasize);
673  /* return the real parameter size */
674  *psize = framedatasize;
675  }
676  /* parameter buffer too small */
677  else
678  {
679  wkc = 0;
680  ecx_packeterror(context, slave, 0, 0, 3); /* data container too small for type */
681  }
682  }
683  /* other slave response */
684  else
685  {
686  if ((aSDOp->Command) == ECT_SDO_ABORT) /* SDO abort frame received */
687  {
688  ecx_SDOerror(context, slave, 0, 0, etohl(aSDOp->ldata[0]));
689  }
690  else
691  {
692  ecx_packeterror(context, slave, 0, 0, 1); /* Unexpected frame returned */
693  }
694  wkc = 0;
695  }
696  }
697  }
698 
699  return wkc;
700 }
701 
708 int ecx_readPDOassign(ecx_contextt *context, uint16 Slave, uint16 PDOassign)
709 {
710  uint16 idxloop, nidx, subidxloop, rdat, idx, subidx;
711  uint8 subcnt;
712  int wkc, bsize = 0, rdl;
713  int32 rdat2;
714 
715  rdl = sizeof(rdat); rdat = 0;
716  /* read PDO assign subindex 0 ( = number of PDO's) */
717  wkc = ecx_SDOread(context, Slave, PDOassign, 0x00, FALSE, &rdl, &rdat, EC_TIMEOUTRXM);
718  rdat = etohs(rdat);
719  /* positive result from slave ? */
720  if ((wkc > 0) && (rdat > 0))
721  {
722  /* number of available sub indexes */
723  nidx = rdat;
724  bsize = 0;
725  /* read all PDO's */
726  for (idxloop = 1; idxloop <= nidx; idxloop++)
727  {
728  rdl = sizeof(rdat); rdat = 0;
729  /* read PDO assign */
730  wkc = ecx_SDOread(context, Slave, PDOassign, (uint8)idxloop, FALSE, &rdl, &rdat, EC_TIMEOUTRXM);
731  /* result is index of PDO */
732  idx = etohl(rdat);
733  if (idx > 0)
734  {
735  rdl = sizeof(subcnt); subcnt = 0;
736  /* read number of subindexes of PDO */
737  wkc = ecx_SDOread(context, Slave,idx, 0x00, FALSE, &rdl, &subcnt, EC_TIMEOUTRXM);
738  subidx = subcnt;
739  /* for each subindex */
740  for (subidxloop = 1; subidxloop <= subidx; subidxloop++)
741  {
742  rdl = sizeof(rdat2); rdat2 = 0;
743  /* read SDO that is mapped in PDO */
744  wkc = ecx_SDOread(context, Slave, idx, (uint8)subidxloop, FALSE, &rdl, &rdat2, EC_TIMEOUTRXM);
745  rdat2 = etohl(rdat2);
746  /* extract bitlength of SDO */
747  if (LO_BYTE(rdat2) < 0xff)
748  {
749  bsize += LO_BYTE(rdat2);
750  }
751  else
752  {
753  rdl = sizeof(rdat); rdat = htoes(0xff);
754  /* read Object Entry in Object database */
755 // wkc = ec_readOEsingle(idx, (uint8)SubCount, pODlist, pOElist);
756  bsize += etohs(rdat);
757  }
758  }
759  }
760  }
761  }
762  /* return total found bitlength (PDO) */
763  return bsize;
764 }
765 
772 int ecx_readPDOassignCA(ecx_contextt *context, uint16 Slave, uint16 PDOassign)
773 {
774  uint16 idxloop, nidx, subidxloop, idx, subidx;
775  int wkc, bsize = 0, rdl;
776 
777  /* find maximum size of PDOassign buffer */
778  rdl = sizeof(ec_PDOassignt);
779  context->PDOassign->n=0;
780  /* read rxPDOassign in CA mode, all subindexes are read in one struct */
781  wkc = ecx_SDOread(context, Slave, PDOassign, 0x00, TRUE, &rdl, context->PDOassign, EC_TIMEOUTRXM);
782  /* positive result from slave ? */
783  if ((wkc > 0) && (context->PDOassign->n > 0))
784  {
785  nidx = context->PDOassign->n;
786  bsize = 0;
787  /* for each PDO do */
788  for (idxloop = 1; idxloop <= nidx; idxloop++)
789  {
790  /* get index from PDOassign struct */
791  idx = etohs(context->PDOassign->index[idxloop - 1]);
792  if (idx > 0)
793  {
794  rdl = sizeof(ec_PDOdesct); context->PDOdesc->n = 0;
795  /* read SDO's that are mapped in PDO, CA mode */
796  wkc = ecx_SDOread(context, Slave,idx, 0x00, TRUE, &rdl, context->PDOdesc, EC_TIMEOUTRXM);
797  subidx = context->PDOdesc->n;
798  /* extract all bitlengths of SDO's */
799  for (subidxloop = 1; subidxloop <= subidx; subidxloop++)
800  {
801  bsize += LO_BYTE(etohl(context->PDOdesc->PDO[subidxloop -1]));
802  }
803  }
804  }
805  }
806 
807  /* return total found bitlength (PDO) */
808  return bsize;
809 }
810 
839 int ecx_readPDOmap(ecx_contextt *context, uint16 Slave, int *Osize, int *Isize)
840 {
841  int wkc, rdl;
842  int retVal = 0;
843  uint8 nSM, iSM, tSM;
844  int Tsize;
845  uint8 SMt_bug_add;
846 
847  *Isize = 0;
848  *Osize = 0;
849  SMt_bug_add = 0;
850  rdl = sizeof(nSM); nSM = 0;
851  /* read SyncManager Communication Type object count */
852  wkc = ecx_SDOread(context, Slave, ECT_SDO_SMCOMMTYPE, 0x00, FALSE, &rdl, &nSM, EC_TIMEOUTRXM);
853  /* positive result from slave ? */
854  if ((wkc > 0) && (nSM > 2))
855  {
856  /* make nSM equal to number of defined SM */
857  nSM--;
858  /* limit to maximum number of SM defined, if true the slave can't be configured */
859  if (nSM > EC_MAXSM)
860  nSM = EC_MAXSM;
861  /* iterate for every SM type defined */
862  for (iSM = 2 ; iSM <= nSM ; iSM++)
863  {
864  rdl = sizeof(tSM); tSM = 0;
865  /* read SyncManager Communication Type */
866  wkc = ecx_SDOread(context, Slave, ECT_SDO_SMCOMMTYPE, iSM + 1, FALSE, &rdl, &tSM, EC_TIMEOUTRXM);
867  if (wkc > 0)
868  {
869 // start slave bug prevention code, remove if possible
870  if((iSM == 2) && (tSM == 2)) // SM2 has type 2 == mailbox out, this is a bug in the slave!
871  {
872  SMt_bug_add = 1; // try to correct, this works if the types are 0 1 2 3 and should be 1 2 3 4
873  }
874  if(tSM)
875  {
876  tSM += SMt_bug_add; // only add if SMt > 0
877  }
878  if((iSM == 2) && (tSM == 0)) // SM2 has type 0, this is a bug in the slave!
879  {
880  tSM = 3;
881  }
882  if((iSM == 3) && (tSM == 0)) // SM3 has type 0, this is a bug in the slave!
883  {
884  tSM = 4;
885  }
886 // end slave bug prevention code
887 
888  context->slavelist[Slave].SMtype[iSM] = tSM;
889  /* check if SM is unused -> clear enable flag */
890  if (tSM == 0)
891  {
892  context->slavelist[Slave].SM[iSM].SMflags =
893  htoel( etohl(context->slavelist[Slave].SM[iSM].SMflags) & EC_SMENABLEMASK);
894  }
895  if ((tSM == 3) || (tSM == 4))
896  {
897  /* read the assign PDO */
898  Tsize = ecx_readPDOassign(context, Slave, ECT_SDO_PDOASSIGN + iSM );
899  /* if a mapping is found */
900  if (Tsize)
901  {
902  context->slavelist[Slave].SM[iSM].SMlength = htoes((Tsize + 7) / 8);
903  if (tSM == 3)
904  {
905  /* we are doing outputs */
906  *Osize += Tsize;
907  }
908  else
909  {
910  /* we are doing inputs */
911  *Isize += Tsize;
912  }
913  }
914  }
915  }
916  }
917  }
918 
919  /* found some I/O bits ? */
920  if ((*Isize > 0) || (*Osize > 0))
921  {
922  retVal = 1;
923  }
924 
925  return retVal;
926 }
927 
940 int ecx_readPDOmapCA(ecx_contextt *context, uint16 Slave, int *Osize, int *Isize)
941 {
942  int wkc, rdl;
943  int retVal = 0;
944  uint8 nSM, iSM, tSM;
945  int Tsize;
946  uint8 SMt_bug_add;
947 
948  *Isize = 0;
949  *Osize = 0;
950  SMt_bug_add = 0;
951  rdl = sizeof(ec_SMcommtypet);
952  context->SMcommtype->n = 0;
953  /* read SyncManager Communication Type object count Complete Access*/
954  wkc = ecx_SDOread(context, Slave, ECT_SDO_SMCOMMTYPE, 0x00, TRUE, &rdl, context->SMcommtype, EC_TIMEOUTRXM);
955  /* positive result from slave ? */
956  if ((wkc > 0) && (context->SMcommtype->n > 2))
957  {
958  /* make nSM equal to number of defined SM */
959  nSM = context->SMcommtype->n - 1;
960  /* limit to maximum number of SM defined, if true the slave can't be configured */
961  if (nSM > EC_MAXSM)
962  {
963  nSM = EC_MAXSM;
964  ecx_packeterror(context, Slave, 0, 0, 10); /* #SM larger than EC_MAXSM */
965  }
966  /* iterate for every SM type defined */
967  for (iSM = 2 ; iSM <= nSM ; iSM++)
968  {
969  tSM = context->SMcommtype->SMtype[iSM];
970 
971 // start slave bug prevention code, remove if possible
972  if((iSM == 2) && (tSM == 2)) // SM2 has type 2 == mailbox out, this is a bug in the slave!
973  {
974  SMt_bug_add = 1; // try to correct, this works if the types are 0 1 2 3 and should be 1 2 3 4
975  }
976  if(tSM)
977  {
978  tSM += SMt_bug_add; // only add if SMt > 0
979  }
980 // end slave bug prevention code
981 
982  context->slavelist[Slave].SMtype[iSM] = tSM;
983  /* check if SM is unused -> clear enable flag */
984  if (tSM == 0)
985  {
986  context->slavelist[Slave].SM[iSM].SMflags =
987  htoel( etohl(context->slavelist[Slave].SM[iSM].SMflags) & EC_SMENABLEMASK);
988  }
989  if ((tSM == 3) || (tSM == 4))
990  {
991  /* read the assign PDO */
992  Tsize = ecx_readPDOassignCA(context, Slave, ECT_SDO_PDOASSIGN + iSM );
993  /* if a mapping is found */
994  if (Tsize)
995  {
996  context->slavelist[Slave].SM[iSM].SMlength = htoes((Tsize + 7) / 8);
997  if (tSM == 3)
998  {
999  /* we are doing outputs */
1000  *Osize += Tsize;
1001  }
1002  else
1003  {
1004  /* we are doing inputs */
1005  *Isize += Tsize;
1006  }
1007  }
1008  }
1009  }
1010  }
1011 
1012  /* found some I/O bits ? */
1013  if ((*Isize > 0) || (*Osize > 0))
1014  {
1015  retVal = 1;
1016  }
1017  return retVal;
1018 }
1019 
1027 int ecx_readODlist(ecx_contextt *context, uint16 Slave, ec_ODlistt *pODlist)
1028 {
1029  ec_SDOservicet *SDOp, *aSDOp;
1030  ec_mbxbuft MbxIn, MbxOut;
1031  int wkc;
1032  uint16 x, n, i, sp, offset;
1033  boolean stop;
1034  uint8 cnt;
1035  boolean First;
1036 
1037  pODlist->Slave = Slave;
1038  pODlist->Entries = 0;
1039  ec_clearmbx(&MbxIn);
1040  /* clear pending out mailbox in slave if available. Timeout is set to 0 */
1041  wkc = ecx_mbxreceive(context, Slave, &MbxIn, 0);
1042  ec_clearmbx(&MbxOut);
1043  aSDOp = (ec_SDOservicet*)&MbxIn;
1044  SDOp = (ec_SDOservicet*)&MbxOut;
1045  SDOp->MbxHeader.length = htoes(0x0008);
1046  SDOp->MbxHeader.address = htoes(0x0000);
1047  SDOp->MbxHeader.priority = 0x00;
1048  /* Get new mailbox counter value */
1049  cnt = ec_nextmbxcnt(context->slavelist[Slave].mbx_cnt);
1050  context->slavelist[Slave].mbx_cnt = cnt;
1051  SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
1052  SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOINFO << 12)); /* number 9bits service upper 4 bits */
1053  SDOp->Opcode = ECT_GET_ODLIST_REQ; /* get object description list request */
1054  SDOp->Reserved = 0;
1055  SDOp->Fragments = 0; /* fragments left */
1056  SDOp->wdata[0] = htoes(0x01); /* all objects */
1057  /* send get object description list request to slave */
1058  wkc = ecx_mbxsend(context, Slave, &MbxOut, EC_TIMEOUTTXM);
1059  /* mailbox placed in slave ? */
1060  if (wkc > 0)
1061  {
1062  x = 0;
1063  sp = 0;
1064  First = TRUE;
1065  offset = 1; /* offset to skip info header in first frame, otherwise set to 0 */
1066  do
1067  {
1068  stop = TRUE; /* assume this is last iteration */
1069  ec_clearmbx(&MbxIn);
1070  /* read slave response */
1071  wkc = ecx_mbxreceive(context, Slave, &MbxIn, EC_TIMEOUTRXM);
1072  /* got response ? */
1073  if (wkc > 0)
1074  {
1075  /* response should be CoE and "get object description list response" */
1076  if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
1077  ((aSDOp->Opcode & 0x7f) == ECT_GET_ODLIST_RES))
1078  {
1079  if (First)
1080  {
1081  /* extract number of indexes from mailbox data size */
1082  n = (etohs(aSDOp->MbxHeader.length) - (6 + 2)) / 2;
1083  }
1084  else
1085  {
1086  /* extract number of indexes from mailbox data size */
1087  n = (etohs(aSDOp->MbxHeader.length) - 6) / 2;
1088  }
1089  /* check if indexes fit in buffer structure */
1090  if ((sp + n) > EC_MAXODLIST)
1091  {
1092  n = EC_MAXODLIST + 1 - sp;
1093  ecx_SDOinfoerror(context, Slave, 0, 0, 0xf000000); /* Too many entries for master buffer */
1094  stop = TRUE;
1095  }
1096  /* trim to maximum number of ODlist entries defined */
1097  if ((pODlist->Entries + n) > EC_MAXODLIST)
1098  {
1099  n = EC_MAXODLIST - pODlist->Entries;
1100  }
1101  pODlist->Entries += n;
1102  /* extract indexes one by one */
1103  for (i = 0; i < n; i++)
1104  {
1105  pODlist->Index[sp + i] = etohs(aSDOp->wdata[i + offset]);
1106  }
1107  sp += n;
1108  /* check if more fragments will follow */
1109  if (aSDOp->Fragments > 0)
1110  {
1111  stop = FALSE;
1112  }
1113  First = FALSE;
1114  offset = 0;
1115  }
1116  /* got unexpected response from slave */
1117  else
1118  {
1119  if ((aSDOp->Opcode & 0x7f) == ECT_SDOINFO_ERROR) /* SDO info error received */
1120  {
1121  ecx_SDOinfoerror(context, Slave, 0, 0, etohl(aSDOp->ldata[0]));
1122  stop = TRUE;
1123  }
1124  else
1125  {
1126  ecx_packeterror(context, Slave, 0, 0, 1); /* Unexpected frame returned */
1127  }
1128  wkc = 0;
1129  x += 20;
1130  }
1131  }
1132  x++;
1133  }
1134  while ((x <= 128) && !stop);
1135  }
1136  return wkc;
1137 }
1138 
1147 {
1148  ec_SDOservicet *SDOp, *aSDOp;
1149  int wkc;
1150  uint16 n, Slave;
1151  ec_mbxbuft MbxIn, MbxOut;
1152  uint8 cnt;
1153 
1154  Slave = pODlist->Slave;
1155  pODlist->DataType[Item] = 0;
1156  pODlist->ObjectCode[Item] = 0;
1157  pODlist->MaxSub[Item] = 0;
1158  pODlist->Name[Item][0] = 0;
1159  ec_clearmbx(&MbxIn);
1160  /* clear pending out mailbox in slave if available. Timeout is set to 0 */
1161  wkc = ecx_mbxreceive(context, Slave, &MbxIn, 0);
1162  ec_clearmbx(&MbxOut);
1163  aSDOp = (ec_SDOservicet*)&MbxIn;
1164  SDOp = (ec_SDOservicet*)&MbxOut;
1165  SDOp->MbxHeader.length = htoes(0x0008);
1166  SDOp->MbxHeader.address = htoes(0x0000);
1167  SDOp->MbxHeader.priority = 0x00;
1168  /* Get new mailbox counter value */
1169  cnt = ec_nextmbxcnt(context->slavelist[Slave].mbx_cnt);
1170  context->slavelist[Slave].mbx_cnt = cnt;
1171  SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
1172  SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOINFO << 12)); /* number 9bits service upper 4 bits */
1173  SDOp->Opcode = ECT_GET_OD_REQ; /* get object description request */
1174  SDOp->Reserved = 0;
1175  SDOp->Fragments = 0; /* fragments left */
1176  SDOp->wdata[0] = htoes(pODlist->Index[Item]); /* Data of Index */
1177  /* send get object description request to slave */
1178  wkc = ecx_mbxsend(context, Slave, &MbxOut, EC_TIMEOUTTXM);
1179  /* mailbox placed in slave ? */
1180  if (wkc > 0)
1181  {
1182  ec_clearmbx(&MbxIn);
1183  /* read slave response */
1184  wkc = ecx_mbxreceive(context, Slave, &MbxIn, EC_TIMEOUTRXM);
1185  /* got response ? */
1186  if (wkc > 0)
1187  {
1188  if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
1189  ((aSDOp->Opcode & 0x7f) == ECT_GET_OD_RES))
1190  {
1191  n = (etohs(aSDOp->MbxHeader.length) - 12); /* length of string(name of object) */
1192  if (n > EC_MAXNAME)
1193  {
1194  n = EC_MAXNAME; /* max chars */
1195  }
1196  pODlist->DataType[Item] = etohs(aSDOp->wdata[1]);
1197  pODlist->ObjectCode[Item] = aSDOp->bdata[5];
1198  pODlist->MaxSub[Item] = aSDOp->bdata[4];
1199 
1200  strncpy(pODlist->Name[Item] , (char *)&aSDOp->bdata[6], n);
1201  pODlist->Name[Item][n] = 0x00; /* String terminator */
1202  }
1203  /* got unexpected response from slave */
1204  else
1205  {
1206  if (((aSDOp->Opcode & 0x7f) == ECT_SDOINFO_ERROR)) /* SDO info error received */
1207  {
1208  ecx_SDOinfoerror(context, Slave,pODlist->Index[Item], 0, etohl(aSDOp->ldata[0]));
1209  }
1210  else
1211  {
1212  ecx_packeterror(context, Slave,pODlist->Index[Item], 0, 1); /* Unexpected frame returned */
1213  }
1214  wkc = 0;
1215  }
1216  }
1217  }
1218 
1219  return wkc;
1220 }
1221 
1232 int ecx_readOEsingle(ecx_contextt *context, uint16 Item, uint8 SubI, ec_ODlistt *pODlist, ec_OElistt *pOElist)
1233 {
1234  ec_SDOservicet *SDOp, *aSDOp;
1235  uint16 wkc, Index, Slave;
1236  int16 n;
1237  ec_mbxbuft MbxIn, MbxOut;
1238  uint8 cnt;
1239 
1240  wkc = 0;
1241  Slave = pODlist->Slave;
1242  Index = pODlist->Index[Item];
1243  ec_clearmbx(&MbxIn);
1244  /* clear pending out mailbox in slave if available. Timeout is set to 0 */
1245  wkc = ecx_mbxreceive(context, Slave, &MbxIn, 0);
1246  ec_clearmbx(&MbxOut);
1247  aSDOp = (ec_SDOservicet*)&MbxIn;
1248  SDOp = (ec_SDOservicet*)&MbxOut;
1249  SDOp->MbxHeader.length = htoes(0x000a);
1250  SDOp->MbxHeader.address = htoes(0x0000);
1251  SDOp->MbxHeader.priority = 0x00;
1252  /* Get new mailbox counter value */
1253  cnt = ec_nextmbxcnt(context->slavelist[Slave].mbx_cnt);
1254  context->slavelist[Slave].mbx_cnt = cnt;
1255  SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
1256  SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOINFO << 12)); /* number 9bits service upper 4 bits */
1257  SDOp->Opcode = ECT_GET_OE_REQ; /* get object entry description request */
1258  SDOp->Reserved = 0;
1259  SDOp->Fragments = 0; /* fragments left */
1260  SDOp->wdata[0] = htoes(Index); /* Index */
1261  SDOp->bdata[2] = SubI; /* SubIndex */
1262  SDOp->bdata[3] = 1 + 2 + 4; /* get access rights, object category, PDO */
1263  /* send get object entry description request to slave */
1264  wkc = ecx_mbxsend(context, Slave, &MbxOut, EC_TIMEOUTTXM);
1265  /* mailbox placed in slave ? */
1266  if (wkc > 0)
1267  {
1268  ec_clearmbx(&MbxIn);
1269  /* read slave response */
1270  wkc = ecx_mbxreceive(context, Slave, &MbxIn, EC_TIMEOUTRXM);
1271  /* got response ? */
1272  if (wkc > 0)
1273  {
1274  if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
1275  ((aSDOp->Opcode & 0x7f) == ECT_GET_OE_RES))
1276  {
1277  pOElist->Entries++;
1278  n = (etohs(aSDOp->MbxHeader.length) - 16); /* length of string(name of object) */
1279  if (n > EC_MAXNAME)
1280  {
1281  n = EC_MAXNAME; /* max string length */
1282  }
1283  if (n < 0 )
1284  {
1285  n = 0;
1286  }
1287  pOElist->ValueInfo[SubI] = aSDOp->bdata[3];
1288  pOElist->DataType[SubI] = etohs(aSDOp->wdata[2]);
1289  pOElist->BitLength[SubI] = etohs(aSDOp->wdata[3]);
1290  pOElist->ObjAccess[SubI] = etohs(aSDOp->wdata[4]);
1291 
1292  strncpy(pOElist->Name[SubI] , (char *)&aSDOp->wdata[5], n);
1293  pOElist->Name[SubI][n] = 0x00; /* string terminator */
1294  }
1295  /* got unexpected response from slave */
1296  else
1297  {
1298  if (((aSDOp->Opcode & 0x7f) == ECT_SDOINFO_ERROR)) /* SDO info error received */
1299  {
1300  ecx_SDOinfoerror(context, Slave, Index, SubI, etohl(aSDOp->ldata[0]));
1301  }
1302  else
1303  {
1304  ecx_packeterror(context, Slave, Index, SubI, 1); /* Unexpected frame returned */
1305  }
1306  wkc = 0;
1307  }
1308  }
1309  }
1310 
1311  return wkc;
1312 }
1313 
1322 int ecx_readOE(ecx_contextt *context, uint16 Item, ec_ODlistt *pODlist, ec_OElistt *pOElist)
1323 {
1324  uint16 SubCount;
1325  int wkc;
1326  uint8 SubI;
1327 
1328  wkc = 0;
1329  pOElist->Entries = 0;
1330  SubI = pODlist->MaxSub[Item];
1331  /* for each entry found in ODlist */
1332  for (SubCount = 0; SubCount <= SubI; SubCount++)
1333  {
1334  /* read subindex of entry */
1335  wkc = ecx_readOEsingle(context, Item, (uint8)SubCount, pODlist, pOElist);
1336  }
1337 
1338  return wkc;
1339 }
1340 
1341 #ifdef EC_VER1
1342 void ec_SDOerror(uint16 Slave, uint16 Index, uint8 SubIdx, int32 AbortCode)
1343 {
1344  ecx_SDOerror(&ecx_context, Slave, Index, SubIdx, AbortCode);
1345 }
1346 
1347 int ec_SDOread(uint16 slave, uint16 index, uint8 subindex,
1348  boolean CA, int *psize, void *p, int timeout)
1349 {
1350  return ecx_SDOread(&ecx_context, slave, index, subindex, CA, psize, p, timeout);
1351 }
1352 
1353 int ec_SDOwrite(uint16 Slave, uint16 Index, uint8 SubIndex,
1354  boolean CA, int psize, void *p, int Timeout)
1355 {
1356  return ecx_SDOwrite(&ecx_context, Slave, Index, SubIndex, CA, psize, p, Timeout);
1357 }
1358 
1359 int ec_RxPDO(uint16 Slave, uint16 RxPDOnumber, int psize, void *p)
1360 {
1361  return ecx_RxPDO(&ecx_context, Slave, RxPDOnumber, psize, p);
1362 }
1363 
1364 int ec_TxPDO(uint16 slave, uint16 TxPDOnumber , int *psize, void *p, int timeout)
1365 {
1366  return ecx_TxPDO(&ecx_context, slave, TxPDOnumber, psize, p, timeout);
1367 }
1368 
1370 int ec_readPDOassign(uint16 Slave, uint16 PDOassign)
1371 {
1372  return ecx_readPDOassign(&ecx_context, Slave, PDOassign);
1373 }
1374 
1376 int ec_readPDOassignCA(uint16 Slave, uint16 PDOassign)
1377 {
1378  return ecx_readPDOassignCA(&ecx_context, Slave, PDOassign);
1379 }
1380 
1381 int ec_readPDOmap(uint16 Slave, int *Osize, int *Isize)
1382 {
1383  return ecx_readPDOmap(&ecx_context, Slave, Osize, Isize);
1384 }
1385 
1386 int ec_readPDOmapCA(uint16 Slave, int *Osize, int *Isize)
1387 {
1388  return ecx_readPDOmapCA(&ecx_context, Slave, Osize, Isize);
1389 }
1390 
1391 int ec_readODlist(uint16 Slave, ec_ODlistt *pODlist)
1392 {
1393  return ecx_readODlist(&ecx_context, Slave, pODlist);
1394 }
1395 
1396 int ec_readODdescription(uint16 Item, ec_ODlistt *pODlist)
1397 {
1398  return ecx_readODdescription(&ecx_context, Item, pODlist);
1399 }
1400 
1401 int ec_readOEsingle(uint16 Item, uint8 SubI, ec_ODlistt *pODlist, ec_OElistt *pOElist)
1402 {
1403  return ecx_readOEsingle(&ecx_context, Item, SubI, pODlist, pOElist);
1404 }
1405 
1406 int ec_readOE(uint16 Item, ec_ODlistt *pODlist, ec_OElistt *pOElist)
1407 {
1408  return ecx_readOE(&ecx_context, Item, pODlist, pOElist);
1409 }
1410 #endif
uint16 ObjAccess[EC_MAXOELIST]
Definition: ethercatcoe.h:91
uint16 index[256]
Definition: ethercatmain.h:398
int ecx_readPDOmapCA(ecx_contextt *context, uint16 Slave, int *Osize, int *Isize)
Definition: ethercatcoe.c:940
ec_slavet * slavelist
Definition: ethercatmain.h:418
int ecx_SDOread(ecx_contextt *context, uint16 slave, uint16 index, uint8 subindex, boolean CA, int *psize, void *p, int timeout)
Definition: ethercatcoe.c:153
#define EC_SMENABLEMASK
Definition: ethercatmain.h:134
#define htoel(A)
Definition: ethercattype.h:548
uint8 MaxSub[EC_MAXODLIST]
Definition: ethercatcoe.h:74
uint8_t uint8
Definition: osal.h:33
int ecx_readODdescription(ecx_contextt *context, uint16 Item, ec_ODlistt *pODlist)
Definition: ethercatcoe.c:1146
#define ECT_SDO_PDOASSIGN
Definition: ethercattype.h:468
int ecx_RxPDO(ecx_contextt *context, uint16 Slave, uint16 RxPDOnumber, int psize, void *p)
Definition: ethercatcoe.c:585
uint16 mbx_l
Definition: ethercatmain.h:188
ec_smt SM[EC_MAXSM]
Definition: ethercatmain.h:174
int ecx_readODlist(ecx_contextt *context, uint16 Slave, ec_ODlistt *pODlist)
Definition: ethercatcoe.c:1027
uint8 ValueInfo[EC_MAXOELIST]
Definition: ethercatcoe.h:85
uint32 ldata[0x80]
Definition: ethercatcoe.c:70
uint8 SubIndex
Definition: ethercatcoe.c:65
void ecx_pusherror(ecx_contextt *context, const ec_errort *Ec)
Definition: ethercatmain.c:188
void ec_clearmbx(ec_mbxbuft *Mbx)
Definition: ethercatmain.c:832
uint8 SubIdx
Definition: ethercattype.h:503
void ecx_packeterror(ecx_contextt *context, uint16 Slave, uint16 Index, uint8 SubIdx, uint16 ErrorCode)
Definition: ethercatmain.c:253
PACKED_END PACKED_BEGIN struct PACKED ec_SDOservicet
int ecx_TxPDO(ecx_contextt *context, uint16 slave, uint16 TxPDOnumber, int *psize, void *p, int timeout)
Definition: ethercatcoe.c:632
uint8 Command
Definition: ethercatcoe.c:63
uint16_t uint16
Definition: osal.h:34
int ecx_readOEsingle(ecx_contextt *context, uint16 Item, uint8 SubI, ec_ODlistt *pODlist, ec_OElistt *pOElist)
Definition: ethercatcoe.c:1232
uint16 Fragments
Definition: ethercatcoe.c:83
#define EC_TIMEOUTRXM
Definition: ethercattype.h:100
General typedefs and defines for EtherCAT.
#define etohs(A)
Definition: ethercattype.h:550
Headerfile for ethercatcoe.c.
#define TRUE
Definition: osal.h:28
uint8 SMtype[EC_MAXSM]
Definition: ethercatmain.h:176
ec_err_type Etype
Definition: ethercattype.h:505
#define EC_MAXSM
Definition: ethercatmain.h:70
ec_timet osal_current_time(void)
Definition: linux/osal.c:52
boolean * ecaterror
Definition: ethercatmain.h:438
#define ECT_SDO_SMCOMMTYPE
Definition: ethercattype.h:466
PACKED_END PACKED_BEGIN struct PACKED ec_PDOassignt
uint16 Slave
Definition: ethercatcoe.h:64
PACKED_BEGIN struct PACKED ec_mbxheadert
int ecx_SDOwrite(ecx_contextt *context, uint16 Slave, uint16 Index, uint8 SubIndex, boolean CA, int psize, void *p, int Timeout)
Definition: ethercatcoe.c:363
uint8 n
Definition: ethercatmain.h:386
uint16 Index[EC_MAXODLIST]
Definition: ethercatcoe.h:68
#define EC_TIMEOUTTXM
Definition: ethercattype.h:98
PACKED_END void ecx_SDOerror(ecx_contextt *context, uint16 Slave, uint16 Index, uint8 SubIdx, int32 AbortCode)
Definition: ethercatcoe.c:101
uint8 bdata[0x200]
Definition: ethercatcoe.c:68
uint16 Slave
Definition: ethercattype.h:499
ec_mbxheadert MbxHeader
Definition: ethercatcoe.c:61
uint16 Index
Definition: ethercatcoe.c:64
#define FALSE
Definition: osal.h:29
uint16 CANOpen
Definition: ethercatcoe.c:62
int32_t int32
Definition: osal.h:32
#define LO_BYTE(w)
Definition: ethercattype.h:528
uint8 ec_nextmbxcnt(uint8 cnt)
Definition: ethercatmain.c:818
uint16 BitLength[EC_MAXOELIST]
Definition: ethercatcoe.h:89
PACKED_END PACKED_BEGIN struct PACKED ec_PDOdesct
static void ecx_SDOinfoerror(ecx_contextt *context, uint16 Slave, uint16 Index, uint8 SubIdx, int32 AbortCode)
Definition: ethercatcoe.c:123
char Name[EC_MAXOELIST][EC_MAXNAME+1]
Definition: ethercatcoe.h:93
uint8 mbx_cnt
Definition: ethercatmain.h:198
int ecx_mbxsend(ecx_contextt *context, uint16 slave, ec_mbxbuft *mbx, int timeout)
Definition: ethercatmain.c:878
uint16 DataType[EC_MAXODLIST]
Definition: ethercatcoe.h:70
ec_PDOassignt * PDOassign
Definition: ethercatmain.h:448
int32 AbortCode
Definition: ethercattype.h:509
ec_timet Time
Definition: ethercattype.h:495
ec_PDOdesct * PDOdesc
Definition: ethercatmain.h:450
uint8 Reserved
Definition: ethercatcoe.c:82
Headerfile for ethercatbase.c.
#define htoes(A)
Definition: ethercattype.h:547
#define EC_MAXNAME
Definition: ethercatmain.h:58
uint16 Index
Definition: ethercattype.h:501
int ecx_readPDOassignCA(ecx_contextt *context, uint16 Slave, uint16 PDOassign)
Definition: ethercatcoe.c:772
#define etohl(A)
Definition: ethercattype.h:551
Headerfile for ethercatmain.c.
uint8 ObjectCode[EC_MAXODLIST]
Definition: ethercatcoe.h:72
int ecx_readPDOassign(ecx_contextt *context, uint16 Slave, uint16 PDOassign)
Definition: ethercatcoe.c:708
uint32_t uint32
Definition: osal.h:35
uint8 Opcode
Definition: ethercatcoe.c:81
uint16 Entries
Definition: ethercatcoe.h:66
ec_SMcommtypet * SMcommtype
Definition: ethercatmain.h:446
uint16 Entries
Definition: ethercatcoe.h:83
int16_t int16
Definition: osal.h:31
PACKED_BEGIN struct PACKED ec_SDOt
#define EC_MAXODLIST
Definition: ethercatcoe.h:55
char Name[EC_MAXODLIST][EC_MAXNAME+1]
Definition: ethercatcoe.h:76
uint16 wdata[0x100]
Definition: ethercatcoe.c:69
int ecx_mbxreceive(ecx_contextt *context, uint16 slave, ec_mbxbuft *mbx, int timeout)
Definition: ethercatmain.c:911
int ecx_readOE(ecx_contextt *context, uint16 Item, ec_ODlistt *pODlist, ec_OElistt *pOElist)
Definition: ethercatcoe.c:1322
int ecx_readPDOmap(ecx_contextt *context, uint16 Slave, int *Osize, int *Isize)
Definition: ethercatcoe.c:839
PACKED_BEGIN struct PACKED ec_SMcommtypet
uint16 DataType[EC_MAXOELIST]
Definition: ethercatcoe.h:87
uint8 ec_mbxbuft[EC_MAXMBX+1]
Definition: ethercatmain.h:341


youbot_driver
Author(s): Jan Paulus
autogenerated on Mon Jun 10 2019 15:46:24