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 "ethercat_soem/osal.h"
00050 #include "ethercat_soem/oshw.h"
00051 #include "ethercat_soem/ethercattype.h"
00052 #include "ethercat_soem/ethercatbase.h"
00053 #include "ethercat_soem/ethercatmain.h"
00054 #include "ethercat_soem/ethercatsoe.h"
00055
00056
00058 PACKED_BEGIN
00059 typedef struct 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 PACKED_END
00074
00082 void ecx_SoEerror(ecx_contextt *context, uint16 Slave, uint16 idn, uint16 Error)
00083 {
00084 ec_errort Ec;
00085
00086 Ec.Time = osal_current_time();
00087 Ec.Slave = Slave;
00088 Ec.Index = idn;
00089 Ec.SubIdx = 0;
00090 *(context->ecaterror) = TRUE;
00091 Ec.Etype = EC_ERR_TYPE_SOE_ERROR;
00092 Ec.ErrorCode = Error;
00093 ecx_pusherror(context, &Ec);
00094 }
00095
00112 int ecx_SoEread(ecx_contextt *context, 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 = ecx_mbxreceive(context, 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(context->slavelist[slave].mbx_cnt);
00135 context->slavelist[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 = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
00149 if (wkc > 0)
00150 {
00151 while (NotLast)
00152 {
00153
00154 ec_clearmbx(&MbxIn);
00155
00156 wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, timeout);
00157 if (wkc > 0)
00158 {
00159
00160 if (((aSoEp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_SOE) &&
00161 (aSoEp->opCode == ECT_SOE_READRES) &&
00162 (aSoEp->error == 0) &&
00163 (aSoEp->driveNo == driveNo) &&
00164 (aSoEp->elementflags == elementflags))
00165 {
00166 framedatasize = etohs(aSoEp->MbxHeader.length) - sizeof(ec_SoEt) + sizeof(ec_mbxheadert);
00167 totalsize += framedatasize;
00168
00169 if (totalsize <= *psize)
00170 {
00171
00172 memcpy(bp, mp, framedatasize);
00173
00174 bp += framedatasize;
00175 }
00176 else
00177 {
00178 framedatasize -= totalsize - *psize;
00179 totalsize = *psize;
00180
00181 if (framedatasize > 0) memcpy(bp, mp, framedatasize);
00182 }
00183
00184 if (!aSoEp->incomplete)
00185 {
00186 NotLast = FALSE;
00187 *psize = totalsize;
00188 }
00189 }
00190
00191 else
00192 {
00193 NotLast = FALSE;
00194 if (((aSoEp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_SOE) &&
00195 (aSoEp->opCode == ECT_SOE_READRES) &&
00196 (aSoEp->error == 1))
00197 {
00198 mp = (uint8 *)&MbxIn + (etohs(aSoEp->MbxHeader.length) + sizeof(ec_mbxheadert) - sizeof(uint16));
00199 errorcode = (uint16 *)mp;
00200 ecx_SoEerror(context, slave, idn, *errorcode);
00201 }
00202 else
00203 {
00204 ecx_packeterror(context, slave, idn, 0, 1);
00205 }
00206 wkc = 0;
00207 }
00208 }
00209 else
00210 {
00211 NotLast = FALSE;
00212 ecx_packeterror(context, slave, idn, 0, 4);
00213 }
00214 }
00215 }
00216 return wkc;
00217 }
00218
00234 int ecx_SoEwrite(ecx_contextt *context, uint16 slave, uint8 driveNo, uint8 elementflags, uint16 idn, int psize, void *p, int timeout)
00235 {
00236 ec_SoEt *SoEp, *aSoEp;
00237 uint16 framedatasize, maxdata;
00238 int wkc;
00239 uint8 *mp;
00240 uint8 *hp;
00241 uint16 *errorcode;
00242 ec_mbxbuft MbxIn, MbxOut;
00243 uint8 cnt;
00244 boolean NotLast;
00245
00246 ec_clearmbx(&MbxIn);
00247
00248 wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, 0);
00249 ec_clearmbx(&MbxOut);
00250 aSoEp = (ec_SoEt *)&MbxIn;
00251 SoEp = (ec_SoEt *)&MbxOut;
00252 SoEp->MbxHeader.address = htoes(0x0000);
00253 SoEp->MbxHeader.priority = 0x00;
00254 SoEp->opCode = ECT_SOE_WRITEREQ;
00255 SoEp->error = 0;
00256 SoEp->driveNo = driveNo;
00257 SoEp->elementflags = elementflags;
00258 hp = p;
00259 mp = (uint8 *)&MbxOut + sizeof(ec_SoEt);
00260 maxdata = context->slavelist[slave].mbx_l - sizeof(ec_SoEt);
00261 NotLast = TRUE;
00262 while (NotLast)
00263 {
00264 framedatasize = psize;
00265 NotLast = FALSE;
00266 SoEp->idn = htoes(idn);
00267 SoEp->incomplete = 0;
00268 if (framedatasize > maxdata)
00269 {
00270 framedatasize = maxdata;
00271 NotLast = TRUE;
00272 SoEp->incomplete = 1;
00273 SoEp->fragmentsleft = psize / maxdata;
00274 }
00275 SoEp->MbxHeader.length = htoes(sizeof(ec_SoEt) - sizeof(ec_mbxheadert) + framedatasize);
00276
00277 cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt);
00278 context->slavelist[slave].mbx_cnt = cnt;
00279 SoEp->MbxHeader.mbxtype = ECT_MBXT_SOE + (cnt << 4);
00280
00281 memcpy(mp, hp, framedatasize);
00282 hp += framedatasize;
00283 psize -= framedatasize;
00284
00285 wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
00286 if (wkc > 0)
00287 {
00288 if (!NotLast || !ecx_mbxempty(context, slave, timeout))
00289 {
00290
00291 ec_clearmbx(&MbxIn);
00292
00293 wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, timeout);
00294 if (wkc > 0)
00295 {
00296 NotLast = FALSE;
00297
00298 if (((aSoEp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_SOE) &&
00299 (aSoEp->opCode == ECT_SOE_WRITERES) &&
00300 (aSoEp->error == 0) &&
00301 (aSoEp->driveNo == driveNo) &&
00302 (aSoEp->elementflags == elementflags))
00303 {
00304
00305 }
00306
00307 else
00308 {
00309 if (((aSoEp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_SOE) &&
00310 (aSoEp->opCode == ECT_SOE_READRES) &&
00311 (aSoEp->error == 1))
00312 {
00313 mp = (uint8 *)&MbxIn + (etohs(aSoEp->MbxHeader.length) + sizeof(ec_mbxheadert) - sizeof(uint16));
00314 errorcode = (uint16 *)mp;
00315 ecx_SoEerror(context, slave, idn, *errorcode);
00316 }
00317 else
00318 {
00319 ecx_packeterror(context, slave, idn, 0, 1);
00320 }
00321 wkc = 0;
00322 }
00323 }
00324 else
00325 {
00326 ecx_packeterror(context, slave, idn, 0, 4);
00327 }
00328 }
00329 }
00330 }
00331 return wkc;
00332 }
00333
00346 int ecx_readIDNmap(ecx_contextt *context, uint16 slave, int *Osize, int *Isize)
00347 {
00348 int retVal = 0;
00349 int wkc;
00350 int psize;
00351 uint16 entries, itemcount;
00352 ec_SoEmappingt SoEmapping;
00353 ec_SoEattributet SoEattribute;
00354
00355 *Isize = 0;
00356 *Osize = 0;
00357 psize = sizeof(SoEmapping);
00358
00359 wkc = ecx_SoEread(context, slave, 0, EC_SOE_VALUE_B, EC_IDN_MDTCONFIG, &psize, &SoEmapping, EC_TIMEOUTRXM);
00360 if ((wkc > 0) && (psize >= 4) && ((entries = etohs(SoEmapping.currentlength) / 2) > 0) && (entries <= EC_SOE_MAXMAPPING))
00361 {
00362
00363 *Osize = 16;
00364 for (itemcount = 0 ; itemcount < entries ; itemcount++)
00365 {
00366 psize = sizeof(SoEattribute);
00367
00368 wkc = ecx_SoEread(context, slave, 0, EC_SOE_ATTRIBUTE_B, SoEmapping.idn[itemcount], &psize, &SoEattribute, EC_TIMEOUTRXM);
00369 if ((wkc > 0) && (!SoEattribute.list))
00370 {
00371
00372 *Osize += (int)8 << SoEattribute.length;
00373 }
00374 }
00375 }
00376 psize = sizeof(SoEmapping);
00377
00378 wkc = ecx_SoEread(context, slave, 0, EC_SOE_VALUE_B, EC_IDN_ATCONFIG, &psize, &SoEmapping, EC_TIMEOUTRXM);
00379 if ((wkc > 0) && (psize >= 4) && ((entries = etohs(SoEmapping.currentlength) / 2) > 0) && (entries <= EC_SOE_MAXMAPPING))
00380 {
00381
00382 *Isize = 16;
00383 for (itemcount = 0 ; itemcount < entries ; itemcount++)
00384 {
00385 psize = sizeof(SoEattribute);
00386
00387 wkc = ecx_SoEread(context, slave, 0, EC_SOE_ATTRIBUTE_B, SoEmapping.idn[itemcount], &psize, &SoEattribute, EC_TIMEOUTRXM);
00388 if ((wkc > 0) && (!SoEattribute.list))
00389 {
00390
00391 *Isize += (int)8 << SoEattribute.length;
00392 }
00393 }
00394 }
00395
00396
00397 if ((*Isize > 0) || (*Osize > 0))
00398 {
00399 retVal = 1;
00400 }
00401 return retVal;
00402 }
00403
00404 #ifdef EC_VER1
00405 int ec_SoEread(uint16 slave, uint8 driveNo, uint8 elementflags, uint16 idn, int *psize, void *p, int timeout)
00406 {
00407 return ecx_SoEread(&ecx_context, slave, driveNo, elementflags, idn, psize, p, timeout);
00408 }
00409
00410 int ec_SoEwrite(uint16 slave, uint8 driveNo, uint8 elementflags, uint16 idn, int psize, void *p, int timeout)
00411 {
00412 return ecx_SoEwrite(&ecx_context, slave, driveNo, elementflags, idn, psize, p, timeout);
00413 }
00414
00415 int ec_readIDNmap(uint16 slave, int *Osize, int *Isize)
00416 {
00417 return ecx_readIDNmap(&ecx_context, slave, Osize, Isize);
00418 }
00419 #endif