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
00048 #include <stdio.h>
00049 #include <string.h>
00050 #include <sys/time.h>
00051 #include <unistd.h>
00052 #include "ethercattype.h"
00053 #include "nicdrv.h"
00054 #include "ethercatbase.h"
00055 #include "ethercatmain.h"
00056 #include "ethercatcoe.h"
00057
00058
00059 typedef struct PACKED
00060 {
00061 ec_mbxheadert MbxHeader;
00062 uint16 CANOpen;
00063 uint8 Command;
00064 uint16 Index;
00065 uint8 SubIndex;
00066 union
00067 {
00068 uint8 bdata[0x200];
00069 uint16 wdata[0x100];
00070 uint32 ldata[0x80];
00071 };
00072 } ec_SDOt;
00073
00074
00075 typedef struct PACKED
00076 {
00077 ec_mbxheadert MbxHeader;
00078 uint16 CANOpen;
00079 uint8 Opcode;
00080 uint8 Reserved;
00081 uint16 Fragments;
00082 union
00083 {
00084 uint8 bdata[0x200];
00085 uint16 wdata[0x100];
00086 uint32 ldata[0x80];
00087 };
00088 } ec_SDOservicet;
00089
00090
00091 typedef struct PACKED
00092 {
00093 uint8 n;
00094 uint8 nu1;
00095 uint8 SMtype[EC_MAXSM];
00096 } ec_SMcommtypet;
00097
00098
00099 typedef struct PACKED
00100 {
00101 uint8 n;
00102 uint8 nu1;
00103 uint16 index[256];
00104 } ec_PDOassignt;
00105
00106
00107 typedef struct PACKED
00108 {
00109 uint8 n;
00110 uint8 nu1;
00111 uint32 PDO[256];
00112 } ec_PDOdesct;
00113
00114
00115 static ec_SMcommtypet ec_SMcommtype;
00116
00117 static ec_PDOassignt ec_PDOassign;
00118
00119 static ec_PDOdesct ec_PDOdesc;
00120
00121
00122
00123
00124
00125
00126
00127
00128 void ec_SDOerror(uint16 Slave, uint16 Index, uint8 SubIdx, int32 AbortCode)
00129 {
00130 ec_errort Ec;
00131
00132 gettimeofday(&Ec.Time, 0);
00133 Ec.Slave = Slave;
00134 Ec.Index = Index;
00135 Ec.SubIdx = SubIdx;
00136 EcatError = TRUE;
00137 Ec.Etype = EC_ERR_TYPE_SDO_ERROR;
00138 Ec.AbortCode = AbortCode;
00139 ec_pusherror(&Ec);
00140 }
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 static void ec_SDOinfoerror(uint16 Slave, uint16 Index, uint8 SubIdx, int32 AbortCode)
00151 {
00152 ec_errort Ec;
00153
00154 Ec.Slave = Slave;
00155 Ec.Index = Index;
00156 Ec.SubIdx = SubIdx;
00157 EcatError = TRUE;
00158 Ec.Etype = EC_ERR_TYPE_SDOINFO_ERROR;
00159 Ec.AbortCode = AbortCode;
00160 ec_pusherror(&Ec);
00161 }
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 int ec_SDOread(uint16 slave, uint16 index, uint8 subindex,
00180 boolean CA, int *psize, void *p, int timeout)
00181 {
00182 ec_SDOt *SDOp, *aSDOp;
00183 uint16 bytesize, Framedatasize;
00184 int wkc;
00185 int32 SDOlen;
00186 uint8 *bp;
00187 uint8 *hp;
00188 ec_mbxbuft MbxIn, MbxOut;
00189 uint8 cnt, toggle;
00190 boolean NotLast;
00191
00192 ec_clearmbx(&MbxIn);
00193
00194 wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, 0);
00195 ec_clearmbx(&MbxOut);
00196 aSDOp = (ec_SDOt *)&MbxIn;
00197 SDOp = (ec_SDOt *)&MbxOut;
00198 SDOp->MbxHeader.length = htoes(0x000a);
00199 SDOp->MbxHeader.address = htoes(0x0000);
00200 SDOp->MbxHeader.priority = 0x00;
00201
00202 cnt = ec_nextmbxcnt(ec_slave[slave].mbx_cnt);
00203 ec_slave[slave].mbx_cnt = cnt;
00204 SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4);
00205 SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12));
00206 if (CA)
00207 SDOp->Command = ECT_SDO_UP_REQ_CA;
00208 else
00209 SDOp->Command = ECT_SDO_UP_REQ;
00210 SDOp->Index = htoes(index);
00211 if (CA && (subindex > 1))
00212 subindex = 1;
00213 SDOp->SubIndex = subindex;
00214 SDOp->ldata[0] = 0;
00215
00216 wkc = ec_mbxsend(slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
00217 if (wkc > 0)
00218 {
00219
00220 ec_clearmbx(&MbxIn);
00221
00222 wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, timeout);
00223 if (wkc > 0)
00224 {
00225
00226 if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
00227 ((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_SDORES) &&
00228 (aSDOp->Index == SDOp->Index))
00229 {
00230 if ((aSDOp->Command & 0x02) > 0)
00231 {
00232
00233 bytesize = 4 - ((aSDOp->Command >> 2) & 0x03);
00234 if (*psize >= bytesize)
00235 {
00236
00237 memcpy(p, &aSDOp->ldata[0], bytesize);
00238
00239 *psize = bytesize;
00240 }
00241 else
00242 {
00243 wkc = 0;
00244 ec_packeterror(slave, index, subindex, 3);
00245 }
00246 }
00247 else
00248 {
00249 SDOlen = etohl(aSDOp->ldata[0]);
00250
00251 if (SDOlen <= *psize)
00252 {
00253 bp = p;
00254 hp = p;
00255
00256 Framedatasize = (etohs(aSDOp->MbxHeader.length) - 10);
00257 if (Framedatasize < SDOlen)
00258 {
00259
00260 memcpy(hp, &aSDOp->ldata[1], Framedatasize);
00261
00262 hp += Framedatasize;
00263 *psize = Framedatasize;
00264 NotLast = TRUE;
00265 toggle= 0x00;
00266 while (NotLast)
00267 {
00268 SDOp = (ec_SDOt *)&MbxOut;
00269 SDOp->MbxHeader.length = htoes(0x000a);
00270 SDOp->MbxHeader.address = htoes(0x0000);
00271 SDOp->MbxHeader.priority = 0x00;
00272 cnt = ec_nextmbxcnt(ec_slave[slave].mbx_cnt);
00273 ec_slave[slave].mbx_cnt = cnt;
00274 SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4);
00275 SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12));
00276 SDOp->Command = ECT_SDO_SEG_UP_REQ + toggle;
00277 SDOp->Index = htoes(index);
00278 SDOp->SubIndex = subindex;
00279 SDOp->ldata[0] = 0;
00280
00281 wkc = ec_mbxsend(slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
00282
00283 if (wkc > 0)
00284 {
00285 ec_clearmbx(&MbxIn);
00286
00287 wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, timeout);
00288
00289 if (wkc > 0)
00290 {
00291
00292 if ((((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
00293 ((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_SDORES) &&
00294 ((aSDOp->Command & 0xe0) == 0x00)))
00295 {
00296
00297 Framedatasize = etohs(aSDOp->MbxHeader.length) - 3;
00298 if ((aSDOp->Command & 0x01) > 0)
00299 {
00300 NotLast = FALSE;
00301 if (Framedatasize == 7)
00302
00303 Framedatasize = Framedatasize - ((aSDOp->Command & 0x0e) >> 1);
00304
00305 memcpy(hp, &(aSDOp->Index), Framedatasize);
00306 }
00307 else
00308 {
00309
00310 memcpy(hp, &(aSDOp->Index), Framedatasize);
00311
00312 hp += Framedatasize;
00313 }
00314
00315 *psize += Framedatasize;
00316 }
00317
00318 else
00319 {
00320 NotLast = FALSE;
00321 if ((aSDOp->Command) == ECT_SDO_ABORT)
00322 ec_SDOerror(slave, index, subindex, etohl(aSDOp->ldata[0]));
00323 else
00324 ec_packeterror(slave, index, subindex, 1);
00325 wkc = 0;
00326 }
00327 }
00328 }
00329 toggle = toggle ^ 0x10;
00330 }
00331 }
00332
00333 else
00334 {
00335
00336 memcpy(bp, &aSDOp->ldata[1], SDOlen);
00337 *psize = SDOlen;
00338 }
00339 }
00340
00341 else
00342 {
00343 wkc = 0;
00344 ec_packeterror(slave, index, subindex, 3);
00345 }
00346 }
00347 }
00348
00349 else
00350 {
00351 if ((aSDOp->Command) == ECT_SDO_ABORT)
00352 ec_SDOerror(slave, index, subindex, etohl(aSDOp->ldata[0]));
00353 else
00354 ec_packeterror(slave, index, subindex, 1);
00355 wkc = 0;
00356 }
00357 }
00358 }
00359 return wkc;
00360 }
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377 int ec_SDOwrite(uint16 Slave, uint16 Index, uint8 SubIndex,
00378 boolean CA, int psize, void *p, int Timeout)
00379 {
00380 ec_SDOt *SDOp, *aSDOp;
00381 int wkc, maxdata;
00382 ec_mbxbuft MbxIn, MbxOut;
00383 uint8 cnt, toggle;
00384 uint16 framedatasize;
00385 boolean NotLast;
00386 uint8 *hp;
00387
00388 ec_clearmbx(&MbxIn);
00389
00390 wkc = ec_mbxreceive(Slave, (ec_mbxbuft *)&MbxIn, 0);
00391 ec_clearmbx(&MbxOut);
00392 aSDOp = (ec_SDOt *)&MbxIn;
00393 SDOp = (ec_SDOt *)&MbxOut;
00394 maxdata = ec_slave[Slave].mbx_l - 0x10;
00395 framedatasize = psize;
00396 NotLast = FALSE;
00397 if (framedatasize > maxdata)
00398 {
00399 framedatasize = maxdata;
00400 NotLast = TRUE;
00401 }
00402 SDOp->MbxHeader.length = htoes(0x0a + framedatasize);
00403 SDOp->MbxHeader.address = htoes(0x0000);
00404 SDOp->MbxHeader.priority = 0x00;
00405
00406 cnt = ec_nextmbxcnt(ec_slave[Slave].mbx_cnt);
00407 ec_slave[Slave].mbx_cnt = cnt;
00408 SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4);
00409 SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12));
00410 if (CA)
00411 SDOp->Command = ECT_SDO_DOWN_INIT_CA;
00412 else
00413 SDOp->Command = ECT_SDO_DOWN_INIT;
00414 SDOp->Index = htoes(Index);
00415 SDOp->SubIndex = SubIndex;
00416 if (CA && (SubIndex > 1))
00417 SDOp->SubIndex = 1;
00418 SDOp->ldata[0] = htoel(psize);
00419 hp = p;
00420
00421 memcpy(&SDOp->ldata[1], hp, framedatasize);
00422 hp += framedatasize;
00423 psize -= framedatasize;
00424
00425 wkc = ec_mbxsend(Slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
00426 if (wkc > 0)
00427 {
00428 ec_clearmbx(&MbxIn);
00429
00430 wkc = ec_mbxreceive(Slave, (ec_mbxbuft *)&MbxIn, Timeout);
00431 if (wkc > 0)
00432 {
00433
00434 if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
00435 ((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_SDORES) &&
00436 (aSDOp->Index == SDOp->Index) &&
00437 (aSDOp->SubIndex == SDOp->SubIndex))
00438 {
00439
00440 maxdata += 7;
00441 toggle = 0;
00442
00443 while (NotLast)
00444 {
00445 SDOp = (ec_SDOt *)&MbxOut;
00446 framedatasize = psize;
00447 NotLast = FALSE;
00448 SDOp->Command = 0x01;
00449 if (framedatasize > maxdata)
00450 {
00451 framedatasize = maxdata;
00452 NotLast = TRUE;
00453 SDOp->Command = 0x00;
00454 }
00455 if (!NotLast && (framedatasize < 7))
00456 {
00457 SDOp->MbxHeader.length = htoes(0x0a);
00458 SDOp->Command = 0x01 + ((7 - framedatasize) << 1);
00459 }
00460 else
00461 SDOp->MbxHeader.length = htoes(framedatasize + 3);
00462 SDOp->MbxHeader.address = htoes(0x0000);
00463 SDOp->MbxHeader.priority = 0x00;
00464
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);
00468 SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12));
00469 SDOp->Command = SDOp->Command + toggle;
00470
00471 memcpy(&SDOp->Index, hp, framedatasize);
00472
00473 hp += framedatasize;
00474 psize -= framedatasize;
00475
00476 wkc = ec_mbxsend(Slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
00477 if (wkc > 0)
00478 {
00479 ec_clearmbx(&MbxIn);
00480
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) &&
00486 ((aSDOp->Command & 0xe0) == 0x20))
00487 {
00488
00489 }
00490 else
00491 {
00492 if (aSDOp->Command == ECT_SDO_ABORT)
00493 ec_SDOerror(Slave, Index, SubIndex, etohl(aSDOp->ldata[0]));
00494 else
00495 ec_packeterror(Slave, Index, SubIndex, 1);
00496 wkc = 0;
00497 NotLast = FALSE;
00498 }
00499 }
00500 }
00501 toggle = toggle ^ 0x10;
00502 }
00503 }
00504
00505 else
00506 {
00507 if (aSDOp->Command == ECT_SDO_ABORT)
00508 ec_SDOerror(Slave, Index, SubIndex, etohl(aSDOp->ldata[0]));
00509 else
00510 ec_packeterror(Slave, Index, SubIndex, 1);
00511 wkc = 0;
00512 }
00513 }
00514 }
00515
00516 return wkc;
00517 }
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529 int ec_RxPDO(uint16 Slave, uint16 RxPDOnumber , int psize, void *p)
00530 {
00531 ec_SDOt *SDOp;
00532 int wkc, maxdata;
00533 ec_mbxbuft MbxIn, MbxOut;
00534 uint8 cnt;
00535 uint16 framedatasize;
00536
00537 ec_clearmbx(&MbxIn);
00538
00539 wkc = ec_mbxreceive(Slave, (ec_mbxbuft *)&MbxIn, 0);
00540 ec_clearmbx(&MbxOut);
00541 SDOp = (ec_SDOt *)&MbxOut;
00542 maxdata = ec_slave[Slave].mbx_l - 0x08;
00543 framedatasize = psize;
00544 if (framedatasize > maxdata)
00545 framedatasize = maxdata;
00546 SDOp->MbxHeader.length = htoes(0x02 + framedatasize);
00547 SDOp->MbxHeader.address = htoes(0x0000);
00548 SDOp->MbxHeader.priority = 0x00;
00549
00550 cnt = ec_nextmbxcnt(ec_slave[Slave].mbx_cnt);
00551 ec_slave[Slave].mbx_cnt = cnt;
00552 SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4);
00553 SDOp->CANOpen = htoes((RxPDOnumber & 0x01ff) + (ECT_COES_RXPDO << 12));
00554
00555 memcpy(&SDOp->Command, p, framedatasize);
00556
00557 wkc = ec_mbxsend(Slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
00558
00559 return wkc;
00560 }
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573 int ec_TxPDO(uint16 slave, uint16 TxPDOnumber , int *psize, void *p, int timeout)
00574 {
00575 ec_SDOt *SDOp, *aSDOp;
00576 int wkc;
00577 ec_mbxbuft MbxIn, MbxOut;
00578 uint8 cnt;
00579 uint16 framedatasize;
00580
00581 ec_clearmbx(&MbxIn);
00582
00583 wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, 0);
00584 ec_clearmbx(&MbxOut);
00585 aSDOp = (ec_SDOt *)&MbxIn;
00586 SDOp = (ec_SDOt *)&MbxOut;
00587 SDOp->MbxHeader.length = htoes(0x02);
00588 SDOp->MbxHeader.address = htoes(0x0000);
00589 SDOp->MbxHeader.priority = 0x00;
00590
00591 cnt = ec_nextmbxcnt(ec_slave[slave].mbx_cnt);
00592 ec_slave[slave].mbx_cnt = cnt;
00593 SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4);
00594 SDOp->CANOpen = htoes((TxPDOnumber & 0x01ff) + (ECT_COES_TXPDO_RR << 12));
00595 wkc = ec_mbxsend(slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
00596 if (wkc > 0)
00597 {
00598
00599 ec_clearmbx(&MbxIn);
00600
00601 wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, timeout);
00602 if (wkc > 0)
00603 {
00604
00605 if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
00606 ((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_TXPDO))
00607 {
00608
00609 framedatasize = (aSDOp->MbxHeader.length - 2);
00610 if (*psize >= framedatasize)
00611 {
00612
00613 memcpy(p, &aSDOp->Command, framedatasize);
00614
00615 *psize = framedatasize;
00616 }
00617
00618 else
00619 {
00620 wkc = 0;
00621 ec_packeterror(slave, 0, 0, 3);
00622 }
00623 }
00624
00625 else
00626 {
00627 if ((aSDOp->Command) == ECT_SDO_ABORT)
00628 ec_SDOerror(slave, 0, 0, etohl(aSDOp->ldata[0]));
00629 else
00630 ec_packeterror(slave, 0, 0, 1);
00631 wkc = 0;
00632 }
00633 }
00634 }
00635
00636 return wkc;
00637 }
00638
00639
00640 int ec_readPDOassign(uint16 Slave, uint16 PDOassign)
00641 {
00642 uint16 idxloop, nidx, subidxloop, rdat, idx, subidx;
00643 uint8 subcnt;
00644 int wkc, bsize = 0, rdl;
00645 int32 rdat2;
00646
00647 rdl = sizeof(rdat); rdat = 0;
00648
00649 wkc = ec_SDOread(Slave, PDOassign, 0x00, FALSE, &rdl, &rdat, EC_TIMEOUTRXM);
00650 rdat = etohs(rdat);
00651
00652 if ((wkc > 0) && (rdat > 0))
00653 {
00654
00655 nidx = rdat;
00656 bsize = 0;
00657
00658 for (idxloop = 1; idxloop <= nidx; idxloop++)
00659 {
00660 rdl = sizeof(rdat); rdat = 0;
00661
00662 wkc = ec_SDOread(Slave, PDOassign, (uint8)idxloop, FALSE, &rdl, &rdat, EC_TIMEOUTRXM);
00663
00664 idx = etohl(rdat);
00665 if (idx > 0)
00666 {
00667 rdl = sizeof(subcnt); subcnt = 0;
00668
00669 wkc = ec_SDOread(Slave,idx, 0x00, FALSE, &rdl, &subcnt, EC_TIMEOUTRXM);
00670 subidx = subcnt;
00671
00672 for (subidxloop = 1; subidxloop <= subidx; subidxloop++)
00673 {
00674 rdl = sizeof(rdat2); rdat2 = 0;
00675
00676 wkc = ec_SDOread(Slave, idx, (uint8)subidxloop, FALSE, &rdl, &rdat2, EC_TIMEOUTRXM);
00677 rdat2 = etohl(rdat2);
00678
00679 if (LO_BYTE(rdat2) < 0xff)
00680 bsize += LO_BYTE(rdat2);
00681 else
00682 {
00683 rdl = sizeof(rdat); rdat = htoes(0xff);
00684
00685
00686 bsize += etohs(rdat);
00687 }
00688 };
00689 };
00690 };
00691 };
00692
00693 return bsize;
00694 }
00695
00696
00697 int ec_readPDOassignCA(uint16 Slave, uint16 PDOassign)
00698 {
00699 uint16 idxloop, nidx, subidxloop, idx, subidx;
00700 int wkc, bsize = 0, rdl;
00701
00702
00703 rdl = sizeof(ec_PDOassign);
00704 ec_PDOassign.n=0;
00705
00706 wkc = ec_SDOread(Slave, PDOassign, 0x00, TRUE, &rdl, &ec_PDOassign, EC_TIMEOUTRXM);
00707
00708 if ((wkc > 0) && (ec_PDOassign.n > 0))
00709 {
00710 nidx = ec_PDOassign.n;
00711 bsize = 0;
00712
00713 for (idxloop = 1; idxloop <= nidx; idxloop++)
00714 {
00715
00716 idx = etohs(ec_PDOassign.index[idxloop - 1]);
00717 if (idx > 0)
00718 {
00719 rdl = sizeof(ec_PDOdesc); ec_PDOdesc.n = 0;
00720
00721 wkc = ec_SDOread(Slave,idx, 0x00, TRUE, &rdl, &ec_PDOdesc, EC_TIMEOUTRXM);
00722 subidx = ec_PDOdesc.n;
00723
00724 for (subidxloop = 1; subidxloop <= subidx; subidxloop++)
00725 {
00726 bsize += LO_BYTE(etohl(ec_PDOdesc.PDO[subidxloop -1]));
00727 };
00728 };
00729 };
00730 };
00731
00732 return bsize;
00733 }
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762 int ec_readPDOmap(uint16 Slave, int *Osize, int *Isize)
00763 {
00764 int wkc, rdl;
00765 int retVal = 0;
00766 uint8 nSM, iSM, tSM;
00767 int Tsize;
00768 uint8 SMt_bug_add;
00769
00770 *Isize = 0;
00771 *Osize = 0;
00772 SMt_bug_add = 0;
00773 rdl = sizeof(nSM); nSM = 0;
00774
00775 wkc = ec_SDOread(Slave, ECT_SDO_SMCOMMTYPE, 0x00, FALSE, &rdl, &nSM, EC_TIMEOUTRXM);
00776
00777 if ((wkc > 0) && (nSM > 2))
00778 {
00779
00780 nSM--;
00781
00782 if (nSM > EC_MAXSM)
00783 nSM = EC_MAXSM;
00784
00785 for (iSM = 2 ; iSM <= nSM ; iSM++)
00786 {
00787 rdl = sizeof(tSM); tSM = 0;
00788
00789 wkc = ec_SDOread(Slave, ECT_SDO_SMCOMMTYPE, iSM + 1, FALSE, &rdl, &tSM, EC_TIMEOUTRXM);
00790 if (wkc > 0)
00791 {
00792
00793 if((iSM == 2) && (tSM == 2))
00794 SMt_bug_add = 1;
00795 if(tSM)
00796 tSM += SMt_bug_add;
00797
00798
00799 ec_slave[Slave].SMtype[iSM] = tSM;
00800
00801 if (tSM == 0)
00802 ec_slave[Slave].SM[iSM].SMflags = htoel( etohl(ec_slave[Slave].SM[iSM].SMflags) & EC_SMENABLEMASK);
00803 if ((tSM == 3) || (tSM == 4))
00804 {
00805
00806 Tsize = ec_readPDOassign(Slave, ECT_SDO_PDOASSIGN + iSM );
00807
00808 if (Tsize)
00809 {
00810 ec_slave[Slave].SM[iSM].SMlength = htoes((Tsize + 7) / 8);
00811 if (tSM == 3)
00812
00813 *Osize += Tsize;
00814 else
00815
00816 *Isize += Tsize;
00817 }
00818 }
00819 }
00820 }
00821 }
00822
00823
00824 if ((*Isize > 0) || (*Osize > 0))
00825 retVal = 1;
00826 return retVal;
00827 }
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840 int ec_readPDOmapCA(uint16 Slave, int *Osize, int *Isize)
00841 {
00842 int wkc, rdl;
00843 int retVal = 0;
00844 uint8 nSM, iSM, tSM;
00845 int Tsize;
00846 uint8 SMt_bug_add;
00847
00848 *Isize = 0;
00849 *Osize = 0;
00850 SMt_bug_add = 0;
00851 rdl = sizeof(ec_SMcommtype);
00852 ec_SMcommtype.n = 0;
00853
00854 wkc = ec_SDOread(Slave, ECT_SDO_SMCOMMTYPE, 0x00, TRUE, &rdl, &ec_SMcommtype, EC_TIMEOUTRXM);
00855
00856 if ((wkc > 0) && (ec_SMcommtype.n > 2))
00857 {
00858
00859 nSM = ec_SMcommtype.n - 1;
00860
00861 if (nSM > EC_MAXSM)
00862 nSM = EC_MAXSM;
00863
00864 for (iSM = 2 ; iSM <= nSM ; iSM++)
00865 {
00866 tSM = ec_SMcommtype.SMtype[iSM];
00867
00868
00869 if((iSM == 2) && (tSM == 2))
00870 SMt_bug_add = 1;
00871 if(tSM)
00872 tSM += SMt_bug_add;
00873
00874
00875 ec_slave[Slave].SMtype[iSM] = tSM;
00876
00877 if (tSM == 0)
00878 ec_slave[Slave].SM[iSM].SMflags = htoel( etohl(ec_slave[Slave].SM[iSM].SMflags) & EC_SMENABLEMASK);
00879 if ((tSM == 3) || (tSM == 4))
00880 {
00881
00882 Tsize = ec_readPDOassignCA(Slave, ECT_SDO_PDOASSIGN + iSM );
00883
00884 if (Tsize)
00885 {
00886 ec_slave[Slave].SM[iSM].SMlength = htoes((Tsize + 7) / 8);
00887 if (tSM == 3)
00888
00889 *Osize += Tsize;
00890 else
00891
00892 *Isize += Tsize;
00893 }
00894 }
00895 }
00896 }
00897
00898
00899 if ((*Isize > 0) || (*Osize > 0))
00900 retVal = 1;
00901 return retVal;
00902 }
00903
00904
00905
00906
00907
00908
00909
00910 int ec_readODlist(uint16 Slave, ec_ODlistt *pODlist)
00911 {
00912 ec_SDOservicet *SDOp, *aSDOp;
00913 ec_mbxbuft MbxIn, MbxOut;
00914 int wkc;
00915 uint16 x, n, i, sp, offset;
00916 boolean stop;
00917 uint8 cnt;
00918 boolean First;
00919
00920 pODlist->Slave = Slave;
00921 pODlist->Entries = 0;
00922 ec_clearmbx(&MbxIn);
00923
00924 wkc = ec_mbxreceive(Slave, &MbxIn, 0);
00925 ec_clearmbx(&MbxOut);
00926 aSDOp = (ec_SDOservicet*)&MbxIn;
00927 SDOp = (ec_SDOservicet*)&MbxOut;
00928 SDOp->MbxHeader.length = htoes(0x0008);
00929 SDOp->MbxHeader.address = htoes(0x0000);
00930 SDOp->MbxHeader.priority = 0x00;
00931
00932 cnt = ec_nextmbxcnt(ec_slave[Slave].mbx_cnt);
00933 ec_slave[Slave].mbx_cnt = cnt;
00934 SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4);
00935 SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOINFO << 12));
00936 SDOp->Opcode = ECT_GET_ODLIST_REQ;
00937 SDOp->Reserved = 0;
00938 SDOp->Fragments = 0;
00939 SDOp->wdata[0] = htoes(0x01);
00940
00941 wkc = ec_mbxsend(Slave, &MbxOut, EC_TIMEOUTTXM);
00942
00943 if (wkc > 0)
00944 {
00945 x = 0;
00946 sp = 0;
00947 First = TRUE;
00948 offset = 1;
00949 do
00950 {
00951 stop = TRUE;
00952 ec_clearmbx(&MbxIn);
00953
00954 wkc = ec_mbxreceive(Slave, &MbxIn, EC_TIMEOUTRXM);
00955
00956 if (wkc > 0)
00957 {
00958
00959 if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
00960 ((aSDOp->Opcode & 0x7f) == ECT_GET_ODLIST_RES))
00961 {
00962 if (First)
00963
00964 n = (etohs(aSDOp->MbxHeader.length) - (6 + 2)) / 2;
00965 else
00966
00967 n = (etohs(aSDOp->MbxHeader.length) - 6) / 2;
00968
00969 if ((sp + n) > EC_MAXODLIST)
00970 {
00971 n = EC_MAXODLIST + 1 - sp;
00972 ec_SDOinfoerror(Slave, 0, 0, 0xf000000);
00973 stop = TRUE;
00974 }
00975
00976 if ((pODlist->Entries + n) > EC_MAXODLIST)
00977 n = EC_MAXODLIST - pODlist->Entries;
00978 pODlist->Entries += n;
00979
00980 for (i = 0; i < n; i++)
00981 pODlist->Index[sp + i] = etohs(aSDOp->wdata[i + offset]);
00982 sp += n;
00983
00984 if (aSDOp->Fragments > 0)
00985 stop = FALSE;
00986 First = FALSE;
00987 offset = 0;
00988 }
00989
00990 else
00991 {
00992 if ((aSDOp->Opcode & 0x7f) == ECT_SDOINFO_ERROR)
00993 {
00994 ec_SDOinfoerror(Slave, 0, 0, etohl(aSDOp->ldata[0]));
00995 stop = TRUE;
00996 }
00997 else
00998 ec_packeterror(Slave, 0, 0, 1);
00999 wkc = 0;
01000 x += 20;
01001 }
01002 }
01003 x++;
01004 }
01005 while ((x <= 128) && !stop);
01006 }
01007 return wkc;
01008 }
01009
01010
01011
01012
01013
01014
01015
01016 int ec_readODdescription(uint16 Item, ec_ODlistt *pODlist)
01017 {
01018 ec_SDOservicet *SDOp, *aSDOp;
01019 int wkc;
01020 uint16 n, Slave;
01021 ec_mbxbuft MbxIn, MbxOut;
01022 uint8 cnt;
01023
01024 Slave = pODlist->Slave;
01025 pODlist->DataType[Item] = 0;
01026 pODlist->ObjectCode[Item] = 0;
01027 pODlist->MaxSub[Item] = 0;
01028 pODlist->Name[Item][0] = 0;
01029 ec_clearmbx(&MbxIn);
01030
01031 wkc = ec_mbxreceive(Slave, &MbxIn, 0);
01032 ec_clearmbx(&MbxOut);
01033 aSDOp = (ec_SDOservicet*)&MbxIn;
01034 SDOp = (ec_SDOservicet*)&MbxOut;
01035 SDOp->MbxHeader.length = htoes(0x0008);
01036 SDOp->MbxHeader.address = htoes(0x0000);
01037 SDOp->MbxHeader.priority = 0x00;
01038
01039 cnt = ec_nextmbxcnt(ec_slave[Slave].mbx_cnt);
01040 ec_slave[Slave].mbx_cnt = cnt;
01041 SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4);
01042 SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOINFO << 12));
01043 SDOp->Opcode = ECT_GET_OD_REQ;
01044 SDOp->Reserved = 0;
01045 SDOp->Fragments = 0;
01046 SDOp->wdata[0] = htoes(pODlist->Index[Item]);
01047
01048 wkc = ec_mbxsend(Slave, &MbxOut, EC_TIMEOUTTXM);
01049
01050 if (wkc > 0)
01051 {
01052 ec_clearmbx(&MbxIn);
01053
01054 wkc = ec_mbxreceive(Slave, &MbxIn, EC_TIMEOUTRXM);
01055
01056 if (wkc > 0)
01057 {
01058 if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
01059 ((aSDOp->Opcode & 0x7f) == ECT_GET_OD_RES))
01060 {
01061 n = (etohs(aSDOp->MbxHeader.length) - 12);
01062 if (n > EC_MAXNAME)
01063 n = EC_MAXNAME;
01064 pODlist->DataType[Item] = etohs(aSDOp->wdata[1]);
01065 pODlist->ObjectCode[Item] = aSDOp->bdata[5];
01066 pODlist->MaxSub[Item] = aSDOp->bdata[4];
01067
01068 strncpy(pODlist->Name[Item] , (char *)&aSDOp->bdata[6], n);
01069 pODlist->Name[Item][n] = 0x00;
01070 }
01071
01072 else
01073 {
01074 if (((aSDOp->Opcode & 0x7f) == ECT_SDOINFO_ERROR))
01075 ec_SDOinfoerror(Slave,pODlist->Index[Item], 0, etohl(aSDOp->ldata[0]));
01076 else
01077 ec_packeterror(Slave,pODlist->Index[Item], 0, 1);
01078 wkc = 0;
01079 }
01080 }
01081 }
01082 return wkc;
01083 }
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094 static int ec_readOEsingle(uint16 Item, uint8 SubI, ec_ODlistt *pODlist, ec_OElistt *pOElist)
01095 {
01096 ec_SDOservicet *SDOp, *aSDOp;
01097 uint16 wkc, Index, Slave;
01098 int16 n;
01099 ec_mbxbuft MbxIn, MbxOut;
01100 uint8 cnt;
01101
01102 wkc = 0;
01103 Slave = pODlist->Slave;
01104 Index = pODlist->Index[Item];
01105 ec_clearmbx(&MbxIn);
01106
01107 wkc = ec_mbxreceive(Slave, &MbxIn, 0);
01108 ec_clearmbx(&MbxOut);
01109 aSDOp = (ec_SDOservicet*)&MbxIn;
01110 SDOp = (ec_SDOservicet*)&MbxOut;
01111 SDOp->MbxHeader.length = htoes(0x000a);
01112 SDOp->MbxHeader.address = htoes(0x0000);
01113 SDOp->MbxHeader.priority = 0x00;
01114
01115 cnt = ec_nextmbxcnt(ec_slave[Slave].mbx_cnt);
01116 ec_slave[Slave].mbx_cnt = cnt;
01117 SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4);
01118 SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOINFO << 12));
01119 SDOp->Opcode = ECT_GET_OE_REQ;
01120 SDOp->Reserved = 0;
01121 SDOp->Fragments = 0;
01122 SDOp->wdata[0] = htoes(Index);
01123 SDOp->bdata[2] = SubI;
01124 SDOp->bdata[3] = 1 + 2 + 4;
01125
01126 wkc = ec_mbxsend(Slave, &MbxOut, EC_TIMEOUTTXM);
01127
01128 if (wkc > 0)
01129 {
01130 ec_clearmbx(&MbxIn);
01131
01132 wkc = ec_mbxreceive(Slave, &MbxIn, EC_TIMEOUTRXM);
01133
01134 if (wkc > 0)
01135 {
01136 if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
01137 ((aSDOp->Opcode & 0x7f) == ECT_GET_OE_RES))
01138 {
01139 pOElist->Entries++;
01140 n = (etohs(aSDOp->MbxHeader.length) - 16);
01141 if (n > EC_MAXNAME)
01142 n = EC_MAXNAME;
01143 if (n < 0 )
01144 n = 0;
01145 pOElist->ValueInfo[SubI] = aSDOp->bdata[3];
01146 pOElist->DataType[SubI] = etohs(aSDOp->wdata[2]);
01147 pOElist->BitLength[SubI] = etohs(aSDOp->wdata[3]);
01148 pOElist->ObjAccess[SubI] = etohs(aSDOp->wdata[4]);
01149
01150 strncpy(pOElist->Name[SubI] , (char *)&aSDOp->wdata[5], n);
01151 pOElist->Name[SubI][n] = 0x00;
01152 }
01153
01154 else
01155 {
01156 if (((aSDOp->Opcode & 0x7f) == ECT_SDOINFO_ERROR))
01157 ec_SDOinfoerror(Slave, Index, SubI, etohl(aSDOp->ldata[0]));
01158 else
01159 ec_packeterror(Slave, Index, SubI, 1);
01160 wkc = 0;
01161 }
01162 }
01163 }
01164 return wkc;
01165 }
01166
01167
01168
01169
01170
01171
01172
01173
01174 int ec_readOE(uint16 Item, ec_ODlistt *pODlist, ec_OElistt *pOElist)
01175 {
01176 uint16 SubCount;
01177 int wkc;
01178 uint8 SubI;
01179
01180 wkc = 0;
01181 pOElist->Entries = 0;
01182 SubI = pODlist->MaxSub[Item];
01183
01184 for (SubCount = 0; SubCount <= (SubI); SubCount++)
01185
01186 wkc = ec_readOEsingle(Item, (uint8)SubCount, pODlist, pOElist);
01187 return wkc;
01188 }