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