00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00047 #include <stdio.h>
00048 #include <string.h>
00049 #include <sys/time.h>
00050 #include <unistd.h>
00051 #include <youbot_driver/soem/ethercattype.h>
00052 #include <youbot_driver/soem/nicdrv.h>
00053 #include <youbot_driver/soem/ethercatbase.h>
00054 #include <youbot_driver/soem/ethercatmain.h>
00055 #include <youbot_driver/soem/ethercatsoe.h>
00056
00058 typedef struct
00059 PACKED
00060 {
00061 ec_mbxheadert MbxHeader;
00062 uint8 opCode :3;
00063 uint8 incomplete :1;
00064 uint8 error :1;
00065 uint8 driveNo :3;
00066 uint8 elementflags;
00067 union
00068 {
00069 uint16 idn;
00070 uint16 fragmentsleft;
00071 };
00072 } ec_SoEt;
00073
00074 static ec_SoEmappingt SoEmapping;
00075 static ec_SoEattributet SoEattribute;
00076
00083 void ec_SoEerror(uint16 Slave, uint16 idn, uint16 Error)
00084 {
00085 ec_errort Ec;
00086
00087 gettimeofday(&Ec.Time, 0);
00088 Ec.Slave = Slave;
00089 Ec.Index = idn;
00090 Ec.SubIdx = 0;
00091 EcatError = TRUE;
00092 Ec.Etype = EC_ERR_TYPE_SOE_ERROR;
00093 Ec.ErrorCode = Error;
00094 ec_pusherror(&Ec);
00095 }
00096
00112 int ec_SoEread(uint16 slave, uint8 driveNo, uint8 elementflags, uint16 idn, int *psize, void *p, int timeout)
00113 {
00114 ec_SoEt *SoEp, *aSoEp;
00115 uint16 totalsize, framedatasize;
00116 int wkc;
00117 uint8 *bp;
00118 uint8 *mp;
00119 uint16 *errorcode;
00120 ec_mbxbuft MbxIn, MbxOut;
00121 uint8 cnt;
00122 boolean NotLast;
00123
00124 ec_clearmbx(&MbxIn);
00125
00126 wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, 0);
00127 ec_clearmbx(&MbxOut);
00128 aSoEp = (ec_SoEt *)&MbxIn;
00129 SoEp = (ec_SoEt *)&MbxOut;
00130 SoEp->MbxHeader.length = htoes(sizeof(ec_SoEt) - sizeof(ec_mbxheadert));
00131 SoEp->MbxHeader.address = htoes(0x0000);
00132 SoEp->MbxHeader.priority = 0x00;
00133
00134 cnt = ec_nextmbxcnt(ec_slave[slave].mbx_cnt);
00135 ec_slave[slave].mbx_cnt = cnt;
00136 SoEp->MbxHeader.mbxtype = ECT_MBXT_SOE + (cnt << 4);
00137 SoEp->opCode = ECT_SOE_READREQ;
00138 SoEp->incomplete = 0;
00139 SoEp->error = 0;
00140 SoEp->driveNo = driveNo;
00141 SoEp->elementflags = elementflags;
00142 SoEp->idn = htoes(idn);
00143 totalsize = 0;
00144 bp = p;
00145 mp = (uint8 *)&MbxIn + sizeof(ec_SoEt);
00146 NotLast = TRUE;
00147
00148 wkc = ec_mbxsend(slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
00149 if (wkc > 0)
00150 {
00151 while (NotLast)
00152 {
00153
00154 ec_clearmbx(&MbxIn);
00155
00156 wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, timeout);
00157 if (wkc > 0)
00158 {
00159
00160 if (((aSoEp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_SOE) && (aSoEp->opCode == ECT_SOE_READRES)
00161 && (aSoEp->error == 0) && (aSoEp->driveNo == driveNo) && (aSoEp->elementflags == elementflags))
00162 {
00163 framedatasize = etohs(aSoEp->MbxHeader.length) - sizeof(ec_SoEt) + sizeof(ec_mbxheadert);
00164 totalsize += framedatasize;
00165
00166 if (totalsize <= *psize)
00167 {
00168
00169 memcpy(bp, mp, framedatasize);
00170
00171 bp += framedatasize;
00172 }
00173 else
00174 {
00175 framedatasize -= totalsize - *psize;
00176 totalsize = *psize;
00177
00178 if (framedatasize > 0)
00179 memcpy(bp, mp, framedatasize);
00180 }
00181
00182 if (!aSoEp->incomplete)
00183 {
00184 NotLast = FALSE;
00185 *psize = totalsize;
00186 }
00187 }
00188
00189 else
00190 {
00191 NotLast = FALSE;
00192 if (((aSoEp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_SOE) && (aSoEp->opCode == ECT_SOE_READRES)
00193 && (aSoEp->error == 1))
00194 {
00195 mp = (uint8 *)&MbxIn + (etohs(aSoEp->MbxHeader.length) + sizeof(ec_mbxheadert) - sizeof(uint16));
00196 errorcode = (uint16 *)mp;
00197 ec_SoEerror(slave, idn, *errorcode);
00198 }
00199 else
00200 {
00201 ec_packeterror(slave, idn, 0, 1);
00202 }
00203 wkc = 0;
00204 }
00205 }
00206 else
00207 {
00208 NotLast = FALSE;
00209 ec_packeterror(slave, idn, 0, 4);
00210 }
00211 }
00212 }
00213 return wkc;
00214 }
00215
00230 int ec_SoEwrite(uint16 slave, uint8 driveNo, uint8 elementflags, uint16 idn, int psize, void *p, int timeout)
00231 {
00232 ec_SoEt *SoEp, *aSoEp;
00233 uint16 framedatasize, maxdata;
00234 int wkc;
00235 uint8 *mp;
00236 uint8 *hp;
00237 uint16 *errorcode;
00238 ec_mbxbuft MbxIn, MbxOut;
00239 uint8 cnt;
00240 boolean NotLast;
00241
00242 ec_clearmbx(&MbxIn);
00243
00244 wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, 0);
00245 ec_clearmbx(&MbxOut);
00246 aSoEp = (ec_SoEt *)&MbxIn;
00247 SoEp = (ec_SoEt *)&MbxOut;
00248 SoEp->MbxHeader.address = htoes(0x0000);
00249 SoEp->MbxHeader.priority = 0x00;
00250 SoEp->opCode = ECT_SOE_WRITEREQ;
00251 SoEp->error = 0;
00252 SoEp->driveNo = driveNo;
00253 SoEp->elementflags = elementflags;
00254 hp = p;
00255 mp = (uint8 *)&MbxOut + sizeof(ec_SoEt);
00256 maxdata = ec_slave[slave].mbx_l - sizeof(ec_SoEt);
00257 NotLast = TRUE;
00258 while (NotLast)
00259 {
00260 framedatasize = psize;
00261 NotLast = FALSE;
00262 SoEp->idn = htoes(idn);
00263 SoEp->incomplete = 0;
00264 if (framedatasize > maxdata)
00265 {
00266 framedatasize = maxdata;
00267 NotLast = TRUE;
00268 SoEp->incomplete = 1;
00269 SoEp->fragmentsleft = psize / maxdata;
00270 }
00271 SoEp->MbxHeader.length = htoes(sizeof(ec_SoEt) - sizeof(ec_mbxheadert) + framedatasize);
00272
00273 cnt = ec_nextmbxcnt(ec_slave[slave].mbx_cnt);
00274 ec_slave[slave].mbx_cnt = cnt;
00275 SoEp->MbxHeader.mbxtype = ECT_MBXT_SOE + (cnt << 4);
00276
00277 memcpy(mp, hp, framedatasize);
00278 hp += framedatasize;
00279 psize -= framedatasize;
00280
00281 wkc = ec_mbxsend(slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
00282 if (wkc > 0)
00283 {
00284 if (!NotLast || !ec_mbxempty(slave, timeout))
00285 {
00286
00287 ec_clearmbx(&MbxIn);
00288
00289 wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, timeout);
00290 if (wkc > 0)
00291 {
00292 NotLast = FALSE;
00293
00294 if (((aSoEp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_SOE) && (aSoEp->opCode == ECT_SOE_WRITERES)
00295 && (aSoEp->error == 0) && (aSoEp->driveNo == driveNo) && (aSoEp->elementflags == elementflags))
00296 {
00297
00298 }
00299
00300 else
00301 {
00302 if (((aSoEp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_SOE) && (aSoEp->opCode == ECT_SOE_READRES)
00303 && (aSoEp->error == 1))
00304 {
00305 mp = (uint8 *)&MbxIn + (etohs(aSoEp->MbxHeader.length) + sizeof(ec_mbxheadert) - sizeof(uint16));
00306 errorcode = (uint16 *)mp;
00307 ec_SoEerror(slave, idn, *errorcode);
00308 }
00309 else
00310 {
00311 ec_packeterror(slave, idn, 0, 1);
00312 }
00313 wkc = 0;
00314 }
00315 }
00316 else
00317 {
00318 ec_packeterror(slave, idn, 0, 4);
00319 }
00320 }
00321 }
00322 }
00323 return wkc;
00324 }
00325
00337 int ec_readIDNmap(uint16 slave, int *Osize, int *Isize)
00338 {
00339 int retVal = 0;
00340 int wkc;
00341 int psize;
00342 uint16 entries, itemcount;
00343
00344 *Isize = 0;
00345 *Osize = 0;
00346 psize = sizeof(SoEmapping);
00347
00348 wkc = ec_SoEread(slave, 0, EC_SOE_VALUE_B, EC_IDN_MDTCONFIG, &psize, &SoEmapping, EC_TIMEOUTRXM);
00349 if ((wkc > 0) && (psize >= 4) && ((entries = etohs(SoEmapping.currentlength) / 2) > 0)
00350 && (entries <= EC_SOE_MAXMAPPING))
00351 {
00352
00353 *Osize = 16;
00354 for (itemcount = 0; itemcount < entries; itemcount++)
00355 {
00356 psize = sizeof(SoEattribute);
00357
00358 wkc = ec_SoEread(slave, 0, EC_SOE_ATTRIBUTE_B, SoEmapping.idn[itemcount], &psize, &SoEattribute, EC_TIMEOUTRXM);
00359 if ((wkc > 0) && (!SoEattribute.list))
00360 {
00361
00362 *Osize += (int)8 << SoEattribute.length;
00363 }
00364 }
00365 }
00366 psize = sizeof(SoEmapping);
00367
00368 wkc = ec_SoEread(slave, 0, EC_SOE_VALUE_B, EC_IDN_ATCONFIG, &psize, &SoEmapping, EC_TIMEOUTRXM);
00369 if ((wkc > 0) && (psize >= 4) && ((entries = etohs(SoEmapping.currentlength) / 2) > 0)
00370 && (entries <= EC_SOE_MAXMAPPING))
00371 {
00372
00373 *Isize = 16;
00374 for (itemcount = 0; itemcount < entries; itemcount++)
00375 {
00376 psize = sizeof(SoEattribute);
00377
00378 wkc = ec_SoEread(slave, 0, EC_SOE_ATTRIBUTE_B, SoEmapping.idn[itemcount], &psize, &SoEattribute, EC_TIMEOUTRXM);
00379 if ((wkc > 0) && (!SoEattribute.list))
00380 {
00381
00382 *Isize += (int)8 << SoEattribute.length;
00383 }
00384 }
00385 }
00386
00387
00388 if ((*Isize > 0) || (*Osize > 0))
00389 {
00390 retVal = 1;
00391 }
00392 return retVal;
00393 }