ethercatcoe.c
Go to the documentation of this file.
00001 /*
00002  * Simple Open EtherCAT Master Library 
00003  *
00004  * File    : ethercatcoe.c
00005  * Version : 1.2.5
00006  * Date    : 09-04-2011
00007  * Copyright (C) 2005-2011 Speciaal Machinefabriek Ketels v.o.f.
00008  * Copyright (C) 2005-2011 Arthur Ketels
00009  * Copyright (C) 2008-2009 TU/e Technische Universiteit Eindhoven 
00010  *
00011  * SOEM is free software; you can redistribute it and/or modify it under
00012  * the terms of the GNU General Public License version 2 as published by the Free
00013  * Software Foundation.
00014  *
00015  * SOEM is distributed in the hope that it will be useful, but WITHOUT ANY
00016  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
00017  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00018  * for more details.
00019  *
00020  * As a special exception, if other files instantiate templates or use macros
00021  * or inline functions from this file, or you compile this file and link it
00022  * with other works to produce a work based on this file, this file does not
00023  * by itself cause the resulting work to be covered by the GNU General Public
00024  * License. However the source code for this file must still be made available
00025  * in accordance with section (3) of the GNU General Public License.
00026  *
00027  * This exception does not invalidate any other reasons why a work based on
00028  * this file might be covered by the GNU General Public License.
00029  *
00030  * The EtherCAT Technology, the trade name and logo “EtherCAT” are the intellectual
00031  * property of, and protected by Beckhoff Automation GmbH. You can use SOEM for
00032  * the sole purpose of creating, using and/or selling or otherwise distributing
00033  * an EtherCAT network master provided that an EtherCAT Master License is obtained
00034  * from Beckhoff Automation GmbH.
00035  *
00036  * In case you did not receive a copy of the EtherCAT Master License along with
00037  * SOEM write to Beckhoff Automation GmbH, Eiserstraße 5, D-33415 Verl, Germany
00038  * (www.beckhoff.com).
00039  */
00040 
00048 #include <stdio.h>
00049 #include <string.h>
00050 #include <sys/time.h>
00051 #include <unistd.h>
00052 #include <youbot_driver/soem/ethercattype.h>
00053 #include <youbot_driver/soem/nicdrv.h>
00054 #include <youbot_driver/soem/ethercatbase.h>
00055 #include <youbot_driver/soem/ethercatmain.h>
00056 #include <youbot_driver/soem/ethercatcoe.h>
00057 
00059 typedef struct
00060   PACKED
00061   {
00062     ec_mbxheadert MbxHeader;
00063     uint16 CANOpen;
00064     uint8 Command;
00065     uint16 Index;
00066     uint8 SubIndex;
00067     union
00068     {
00069       uint8 bdata[0x200]; /* variants for easy data access */
00070       uint16 wdata[0x100];
00071       uint32 ldata[0x80];
00072     };
00073   } ec_SDOt;
00074 
00076   typedef struct
00077     PACKED
00078     {
00079       ec_mbxheadert MbxHeader;
00080       uint16 CANOpen;
00081       uint8 Opcode;
00082       uint8 Reserved;
00083       uint16 Fragments;
00084       union
00085       {
00086         uint8 bdata[0x200]; /* variants for easy data access */
00087         uint16 wdata[0x100];
00088         uint32 ldata[0x80];
00089       };
00090     } ec_SDOservicet;
00091 
00093     typedef struct
00094       PACKED
00095       {
00096         uint8 n;
00097         uint8 nu1;
00098         uint8 SMtype[EC_MAXSM];
00099       } ec_SMcommtypet;
00100 
00102       typedef struct
00103         PACKED
00104         {
00105           uint8 n;
00106           uint8 nu1;
00107           uint16 index[256];
00108         } ec_PDOassignt;
00109 
00111         typedef struct
00112           PACKED
00113           {
00114             uint8 n;
00115             uint8 nu1;
00116             uint32 PDO[256];
00117           } ec_PDOdesct;
00118 
00120           static ec_SMcommtypet ec_SMcommtype;
00122           static ec_PDOassignt ec_PDOassign;
00124           static ec_PDOdesct ec_PDOdesc;
00125 
00133           void ec_SDOerror(uint16 Slave, uint16 Index, uint8 SubIdx, int32 AbortCode)
00134           {
00135             ec_errort Ec;
00136 
00137             gettimeofday(&Ec.Time, 0);
00138             Ec.Slave = Slave;
00139             Ec.Index = Index;
00140             Ec.SubIdx = SubIdx;
00141             EcatError = TRUE;
00142             Ec.Etype = EC_ERR_TYPE_SDO_ERROR;
00143             Ec.AbortCode = AbortCode;
00144             ec_pusherror(&Ec);
00145           }
00146 
00154           static void ec_SDOinfoerror(uint16 Slave, uint16 Index, uint8 SubIdx, int32 AbortCode)
00155           {
00156             ec_errort Ec;
00157 
00158             Ec.Slave = Slave;
00159             Ec.Index = Index;
00160             Ec.SubIdx = SubIdx;
00161             EcatError = TRUE;
00162             Ec.Etype = EC_ERR_TYPE_SDOINFO_ERROR;
00163             Ec.AbortCode = AbortCode;
00164             ec_pusherror(&Ec);
00165           }
00166 
00183           int ec_SDOread(uint16 slave, uint16 index, uint8 subindex, boolean CA, int *psize, void *p, int timeout)
00184           {
00185             ec_SDOt *SDOp, *aSDOp;
00186             uint16 bytesize, Framedatasize;
00187             int wkc;
00188             int32 SDOlen;
00189             uint8 *bp;
00190             uint8 *hp;
00191             ec_mbxbuft MbxIn, MbxOut;
00192             uint8 cnt, toggle;
00193             boolean NotLast;
00194 
00195             ec_clearmbx(&MbxIn);
00196             /* Empty slave out mailbox if something is in. Timout set to 0 */
00197             wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, 0);
00198             ec_clearmbx(&MbxOut);
00199             aSDOp = (ec_SDOt *)&MbxIn;
00200             SDOp = (ec_SDOt *)&MbxOut;
00201             SDOp->MbxHeader.length = htoes(0x000a);
00202             SDOp->MbxHeader.address = htoes(0x0000);
00203             SDOp->MbxHeader.priority = 0x00;
00204             /* get new mailbox count value, used as session handle */
00205             cnt = ec_nextmbxcnt(ec_slave[slave].mbx_cnt);
00206             ec_slave[slave].mbx_cnt = cnt;
00207             SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
00208             SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12)); /* number 9bits service upper 4 bits (SDO request) */
00209             if (CA)
00210               SDOp->Command = ECT_SDO_UP_REQ_CA; /* upload request complete access */
00211             else
00212               SDOp->Command = ECT_SDO_UP_REQ; /* upload request normal */
00213             SDOp->Index = htoes(index);
00214             if (CA && (subindex > 1))
00215               subindex = 1;
00216             SDOp->SubIndex = subindex;
00217             SDOp->ldata[0] = 0;
00218             /* send CoE request to slave */
00219             wkc = ec_mbxsend(slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
00220             if (wkc > 0) /* succeeded to place mailbox in slave ? */
00221             {
00222               /* clean mailboxbuffer */
00223               ec_clearmbx(&MbxIn);
00224               /* read slave response */
00225               wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, timeout);
00226               if (wkc > 0) /* succeeded to read slave response ? */
00227               {
00228                 /* slave response should be CoE, SDO response and the correct index */
00229                 if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE)
00230                     && ((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_SDORES) && (aSDOp->Index == SDOp->Index))
00231                 {
00232                   if ((aSDOp->Command & 0x02) > 0)
00233                   {
00234                     /* expedited frame response */
00235                     bytesize = 4 - ((aSDOp->Command >> 2) & 0x03);
00236                     if (*psize >= bytesize) /* parameter buffer big enough ? */
00237                     {
00238                       /* copy parameter in parameter buffer */
00239                       memcpy(p, &aSDOp->ldata[0], bytesize);
00240                       /* return the real parameter size */
00241                       *psize = bytesize;
00242                     }
00243                     else
00244                     {
00245                       wkc = 0;
00246                       ec_packeterror(slave, index, subindex, 3); /*  data container too small for type */
00247                     }
00248                   }
00249                   else
00250                   { /* normal frame response */
00251                     SDOlen = etohl(aSDOp->ldata[0]);
00252                     /* Does parameter fit in parameter buffer ? */
00253                     if (SDOlen <= *psize)
00254                     {
00255                       bp = p;
00256                       hp = p;
00257                       /* calculate mailbox transfer size */
00258                       Framedatasize = (etohs(aSDOp->MbxHeader.length) - 10);
00259                       if (Framedatasize < SDOlen) /* transfer in segments? */
00260                       {
00261                         /* copy parameter data in parameter buffer */
00262                         memcpy(hp, &aSDOp->ldata[1], Framedatasize);
00263                         /* increment buffer pointer */
00264                         hp += Framedatasize;
00265                         *psize = Framedatasize;
00266                         NotLast = TRUE;
00267                         toggle= 0x00;
00268                         while (NotLast) /* segmented transfer */
00269                         {
00270                           SDOp = (ec_SDOt *)&MbxOut;
00271                           SDOp->MbxHeader.length = htoes(0x000a);
00272                           SDOp->MbxHeader.address = htoes(0x0000);
00273                           SDOp->MbxHeader.priority = 0x00;
00274                           cnt = ec_nextmbxcnt(ec_slave[slave].mbx_cnt);
00275                           ec_slave[slave].mbx_cnt = cnt;
00276                           SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
00277                           SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12)); /* number 9bits service upper 4 bits (SDO request) */
00278                           SDOp->Command = ECT_SDO_SEG_UP_REQ + toggle; /* segment upload request */
00279                           SDOp->Index = htoes(index);
00280                           SDOp->SubIndex = subindex;
00281                           SDOp->ldata[0] = 0;
00282                           /* send segmented upload request to slave */
00283                           wkc = ec_mbxsend(slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
00284                           /* is mailbox transfered to slave ? */
00285                           if (wkc > 0)
00286                           {
00287                             ec_clearmbx(&MbxIn);
00288                             /* read slave response */
00289                             wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, timeout);
00290                             /* has slave responded ? */
00291                             if (wkc > 0)
00292                             {
00293                               /* slave response should be CoE, SDO response */
00294                               if ((((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
00295                                       ((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_SDORES) &&
00296                                       ((aSDOp->Command & 0xe0) == 0x00)))
00297                               {
00298                                 /* calculate mailbox transfer size */
00299                                 Framedatasize = etohs(aSDOp->MbxHeader.length) - 3;
00300                                 if ((aSDOp->Command & 0x01) > 0)
00301                                 { /* last segment */
00302                                   NotLast = FALSE;
00303                                   if (Framedatasize == 7)
00304                                   /* substract unused bytes from frame */
00305                                   Framedatasize = Framedatasize - ((aSDOp->Command & 0x0e) >> 1);
00306                                   /* copy to parameter buffer */
00307                                   memcpy(hp, &(aSDOp->Index), Framedatasize);
00308                                 }
00309                                 else /* segments follow */
00310                                 {
00311                                   /* copy to parameter buffer */
00312                                   memcpy(hp, &(aSDOp->Index), Framedatasize);
00313                                   /* increment buffer pointer */
00314                                   hp += Framedatasize;
00315                                 }
00316                                 /* update parametersize */
00317                                 *psize += Framedatasize;
00318                               }
00319                               /* unexpected frame returned from slave */
00320                               else
00321                               {
00322                                 NotLast = FALSE;
00323                                 if ((aSDOp->Command) == ECT_SDO_ABORT) /* SDO abort frame received */
00324                                 ec_SDOerror(slave, index, subindex, etohl(aSDOp->ldata[0]));
00325                                 else
00326                                 ec_packeterror(slave, index, subindex, 1); /* Unexpected frame returned */
00327                                 wkc = 0;
00328                               }
00329                             }
00330                           }
00331                           toggle = toggle ^ 0x10; /* toggle bit for segment request */
00332                         }
00333                       }
00334                       /* non segmented transfer */
00335                       else
00336                       {
00337                         /* copy to parameter buffer */
00338                         memcpy(bp, &aSDOp->ldata[1], SDOlen);
00339                         *psize = SDOlen;
00340                       }
00341                     }
00342                     /* parameter buffer too small */
00343                     else
00344                     {
00345                       wkc = 0;
00346                       ec_packeterror(slave, index, subindex, 3); /*  data container too small for type */
00347                     }
00348                   }
00349                 }
00350                 /* other slave response */
00351                 else
00352                 {
00353                   if ((aSDOp->Command) == ECT_SDO_ABORT) /* SDO abort frame received */
00354                   ec_SDOerror(slave, index, subindex, etohl(aSDOp->ldata[0]));
00355                   else
00356                   ec_packeterror(slave, index, subindex, 1); /* Unexpected frame returned */
00357                   wkc = 0;
00358                 }
00359               }
00360             }
00361             return wkc;
00362           }
00363 
00379           int ec_SDOwrite(uint16 Slave, uint16 Index, uint8 SubIndex, boolean CA, int psize, void *p, int Timeout)
00380           {
00381             ec_SDOt *SDOp, *aSDOp;
00382             int wkc, maxdata;
00383             ec_mbxbuft MbxIn, MbxOut;
00384             uint8 cnt, toggle;
00385             uint16 framedatasize;
00386             boolean NotLast;
00387             uint8 *hp;
00388 
00389             ec_clearmbx(&MbxIn);
00390             /* Empty slave out mailbox if something is in. Timout set to 0 */
00391             wkc = ec_mbxreceive(Slave, (ec_mbxbuft *)&MbxIn, 0);
00392             ec_clearmbx(&MbxOut);
00393             aSDOp = (ec_SDOt *)&MbxIn;
00394             SDOp = (ec_SDOt *)&MbxOut;
00395             maxdata = ec_slave[Slave].mbx_l - 0x10; /* data section=mailbox size - 6 mbx - 2 CoE - 8 sdo req */
00396             framedatasize = psize;
00397             NotLast = FALSE;
00398             if (framedatasize > maxdata)
00399             {
00400               framedatasize = maxdata; /*  segmented transfer needed  */
00401               NotLast = TRUE;
00402             }
00403             SDOp->MbxHeader.length = htoes(0x0a + framedatasize);
00404             SDOp->MbxHeader.address = htoes(0x0000);
00405             SDOp->MbxHeader.priority = 0x00;
00406             /* get new mailbox counter, used for session handle */
00407             cnt = ec_nextmbxcnt(ec_slave[Slave].mbx_cnt);
00408             ec_slave[Slave].mbx_cnt = cnt;
00409             SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
00410             SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12)); /* number 9bits service upper 4 bits */
00411             if (CA)
00412               SDOp->Command = ECT_SDO_DOWN_INIT_CA; /* Complete Access, normal SDO init download transfer */
00413             else
00414               SDOp->Command = ECT_SDO_DOWN_INIT; /* normal SDO init download transfer */
00415             SDOp->Index = htoes(Index);
00416             SDOp->SubIndex = SubIndex;
00417             if (CA && (SubIndex > 1))
00418               SDOp->SubIndex = 1;
00419             SDOp->ldata[0] = htoel(psize);
00420             hp = p;
00421             /* copy parameter data to mailbox */
00422             memcpy(&SDOp->ldata[1], hp, framedatasize);
00423             hp += framedatasize;
00424             psize -= framedatasize;
00425             /* send mailbox SDO download request to slave */
00426             wkc = ec_mbxsend(Slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
00427             if (wkc > 0)
00428             {
00429               ec_clearmbx(&MbxIn);
00430               /* read slave response */
00431               wkc = ec_mbxreceive(Slave, (ec_mbxbuft *)&MbxIn, Timeout);
00432               if (wkc > 0)
00433               {
00434                 /* response should be CoE, SDO response, correct index and subindex */
00435                 if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE)
00436                     && ((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_SDORES) && (aSDOp->Index == SDOp->Index)
00437                     && (aSDOp->SubIndex == SDOp->SubIndex))
00438                 {
00439                   /* all ok */
00440                   maxdata += 7;
00441                   toggle = 0;
00442                   /* repeat while segments left */
00443                   while (NotLast)
00444                   {
00445                     SDOp = (ec_SDOt *)&MbxOut;
00446                     framedatasize = psize;
00447                     NotLast = FALSE;
00448                     SDOp->Command = 0x01; /* last segment */
00449                     if (framedatasize > maxdata)
00450                     {
00451                       framedatasize = maxdata; /*  more segments needed  */
00452                       NotLast = TRUE;
00453                       SDOp->Command = 0x00; /* segments follow */
00454                     }
00455                     if (!NotLast && (framedatasize < 7))
00456                     {
00457                       SDOp->MbxHeader.length = htoes(0x0a); /* minimum size */
00458                       SDOp->Command = 0x01 + ((7 - framedatasize) << 1); /* last segment reduced octets */
00459                     }
00460                     else
00461                       SDOp->MbxHeader.length = htoes(framedatasize + 3); /* data + 2 CoE + 1 SDO */
00462                     SDOp->MbxHeader.address = htoes(0x0000);
00463                     SDOp->MbxHeader.priority = 0x00;
00464                     /* get new mailbox counter value */
00465                     cnt = ec_nextmbxcnt(ec_slave[Slave].mbx_cnt);
00466                     ec_slave[Slave].mbx_cnt = cnt;
00467                     SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
00468                     SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12)); /* number 9bits service upper 4 bits (SDO request) */
00469                     SDOp->Command = SDOp->Command + toggle; /* add toggle bit to command byte */
00470                     /* copy parameter data to mailbox */
00471                     memcpy(&SDOp->Index, hp, framedatasize);
00472                     /* update parameter buffer pointer */
00473                     hp += framedatasize;
00474                     psize -= framedatasize;
00475                     /* send SDO download request */
00476                     wkc = ec_mbxsend(Slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
00477                     if (wkc > 0)
00478                     {
00479                       ec_clearmbx(&MbxIn);
00480                       /* read slave response */
00481                       wkc = ec_mbxreceive(Slave, (ec_mbxbuft *)&MbxIn, Timeout);
00482                       if (wkc > 0)
00483                       {
00484                         if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE)
00485                             && ((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_SDORES) && ((aSDOp->Command & 0xe0) == 0x20))
00486                         {
00487                           /* all OK, nothing to do */
00488                         }
00489                         else
00490                         {
00491                           if (aSDOp->Command == ECT_SDO_ABORT) /* SDO abort frame received */
00492                             ec_SDOerror(Slave, Index, SubIndex, etohl(aSDOp->ldata[0]));
00493                             else
00494                             ec_packeterror(Slave, Index, SubIndex, 1); /* Unexpected frame returned */
00495                             wkc = 0;
00496                             NotLast = FALSE;
00497                           }
00498                         }
00499                       }
00500                     toggle = toggle ^ 0x10; /* toggle bit for segment request */
00501                   }
00502                 }
00503                 /* unexpected response from slave */
00504                 else
00505                 {
00506                   if (aSDOp->Command == ECT_SDO_ABORT) /* SDO abort frame received */
00507                     ec_SDOerror(Slave, Index, SubIndex, etohl(aSDOp->ldata[0]));
00508                     else
00509                     ec_packeterror(Slave, Index, SubIndex, 1); /* Unexpected frame returned */
00510                     wkc = 0;
00511                   }
00512                 }
00513               }
00514 
00515             return wkc;
00516           }
00517 
00528           int ec_RxPDO(uint16 Slave, uint16 RxPDOnumber, int psize, void *p)
00529           {
00530             ec_SDOt *SDOp;
00531             int wkc, maxdata;
00532             ec_mbxbuft MbxIn, MbxOut;
00533             uint8 cnt;
00534             uint16 framedatasize;
00535 
00536             ec_clearmbx(&MbxIn);
00537             /* Empty slave out mailbox if something is in. Timout set to 0 */
00538             wkc = ec_mbxreceive(Slave, (ec_mbxbuft *)&MbxIn, 0);
00539             ec_clearmbx(&MbxOut);
00540             SDOp = (ec_SDOt *)&MbxOut;
00541             maxdata = ec_slave[Slave].mbx_l - 0x08; /* data section=mailbox size - 6 mbx - 2 CoE */
00542             framedatasize = psize;
00543             if (framedatasize > maxdata)
00544               framedatasize = maxdata; /*  limit transfer */
00545             SDOp->MbxHeader.length = htoes(0x02 + framedatasize);
00546             SDOp->MbxHeader.address = htoes(0x0000);
00547             SDOp->MbxHeader.priority = 0x00;
00548             /* get new mailbox counter, used for session handle */
00549             cnt = ec_nextmbxcnt(ec_slave[Slave].mbx_cnt);
00550             ec_slave[Slave].mbx_cnt = cnt;
00551             SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
00552             SDOp->CANOpen = htoes((RxPDOnumber & 0x01ff) + (ECT_COES_RXPDO << 12)); /* number 9bits service upper 4 bits */
00553             /* copy PDO data to mailbox */
00554             memcpy(&SDOp->Command, p, framedatasize);
00555             /* send mailbox SDO download request to slave */
00556             wkc = ec_mbxsend(Slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
00557 
00558             return wkc;
00559           }
00560 
00572           int ec_TxPDO(uint16 slave, uint16 TxPDOnumber, int *psize, void *p, int timeout)
00573           {
00574             ec_SDOt *SDOp, *aSDOp;
00575             int wkc;
00576             ec_mbxbuft MbxIn, MbxOut;
00577             uint8 cnt;
00578             uint16 framedatasize;
00579 
00580             ec_clearmbx(&MbxIn);
00581             /* Empty slave out mailbox if something is in. Timout set to 0 */
00582             wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, 0);
00583             ec_clearmbx(&MbxOut);
00584             aSDOp = (ec_SDOt *)&MbxIn;
00585             SDOp = (ec_SDOt *)&MbxOut;
00586             SDOp->MbxHeader.length = htoes(0x02);
00587             SDOp->MbxHeader.address = htoes(0x0000);
00588             SDOp->MbxHeader.priority = 0x00;
00589             /* get new mailbox counter, used for session handle */
00590             cnt = ec_nextmbxcnt(ec_slave[slave].mbx_cnt);
00591             ec_slave[slave].mbx_cnt = cnt;
00592             SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
00593             SDOp->CANOpen = htoes((TxPDOnumber & 0x01ff) + (ECT_COES_TXPDO_RR << 12)); /* number 9bits service upper 4 bits */
00594             wkc = ec_mbxsend(slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
00595             if (wkc > 0)
00596             {
00597               /* clean mailboxbuffer */
00598               ec_clearmbx(&MbxIn);
00599               /* read slave response */
00600               wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, timeout);
00601               if (wkc > 0) /* succeeded to read slave response ? */
00602               {
00603                 /* slave response should be CoE, TxPDO */
00604                 if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE)
00605                     && ((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_TXPDO))
00606                 {
00607                   /* TxPDO response */
00608                   framedatasize = (aSDOp->MbxHeader.length - 2);
00609                   if (*psize >= framedatasize) /* parameter buffer big enough ? */
00610                   {
00611                     /* copy parameter in parameter buffer */
00612                     memcpy(p, &aSDOp->Command, framedatasize);
00613                     /* return the real parameter size */
00614                     *psize = framedatasize;
00615                   }
00616                   /* parameter buffer too small */
00617                   else
00618                   {
00619                     wkc = 0;
00620                     ec_packeterror(slave, 0, 0, 3); /*  data container too small for type */
00621                   }
00622                 }
00623                 /* other slave response */
00624                 else
00625                 {
00626                   if ((aSDOp->Command) == ECT_SDO_ABORT) /* SDO abort frame received */
00627                     ec_SDOerror(slave, 0, 0, etohl(aSDOp->ldata[0]));
00628                     else
00629                     ec_packeterror(slave, 0, 0, 1); /* Unexpected frame returned */
00630                     wkc = 0;
00631                   }
00632                 }
00633               }
00634 
00635             return wkc;
00636           }
00637 
00639           int ec_readPDOassign(uint16 Slave, uint16 PDOassign)
00640           {
00641             uint16 idxloop, nidx, subidxloop, rdat, idx, subidx;
00642             uint8 subcnt;
00643             int wkc, bsize = 0, rdl;
00644             int32 rdat2;
00645 
00646             rdl = sizeof(rdat);
00647             rdat = 0;
00648             /* read PDO assign subindex 0 ( = number of PDO's) */
00649             wkc = ec_SDOread(Slave, PDOassign, 0x00, FALSE, &rdl, &rdat, EC_TIMEOUTRXM);
00650             rdat = etohs(rdat);
00651             /* positive result from slave ? */
00652             if ((wkc > 0) && (rdat > 0))
00653             {
00654               /* number of available sub indexes */
00655               nidx = rdat;
00656               bsize = 0;
00657               /* read all PDO's */
00658               for (idxloop = 1; idxloop <= nidx; idxloop++)
00659               {
00660                 rdl = sizeof(rdat);
00661                 rdat = 0;
00662                 /* read PDO assign */
00663                 wkc = ec_SDOread(Slave, PDOassign, (uint8)idxloop, FALSE, &rdl, &rdat, EC_TIMEOUTRXM);
00664                 /* result is index of PDO */
00665                 idx = etohl(rdat);
00666                 if (idx > 0)
00667                 {
00668                   rdl = sizeof(subcnt);
00669                   subcnt = 0;
00670                   /* read number of subindexes of PDO */
00671                   wkc = ec_SDOread(Slave, idx, 0x00, FALSE, &rdl, &subcnt, EC_TIMEOUTRXM);
00672                   subidx = subcnt;
00673                   /* for each subindex */
00674                   for (subidxloop = 1; subidxloop <= subidx; subidxloop++)
00675                   {
00676                     rdl = sizeof(rdat2);
00677                     rdat2 = 0;
00678                     /* read SDO that is mapped in PDO */
00679                     wkc = ec_SDOread(Slave, idx, (uint8)subidxloop, FALSE, &rdl, &rdat2, EC_TIMEOUTRXM);
00680                     rdat2 = etohl(rdat2);
00681                     /* extract bitlength of SDO */
00682                     if (LO_BYTE(rdat2) < 0xff)
00683                       bsize += LO_BYTE(rdat2);
00684                     else
00685                     {
00686                       rdl = sizeof(rdat);
00687                       rdat = htoes(0xff);
00688                       /* read Object Entry in Object database */
00689 //                                              wkc = ec_readOEsingle(idx, (uint8)SubCount, pODlist, pOElist);
00690                       bsize += etohs(rdat);
00691                     }
00692                   };
00693                 };
00694               };
00695             };
00696             /* return total found bitlength (PDO) */
00697             return bsize;
00698           }
00699 
00701           int ec_readPDOassignCA(uint16 Slave, uint16 PDOassign)
00702           {
00703             uint16 idxloop, nidx, subidxloop, idx, subidx;
00704             int wkc, bsize = 0, rdl;
00705 
00706             /* find maximum size of PDOassign buffer */
00707             rdl = sizeof(ec_PDOassign);
00708             ec_PDOassign.n = 0;
00709             /* read rxPDOassign in CA mode, all subindexes are read in one struct */
00710             wkc = ec_SDOread(Slave, PDOassign, 0x00, TRUE, &rdl, &ec_PDOassign, EC_TIMEOUTRXM);
00711             /* positive result from slave ? */
00712             if ((wkc > 0) && (ec_PDOassign.n > 0))
00713             {
00714               nidx = ec_PDOassign.n;
00715               bsize = 0;
00716               /* for each PDO do */
00717               for (idxloop = 1; idxloop <= nidx; idxloop++)
00718               {
00719                 /* get index from PDOassign struct */
00720                 idx = etohs(ec_PDOassign.index[idxloop - 1]);
00721                 if (idx > 0)
00722                 {
00723                   rdl = sizeof(ec_PDOdesc); ec_PDOdesc.n = 0;
00724                   /* read SDO's that are mapped in PDO, CA mode */
00725                   wkc = ec_SDOread(Slave,idx, 0x00, TRUE, &rdl, &ec_PDOdesc, EC_TIMEOUTRXM);
00726                   subidx = ec_PDOdesc.n;
00727                   /* extract all bitlengths of SDO's */
00728                   for (subidxloop = 1; subidxloop <= subidx; subidxloop++)
00729                   {
00730                     bsize += LO_BYTE(etohl(ec_PDOdesc.PDO[subidxloop -1]));
00731                   };
00732                 };
00733               };
00734             };
00735             /* return total found bitlength (PDO) */
00736             return bsize;
00737           }
00738 
00766           int ec_readPDOmap(uint16 Slave, int *Osize, int *Isize)
00767           {
00768             int wkc, rdl;
00769             int retVal = 0;
00770             uint8 nSM, iSM, tSM;
00771             int Tsize;
00772             uint8 SMt_bug_add;
00773 
00774             *Isize = 0;
00775             *Osize = 0;
00776             SMt_bug_add = 0;
00777             rdl = sizeof(nSM);
00778             nSM = 0;
00779             /* read SyncManager Communication Type object count */
00780             wkc = ec_SDOread(Slave, ECT_SDO_SMCOMMTYPE, 0x00, FALSE, &rdl, &nSM, EC_TIMEOUTRXM);
00781             /* positive result from slave ? */
00782             if ((wkc > 0) && (nSM > 2))
00783             {
00784               /* make nSM equal to number of defined SM */
00785               nSM--;
00786               /* limit to maximum number of SM defined, if true the slave can't be configured */
00787               if (nSM > EC_MAXSM)
00788                 nSM = EC_MAXSM;
00789               /* iterate for every SM type defined */
00790               for (iSM = 2; iSM <= nSM; iSM++)
00791               {
00792                 rdl = sizeof(tSM);
00793                 tSM = 0;
00794                 /* read SyncManager Communication Type */
00795                 wkc = ec_SDOread(Slave, ECT_SDO_SMCOMMTYPE, iSM + 1, FALSE, &rdl, &tSM, EC_TIMEOUTRXM);
00796                 if (wkc > 0)
00797                 {
00798 // start slave bug prevention code, remove if possible                          
00799                   if ((iSM == 2) && (tSM == 2)) // SM2 has type 2 == mailbox out, this is a bug in the slave!
00800                     SMt_bug_add = 1; // try to correct, this works if the types are 0 1 2 3 and should be 1 2 3 4
00801                   if (tSM)
00802                     tSM += SMt_bug_add; // only add if SMt > 0
00803 // end slave bug prevention code                                
00804 
00805                   ec_slave[Slave].SMtype[iSM] = tSM;
00806                   /* check if SM is unused -> clear enable flag */
00807                   if (tSM == 0)
00808                     ec_slave[Slave].SM[iSM].SMflags = htoel( etohl(ec_slave[Slave].SM[iSM].SMflags) & EC_SMENABLEMASK);
00809                   if ((tSM == 3) || (tSM == 4))
00810                   {
00811                     /* read the assign PDO */
00812                     Tsize = ec_readPDOassign(Slave, ECT_SDO_PDOASSIGN + iSM);
00813                     /* if a mapping is found */
00814                     if (Tsize)
00815                     {
00816                       ec_slave[Slave].SM[iSM].SMlength = htoes((Tsize + 7) / 8);
00817                       if (tSM == 3)
00818                         /* we are doing outputs */
00819                         *Osize += Tsize;
00820                       else
00821                         /* we are doing inputs */
00822                         *Isize += Tsize;
00823                     }
00824                   }
00825                 }
00826               }
00827             }
00828 
00829             /* found some I/O bits ? */
00830             if ((*Isize > 0) || (*Osize > 0))
00831               retVal = 1;
00832             return retVal;
00833           }
00834 
00846           int ec_readPDOmapCA(uint16 Slave, int *Osize, int *Isize)
00847           {
00848             int wkc, rdl;
00849             int retVal = 0;
00850             uint8 nSM, iSM, tSM;
00851             int Tsize;
00852             uint8 SMt_bug_add;
00853 
00854             *Isize = 0;
00855             *Osize = 0;
00856             SMt_bug_add = 0;
00857             rdl = sizeof(ec_SMcommtype);
00858             ec_SMcommtype.n = 0;
00859             /* read SyncManager Communication Type object count Complete Access*/
00860             wkc = ec_SDOread(Slave, ECT_SDO_SMCOMMTYPE, 0x00, TRUE, &rdl, &ec_SMcommtype, EC_TIMEOUTRXM);
00861             /* positive result from slave ? */
00862             if ((wkc > 0) && (ec_SMcommtype.n > 2))
00863             {
00864               /* make nSM equal to number of defined SM */
00865               nSM = ec_SMcommtype.n - 1;
00866               /* limit to maximum number of SM defined, if true the slave can't be configured */
00867               if (nSM > EC_MAXSM)
00868                 nSM = EC_MAXSM;
00869               /* iterate for every SM type defined */
00870               for (iSM = 2; iSM <= nSM; iSM++)
00871               {
00872                 tSM = ec_SMcommtype.SMtype[iSM];
00873 
00874 // start slave bug prevention code, remove if possible                          
00875                 if ((iSM == 2) && (tSM == 2)) // SM2 has type 2 == mailbox out, this is a bug in the slave!
00876                   SMt_bug_add = 1; // try to correct, this works if the types are 0 1 2 3 and should be 1 2 3 4
00877                 if (tSM)
00878                   tSM += SMt_bug_add; // only add if SMt > 0
00879 // end slave bug prevention code
00880 
00881                 ec_slave[Slave].SMtype[iSM] = tSM;
00882                 /* check if SM is unused -> clear enable flag */
00883                 if (tSM == 0)
00884                   ec_slave[Slave].SM[iSM].SMflags = htoel( etohl(ec_slave[Slave].SM[iSM].SMflags) & EC_SMENABLEMASK);
00885                 if ((tSM == 3) || (tSM == 4))
00886                 {
00887                   /* read the assign PDO */
00888                   Tsize = ec_readPDOassignCA(Slave, ECT_SDO_PDOASSIGN + iSM);
00889                   /* if a mapping is found */
00890                   if (Tsize)
00891                   {
00892                     ec_slave[Slave].SM[iSM].SMlength = htoes((Tsize + 7) / 8);
00893                     if (tSM == 3)
00894                       /* we are doing outputs */
00895                       *Osize += Tsize;
00896                     else
00897                       /* we are doing inputs */
00898                       *Isize += Tsize;
00899                   }
00900                 }
00901               }
00902             }
00903 
00904             /* found some I/O bits ? */
00905             if ((*Isize > 0) || (*Osize > 0))
00906               retVal = 1;
00907             return retVal;
00908           }
00909 
00916           int ec_readODlist(uint16 Slave, ec_ODlistt *pODlist)
00917           {
00918             ec_SDOservicet *SDOp, *aSDOp;
00919             ec_mbxbuft MbxIn, MbxOut;
00920             int wkc;
00921             uint16 x, n, i, sp, offset;
00922             boolean stop;
00923             uint8 cnt;
00924             boolean First;
00925 
00926             pODlist->Slave = Slave;
00927             pODlist->Entries = 0;
00928             ec_clearmbx(&MbxIn);
00929             /* clear pending out mailbox in slave if available. Timeout is set to 0 */
00930             wkc = ec_mbxreceive(Slave, &MbxIn, 0);
00931             ec_clearmbx(&MbxOut);
00932             aSDOp = (ec_SDOservicet*)&MbxIn;
00933             SDOp = (ec_SDOservicet*)&MbxOut;
00934             SDOp->MbxHeader.length = htoes(0x0008);
00935             SDOp->MbxHeader.address = htoes(0x0000);
00936             SDOp->MbxHeader.priority = 0x00;
00937             /* Get new mailbox counter value */
00938             cnt = ec_nextmbxcnt(ec_slave[Slave].mbx_cnt);
00939             ec_slave[Slave].mbx_cnt = cnt;
00940             SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
00941             SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOINFO << 12)); /* number 9bits service upper 4 bits */
00942             SDOp->Opcode = ECT_GET_ODLIST_REQ; /* get object description list request */
00943             SDOp->Reserved = 0;
00944             SDOp->Fragments = 0; /* fragments left */
00945             SDOp->wdata[0] = htoes(0x01); /* all objects */
00946             /* send get object description list request to slave */
00947             wkc = ec_mbxsend(Slave, &MbxOut, EC_TIMEOUTTXM);
00948             /* mailbox placed in slave ? */
00949             if (wkc > 0)
00950             {
00951               x = 0;
00952               sp = 0;
00953               First = TRUE;
00954               offset = 1; /* offset to skip info header in first frame, otherwise set to 0 */
00955               do
00956               {
00957                 stop = TRUE; /* assume this is last iteration */
00958                 ec_clearmbx(&MbxIn);
00959                 /* read slave response */
00960                 wkc = ec_mbxreceive(Slave, &MbxIn, EC_TIMEOUTRXM);
00961                 /* got response ? */
00962                 if (wkc > 0)
00963                 {
00964                   /* response should be CoE and "get object description list response" */
00965                   if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE)
00966                       && ((aSDOp->Opcode & 0x7f) == ECT_GET_ODLIST_RES))
00967                   {
00968                     if (First)
00969                       /* extract number of indexes from mailbox data size */
00970                       n = (etohs(aSDOp->MbxHeader.length) - (6 + 2)) / 2;
00971                     else
00972                       /* extract number of indexes from mailbox data size */
00973                       n = (etohs(aSDOp->MbxHeader.length) - 6) / 2;
00974                     /* check if indexes fit in buffer structure */
00975                     if ((sp + n) > EC_MAXODLIST)
00976                     {
00977                       n = EC_MAXODLIST + 1 - sp;
00978                       ec_SDOinfoerror(Slave, 0, 0, 0xf000000); /* Too many entries for master buffer */
00979                       stop = TRUE;
00980                     }
00981                     /* trim to maximum number of ODlist entries defined */
00982                     if ((pODlist->Entries + n) > EC_MAXODLIST)
00983                       n = EC_MAXODLIST - pODlist->Entries;
00984                     pODlist->Entries += n;
00985                     /* extract indexes one by one */
00986                     for (i = 0; i < n; i++)
00987                       pODlist->Index[sp + i] = etohs(aSDOp->wdata[i + offset]);
00988                     sp += n;
00989                     /* check if more fragments will follow */
00990                     if (aSDOp->Fragments > 0)
00991                       stop = FALSE;
00992                     First = FALSE;
00993                     offset = 0;
00994                   }
00995                   /* got unexpected response from slave */
00996                   else
00997                   {
00998                     if ((aSDOp->Opcode & 0x7f) == ECT_SDOINFO_ERROR) /* SDO info error received */
00999                     {
01000                       ec_SDOinfoerror(Slave, 0, 0, etohl(aSDOp->ldata[0]));
01001                       stop = TRUE;
01002                     }
01003                     else
01004                     ec_packeterror(Slave, 0, 0, 1); /* Unexpected frame returned */
01005                     wkc = 0;
01006                     x += 20;
01007                   }
01008                 }
01009                 x++;
01010               } while ((x <= 128) && !stop);
01011             }
01012             return wkc;
01013           }
01014 
01021           int ec_readODdescription(uint16 Item, ec_ODlistt *pODlist)
01022           {
01023             ec_SDOservicet *SDOp, *aSDOp;
01024             int wkc;
01025             uint16 n, Slave;
01026             ec_mbxbuft MbxIn, MbxOut;
01027             uint8 cnt;
01028 
01029             Slave = pODlist->Slave;
01030             pODlist->DataType[Item] = 0;
01031             pODlist->ObjectCode[Item] = 0;
01032             pODlist->MaxSub[Item] = 0;
01033             pODlist->Name[Item][0] = 0;
01034             ec_clearmbx(&MbxIn);
01035             /* clear pending out mailbox in slave if available. Timeout is set to 0 */
01036             wkc = ec_mbxreceive(Slave, &MbxIn, 0);
01037             ec_clearmbx(&MbxOut);
01038             aSDOp = (ec_SDOservicet*)&MbxIn;
01039             SDOp = (ec_SDOservicet*)&MbxOut;
01040             SDOp->MbxHeader.length = htoes(0x0008);
01041             SDOp->MbxHeader.address = htoes(0x0000);
01042             SDOp->MbxHeader.priority = 0x00;
01043             /* Get new mailbox counter value */
01044             cnt = ec_nextmbxcnt(ec_slave[Slave].mbx_cnt);
01045             ec_slave[Slave].mbx_cnt = cnt;
01046             SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
01047             SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOINFO << 12)); /* number 9bits service upper 4 bits */
01048             SDOp->Opcode = ECT_GET_OD_REQ; /* get object description request */
01049             SDOp->Reserved = 0;
01050             SDOp->Fragments = 0; /* fragments left */
01051             SDOp->wdata[0] = htoes(pODlist->Index[Item]); /* Data of Index */
01052             /* send get object description request to slave */
01053             wkc = ec_mbxsend(Slave, &MbxOut, EC_TIMEOUTTXM);
01054             /* mailbox placed in slave ? */
01055             if (wkc > 0)
01056             {
01057               ec_clearmbx(&MbxIn);
01058               /* read slave response */
01059               wkc = ec_mbxreceive(Slave, &MbxIn, EC_TIMEOUTRXM);
01060               /* got response ? */
01061               if (wkc > 0)
01062               {
01063                 if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) && ((aSDOp->Opcode & 0x7f) == ECT_GET_OD_RES))
01064                 {
01065                   n = (etohs(aSDOp->MbxHeader.length) - 12); /* length of string(name of object) */
01066                   if (n > EC_MAXNAME)
01067                     n = EC_MAXNAME; /* max chars */
01068                   pODlist->DataType[Item] = etohs(aSDOp->wdata[1]);
01069                   pODlist->ObjectCode[Item] = aSDOp->bdata[5];
01070                   pODlist->MaxSub[Item] = aSDOp->bdata[4];
01071 
01072                   strncpy(pODlist->Name[Item], (char *)&aSDOp->bdata[6], n);
01073                   pODlist->Name[Item][n] = 0x00; /* String terminator */
01074                 }
01075                 /* got unexpected response from slave */
01076                 else
01077                 {
01078                   if (((aSDOp->Opcode & 0x7f) == ECT_SDOINFO_ERROR)) /* SDO info error received */
01079                     ec_SDOinfoerror(Slave, pODlist->Index[Item], 0, etohl(aSDOp->ldata[0]));
01080                     else
01081                     ec_packeterror(Slave,pODlist->Index[Item], 0, 1); /* Unexpected frame returned */
01082                     wkc = 0;
01083                   }
01084                 }
01085               }
01086             return wkc;
01087           }
01088 
01098           static int ec_readOEsingle(uint16 Item, uint8 SubI, ec_ODlistt *pODlist, ec_OElistt *pOElist)
01099           {
01100             ec_SDOservicet *SDOp, *aSDOp;
01101             uint16 wkc, Index, Slave;
01102             int16 n;
01103             ec_mbxbuft MbxIn, MbxOut;
01104             uint8 cnt;
01105 
01106             wkc = 0;
01107             Slave = pODlist->Slave;
01108             Index = pODlist->Index[Item];
01109             ec_clearmbx(&MbxIn);
01110             /* clear pending out mailbox in slave if available. Timeout is set to 0 */
01111             wkc = ec_mbxreceive(Slave, &MbxIn, 0);
01112             ec_clearmbx(&MbxOut);
01113             aSDOp = (ec_SDOservicet*)&MbxIn;
01114             SDOp = (ec_SDOservicet*)&MbxOut;
01115             SDOp->MbxHeader.length = htoes(0x000a);
01116             SDOp->MbxHeader.address = htoes(0x0000);
01117             SDOp->MbxHeader.priority = 0x00;
01118             /* Get new mailbox counter value */
01119             cnt = ec_nextmbxcnt(ec_slave[Slave].mbx_cnt);
01120             ec_slave[Slave].mbx_cnt = cnt;
01121             SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
01122             SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOINFO << 12)); /* number 9bits service upper 4 bits */
01123             SDOp->Opcode = ECT_GET_OE_REQ; /* get object entry description request */
01124             SDOp->Reserved = 0;
01125             SDOp->Fragments = 0; /* fragments left */
01126             SDOp->wdata[0] = htoes(Index); /* Index */
01127             SDOp->bdata[2] = SubI; /* SubIndex */
01128             SDOp->bdata[3] = 1 + 2 + 4; /* get access rights, object category, PDO */
01129             /* send get object entry description request to slave */
01130             wkc = ec_mbxsend(Slave, &MbxOut, EC_TIMEOUTTXM);
01131             /* mailbox placed in slave ? */
01132             if (wkc > 0)
01133             {
01134               ec_clearmbx(&MbxIn);
01135               /* read slave response */
01136               wkc = ec_mbxreceive(Slave, &MbxIn, EC_TIMEOUTRXM);
01137               /* got response ? */
01138               if (wkc > 0)
01139               {
01140                 if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) && ((aSDOp->Opcode & 0x7f) == ECT_GET_OE_RES))
01141                 {
01142                   pOElist->Entries++;
01143                   n = (etohs(aSDOp->MbxHeader.length) - 16); /* length of string(name of object) */
01144                   if (n > EC_MAXNAME)
01145                     n = EC_MAXNAME; /* max string length */
01146                   if (n < 0)
01147                     n = 0;
01148                   pOElist->ValueInfo[SubI] = aSDOp->bdata[3];
01149                   pOElist->DataType[SubI] = etohs(aSDOp->wdata[2]);
01150                   pOElist->BitLength[SubI] = etohs(aSDOp->wdata[3]);
01151                   pOElist->ObjAccess[SubI] = etohs(aSDOp->wdata[4]);
01152 
01153                   strncpy(pOElist->Name[SubI], (char *)&aSDOp->wdata[5], n);
01154                   pOElist->Name[SubI][n] = 0x00; /* string terminator */
01155                 }
01156                 /* got unexpected response from slave */
01157                 else
01158                 {
01159                   if (((aSDOp->Opcode & 0x7f) == ECT_SDOINFO_ERROR)) /* SDO info error received */
01160                     ec_SDOinfoerror(Slave, Index, SubI, etohl(aSDOp->ldata[0]));
01161                     else
01162                     ec_packeterror(Slave, Index, SubI, 1); /* Unexpected frame returned */
01163                     wkc = 0;
01164                   }
01165                 }
01166               }
01167             return wkc;
01168           }
01169 
01177           int ec_readOE(uint16 Item, ec_ODlistt *pODlist, ec_OElistt *pOElist)
01178           {
01179             uint16 SubCount;
01180             int wkc;
01181             uint8 SubI;
01182 
01183             wkc = 0;
01184             pOElist->Entries = 0;
01185             SubI = pODlist->MaxSub[Item];
01186             /* for each entry found in ODlist */
01187             for (SubCount = 0; SubCount <= (SubI); SubCount++)
01188               /* read subindex of entry */
01189               wkc = ec_readOEsingle(Item, (uint8)SubCount, pODlist, pOElist);
01190             return wkc;
01191           }


youbot_driver
Author(s): Jan Paulus
autogenerated on Mon Oct 6 2014 09:08:01