ethercatmain.c
Go to the documentation of this file.
1 /*
2  * Licensed under the GNU General Public License version 2 with exceptions. See
3  * LICENSE file in the project root for full license information
4  */
5 
18 #include <stdio.h>
19 #include <string.h>
20 #include "osal.h"
21 #include "oshw.h"
22 #include "ethercat.h"
23 
24 
26 #define EC_LOCALDELAY 200
27 
30 typedef struct PACKED
31 {
35 } ec_eepromt;
37 
40 typedef struct PACKED
41 {
45 } ec_mbxerrort;
47 
50 typedef struct PACKED
51 {
58 } ec_emcyt;
60 
61 #ifdef EC_VER1
62 
72 
80 
87 
93 boolean EcatError = FALSE;
94 
96 
99 
101  &ecx_port, // .port =
102  &ec_slave[0], // .slavelist =
103  &ec_slavecount, // .slavecount =
104  EC_MAXSLAVE, // .maxslave =
105  &ec_group[0], // .grouplist =
106  EC_MAXGROUP, // .maxgroup =
107  &ec_esibuf[0], // .esibuf =
108  &ec_esimap[0], // .esimap =
109  0, // .esislave =
110  &ec_elist, // .elist =
111  &ec_idxstack, // .idxstack =
112  &EcatError, // .ecaterror =
113  0, // .DCtO =
114  0, // .DCl =
115  &ec_DCtime, // .DCtime =
116  &ec_SMcommtype[0], // .SMcommtype =
117  &ec_PDOassign[0], // .PDOassign =
118  &ec_PDOdesc[0], // .PDOdesc =
119  &ec_SM, // .eepSM =
120  &ec_FMMU, // .eepFMMU =
121  NULL, // .FOEhook()
122  NULL, // .EOEhook()
123  0 // .manualstatechange
124 };
125 #endif
126 
132 {
133  ec_adaptert * ret_adapter;
134 
135  ret_adapter = oshw_find_adapters ();
136 
137  return ret_adapter;
138 }
139 
145 {
146  oshw_free_adapters (adapter);
147 }
148 
154 void ecx_pusherror(ecx_contextt *context, const ec_errort *Ec)
155 {
156  context->elist->Error[context->elist->head] = *Ec;
157  context->elist->Error[context->elist->head].Signal = TRUE;
158  context->elist->head++;
159  if (context->elist->head > EC_MAXELIST)
160  {
161  context->elist->head = 0;
162  }
163  if (context->elist->head == context->elist->tail)
164  {
165  context->elist->tail++;
166  }
167  if (context->elist->tail > EC_MAXELIST)
168  {
169  context->elist->tail = 0;
170  }
171  *(context->ecaterror) = TRUE;
172 }
173 
180 boolean ecx_poperror(ecx_contextt *context, ec_errort *Ec)
181 {
182  boolean notEmpty = (context->elist->head != context->elist->tail);
183 
184  *Ec = context->elist->Error[context->elist->tail];
185  context->elist->Error[context->elist->tail].Signal = FALSE;
186  if (notEmpty)
187  {
188  context->elist->tail++;
189  if (context->elist->tail > EC_MAXELIST)
190  {
191  context->elist->tail = 0;
192  }
193  }
194  else
195  {
196  *(context->ecaterror) = FALSE;
197  }
198  return notEmpty;
199 }
200 
206 boolean ecx_iserror(ecx_contextt *context)
207 {
208  return (context->elist->head != context->elist->tail);
209 }
210 
220 {
221  ec_errort Ec;
222 
223  memset(&Ec, 0, sizeof(Ec));
224  Ec.Time = osal_current_time();
225  Ec.Slave = Slave;
226  Ec.Index = Index;
227  Ec.SubIdx = SubIdx;
228  *(context->ecaterror) = TRUE;
230  Ec.ErrorCode = ErrorCode;
231  ecx_pusherror(context, &Ec);
232 }
233 
240 static void ecx_mbxerror(ecx_contextt *context, uint16 Slave,uint16 Detail)
241 {
242  ec_errort Ec;
243 
244  memset(&Ec, 0, sizeof(Ec));
245  Ec.Time = osal_current_time();
246  Ec.Slave = Slave;
247  Ec.Index = 0;
248  Ec.SubIdx = 0;
250  Ec.ErrorCode = Detail;
251  ecx_pusherror(context, &Ec);
252 }
253 
265  uint8 b1, uint16 w1, uint16 w2)
266 {
267  ec_errort Ec;
268 
269  memset(&Ec, 0, sizeof(Ec));
270  Ec.Time = osal_current_time();
271  Ec.Slave = Slave;
272  Ec.Index = 0;
273  Ec.SubIdx = 0;
275  Ec.ErrorCode = ErrorCode;
276  Ec.ErrorReg = (uint8)ErrorReg;
277  Ec.b1 = b1;
278  Ec.w1 = w1;
279  Ec.w2 = w2;
280  ecx_pusherror(context, &Ec);
281 }
282 
288 int ecx_init(ecx_contextt *context, const char * ifname)
289 {
290  return ecx_setupnic(context->port, ifname, FALSE);
291 }
292 
300 int ecx_init_redundant(ecx_contextt *context, ecx_redportt *redport, const char *ifname, char *if2name)
301 {
302  int rval, zbuf;
303  ec_etherheadert *ehp;
304 
305  context->port->redport = redport;
306  ecx_setupnic(context->port, ifname, FALSE);
307  rval = ecx_setupnic(context->port, if2name, TRUE);
308  /* prepare "dummy" BRD tx frame for redundant operation */
309  ehp = (ec_etherheadert *)&(context->port->txbuf2);
310  ehp->sa1 = oshw_htons(secMAC[0]);
311  zbuf = 0;
312  ecx_setupdatagram(context->port, &(context->port->txbuf2), EC_CMD_BRD, 0, 0x0000, 0x0000, 2, &zbuf);
314 
315  return rval;
316 }
317 
321 void ecx_close(ecx_contextt *context)
322 {
323  ecx_closenic(context->port);
324 };
325 
335 {
336  uint16 configadr, eadr;
337  uint64 edat64;
338  uint32 edat32;
339  uint16 mapw, mapb;
340  int lp,cnt;
341  uint8 retval;
342 
343  retval = 0xff;
344  if (slave != context->esislave) /* not the same slave? */
345  {
346  memset(context->esimap, 0x00, EC_MAXEEPBITMAP * sizeof(uint32)); /* clear esibuf cache map */
347  context->esislave = slave;
348  }
349  if (address < EC_MAXEEPBUF)
350  {
351  mapw = address >> 5;
352  mapb = address - (mapw << 5);
353  if (context->esimap[mapw] & (uint32)(1 << mapb))
354  {
355  /* byte is already in buffer */
356  retval = context->esibuf[address];
357  }
358  else
359  {
360  /* byte is not in buffer, put it there */
361  configadr = context->slavelist[slave].configadr;
362  ecx_eeprom2master(context, slave); /* set eeprom control to master */
363  eadr = address >> 1;
364  edat64 = ecx_readeepromFP (context, configadr, eadr, EC_TIMEOUTEEP);
365  /* 8 byte response */
366  if (context->slavelist[slave].eep_8byte)
367  {
368  put_unaligned64(edat64, &(context->esibuf[eadr << 1]));
369  cnt = 8;
370  }
371  /* 4 byte response */
372  else
373  {
374  edat32 = (uint32)edat64;
375  put_unaligned32(edat32, &(context->esibuf[eadr << 1]));
376  cnt = 4;
377  }
378  /* find bitmap location */
379  mapw = eadr >> 4;
380  mapb = (eadr << 1) - (mapw << 5);
381  for(lp = 0 ; lp < cnt ; lp++)
382  {
383  /* set bitmap for each byte that is read */
384  context->esimap[mapw] |= (1 << mapb);
385  mapb++;
386  if (mapb > 31)
387  {
388  mapb = 0;
389  mapw++;
390  }
391  }
392  retval = context->esibuf[address];
393  }
394  }
395 
396  return retval;
397 }
398 
406 {
407  int16 a;
408  uint16 p;
409  uint8 eectl = context->slavelist[slave].eep_pdi;
410 
411  a = ECT_SII_START << 1;
412  /* read first SII section category */
413  p = ecx_siigetbyte(context, slave, a++);
414  p += (ecx_siigetbyte(context, slave, a++) << 8);
415  /* traverse SII while category is not found and not EOF */
416  while ((p != cat) && (p != 0xffff))
417  {
418  /* read section length */
419  p = ecx_siigetbyte(context, slave, a++);
420  p += (ecx_siigetbyte(context, slave, a++) << 8);
421  /* locate next section category */
422  a += p << 1;
423  /* read section category */
424  p = ecx_siigetbyte(context, slave, a++);
425  p += (ecx_siigetbyte(context, slave, a++) << 8);
426  }
427  if (p != cat)
428  {
429  a = 0;
430  }
431  if (eectl)
432  {
433  ecx_eeprom2pdi(context, slave); /* if eeprom control was previously pdi then restore */
434  }
435 
436  return a;
437 }
438 
445 void ecx_siistring(ecx_contextt *context, char *str, uint16 slave, uint16 Sn)
446 {
447  uint16 a,i,j,l,n,ba;
448  char *ptr;
449  uint8 eectl = context->slavelist[slave].eep_pdi;
450 
451  ptr = str;
452  a = ecx_siifind (context, slave, ECT_SII_STRING); /* find string section */
453  if (a > 0)
454  {
455  ba = a + 2; /* skip SII section header */
456  n = ecx_siigetbyte(context, slave, ba++); /* read number of strings in section */
457  if (Sn <= n) /* is req string available? */
458  {
459  for (i = 1; i <= Sn; i++) /* walk through strings */
460  {
461  l = ecx_siigetbyte(context, slave, ba++); /* length of this string */
462  if (i < Sn)
463  {
464  ba += l;
465  }
466  else
467  {
468  ptr = str;
469  for (j = 1; j <= l; j++) /* copy one string */
470  {
471  if(j <= EC_MAXNAME)
472  {
473  *ptr = (char)ecx_siigetbyte(context, slave, ba++);
474  ptr++;
475  }
476  else
477  {
478  ba++;
479  }
480  }
481  }
482  }
483  *ptr = 0; /* add zero terminator */
484  }
485  else
486  {
487  ptr = str;
488  *ptr = 0; /* empty string */
489  }
490  }
491  if (eectl)
492  {
493  ecx_eeprom2pdi(context, slave); /* if eeprom control was previously pdi then restore */
494  }
495 }
496 
504 {
505  uint16 a;
506  uint8 eectl = context->slavelist[slave].eep_pdi;
507 
508  FMMU->nFMMU = 0;
509  FMMU->FMMU0 = 0;
510  FMMU->FMMU1 = 0;
511  FMMU->FMMU2 = 0;
512  FMMU->FMMU3 = 0;
513  FMMU->Startpos = ecx_siifind(context, slave, ECT_SII_FMMU);
514 
515  if (FMMU->Startpos > 0)
516  {
517  a = FMMU->Startpos;
518  FMMU->nFMMU = ecx_siigetbyte(context, slave, a++);
519  FMMU->nFMMU += (ecx_siigetbyte(context, slave, a++) << 8);
520  FMMU->nFMMU *= 2;
521  FMMU->FMMU0 = ecx_siigetbyte(context, slave, a++);
522  FMMU->FMMU1 = ecx_siigetbyte(context, slave, a++);
523  if (FMMU->nFMMU > 2)
524  {
525  FMMU->FMMU2 = ecx_siigetbyte(context, slave, a++);
526  FMMU->FMMU3 = ecx_siigetbyte(context, slave, a++);
527  }
528  }
529  if (eectl)
530  {
531  ecx_eeprom2pdi(context, slave); /* if eeprom control was previously pdi then restore */
532  }
533 
534  return FMMU->nFMMU;
535 }
536 
544 {
545  uint16 a,w;
546  uint8 eectl = context->slavelist[slave].eep_pdi;
547 
548  SM->nSM = 0;
549  SM->Startpos = ecx_siifind(context, slave, ECT_SII_SM);
550  if (SM->Startpos > 0)
551  {
552  a = SM->Startpos;
553  w = ecx_siigetbyte(context, slave, a++);
554  w += (ecx_siigetbyte(context, slave, a++) << 8);
555  SM->nSM = (w / 4);
556  SM->PhStart = ecx_siigetbyte(context, slave, a++);
557  SM->PhStart += (ecx_siigetbyte(context, slave, a++) << 8);
558  SM->Plength = ecx_siigetbyte(context, slave, a++);
559  SM->Plength += (ecx_siigetbyte(context, slave, a++) << 8);
560  SM->Creg = ecx_siigetbyte(context, slave, a++);
561  SM->Sreg = ecx_siigetbyte(context, slave, a++);
562  SM->Activate = ecx_siigetbyte(context, slave, a++);
563  SM->PDIctrl = ecx_siigetbyte(context, slave, a++);
564  }
565  if (eectl)
566  {
567  ecx_eeprom2pdi(context, slave); /* if eeprom control was previously pdi then restore */
568  }
569 
570  return SM->nSM;
571 }
572 
581 {
582  uint16 a;
583  uint16 retVal = 0;
584  uint8 eectl = context->slavelist[slave].eep_pdi;
585 
586  if (n < SM->nSM)
587  {
588  a = SM->Startpos + 2 + (n * 8);
589  SM->PhStart = ecx_siigetbyte(context, slave, a++);
590  SM->PhStart += (ecx_siigetbyte(context, slave, a++) << 8);
591  SM->Plength = ecx_siigetbyte(context, slave, a++);
592  SM->Plength += (ecx_siigetbyte(context, slave, a++) << 8);
593  SM->Creg = ecx_siigetbyte(context, slave, a++);
594  SM->Sreg = ecx_siigetbyte(context, slave, a++);
595  SM->Activate = ecx_siigetbyte(context, slave, a++);
596  SM->PDIctrl = ecx_siigetbyte(context, slave, a++);
597  retVal = 1;
598  }
599  if (eectl)
600  {
601  ecx_eeprom2pdi(context, slave); /* if eeprom control was previously pdi then restore */
602  }
603 
604  return retVal;
605 }
606 
615 {
616  uint16 a , w, c, e, er, Size;
617  uint8 eectl = context->slavelist[slave].eep_pdi;
618 
619  Size = 0;
620  PDO->nPDO = 0;
621  PDO->Length = 0;
622  PDO->Index[1] = 0;
623  for (c = 0 ; c < EC_MAXSM ; c++) PDO->SMbitsize[c] = 0;
624  if (t > 1)
625  t = 1;
626  PDO->Startpos = ecx_siifind(context, slave, ECT_SII_PDO + t);
627  if (PDO->Startpos > 0)
628  {
629  a = PDO->Startpos;
630  w = ecx_siigetbyte(context, slave, a++);
631  w += (ecx_siigetbyte(context, slave, a++) << 8);
632  PDO->Length = w;
633  c = 1;
634  /* traverse through all PDOs */
635  do
636  {
637  PDO->nPDO++;
638  PDO->Index[PDO->nPDO] = ecx_siigetbyte(context, slave, a++);
639  PDO->Index[PDO->nPDO] += (ecx_siigetbyte(context, slave, a++) << 8);
640  PDO->BitSize[PDO->nPDO] = 0;
641  c++;
642  e = ecx_siigetbyte(context, slave, a++);
643  PDO->SyncM[PDO->nPDO] = ecx_siigetbyte(context, slave, a++);
644  a += 4;
645  c += 2;
646  if (PDO->SyncM[PDO->nPDO] < EC_MAXSM) /* active and in range SM? */
647  {
648  /* read all entries defined in PDO */
649  for (er = 1; er <= e; er++)
650  {
651  c += 4;
652  a += 5;
653  PDO->BitSize[PDO->nPDO] += ecx_siigetbyte(context, slave, a++);
654  a += 2;
655  }
656  PDO->SMbitsize[ PDO->SyncM[PDO->nPDO] ] += PDO->BitSize[PDO->nPDO];
657  Size += PDO->BitSize[PDO->nPDO];
658  c++;
659  }
660  else /* PDO deactivated because SM is 0xff or > EC_MAXSM */
661  {
662  c += 4 * e;
663  a += 8 * e;
664  c++;
665  }
666  if (PDO->nPDO >= (EC_MAXEEPDO - 1))
667  {
668  c = PDO->Length; /* limit number of PDO entries in buffer */
669  }
670  }
671  while (c < PDO->Length);
672  }
673  if (eectl)
674  {
675  ecx_eeprom2pdi(context, slave); /* if eeprom control was previously pdi then restore */
676  }
677 
678  return (Size);
679 }
680 
681 #define MAX_FPRD_MULTI 64
682 
683 int ecx_FPRD_multi(ecx_contextt *context, int n, uint16 *configlst, ec_alstatust *slstatlst, int timeout)
684 {
685  int wkc;
686  uint8 idx;
687  ecx_portt *port;
688  int sldatapos[MAX_FPRD_MULTI];
689  int slcnt;
690 
691  port = context->port;
692  idx = ecx_getindex(port);
693  slcnt = 0;
694  ecx_setupdatagram(port, &(port->txbuf[idx]), EC_CMD_FPRD, idx,
695  *(configlst + slcnt), ECT_REG_ALSTAT, sizeof(ec_alstatust), slstatlst + slcnt);
696  sldatapos[slcnt] = EC_HEADERSIZE;
697  while(++slcnt < (n - 1))
698  {
699  sldatapos[slcnt] = ecx_adddatagram(port, &(port->txbuf[idx]), EC_CMD_FPRD, idx, TRUE,
700  *(configlst + slcnt), ECT_REG_ALSTAT, sizeof(ec_alstatust), slstatlst + slcnt);
701  }
702  if(slcnt < n)
703  {
704  sldatapos[slcnt] = ecx_adddatagram(port, &(port->txbuf[idx]), EC_CMD_FPRD, idx, FALSE,
705  *(configlst + slcnt), ECT_REG_ALSTAT, sizeof(ec_alstatust), slstatlst + slcnt);
706  }
707  wkc = ecx_srconfirm(port, idx, timeout);
708  if (wkc >= 0)
709  {
710  for(slcnt = 0 ; slcnt < n ; slcnt++)
711  {
712  memcpy(slstatlst + slcnt, &(port->rxbuf[idx][sldatapos[slcnt]]), sizeof(ec_alstatust));
713  }
714  }
715  ecx_setbufstat(port, idx, EC_BUF_EMPTY);
716  return wkc;
717 }
718 
724 {
725  uint16 slave, fslave, lslave, configadr, lowest, rval, bitwisestate;
727  uint16 slca[MAX_FPRD_MULTI];
728  boolean noerrorflag, allslavessamestate;
729  boolean allslavespresent = FALSE;
730  int wkc;
731 
732  /* Try to establish the state of all slaves sending only one broadcast datagram.
733  * This way a number of datagrams equal to the number of slaves will be sent only if needed.*/
734  rval = 0;
735  wkc = ecx_BRD(context->port, 0, ECT_REG_ALSTAT, sizeof(rval), &rval, EC_TIMEOUTRET);
736 
737  if(wkc >= *(context->slavecount))
738  {
739  allslavespresent = TRUE;
740  }
741 
742  rval = etohs(rval);
743  bitwisestate = (rval & 0x0f);
744 
745  if ((rval & EC_STATE_ERROR) == 0)
746  {
747  noerrorflag = TRUE;
748  context->slavelist[0].ALstatuscode = 0;
749  }
750  else
751  {
752  noerrorflag = FALSE;
753  }
754 
755  switch (bitwisestate)
756  {
757  case EC_STATE_INIT:
758  case EC_STATE_PRE_OP:
759  case EC_STATE_BOOT:
760  case EC_STATE_SAFE_OP:
762  allslavessamestate = TRUE;
763  context->slavelist[0].state = bitwisestate;
764  break;
765  default:
766  allslavessamestate = FALSE;
767  break;
768  }
769 
770  if (noerrorflag && allslavessamestate && allslavespresent)
771  {
772  /* No slave has toggled the error flag so the alstatuscode
773  * (even if different from 0) should be ignored and
774  * the slaves have reached the same state so the internal state
775  * can be updated without sending any datagram. */
776  for (slave = 1; slave <= *(context->slavecount); slave++)
777  {
778  context->slavelist[slave].ALstatuscode = 0x0000;
779  context->slavelist[slave].state = bitwisestate;
780  }
781  lowest = bitwisestate;
782  }
783  else
784  {
785  /* Not all slaves have the same state or at least one is in error so one datagram per slave
786  * is needed. */
787  context->slavelist[0].ALstatuscode = 0;
788  lowest = 0xff;
789  fslave = 1;
790  do
791  {
792  lslave = *(context->slavecount);
793  if ((lslave - fslave) >= MAX_FPRD_MULTI)
794  {
795  lslave = fslave + MAX_FPRD_MULTI - 1;
796  }
797  for (slave = fslave; slave <= lslave; slave++)
798  {
799  const ec_alstatust zero = { 0, 0, 0 };
800 
801  configadr = context->slavelist[slave].configadr;
802  slca[slave - fslave] = configadr;
803  sl[slave - fslave] = zero;
804  }
805  ecx_FPRD_multi(context, (lslave - fslave) + 1, &(slca[0]), &(sl[0]), EC_TIMEOUTRET3);
806  for (slave = fslave; slave <= lslave; slave++)
807  {
808  configadr = context->slavelist[slave].configadr;
809  rval = etohs(sl[slave - fslave].alstatus);
810  context->slavelist[slave].ALstatuscode = etohs(sl[slave - fslave].alstatuscode);
811  if ((rval & 0xf) < lowest)
812  {
813  lowest = (rval & 0xf);
814  }
815  context->slavelist[slave].state = rval;
816  context->slavelist[0].ALstatuscode |= context->slavelist[slave].ALstatuscode;
817  }
818  fslave = lslave + 1;
819  } while (lslave < *(context->slavecount));
820  context->slavelist[0].state = lowest;
821  }
822 
823  return lowest;
824 }
825 
833 {
834  int ret;
835  uint16 configadr, slstate;
836 
837  if (slave == 0)
838  {
839  slstate = htoes(context->slavelist[slave].state);
840  ret = ecx_BWR(context->port, 0, ECT_REG_ALCTL, sizeof(slstate),
841  &slstate, EC_TIMEOUTRET3);
842  }
843  else
844  {
845  configadr = context->slavelist[slave].configadr;
846 
847  ret = ecx_FPWRw(context->port, configadr, ECT_REG_ALCTL,
848  htoes(context->slavelist[slave].state), EC_TIMEOUTRET3);
849  }
850  return ret;
851 }
852 
862 uint16 ecx_statecheck(ecx_contextt *context, uint16 slave, uint16 reqstate, int timeout)
863 {
864  uint16 configadr, state, rval;
865  ec_alstatust slstat;
866  osal_timert timer;
867 
868  if ( slave > *(context->slavecount) )
869  {
870  return 0;
871  }
872  osal_timer_start(&timer, timeout);
873  configadr = context->slavelist[slave].configadr;
874  do
875  {
876  if (slave < 1)
877  {
878  rval = 0;
879  ecx_BRD(context->port, 0, ECT_REG_ALSTAT, sizeof(rval), &rval , EC_TIMEOUTRET);
880  rval = etohs(rval);
881  }
882  else
883  {
884  slstat.alstatus = 0;
885  slstat.alstatuscode = 0;
886  ecx_FPRD(context->port, configadr, ECT_REG_ALSTAT, sizeof(slstat), &slstat, EC_TIMEOUTRET);
887  rval = etohs(slstat.alstatus);
888  context->slavelist[slave].ALstatuscode = etohs(slstat.alstatuscode);
889  }
890  state = rval & 0x000f; /* read slave status */
891  if (state != reqstate)
892  {
893  osal_usleep(1000);
894  }
895  }
896  while ((state != reqstate) && (osal_timer_is_expired(&timer) == FALSE));
897  context->slavelist[slave].state = rval;
898 
899  return state;
900 }
901 
908 {
909  cnt++;
910  if (cnt > 7)
911  {
912  cnt = 1; /* wrap around to 1, not 0 */
913  }
914 
915  return cnt;
916 }
917 
922 {
923  memset(Mbx, 0x00, EC_MAXMBX);
924 }
925 
932 int ecx_mbxempty(ecx_contextt *context, uint16 slave, int timeout)
933 {
934  uint16 configadr;
935  uint8 SMstat;
936  int wkc;
937  osal_timert timer;
938 
939  osal_timer_start(&timer, timeout);
940  configadr = context->slavelist[slave].configadr;
941  do
942  {
943  SMstat = 0;
944  wkc = ecx_FPRD(context->port, configadr, ECT_REG_SM0STAT, sizeof(SMstat), &SMstat, EC_TIMEOUTRET);
945  SMstat = etohs(SMstat);
946  if (((SMstat & 0x08) != 0) && (timeout > EC_LOCALDELAY))
947  {
949  }
950  }
951  while (((wkc <= 0) || ((SMstat & 0x08) != 0)) && (osal_timer_is_expired(&timer) == FALSE));
952 
953  if ((wkc > 0) && ((SMstat & 0x08) == 0))
954  {
955  return 1;
956  }
957 
958  return 0;
959 }
960 
968 int ecx_mbxsend(ecx_contextt *context, uint16 slave,ec_mbxbuft *mbx, int timeout)
969 {
970  uint16 mbxwo,mbxl,configadr;
971  int wkc;
972 
973  wkc = 0;
974  configadr = context->slavelist[slave].configadr;
975  mbxl = context->slavelist[slave].mbx_l;
976  if ((mbxl > 0) && (mbxl <= EC_MAXMBX))
977  {
978  if (ecx_mbxempty(context, slave, timeout))
979  {
980  mbxwo = context->slavelist[slave].mbx_wo;
981  /* write slave in mailbox */
982  wkc = ecx_FPWR(context->port, configadr, mbxwo, mbxl, mbx, EC_TIMEOUTRET3);
983  }
984  else
985  {
986  wkc = 0;
987  }
988  }
989 
990  return wkc;
991 }
992 
1001 int ecx_mbxreceive(ecx_contextt *context, uint16 slave, ec_mbxbuft *mbx, int timeout)
1002 {
1003  uint16 mbxro,mbxl,configadr;
1004  int wkc=0;
1005  int wkc2;
1006  uint16 SMstat;
1007  uint8 SMcontr;
1008  ec_mbxheadert *mbxh;
1009  ec_emcyt *EMp;
1010  ec_mbxerrort *MBXEp;
1011 
1012  configadr = context->slavelist[slave].configadr;
1013  mbxl = context->slavelist[slave].mbx_rl;
1014  if ((mbxl > 0) && (mbxl <= EC_MAXMBX))
1015  {
1016  osal_timert timer;
1017 
1018  osal_timer_start(&timer, timeout);
1019  wkc = 0;
1020  do /* wait for read mailbox available */
1021  {
1022  SMstat = 0;
1023  wkc = ecx_FPRD(context->port, configadr, ECT_REG_SM1STAT, sizeof(SMstat), &SMstat, EC_TIMEOUTRET);
1024  SMstat = etohs(SMstat);
1025  if (((SMstat & 0x08) == 0) && (timeout > EC_LOCALDELAY))
1026  {
1028  }
1029  }
1030  while (((wkc <= 0) || ((SMstat & 0x08) == 0)) && (osal_timer_is_expired(&timer) == FALSE));
1031 
1032  if ((wkc > 0) && ((SMstat & 0x08) > 0)) /* read mailbox available ? */
1033  {
1034  mbxro = context->slavelist[slave].mbx_ro;
1035  mbxh = (ec_mbxheadert *)mbx;
1036  do
1037  {
1038  wkc = ecx_FPRD(context->port, configadr, mbxro, mbxl, mbx, EC_TIMEOUTRET); /* get mailbox */
1039  if ((wkc > 0) && ((mbxh->mbxtype & 0x0f) == 0x00)) /* Mailbox error response? */
1040  {
1041  MBXEp = (ec_mbxerrort *)mbx;
1042  ecx_mbxerror(context, slave, etohs(MBXEp->Detail));
1043  wkc = 0; /* prevent emergency to cascade up, it is already handled. */
1044  }
1045  else if ((wkc > 0) && ((mbxh->mbxtype & 0x0f) == ECT_MBXT_COE)) /* CoE response? */
1046  {
1047  EMp = (ec_emcyt *)mbx;
1048  if ((etohs(EMp->CANOpen) >> 12) == 0x01) /* Emergency request? */
1049  {
1050  ecx_mbxemergencyerror(context, slave, etohs(EMp->ErrorCode), EMp->ErrorReg,
1051  EMp->bData, etohs(EMp->w1), etohs(EMp->w2));
1052  wkc = 0; /* prevent emergency to cascade up, it is already handled. */
1053  }
1054  }
1055  else if ((wkc > 0) && ((mbxh->mbxtype & 0x0f) == ECT_MBXT_EOE)) /* EoE response? */
1056  {
1057  ec_EOEt * eoembx = (ec_EOEt *)mbx;
1058  uint16 frameinfo1 = etohs(eoembx->frameinfo1);
1059  /* All non fragment data frame types are expected to be handled by
1060  * slave send/receive API if the EoE hook is set
1061  */
1062  if (EOE_HDR_FRAME_TYPE_GET(frameinfo1) == EOE_FRAG_DATA)
1063  {
1064  if (context->EOEhook)
1065  {
1066  if (context->EOEhook(context, slave, eoembx) > 0)
1067  {
1068  /* Fragment handled by EoE hook */
1069  wkc = 0;
1070  }
1071  }
1072  }
1073  }
1074  else
1075  {
1076  if (wkc <= 0) /* read mailbox lost */
1077  {
1078  SMstat ^= 0x0200; /* toggle repeat request */
1079  SMstat = htoes(SMstat);
1080  wkc2 = ecx_FPWR(context->port, configadr, ECT_REG_SM1STAT, sizeof(SMstat), &SMstat, EC_TIMEOUTRET);
1081  SMstat = etohs(SMstat);
1082  do /* wait for toggle ack */
1083  {
1084  wkc2 = ecx_FPRD(context->port, configadr, ECT_REG_SM1CONTR, sizeof(SMcontr), &SMcontr, EC_TIMEOUTRET);
1085  } while (((wkc2 <= 0) || ((SMcontr & 0x02) != (HI_BYTE(SMstat) & 0x02))) && (osal_timer_is_expired(&timer) == FALSE));
1086  do /* wait for read mailbox available */
1087  {
1088  wkc2 = ecx_FPRD(context->port, configadr, ECT_REG_SM1STAT, sizeof(SMstat), &SMstat, EC_TIMEOUTRET);
1089  SMstat = etohs(SMstat);
1090  if (((SMstat & 0x08) == 0) && (timeout > EC_LOCALDELAY))
1091  {
1093  }
1094  } while (((wkc2 <= 0) || ((SMstat & 0x08) == 0)) && (osal_timer_is_expired(&timer) == FALSE));
1095  }
1096  }
1097  } while ((wkc <= 0) && (osal_timer_is_expired(&timer) == FALSE)); /* if WKC<=0 repeat */
1098  }
1099  else /* no read mailbox available */
1100  {
1101  if (wkc > 0)
1102  wkc = EC_TIMEOUT;
1103  }
1104  }
1105 
1106  return wkc;
1107 }
1108 
1115 {
1116  int address, incr;
1117  uint16 configadr;
1118  uint64 *p64;
1119  uint16 *p16;
1120  uint64 edat;
1121  uint8 eectl = context->slavelist[slave].eep_pdi;
1122 
1123  ecx_eeprom2master(context, slave); /* set eeprom control to master */
1124  configadr = context->slavelist[slave].configadr;
1125  address = ECT_SII_START;
1126  p16=(uint16*)esibuf;
1127  if (context->slavelist[slave].eep_8byte)
1128  {
1129  incr = 4;
1130  }
1131  else
1132  {
1133  incr = 2;
1134  }
1135  do
1136  {
1137  edat = ecx_readeepromFP(context, configadr, address, EC_TIMEOUTEEP);
1138  p64 = (uint64*)p16;
1139  *p64 = edat;
1140  p16 += incr;
1141  address += incr;
1142  } while ((address <= (EC_MAXEEPBUF >> 1)) && ((uint32)edat != 0xffffffff));
1143 
1144  if (eectl)
1145  {
1146  ecx_eeprom2pdi(context, slave); /* if eeprom control was previously pdi then restore */
1147  }
1148 }
1149 
1157 uint32 ecx_readeeprom(ecx_contextt *context, uint16 slave, uint16 eeproma, int timeout)
1158 {
1159  uint16 configadr;
1160 
1161  ecx_eeprom2master(context, slave); /* set eeprom control to master */
1162  configadr = context->slavelist[slave].configadr;
1163 
1164  return ((uint32)ecx_readeepromFP(context, configadr, eeproma, timeout));
1165 }
1166 
1175 int ecx_writeeeprom(ecx_contextt *context, uint16 slave, uint16 eeproma, uint16 data, int timeout)
1176 {
1177  uint16 configadr;
1178 
1179  ecx_eeprom2master(context, slave); /* set eeprom control to master */
1180  configadr = context->slavelist[slave].configadr;
1181  return (ecx_writeeepromFP(context, configadr, eeproma, data, timeout));
1182 }
1183 
1190 {
1191  int wkc = 1, cnt = 0;
1192  uint16 configadr;
1193  uint8 eepctl;
1194 
1195  if ( context->slavelist[slave].eep_pdi )
1196  {
1197  configadr = context->slavelist[slave].configadr;
1198  eepctl = 2;
1199  do
1200  {
1201  wkc = ecx_FPWR(context->port, configadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET); /* force Eeprom from PDI */
1202  }
1203  while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
1204  eepctl = 0;
1205  cnt = 0;
1206  do
1207  {
1208  wkc = ecx_FPWR(context->port, configadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET); /* set Eeprom to master */
1209  }
1210  while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
1211  context->slavelist[slave].eep_pdi = 0;
1212  }
1213 
1214  return wkc;
1215 }
1216 
1223 {
1224  int wkc = 1, cnt = 0;
1225  uint16 configadr;
1226  uint8 eepctl;
1227 
1228  if ( !context->slavelist[slave].eep_pdi )
1229  {
1230  configadr = context->slavelist[slave].configadr;
1231  eepctl = 1;
1232  do
1233  {
1234  wkc = ecx_FPWR(context->port, configadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET); /* set Eeprom to PDI */
1235  }
1236  while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
1237  context->slavelist[slave].eep_pdi = 1;
1238  }
1239 
1240  return wkc;
1241 }
1242 
1243 uint16 ecx_eeprom_waitnotbusyAP(ecx_contextt *context, uint16 aiadr,uint16 *estat, int timeout)
1244 {
1245  int wkc, cnt = 0, retval = 0;
1246  osal_timert timer;
1247 
1248  osal_timer_start(&timer, timeout);
1249  do
1250  {
1251  if (cnt++)
1252  {
1254  }
1255  *estat = 0;
1256  wkc=ecx_APRD(context->port, aiadr, ECT_REG_EEPSTAT, sizeof(*estat), estat, EC_TIMEOUTRET);
1257  *estat = etohs(*estat);
1258  }
1259  while (((wkc <= 0) || ((*estat & EC_ESTAT_BUSY) > 0)) && (osal_timer_is_expired(&timer) == FALSE)); /* wait for eeprom ready */
1260  if ((*estat & EC_ESTAT_BUSY) == 0)
1261  {
1262  retval = 1;
1263  }
1264 
1265  return retval;
1266 }
1267 
1275 uint64 ecx_readeepromAP(ecx_contextt *context, uint16 aiadr, uint16 eeproma, int timeout)
1276 {
1277  uint16 estat;
1278  uint32 edat32;
1279  uint64 edat64;
1280  ec_eepromt ed;
1281  int wkc, cnt, nackcnt = 0;
1282 
1283  edat64 = 0;
1284  edat32 = 0;
1285  if (ecx_eeprom_waitnotbusyAP(context, aiadr, &estat, timeout))
1286  {
1287  if (estat & EC_ESTAT_EMASK) /* error bits are set */
1288  {
1289  estat = htoes(EC_ECMD_NOP); /* clear error bits */
1290  wkc = ecx_APWR(context->port, aiadr, ECT_REG_EEPCTL, sizeof(estat), &estat, EC_TIMEOUTRET3);
1291  }
1292 
1293  do
1294  {
1295  ed.comm = htoes(EC_ECMD_READ);
1296  ed.addr = htoes(eeproma);
1297  ed.d2 = 0x0000;
1298  cnt = 0;
1299  do
1300  {
1301  wkc = ecx_APWR(context->port, aiadr, ECT_REG_EEPCTL, sizeof(ed), &ed, EC_TIMEOUTRET);
1302  }
1303  while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
1304  if (wkc)
1305  {
1307  estat = 0x0000;
1308  if (ecx_eeprom_waitnotbusyAP(context, aiadr, &estat, timeout))
1309  {
1310  if (estat & EC_ESTAT_NACK)
1311  {
1312  nackcnt++;
1314  }
1315  else
1316  {
1317  nackcnt = 0;
1318  if (estat & EC_ESTAT_R64)
1319  {
1320  cnt = 0;
1321  do
1322  {
1323  wkc = ecx_APRD(context->port, aiadr, ECT_REG_EEPDAT, sizeof(edat64), &edat64, EC_TIMEOUTRET);
1324  }
1325  while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
1326  }
1327  else
1328  {
1329  cnt = 0;
1330  do
1331  {
1332  wkc = ecx_APRD(context->port, aiadr, ECT_REG_EEPDAT, sizeof(edat32), &edat32, EC_TIMEOUTRET);
1333  }
1334  while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
1335  edat64=(uint64)edat32;
1336  }
1337  }
1338  }
1339  }
1340  }
1341  while ((nackcnt > 0) && (nackcnt < 3));
1342  }
1343 
1344  return edat64;
1345 }
1346 
1355 int ecx_writeeepromAP(ecx_contextt *context, uint16 aiadr, uint16 eeproma, uint16 data, int timeout)
1356 {
1357  uint16 estat;
1358  ec_eepromt ed;
1359  int wkc, rval = 0, cnt = 0, nackcnt = 0;
1360 
1361  if (ecx_eeprom_waitnotbusyAP(context, aiadr, &estat, timeout))
1362  {
1363  if (estat & EC_ESTAT_EMASK) /* error bits are set */
1364  {
1365  estat = htoes(EC_ECMD_NOP); /* clear error bits */
1366  wkc = ecx_APWR(context->port, aiadr, ECT_REG_EEPCTL, sizeof(estat), &estat, EC_TIMEOUTRET3);
1367  }
1368  do
1369  {
1370  cnt = 0;
1371  do
1372  {
1373  wkc = ecx_APWR(context->port, aiadr, ECT_REG_EEPDAT, sizeof(data), &data, EC_TIMEOUTRET);
1374  }
1375  while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
1376 
1377  ed.comm = EC_ECMD_WRITE;
1378  ed.addr = eeproma;
1379  ed.d2 = 0x0000;
1380  cnt = 0;
1381  do
1382  {
1383  wkc = ecx_APWR(context->port, aiadr, ECT_REG_EEPCTL, sizeof(ed), &ed, EC_TIMEOUTRET);
1384  }
1385  while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
1386  if (wkc)
1387  {
1389  estat = 0x0000;
1390  if (ecx_eeprom_waitnotbusyAP(context, aiadr, &estat, timeout))
1391  {
1392  if (estat & EC_ESTAT_NACK)
1393  {
1394  nackcnt++;
1396  }
1397  else
1398  {
1399  nackcnt = 0;
1400  rval = 1;
1401  }
1402  }
1403  }
1404 
1405  }
1406  while ((nackcnt > 0) && (nackcnt < 3));
1407  }
1408 
1409  return rval;
1410 }
1411 
1412 uint16 ecx_eeprom_waitnotbusyFP(ecx_contextt *context, uint16 configadr,uint16 *estat, int timeout)
1413 {
1414  int wkc, cnt = 0, retval = 0;
1415  osal_timert timer;
1416 
1417  osal_timer_start(&timer, timeout);
1418  do
1419  {
1420  if (cnt++)
1421  {
1423  }
1424  *estat = 0;
1425  wkc=ecx_FPRD(context->port, configadr, ECT_REG_EEPSTAT, sizeof(*estat), estat, EC_TIMEOUTRET);
1426  *estat = etohs(*estat);
1427  }
1428  while (((wkc <= 0) || ((*estat & EC_ESTAT_BUSY) > 0)) && (osal_timer_is_expired(&timer) == FALSE)); /* wait for eeprom ready */
1429  if ((*estat & EC_ESTAT_BUSY) == 0)
1430  {
1431  retval = 1;
1432  }
1433 
1434  return retval;
1435 }
1436 
1444 uint64 ecx_readeepromFP(ecx_contextt *context, uint16 configadr, uint16 eeproma, int timeout)
1445 {
1446  uint16 estat;
1447  uint32 edat32;
1448  uint64 edat64;
1449  ec_eepromt ed;
1450  int wkc, cnt, nackcnt = 0;
1451 
1452  edat64 = 0;
1453  edat32 = 0;
1454  if (ecx_eeprom_waitnotbusyFP(context, configadr, &estat, timeout))
1455  {
1456  if (estat & EC_ESTAT_EMASK) /* error bits are set */
1457  {
1458  estat = htoes(EC_ECMD_NOP); /* clear error bits */
1459  wkc=ecx_FPWR(context->port, configadr, ECT_REG_EEPCTL, sizeof(estat), &estat, EC_TIMEOUTRET3);
1460  }
1461 
1462  do
1463  {
1464  ed.comm = htoes(EC_ECMD_READ);
1465  ed.addr = htoes(eeproma);
1466  ed.d2 = 0x0000;
1467  cnt = 0;
1468  do
1469  {
1470  wkc=ecx_FPWR(context->port, configadr, ECT_REG_EEPCTL, sizeof(ed), &ed, EC_TIMEOUTRET);
1471  }
1472  while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
1473  if (wkc)
1474  {
1476  estat = 0x0000;
1477  if (ecx_eeprom_waitnotbusyFP(context, configadr, &estat, timeout))
1478  {
1479  if (estat & EC_ESTAT_NACK)
1480  {
1481  nackcnt++;
1483  }
1484  else
1485  {
1486  nackcnt = 0;
1487  if (estat & EC_ESTAT_R64)
1488  {
1489  cnt = 0;
1490  do
1491  {
1492  wkc=ecx_FPRD(context->port, configadr, ECT_REG_EEPDAT, sizeof(edat64), &edat64, EC_TIMEOUTRET);
1493  }
1494  while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
1495  }
1496  else
1497  {
1498  cnt = 0;
1499  do
1500  {
1501  wkc=ecx_FPRD(context->port, configadr, ECT_REG_EEPDAT, sizeof(edat32), &edat32, EC_TIMEOUTRET);
1502  }
1503  while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
1504  edat64=(uint64)edat32;
1505  }
1506  }
1507  }
1508  }
1509  }
1510  while ((nackcnt > 0) && (nackcnt < 3));
1511  }
1512 
1513  return edat64;
1514 }
1515 
1524 int ecx_writeeepromFP(ecx_contextt *context, uint16 configadr, uint16 eeproma, uint16 data, int timeout)
1525 {
1526  uint16 estat;
1527  ec_eepromt ed;
1528  int wkc, rval = 0, cnt = 0, nackcnt = 0;
1529 
1530  if (ecx_eeprom_waitnotbusyFP(context, configadr, &estat, timeout))
1531  {
1532  if (estat & EC_ESTAT_EMASK) /* error bits are set */
1533  {
1534  estat = htoes(EC_ECMD_NOP); /* clear error bits */
1535  wkc = ecx_FPWR(context->port, configadr, ECT_REG_EEPCTL, sizeof(estat), &estat, EC_TIMEOUTRET3);
1536  }
1537  do
1538  {
1539  cnt = 0;
1540  do
1541  {
1542  wkc = ecx_FPWR(context->port, configadr, ECT_REG_EEPDAT, sizeof(data), &data, EC_TIMEOUTRET);
1543  }
1544  while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
1545  ed.comm = EC_ECMD_WRITE;
1546  ed.addr = eeproma;
1547  ed.d2 = 0x0000;
1548  cnt = 0;
1549  do
1550  {
1551  wkc = ecx_FPWR(context->port, configadr, ECT_REG_EEPCTL, sizeof(ed), &ed, EC_TIMEOUTRET);
1552  }
1553  while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
1554  if (wkc)
1555  {
1557  estat = 0x0000;
1558  if (ecx_eeprom_waitnotbusyFP(context, configadr, &estat, timeout))
1559  {
1560  if (estat & EC_ESTAT_NACK)
1561  {
1562  nackcnt++;
1564  }
1565  else
1566  {
1567  nackcnt = 0;
1568  rval = 1;
1569  }
1570  }
1571  }
1572  }
1573  while ((nackcnt > 0) && (nackcnt < 3));
1574  }
1575 
1576  return rval;
1577 }
1578 
1586 {
1587  uint16 configadr, estat;
1588  ec_eepromt ed;
1589  int wkc, cnt = 0;
1590 
1591  ecx_eeprom2master(context, slave); /* set eeprom control to master */
1592  configadr = context->slavelist[slave].configadr;
1593  if (ecx_eeprom_waitnotbusyFP(context, configadr, &estat, EC_TIMEOUTEEP))
1594  {
1595  if (estat & EC_ESTAT_EMASK) /* error bits are set */
1596  {
1597  estat = htoes(EC_ECMD_NOP); /* clear error bits */
1598  wkc = ecx_FPWR(context->port, configadr, ECT_REG_EEPCTL, sizeof(estat), &estat, EC_TIMEOUTRET3);
1599  }
1600  ed.comm = htoes(EC_ECMD_READ);
1601  ed.addr = htoes(eeproma);
1602  ed.d2 = 0x0000;
1603  do
1604  {
1605  wkc = ecx_FPWR(context->port, configadr, ECT_REG_EEPCTL, sizeof(ed), &ed, EC_TIMEOUTRET);
1606  }
1607  while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
1608  }
1609 }
1610 
1619 {
1620  uint16 estat, configadr;
1621  uint32 edat;
1622  int wkc, cnt = 0;
1623 
1624  configadr = context->slavelist[slave].configadr;
1625  edat = 0;
1626  estat = 0x0000;
1627  if (ecx_eeprom_waitnotbusyFP(context, configadr, &estat, timeout))
1628  {
1629  do
1630  {
1631  wkc = ecx_FPRD(context->port, configadr, ECT_REG_EEPDAT, sizeof(edat), &edat, EC_TIMEOUTRET);
1632  }
1633  while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
1634  }
1635 
1636  return edat;
1637 }
1638 
1645 static void ecx_pushindex(ecx_contextt *context, uint8 idx, void *data, uint16 length)
1646 {
1647  if(context->idxstack->pushed < EC_MAXBUF)
1648  {
1649  context->idxstack->idx[context->idxstack->pushed] = idx;
1650  context->idxstack->data[context->idxstack->pushed] = data;
1651  context->idxstack->length[context->idxstack->pushed] = length;
1652  context->idxstack->pushed++;
1653  }
1654 }
1655 
1660 static int ecx_pullindex(ecx_contextt *context)
1661 {
1662  int rval = -1;
1663  if(context->idxstack->pulled < context->idxstack->pushed)
1664  {
1665  rval = context->idxstack->pulled;
1666  context->idxstack->pulled++;
1667  }
1668 
1669  return rval;
1670 }
1671 
1677 static void ecx_clearindex(ecx_contextt *context) {
1678 
1679  context->idxstack->pushed = 0;
1680  context->idxstack->pulled = 0;
1681 
1682 }
1683 
1697 static int ecx_main_send_processdata(ecx_contextt *context, uint8 group, boolean use_overlap_io)
1698 {
1699  uint32 LogAdr;
1700  uint16 w1, w2;
1701  int length, sublength;
1702  uint8 idx;
1703  int wkc;
1704  uint8* data;
1705  boolean first=FALSE;
1706  uint16 currentsegment = 0;
1707  uint32 iomapinputoffset;
1708 
1709  wkc = 0;
1710  if(context->grouplist[group].hasdc)
1711  {
1712  first = TRUE;
1713  }
1714 
1715  /* For overlapping IO map use the biggest */
1716  if(use_overlap_io == TRUE)
1717  {
1718  /* For overlap IOmap make the frame EQ big to biggest part */
1719  length = (context->grouplist[group].Obytes > context->grouplist[group].Ibytes) ?
1720  context->grouplist[group].Obytes : context->grouplist[group].Ibytes;
1721  /* Save the offset used to compensate where to save inputs when frame returns */
1722  iomapinputoffset = context->grouplist[group].Obytes;
1723  }
1724  else
1725  {
1726  length = context->grouplist[group].Obytes + context->grouplist[group].Ibytes;
1727  iomapinputoffset = 0;
1728  }
1729 
1730  LogAdr = context->grouplist[group].logstartaddr;
1731  if(length)
1732  {
1733 
1734  wkc = 1;
1735  /* LRW blocked by one or more slaves ? */
1736  if(context->grouplist[group].blockLRW)
1737  {
1738  /* if inputs available generate LRD */
1739  if(context->grouplist[group].Ibytes)
1740  {
1741  currentsegment = context->grouplist[group].Isegment;
1742  data = context->grouplist[group].inputs;
1743  length = context->grouplist[group].Ibytes;
1744  LogAdr += context->grouplist[group].Obytes;
1745  /* segment transfer if needed */
1746  do
1747  {
1748  if(currentsegment == context->grouplist[group].Isegment)
1749  {
1750  sublength = context->grouplist[group].IOsegment[currentsegment++] - context->grouplist[group].Ioffset;
1751  }
1752  else
1753  {
1754  sublength = context->grouplist[group].IOsegment[currentsegment++];
1755  }
1756  /* get new index */
1757  idx = ecx_getindex(context->port);
1758  w1 = LO_WORD(LogAdr);
1759  w2 = HI_WORD(LogAdr);
1760  ecx_setupdatagram(context->port, &(context->port->txbuf[idx]), EC_CMD_LRD, idx, w1, w2, sublength, data);
1761  if(first)
1762  {
1763  context->DCl = sublength;
1764  /* FPRMW in second datagram */
1765  context->DCtO = ecx_adddatagram(context->port, &(context->port->txbuf[idx]), EC_CMD_FRMW, idx, FALSE,
1766  context->slavelist[context->grouplist[group].DCnext].configadr,
1767  ECT_REG_DCSYSTIME, sizeof(int64), context->DCtime);
1768  first = FALSE;
1769  }
1770  /* send frame */
1771  ecx_outframe_red(context->port, idx);
1772  /* push index and data pointer on stack */
1773  ecx_pushindex(context, idx, data, sublength);
1774  length -= sublength;
1775  LogAdr += sublength;
1776  data += sublength;
1777  } while (length && (currentsegment < context->grouplist[group].nsegments));
1778  }
1779  /* if outputs available generate LWR */
1780  if(context->grouplist[group].Obytes)
1781  {
1782  data = context->grouplist[group].outputs;
1783  length = context->grouplist[group].Obytes;
1784  LogAdr = context->grouplist[group].logstartaddr;
1785  currentsegment = 0;
1786  /* segment transfer if needed */
1787  do
1788  {
1789  sublength = context->grouplist[group].IOsegment[currentsegment++];
1790  if((length - sublength) < 0)
1791  {
1792  sublength = length;
1793  }
1794  /* get new index */
1795  idx = ecx_getindex(context->port);
1796  w1 = LO_WORD(LogAdr);
1797  w2 = HI_WORD(LogAdr);
1798  ecx_setupdatagram(context->port, &(context->port->txbuf[idx]), EC_CMD_LWR, idx, w1, w2, sublength, data);
1799  if(first)
1800  {
1801  context->DCl = sublength;
1802  /* FPRMW in second datagram */
1803  context->DCtO = ecx_adddatagram(context->port, &(context->port->txbuf[idx]), EC_CMD_FRMW, idx, FALSE,
1804  context->slavelist[context->grouplist[group].DCnext].configadr,
1805  ECT_REG_DCSYSTIME, sizeof(int64), context->DCtime);
1806  first = FALSE;
1807  }
1808  /* send frame */
1809  ecx_outframe_red(context->port, idx);
1810  /* push index and data pointer on stack */
1811  ecx_pushindex(context, idx, data, sublength);
1812  length -= sublength;
1813  LogAdr += sublength;
1814  data += sublength;
1815  } while (length && (currentsegment < context->grouplist[group].nsegments));
1816  }
1817  }
1818  /* LRW can be used */
1819  else
1820  {
1821  if (context->grouplist[group].Obytes)
1822  {
1823  data = context->grouplist[group].outputs;
1824  }
1825  else
1826  {
1827  data = context->grouplist[group].inputs;
1828  /* Clear offset, don't compensate for overlapping IOmap if we only got inputs */
1829  iomapinputoffset = 0;
1830  }
1831  /* segment transfer if needed */
1832  do
1833  {
1834  sublength = context->grouplist[group].IOsegment[currentsegment++];
1835  /* get new index */
1836  idx = ecx_getindex(context->port);
1837  w1 = LO_WORD(LogAdr);
1838  w2 = HI_WORD(LogAdr);
1839  ecx_setupdatagram(context->port, &(context->port->txbuf[idx]), EC_CMD_LRW, idx, w1, w2, sublength, data);
1840  if(first)
1841  {
1842  context->DCl = sublength;
1843  /* FPRMW in second datagram */
1844  context->DCtO = ecx_adddatagram(context->port, &(context->port->txbuf[idx]), EC_CMD_FRMW, idx, FALSE,
1845  context->slavelist[context->grouplist[group].DCnext].configadr,
1846  ECT_REG_DCSYSTIME, sizeof(int64), context->DCtime);
1847  first = FALSE;
1848  }
1849  /* send frame */
1850  ecx_outframe_red(context->port, idx);
1851  /* push index and data pointer on stack.
1852  * the iomapinputoffset compensate for where the inputs are stored
1853  * in the IOmap if we use an overlapping IOmap. If a regular IOmap
1854  * is used it should always be 0.
1855  */
1856  ecx_pushindex(context, idx, (data + iomapinputoffset), sublength);
1857  length -= sublength;
1858  LogAdr += sublength;
1859  data += sublength;
1860  } while (length && (currentsegment < context->grouplist[group].nsegments));
1861  }
1862  }
1863 
1864  return wkc;
1865 }
1866 
1880 {
1881  return ecx_main_send_processdata(context, group, TRUE);
1882 }
1883 
1897 {
1898  return ecx_main_send_processdata(context, group, FALSE);
1899 }
1900 
1910 int ecx_receive_processdata_group(ecx_contextt *context, uint8 group, int timeout)
1911 {
1912  int pos, idx;
1913  int wkc = 0, wkc2;
1914  uint16 le_wkc = 0;
1915  int valid_wkc = 0;
1916  int64 le_DCtime;
1917  boolean first = FALSE;
1918 
1919  if(context->grouplist[group].hasdc)
1920  {
1921  first = TRUE;
1922  }
1923  /* get first index */
1924  pos = ecx_pullindex(context);
1925  /* read the same number of frames as send */
1926  while (pos >= 0)
1927  {
1928  idx = context->idxstack->idx[pos];
1929  wkc2 = ecx_waitinframe(context->port, context->idxstack->idx[pos], timeout);
1930  /* check if there is input data in frame */
1931  if (wkc2 > EC_NOFRAME)
1932  {
1933  if((context->port->rxbuf[idx][EC_CMDOFFSET]==EC_CMD_LRD) || (context->port->rxbuf[idx][EC_CMDOFFSET]==EC_CMD_LRW))
1934  {
1935  if(first)
1936  {
1937  memcpy(context->idxstack->data[pos], &(context->port->rxbuf[idx][EC_HEADERSIZE]), context->DCl);
1938  memcpy(&le_wkc, &(context->port->rxbuf[idx][EC_HEADERSIZE + context->DCl]), EC_WKCSIZE);
1939  wkc = etohs(le_wkc);
1940  memcpy(&le_DCtime, &(context->port->rxbuf[idx][context->DCtO]), sizeof(le_DCtime));
1941  *(context->DCtime) = etohll(le_DCtime);
1942  first = FALSE;
1943  }
1944  else
1945  {
1946  /* copy input data back to process data buffer */
1947  memcpy(context->idxstack->data[pos], &(context->port->rxbuf[idx][EC_HEADERSIZE]), context->idxstack->length[pos]);
1948  wkc += wkc2;
1949  }
1950  valid_wkc = 1;
1951  }
1952  else if(context->port->rxbuf[idx][EC_CMDOFFSET]==EC_CMD_LWR)
1953  {
1954  if(first)
1955  {
1956  memcpy(&le_wkc, &(context->port->rxbuf[idx][EC_HEADERSIZE + context->DCl]), EC_WKCSIZE);
1957  /* output WKC counts 2 times when using LRW, emulate the same for LWR */
1958  wkc = etohs(le_wkc) * 2;
1959  memcpy(&le_DCtime, &(context->port->rxbuf[idx][context->DCtO]), sizeof(le_DCtime));
1960  *(context->DCtime) = etohll(le_DCtime);
1961  first = FALSE;
1962  }
1963  else
1964  {
1965  /* output WKC counts 2 times when using LRW, emulate the same for LWR */
1966  wkc += wkc2 * 2;
1967  }
1968  valid_wkc = 1;
1969  }
1970  }
1971  /* release buffer */
1972  ecx_setbufstat(context->port, idx, EC_BUF_EMPTY);
1973  /* get next index */
1974  pos = ecx_pullindex(context);
1975  }
1976 
1977  ecx_clearindex(context);
1978 
1979  /* if no frames has arrived */
1980  if (valid_wkc == 0)
1981  {
1982  return EC_NOFRAME;
1983  }
1984  return wkc;
1985 }
1986 
1987 
1989 {
1990  return ecx_send_processdata_group(context, 0);
1991 }
1992 
1994 {
1995  return ecx_send_overlap_processdata_group(context, 0);
1996 }
1997 
1998 int ecx_receive_processdata(ecx_contextt *context, int timeout)
1999 {
2000  return ecx_receive_processdata_group(context, 0, timeout);
2001 }
2002 
2003 #ifdef EC_VER1
2004 void ec_pusherror(const ec_errort *Ec)
2005 {
2006  ecx_pusherror(&ecx_context, Ec);
2007 }
2008 
2010 {
2011  return ecx_poperror(&ecx_context, Ec);
2012 }
2013 
2014 boolean ec_iserror(void)
2015 {
2016  return ecx_iserror(&ecx_context);
2017 }
2018 
2020 {
2021  ecx_packeterror(&ecx_context, Slave, Index, SubIdx, ErrorCode);
2022 }
2023 
2029 int ec_init(const char * ifname)
2030 {
2031  return ecx_init(&ecx_context, ifname);
2032 }
2033 
2040 int ec_init_redundant(const char *ifname, char *if2name)
2041 {
2042  return ecx_init_redundant (&ecx_context, &ecx_redport, ifname, if2name);
2043 }
2044 
2048 void ec_close(void)
2049 {
2050  ecx_close(&ecx_context);
2051 };
2052 
2062 {
2063  return ecx_siigetbyte (&ecx_context, slave, address);
2064 }
2065 
2073 {
2074  return ecx_siifind (&ecx_context, slave, cat);
2075 }
2076 
2083 void ec_siistring(char *str, uint16 slave, uint16 Sn)
2084 {
2085  ecx_siistring(&ecx_context, str, slave, Sn);
2086 }
2087 
2095 {
2096  return ecx_siiFMMU (&ecx_context, slave, FMMU);
2097 }
2098 
2106 {
2107  return ecx_siiSM (&ecx_context, slave, SM);
2108 }
2109 
2118 {
2119  return ecx_siiSMnext (&ecx_context, slave, SM, n);
2120 }
2121 
2130 {
2131  return ecx_siiPDO (&ecx_context, slave, PDO, t);
2132 }
2133 
2138 int ec_readstate(void)
2139 {
2140  return ecx_readstate (&ecx_context);
2141 }
2142 
2150 {
2151  return ecx_writestate(&ecx_context, slave);
2152 }
2153 
2162 uint16 ec_statecheck(uint16 slave, uint16 reqstate, int timeout)
2163 {
2164  return ecx_statecheck (&ecx_context, slave, reqstate, timeout);
2165 }
2166 
2173 int ec_mbxempty(uint16 slave, int timeout)
2174 {
2175  return ecx_mbxempty (&ecx_context, slave, timeout);
2176 }
2177 
2185 int ec_mbxsend(uint16 slave,ec_mbxbuft *mbx, int timeout)
2186 {
2187  return ecx_mbxsend (&ecx_context, slave, mbx, timeout);
2188 }
2189 
2198 int ec_mbxreceive(uint16 slave, ec_mbxbuft *mbx, int timeout)
2199 {
2200  return ecx_mbxreceive (&ecx_context, slave, mbx, timeout);
2201 }
2202 
2209 {
2210  ecx_esidump (&ecx_context, slave, esibuf);
2211 }
2212 
2220 uint32 ec_readeeprom(uint16 slave, uint16 eeproma, int timeout)
2221 {
2222  return ecx_readeeprom (&ecx_context, slave, eeproma, timeout);
2223 }
2224 
2233 int ec_writeeeprom(uint16 slave, uint16 eeproma, uint16 data, int timeout)
2234 {
2235  return ecx_writeeeprom (&ecx_context, slave, eeproma, data, timeout);
2236 }
2237 
2244 {
2245  return ecx_eeprom2master(&ecx_context, slave);
2246 }
2247 
2249 {
2250  return ecx_eeprom2pdi(&ecx_context, slave);
2251 }
2252 
2253 uint16 ec_eeprom_waitnotbusyAP(uint16 aiadr,uint16 *estat, int timeout)
2254 {
2255  return ecx_eeprom_waitnotbusyAP (&ecx_context, aiadr, estat, timeout);
2256 }
2257 
2264 uint64 ec_readeepromAP(uint16 aiadr, uint16 eeproma, int timeout)
2265 {
2266  return ecx_readeepromAP (&ecx_context, aiadr, eeproma, timeout);
2267 }
2268 
2277 int ec_writeeepromAP(uint16 aiadr, uint16 eeproma, uint16 data, int timeout)
2278 {
2279  return ecx_writeeepromAP (&ecx_context, aiadr, eeproma, data, timeout);
2280 }
2281 
2282 uint16 ec_eeprom_waitnotbusyFP(uint16 configadr,uint16 *estat, int timeout)
2283 {
2284  return ecx_eeprom_waitnotbusyFP (&ecx_context, configadr, estat, timeout);
2285 }
2286 
2294 uint64 ec_readeepromFP(uint16 configadr, uint16 eeproma, int timeout)
2295 {
2296  return ecx_readeepromFP (&ecx_context, configadr, eeproma, timeout);
2297 }
2298 
2307 int ec_writeeepromFP(uint16 configadr, uint16 eeproma, uint16 data, int timeout)
2308 {
2309  return ecx_writeeepromFP (&ecx_context, configadr, eeproma, data, timeout);
2310 }
2311 
2319 {
2320  ecx_readeeprom1 (&ecx_context, slave, eeproma);
2321 }
2322 
2331 {
2332  return ecx_readeeprom2 (&ecx_context, slave, timeout);
2333 }
2334 
2348 {
2349  return ecx_send_processdata_group (&ecx_context, group);
2350 }
2351 
2365 {
2366  return ecx_send_overlap_processdata_group(&ecx_context, group);
2367 }
2368 
2378 int ec_receive_processdata_group(uint8 group, int timeout)
2379 {
2380  return ecx_receive_processdata_group (&ecx_context, group, timeout);
2381 }
2382 
2384 {
2385  return ec_send_processdata_group(0);
2386 }
2387 
2389 {
2391 }
2392 
2393 int ec_receive_processdata(int timeout)
2394 {
2395  return ec_receive_processdata_group(0, timeout);
2396 }
2397 #endif
int ecx_send_processdata(ecx_contextt *context)
int ecx_init_redundant(ecx_contextt *context, ecx_redportt *redport, const char *ifname, char *if2name)
Definition: ethercatmain.c:300
uint16 ErrorCode
Definition: ethercatmain.c:54
uint16 mbx_ro
Definition: ethercatmain.h:163
int ecx_adddatagram(ecx_portt *port, void *frame, uint8 com, uint8 idx, boolean more, uint16 ADP, uint16 ADO, uint16 length, void *data)
Definition: ethercatbase.c:106
int ecx_mbxempty(ecx_contextt *context, uint16 slave, int timeout)
Definition: ethercatmain.c:932
#define EC_MAXMBX
Definition: ethercatmain.h:31
#define EC_ESTAT_NACK
Definition: ethercattype.h:277
int64 * DCtime
Definition: ethercatmain.h:415
static uint32 ec_esimap[EC_MAXEEPBITMAP]
Definition: ethercatmain.c:76
uint8 ErrorReg
Definition: ethercatmain.c:55
int ec_writeeepromAP(uint16 aiadr, uint16 eeproma, uint16 data, int timeout)
ec_bufT txbuf[EC_MAXBUF]
Definition: erika/nicdrv.h:68
uint64 ec_readeepromFP(uint16 configadr, uint16 eeproma, int timeout)
boolean osal_timer_is_expired(osal_timert *self)
Definition: erika/osal.c:74
uint16 ec_eeprom_waitnotbusyFP(uint16 configadr, uint16 *estat, int timeout)
int ec_readstate(void)
uint8 ecx_siigetbyte(ecx_contextt *context, uint16 slave, uint16 address)
Definition: ethercatmain.c:334
uint8 ec_siigetbyte(uint16 slave, uint16 address)
int ec_send_processdata(void)
#define EC_MAXGROUP
Definition: ethercatmain.h:27
void ec_free_adapters(ec_adaptert *adapter)
Definition: ethercatmain.c:144
boolean ec_poperror(ec_errort *Ec)
uint16 comm
Definition: ethercatmain.c:32
uint16 d2
Definition: ethercatmain.c:34
uint16 PhStart
Definition: ethercatmain.h:291
void ecx_close(ecx_contextt *context)
Definition: ethercatmain.c:321
int16 head
Definition: ethercatmain.h:348
uint16 esislave
Definition: ethercatmain.h:403
#define EC_MAXBUF
Definition: ethercattype.h:62
uint8_t uint8
Definition: osal.h:28
void oshw_free_adapters(ec_adaptert *adapter)
Definition: erika/oshw.c:74
uint16 ecx_statecheck(ecx_contextt *context, uint16 slave, uint16 reqstate, int timeout)
Definition: ethercatmain.c:862
void ecx_pusherror(ecx_contextt *context, const ec_errort *Ec)
Definition: ethercatmain.c:154
ec_bufT txbuf2
Definition: erika/nicdrv.h:72
#define EC_MAXEEPBUF
Definition: ethercattype.h:80
int ecx_send_overlap_processdata(ecx_contextt *context)
uint16 mbx_rl
Definition: ethercatmain.h:161
Headerfile for all ethercat headers.
int ec_receive_processdata(int timeout)
int ecx_FPWRw(ecx_portt *port, uint16 ADP, uint16 ADO, uint16 data, int timeout)
Definition: ethercatbase.c:421
PACKED_BEGIN struct PACKED ec_SMcommtype ec_SMcommtypet
uint8 eep_pdi
Definition: ethercatmain.h:211
uint16 state
Definition: ethercatmain.h:109
PACKED_BEGIN struct PACKED ec_etherheadert
int ec_init(const char *ifname)
uint8 SubIdx
Definition: ethercattype.h:489
uint16 w2
Definition: ethercattype.h:503
ec_adaptert * oshw_find_adapters(void)
Definition: erika/oshw.c:52
#define EOE_FRAG_DATA
Definition: ethercateoe.h:103
void ecx_siistring(ecx_contextt *context, char *str, uint16 slave, uint16 Sn)
Definition: ethercatmain.c:445
int ecx_FPWR(ecx_portt *port, uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout)
Definition: ethercatbase.c:399
uint8 * outputs
Definition: ethercatmain.h:246
int txbuflength2
Definition: erika/nicdrv.h:74
uint16_t uint16
Definition: osal.h:29
int ecx_closenic(ecx_portt *port)
Definition: erika/nicdrv.c:140
#define EC_MAXEEPBITMAP
Definition: ethercattype.h:78
int ecx_setupdatagram(ecx_portt *port, void *frame, uint8 com, uint8 idx, uint16 ADP, uint16 ADO, uint16 length, void *data)
Definition: ethercatbase.c:68
uint32 length
Definition: ethercatsoe.h:96
PACKED_BEGIN struct PACKED ec_eepromt
void ecx_packeterror(ecx_contextt *context, uint16 Slave, uint16 Index, uint8 SubIdx, uint16 ErrorCode)
Definition: ethercatmain.c:219
int(* EOEhook)(ecx_contextt *context, uint16 slave, void *eoembx)
Definition: ethercatmain.h:429
int64 ec_DCtime
Definition: ethercatmain.c:95
uint16 Index[EC_MAXEEPDO]
Definition: ethercatmain.h:305
boolean ec_iserror(void)
uint16 ALstatuscode
Definition: ethercatmain.h:111
int ecx_eeprom2master(ecx_contextt *context, uint16 slave)
int ecx_APWR(ecx_portt *port, uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout)
Definition: ethercatbase.c:362
uint16 oshw_htons(uint16 host)
Definition: erika/oshw.c:31
uint8 * esibuf
Definition: ethercatmain.h:399
#define EC_MAXEEPDO
Definition: ethercatmain.h:33
#define etohs(A)
Definition: ethercattype.h:536
uint32 ec_readeeprom(uint16 slave, uint16 eeproma, int timeout)
uint16 ecx_siiFMMU(ecx_contextt *context, uint16 slave, ec_eepromFMMUt *FMMU)
Definition: ethercatmain.c:503
#define TRUE
Definition: osal.h:19
uint32 ecx_readeeprom(ecx_contextt *context, uint16 slave, uint16 eeproma, int timeout)
void ec_siistring(char *str, uint16 slave, uint16 Sn)
#define ETH_HEADERSIZE
Definition: ethercattype.h:103
static int ecx_main_send_processdata(ecx_contextt *context, uint8 group, boolean use_overlap_io)
int ecx_FPRD(ecx_portt *port, uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout)
Definition: ethercatbase.c:318
boolean hasdc
Definition: ethercatmain.h:252
ec_err_type Etype
Definition: ethercattype.h:491
void ecx_esidump(ecx_contextt *context, uint16 slave, uint8 *esibuf)
void ec_clearmbx(ec_mbxbuft *Mbx)
Definition: ethercatmain.c:921
static ec_eepromFMMUt ec_FMMU
Definition: ethercatmain.c:91
uint8 blockLRW
Definition: ethercatmain.h:258
uint16 ec_siiFMMU(uint16 slave, ec_eepromFMMUt *FMMU)
uint16 Startpos
Definition: ethercatmain.h:289
int ecx_getindex(ecx_portt *port)
Definition: erika/nicdrv.c:168
ec_eringt * elist
Definition: ethercatmain.h:405
static void ecx_mbxerror(ecx_contextt *context, uint16 Slave, uint16 Detail)
Definition: ethercatmain.c:240
#define HI_BYTE(w)
Definition: ethercattype.h:512
PACKED_END struct ec_idxstack ec_idxstackT
#define EC_ESTAT_BUSY
Definition: ethercattype.h:273
ecx_portt ecx_port
Definition: ethercatmain.c:97
#define EC_MAXSM
Definition: ethercatmain.h:35
int ec_init_redundant(const char *ifname, char *if2name)
ecx_portt * port
Definition: ethercatmain.h:387
uint8 Activate
Definition: ethercatmain.h:295
uint32 IOsegment[EC_MAXIOSEGMENTS]
Definition: ethercatmain.h:272
uint16 ecx_siiSMnext(ecx_contextt *context, uint16 slave, ec_eepromSMt *SM, uint16 n)
Definition: ethercatmain.c:580
ec_groupt * grouplist
Definition: ethercatmain.h:395
ec_bufT rxbuf[EC_MAXBUF]
Definition: erika/nicdrv.h:58
int ec_eeprom2pdi(uint16 slave)
int ecx_send_overlap_processdata_group(ecx_contextt *context, uint8 group)
int ecx_writeeeprom(ecx_contextt *context, uint16 slave, uint16 eeproma, uint16 data, int timeout)
int ecx_mbxsend(ecx_contextt *context, uint16 slave, ec_mbxbuft *mbx, int timeout)
Definition: ethercatmain.c:968
PACKED_END PACKED_BEGIN struct PACKED ec_mbxerrort
int ec_send_overlap_processdata_group(uint8 group)
ec_timet osal_current_time(void)
Definition: erika/osal.c:37
int ecx_init(ecx_contextt *context, const char *ifname)
Definition: ethercatmain.c:288
static void ecx_mbxemergencyerror(ecx_contextt *context, uint16 Slave, uint16 ErrorCode, uint16 ErrorReg, uint8 b1, uint16 w1, uint16 w2)
Definition: ethercatmain.c:264
int ecx_BRD(ecx_portt *port, uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout)
Definition: ethercatbase.c:185
int ecx_writeeepromAP(ecx_contextt *context, uint16 aiadr, uint16 eeproma, uint16 data, int timeout)
#define put_unaligned32(val, ptr)
Definition: ethercattype.h:525
uint16 SMbitsize[EC_MAXSM]
Definition: ethercatmain.h:308
uint32 ecx_readeeprom2(ecx_contextt *context, uint16 slave, int timeout)
#define EC_HEADERSIZE
Definition: ethercattype.h:127
ec_errort Error[EC_MAXELIST+1]
Definition: ethercatmain.h:350
uint16 configadr
Definition: ethercatmain.h:113
void ec_pusherror(const ec_errort *Ec)
PACKED_END PACKED_BEGIN struct PACKED ec_PDOassign ec_PDOassignt
int ec_eeprom2master(uint16 slave)
int ec_send_overlap_processdata(void)
int ecx_writeeepromFP(ecx_contextt *context, uint16 configadr, uint16 eeproma, uint16 data, int timeout)
uint16 Slave
Definition: ethercattype.h:485
uint64 ecx_readeepromAP(ecx_contextt *context, uint16 aiadr, uint16 eeproma, int timeout)
ec_mbxheadert MbxHeader
Definition: ethercatcoe.c:26
uint16 Index
Definition: ethercatcoe.c:29
int ec_siiPDO(uint16 slave, ec_eepromPDOt *PDO, uint8 t)
int osal_usleep(uint32 usec)
Definition: erika/osal.c:22
int ecx_writestate(ecx_contextt *context, uint16 slave)
Definition: ethercatmain.c:832
PACKED_END PACKED_BEGIN struct PACKED ec_emcyt
void ec_packeterror(uint16 Slave, uint16 Index, uint8 SubIdx, uint16 ErrorCode)
int ecx_mbxreceive(ecx_contextt *context, uint16 slave, ec_mbxbuft *mbx, int timeout)
void ec_readeeprom1(uint16 slave, uint16 eeproma)
int slave
Definition: aliastool.c:44
int ecx_receive_processdata_group(ecx_contextt *context, uint8 group, int timeout)
int64_t int64
Definition: osal.h:31
#define FALSE
Definition: osal.h:22
uint32 * esimap
Definition: ethercatmain.h:401
int ecx_waitinframe(ecx_portt *port, int idx, int timeout)
Definition: erika/nicdrv.c:467
uint16 CANOpen
Definition: ethercatcoe.c:27
ecx_redportt * redport
Definition: erika/nicdrv.h:80
PACKED_BEGIN struct PACKED ec_EOEt
PACKED_END PACKED_BEGIN struct PACKED ec_alstatus ec_alstatust
uint32 logstartaddr
Definition: ethercatmain.h:242
#define PACKED_END
uint16 ec_siiSM(uint16 slave, ec_eepromSMt *SM)
int ec_mbxsend(uint16 slave, ec_mbxbuft *mbx, int timeout)
uint32 ec_readeeprom2(uint16 slave, int timeout)
uint32 Ibytes
Definition: ethercatmain.h:248
uint16 Plength
Definition: ethercatmain.h:292
int ecx_BWR(ecx_portt *port, uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout)
Definition: ethercatbase.c:158
#define EC_MAX_MAPT
Definition: ethercatmain.h:41
#define ECT_SII_START
Definition: ethercattype.h:282
int ecx_FPRD_multi(ecx_contextt *context, int n, uint16 *configlst, ec_alstatust *slstatlst, int timeout)
Definition: ethercatmain.c:683
int16 ec_siifind(uint16 slave, uint16 cat)
#define EC_TIMEOUTEEP
Definition: ethercattype.h:70
#define EC_CMDOFFSET
Definition: ethercattype.h:131
uint32 Obytes
Definition: ethercatmain.h:244
int ecx_APRD(ecx_portt *port, uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout)
Definition: ethercatbase.c:217
boolean EcatError
Definition: ethercatmain.c:93
#define EC_MAXELIST
Definition: ethercatmain.h:21
boolean Signal
Definition: ethercattype.h:483
uint64_t uint64
Definition: osal.h:32
int ecx_send_processdata_group(ecx_contextt *context, uint8 group)
int ec_mbxempty(uint16 slave, int timeout)
#define HI_WORD(l)
Definition: ethercattype.h:520
int ec_send_processdata_group(uint8 group)
static ec_eepromSMt ec_SM
Definition: ethercatmain.c:89
int ecx_outframe_red(ecx_portt *port, int idx)
Definition: erika/nicdrv.c:237
void ecx_readeeprom1(ecx_contextt *context, uint16 slave, uint16 eeproma)
static void ecx_clearindex(ecx_contextt *context)
uint8 eep_8byte
Definition: ethercatmain.h:209
int16 tail
Definition: ethercatmain.h:349
uint64 ecx_readeepromFP(ecx_contextt *context, uint16 configadr, uint16 eeproma, int timeout)
PACKED_END PACKED_BEGIN struct PACKED ec_PDOdesc ec_PDOdesct
#define EC_TIMEOUTRET
Definition: ethercattype.h:64
#define LO_WORD(l)
Definition: ethercattype.h:518
ecx_redportt ecx_redport
Definition: ethercatmain.c:98
uint8 * inputs
Definition: ethercatmain.h:250
static ec_idxstackT ec_idxstack
Definition: ethercatmain.c:79
int ec_writestate(uint16 slave)
uint16_t frameinfo1
Definition: ethercateoe.h:160
ec_timet Time
Definition: ethercattype.h:481
boolean ecx_iserror(ecx_contextt *context)
Definition: ethercatmain.c:206
uint16 ErrorCode
Definition: ethercattype.h:499
uint16 mbx_wo
Definition: ethercatmain.h:159
int ec_writeeeprom(uint16 slave, uint16 eeproma, uint16 data, int timeout)
int wkc
Definition: aliastool.c:47
#define EC_MAXSLAVE
Definition: ethercatmain.h:25
#define htoes(A)
Definition: ethercattype.h:533
#define EC_MAXNAME
Definition: ethercatmain.h:23
int ecx_setupnic(ecx_portt *port, const char *ifname, int secondary)
Definition: erika/nicdrv.c:90
#define EC_DEFAULTRETRIES
Definition: ethercattype.h:82
int ecx_siiPDO(ecx_contextt *context, uint16 slave, ec_eepromPDOt *PDO, uint8 t)
Definition: ethercatmain.c:614
int ecx_eeprom2pdi(ecx_contextt *context, uint16 slave)
uint16 Index
Definition: ethercattype.h:487
PACKED_BEGIN struct PACKED ec_mbxheader ec_mbxheadert
uint64 ec_readeepromAP(uint16 aiadr, uint16 eeproma, int timeout)
uint32 ErrorCode
Definition: ethercatfoe.c:37
#define etohll(A)
Definition: ethercattype.h:538
#define MAX_FPRD_MULTI
Definition: ethercatmain.c:681
uint16 Isegment
Definition: ethercatmain.h:262
int ec_receive_processdata_group(uint8 group, int timeout)
boolean ecx_poperror(ecx_contextt *context, ec_errort *Ec)
Definition: ethercatmain.c:180
uint16 Detail
Definition: ethercatmain.c:44
uint16 w2
Definition: ethercatmain.c:57
#define EC_LOCALDELAY
Definition: ethercatmain.c:26
uint16 ec_eeprom_waitnotbusyAP(uint16 aiadr, uint16 *estat, int timeout)
uint16 ec_siiSMnext(uint16 slave, ec_eepromSMt *SM, uint16 n)
static int ecx_pullindex(ecx_contextt *context)
uint32_t uint32
Definition: osal.h:30
void ec_esidump(uint16 slave, uint8 *esibuf)
#define EC_TIMEOUTRET3
Definition: ethercattype.h:66
uint16 addr
Definition: ethercatmain.c:33
int ecx_readstate(ecx_contextt *context)
Definition: ethercatmain.c:723
uint16 mbx_l
Definition: ethercatmain.h:157
ec_adaptert * ec_find_adapters(void)
Definition: ethercatmain.c:131
int ec_writeeepromFP(uint16 configadr, uint16 eeproma, uint16 data, int timeout)
int16_t int16
Definition: osal.h:26
int16 ecx_siifind(ecx_contextt *context, uint16 slave, uint16 cat)
Definition: ethercatmain.c:405
uint8 data[0]
Definition: ethercateoe.h:166
int ecx_srconfirm(ecx_portt *port, int idx, int timeout)
Definition: erika/nicdrv.c:490
uint16 Type
Definition: ethercatmain.c:43
static void ecx_pushindex(ecx_contextt *context, uint8 idx, void *data, uint16 length)
void osal_timer_start(osal_timert *self, uint32 timeout_usec)
Definition: erika/osal.c:59
#define EC_NOFRAME
Definition: ethercattype.h:41
void ec_close(void)
int ecx_receive_processdata(ecx_contextt *context, int timeout)
#define EC_TIMEOUT
Definition: ethercattype.h:49
uint16 ecx_siiSM(ecx_contextt *context, uint16 slave, ec_eepromSMt *SM)
Definition: ethercatmain.c:543
uint16 w1
Definition: ethercattype.h:502
static uint8 esibuf[EC_MAXEEPBUF]
Definition: ec_master.c:60
uint16 ec_statecheck(uint16 slave, uint16 reqstate, int timeout)
uint16 SyncM[EC_MAXEEPDO]
Definition: ethercatmain.h:306
uint8 bData
Definition: ethercatmain.c:56
int ec_slavecount
Definition: ethercatmain.c:69
uint16 ecx_eeprom_waitnotbusyFP(ecx_contextt *context, uint16 configadr, uint16 *estat, int timeout)
static ec_eringt ec_elist
Definition: ethercatmain.c:78
int ec_mbxreceive(uint16 slave, ec_mbxbuft *mbx, int timeout)
const uint16 secMAC[3]
Definition: erika/nicdrv.c:67
boolean * ecaterror
Definition: ethercatmain.h:409
uint16 Startpos
Definition: ethercatmain.h:302
#define EC_ESTAT_EMASK
Definition: ethercattype.h:275
void ecx_setbufstat(ecx_portt *port, int idx, int bufstat)
Definition: erika/nicdrv.c:202
ec_idxstackT * idxstack
Definition: ethercatmain.h:407
uint16 DCnext
Definition: ethercatmain.h:254
uint16 BitSize[EC_MAXEEPDO]
Definition: ethercatmain.h:307
#define EC_ESTAT_R64
Definition: ethercattype.h:271
uint8 ErrorReg
Definition: ethercattype.h:500
#define EC_WKCSIZE
Definition: ethercattype.h:133
#define EOE_HDR_FRAME_TYPE_GET(x)
Definition: ethercateoe.h:61
uint16 w1
Definition: ethercatmain.c:57
ec_slavet * slavelist
Definition: ethercatmain.h:389
uint8 ec_mbxbuft[EC_MAXMBX+1]
Definition: ethercatmain.h:312
uint16 Ioffset
Definition: ethercatmain.h:264
uint8 ec_nextmbxcnt(uint8 cnt)
Definition: ethercatmain.c:907
#define PACKED_BEGIN
int * slavecount
Definition: ethercatmain.h:391
#define put_unaligned64(val, ptr)
Definition: ethercattype.h:528
uint16 ecx_eeprom_waitnotbusyAP(ecx_contextt *context, uint16 aiadr, uint16 *estat, int timeout)
static uint8 ec_esibuf[EC_MAXEEPBUF]
Definition: ethercatmain.c:74


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