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
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];
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];
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
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
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);
00208 SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12));
00209 if (CA)
00210 SDOp->Command = ECT_SDO_UP_REQ_CA;
00211 else
00212 SDOp->Command = ECT_SDO_UP_REQ;
00213 SDOp->Index = htoes(index);
00214 if (CA && (subindex > 1))
00215 subindex = 1;
00216 SDOp->SubIndex = subindex;
00217 SDOp->ldata[0] = 0;
00218
00219 wkc = ec_mbxsend(slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
00220 if (wkc > 0)
00221 {
00222
00223 ec_clearmbx(&MbxIn);
00224
00225 wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, timeout);
00226 if (wkc > 0)
00227 {
00228
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
00235 bytesize = 4 - ((aSDOp->Command >> 2) & 0x03);
00236 if (*psize >= bytesize)
00237 {
00238
00239 memcpy(p, &aSDOp->ldata[0], bytesize);
00240
00241 *psize = bytesize;
00242 }
00243 else
00244 {
00245 wkc = 0;
00246 ec_packeterror(slave, index, subindex, 3);
00247 }
00248 }
00249 else
00250 {
00251 SDOlen = etohl(aSDOp->ldata[0]);
00252
00253 if (SDOlen <= *psize)
00254 {
00255 bp = p;
00256 hp = p;
00257
00258 Framedatasize = (etohs(aSDOp->MbxHeader.length) - 10);
00259 if (Framedatasize < SDOlen)
00260 {
00261
00262 memcpy(hp, &aSDOp->ldata[1], Framedatasize);
00263
00264 hp += Framedatasize;
00265 *psize = Framedatasize;
00266 NotLast = TRUE;
00267 toggle= 0x00;
00268 while (NotLast)
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);
00277 SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12));
00278 SDOp->Command = ECT_SDO_SEG_UP_REQ + toggle;
00279 SDOp->Index = htoes(index);
00280 SDOp->SubIndex = subindex;
00281 SDOp->ldata[0] = 0;
00282
00283 wkc = ec_mbxsend(slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
00284
00285 if (wkc > 0)
00286 {
00287 ec_clearmbx(&MbxIn);
00288
00289 wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, timeout);
00290
00291 if (wkc > 0)
00292 {
00293
00294 if ((((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
00295 ((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_SDORES) &&
00296 ((aSDOp->Command & 0xe0) == 0x00)))
00297 {
00298
00299 Framedatasize = etohs(aSDOp->MbxHeader.length) - 3;
00300 if ((aSDOp->Command & 0x01) > 0)
00301 {
00302 NotLast = FALSE;
00303 if (Framedatasize == 7)
00304
00305 Framedatasize = Framedatasize - ((aSDOp->Command & 0x0e) >> 1);
00306
00307 memcpy(hp, &(aSDOp->Index), Framedatasize);
00308 }
00309 else
00310 {
00311
00312 memcpy(hp, &(aSDOp->Index), Framedatasize);
00313
00314 hp += Framedatasize;
00315 }
00316
00317 *psize += Framedatasize;
00318 }
00319
00320 else
00321 {
00322 NotLast = FALSE;
00323 if ((aSDOp->Command) == ECT_SDO_ABORT)
00324 ec_SDOerror(slave, index, subindex, etohl(aSDOp->ldata[0]));
00325 else
00326 ec_packeterror(slave, index, subindex, 1);
00327 wkc = 0;
00328 }
00329 }
00330 }
00331 toggle = toggle ^ 0x10;
00332 }
00333 }
00334
00335 else
00336 {
00337
00338 memcpy(bp, &aSDOp->ldata[1], SDOlen);
00339 *psize = SDOlen;
00340 }
00341 }
00342
00343 else
00344 {
00345 wkc = 0;
00346 ec_packeterror(slave, index, subindex, 3);
00347 }
00348 }
00349 }
00350
00351 else
00352 {
00353 if ((aSDOp->Command) == ECT_SDO_ABORT)
00354 ec_SDOerror(slave, index, subindex, etohl(aSDOp->ldata[0]));
00355 else
00356 ec_packeterror(slave, index, subindex, 1);
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
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;
00396 framedatasize = psize;
00397 NotLast = FALSE;
00398 if (framedatasize > maxdata)
00399 {
00400 framedatasize = maxdata;
00401 NotLast = TRUE;
00402 }
00403 SDOp->MbxHeader.length = htoes(0x0a + framedatasize);
00404 SDOp->MbxHeader.address = htoes(0x0000);
00405 SDOp->MbxHeader.priority = 0x00;
00406
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);
00410 SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12));
00411 if (CA)
00412 SDOp->Command = ECT_SDO_DOWN_INIT_CA;
00413 else
00414 SDOp->Command = ECT_SDO_DOWN_INIT;
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
00422 memcpy(&SDOp->ldata[1], hp, framedatasize);
00423 hp += framedatasize;
00424 psize -= framedatasize;
00425
00426 wkc = ec_mbxsend(Slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
00427 if (wkc > 0)
00428 {
00429 ec_clearmbx(&MbxIn);
00430
00431 wkc = ec_mbxreceive(Slave, (ec_mbxbuft *)&MbxIn, Timeout);
00432 if (wkc > 0)
00433 {
00434
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
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) && ((aSDOp->Command & 0xe0) == 0x20))
00486 {
00487
00488 }
00489 else
00490 {
00491 if (aSDOp->Command == ECT_SDO_ABORT)
00492 ec_SDOerror(Slave, Index, SubIndex, etohl(aSDOp->ldata[0]));
00493 else
00494 ec_packeterror(Slave, Index, SubIndex, 1);
00495 wkc = 0;
00496 NotLast = FALSE;
00497 }
00498 }
00499 }
00500 toggle = toggle ^ 0x10;
00501 }
00502 }
00503
00504 else
00505 {
00506 if (aSDOp->Command == ECT_SDO_ABORT)
00507 ec_SDOerror(Slave, Index, SubIndex, etohl(aSDOp->ldata[0]));
00508 else
00509 ec_packeterror(Slave, Index, SubIndex, 1);
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
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;
00542 framedatasize = psize;
00543 if (framedatasize > maxdata)
00544 framedatasize = maxdata;
00545 SDOp->MbxHeader.length = htoes(0x02 + framedatasize);
00546 SDOp->MbxHeader.address = htoes(0x0000);
00547 SDOp->MbxHeader.priority = 0x00;
00548
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);
00552 SDOp->CANOpen = htoes((RxPDOnumber & 0x01ff) + (ECT_COES_RXPDO << 12));
00553
00554 memcpy(&SDOp->Command, p, framedatasize);
00555
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
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
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);
00593 SDOp->CANOpen = htoes((TxPDOnumber & 0x01ff) + (ECT_COES_TXPDO_RR << 12));
00594 wkc = ec_mbxsend(slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
00595 if (wkc > 0)
00596 {
00597
00598 ec_clearmbx(&MbxIn);
00599
00600 wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, timeout);
00601 if (wkc > 0)
00602 {
00603
00604 if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE)
00605 && ((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_TXPDO))
00606 {
00607
00608 framedatasize = (aSDOp->MbxHeader.length - 2);
00609 if (*psize >= framedatasize)
00610 {
00611
00612 memcpy(p, &aSDOp->Command, framedatasize);
00613
00614 *psize = framedatasize;
00615 }
00616
00617 else
00618 {
00619 wkc = 0;
00620 ec_packeterror(slave, 0, 0, 3);
00621 }
00622 }
00623
00624 else
00625 {
00626 if ((aSDOp->Command) == ECT_SDO_ABORT)
00627 ec_SDOerror(slave, 0, 0, etohl(aSDOp->ldata[0]));
00628 else
00629 ec_packeterror(slave, 0, 0, 1);
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
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);
00661 rdat = 0;
00662
00663 wkc = ec_SDOread(Slave, PDOassign, (uint8)idxloop, FALSE, &rdl, &rdat, EC_TIMEOUTRXM);
00664
00665 idx = etohl(rdat);
00666 if (idx > 0)
00667 {
00668 rdl = sizeof(subcnt);
00669 subcnt = 0;
00670
00671 wkc = ec_SDOread(Slave, idx, 0x00, FALSE, &rdl, &subcnt, EC_TIMEOUTRXM);
00672 subidx = subcnt;
00673
00674 for (subidxloop = 1; subidxloop <= subidx; subidxloop++)
00675 {
00676 rdl = sizeof(rdat2);
00677 rdat2 = 0;
00678
00679 wkc = ec_SDOread(Slave, idx, (uint8)subidxloop, FALSE, &rdl, &rdat2, EC_TIMEOUTRXM);
00680 rdat2 = etohl(rdat2);
00681
00682 if (LO_BYTE(rdat2) < 0xff)
00683 bsize += LO_BYTE(rdat2);
00684 else
00685 {
00686 rdl = sizeof(rdat);
00687 rdat = htoes(0xff);
00688
00689
00690 bsize += etohs(rdat);
00691 }
00692 };
00693 };
00694 };
00695 };
00696
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
00707 rdl = sizeof(ec_PDOassign);
00708 ec_PDOassign.n = 0;
00709
00710 wkc = ec_SDOread(Slave, PDOassign, 0x00, TRUE, &rdl, &ec_PDOassign, EC_TIMEOUTRXM);
00711
00712 if ((wkc > 0) && (ec_PDOassign.n > 0))
00713 {
00714 nidx = ec_PDOassign.n;
00715 bsize = 0;
00716
00717 for (idxloop = 1; idxloop <= nidx; idxloop++)
00718 {
00719
00720 idx = etohs(ec_PDOassign.index[idxloop - 1]);
00721 if (idx > 0)
00722 {
00723 rdl = sizeof(ec_PDOdesc); ec_PDOdesc.n = 0;
00724
00725 wkc = ec_SDOread(Slave,idx, 0x00, TRUE, &rdl, &ec_PDOdesc, EC_TIMEOUTRXM);
00726 subidx = ec_PDOdesc.n;
00727
00728 for (subidxloop = 1; subidxloop <= subidx; subidxloop++)
00729 {
00730 bsize += LO_BYTE(etohl(ec_PDOdesc.PDO[subidxloop -1]));
00731 };
00732 };
00733 };
00734 };
00735
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
00780 wkc = ec_SDOread(Slave, ECT_SDO_SMCOMMTYPE, 0x00, FALSE, &rdl, &nSM, EC_TIMEOUTRXM);
00781
00782 if ((wkc > 0) && (nSM > 2))
00783 {
00784
00785 nSM--;
00786
00787 if (nSM > EC_MAXSM)
00788 nSM = EC_MAXSM;
00789
00790 for (iSM = 2; iSM <= nSM; iSM++)
00791 {
00792 rdl = sizeof(tSM);
00793 tSM = 0;
00794
00795 wkc = ec_SDOread(Slave, ECT_SDO_SMCOMMTYPE, iSM + 1, FALSE, &rdl, &tSM, EC_TIMEOUTRXM);
00796 if (wkc > 0)
00797 {
00798
00799 if ((iSM == 2) && (tSM == 2))
00800 SMt_bug_add = 1;
00801 if (tSM)
00802 tSM += SMt_bug_add;
00803
00804
00805 ec_slave[Slave].SMtype[iSM] = tSM;
00806
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
00812 Tsize = ec_readPDOassign(Slave, ECT_SDO_PDOASSIGN + iSM);
00813
00814 if (Tsize)
00815 {
00816 ec_slave[Slave].SM[iSM].SMlength = htoes((Tsize + 7) / 8);
00817 if (tSM == 3)
00818
00819 *Osize += Tsize;
00820 else
00821
00822 *Isize += Tsize;
00823 }
00824 }
00825 }
00826 }
00827 }
00828
00829
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
00860 wkc = ec_SDOread(Slave, ECT_SDO_SMCOMMTYPE, 0x00, TRUE, &rdl, &ec_SMcommtype, EC_TIMEOUTRXM);
00861
00862 if ((wkc > 0) && (ec_SMcommtype.n > 2))
00863 {
00864
00865 nSM = ec_SMcommtype.n - 1;
00866
00867 if (nSM > EC_MAXSM)
00868 nSM = EC_MAXSM;
00869
00870 for (iSM = 2; iSM <= nSM; iSM++)
00871 {
00872 tSM = ec_SMcommtype.SMtype[iSM];
00873
00874
00875 if ((iSM == 2) && (tSM == 2))
00876 SMt_bug_add = 1;
00877 if (tSM)
00878 tSM += SMt_bug_add;
00879
00880
00881 ec_slave[Slave].SMtype[iSM] = tSM;
00882
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
00888 Tsize = ec_readPDOassignCA(Slave, ECT_SDO_PDOASSIGN + iSM);
00889
00890 if (Tsize)
00891 {
00892 ec_slave[Slave].SM[iSM].SMlength = htoes((Tsize + 7) / 8);
00893 if (tSM == 3)
00894
00895 *Osize += Tsize;
00896 else
00897
00898 *Isize += Tsize;
00899 }
00900 }
00901 }
00902 }
00903
00904
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
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
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);
00941 SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOINFO << 12));
00942 SDOp->Opcode = ECT_GET_ODLIST_REQ;
00943 SDOp->Reserved = 0;
00944 SDOp->Fragments = 0;
00945 SDOp->wdata[0] = htoes(0x01);
00946
00947 wkc = ec_mbxsend(Slave, &MbxOut, EC_TIMEOUTTXM);
00948
00949 if (wkc > 0)
00950 {
00951 x = 0;
00952 sp = 0;
00953 First = TRUE;
00954 offset = 1;
00955 do
00956 {
00957 stop = TRUE;
00958 ec_clearmbx(&MbxIn);
00959
00960 wkc = ec_mbxreceive(Slave, &MbxIn, EC_TIMEOUTRXM);
00961
00962 if (wkc > 0)
00963 {
00964
00965 if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE)
00966 && ((aSDOp->Opcode & 0x7f) == ECT_GET_ODLIST_RES))
00967 {
00968 if (First)
00969
00970 n = (etohs(aSDOp->MbxHeader.length) - (6 + 2)) / 2;
00971 else
00972
00973 n = (etohs(aSDOp->MbxHeader.length) - 6) / 2;
00974
00975 if ((sp + n) > EC_MAXODLIST)
00976 {
00977 n = EC_MAXODLIST + 1 - sp;
00978 ec_SDOinfoerror(Slave, 0, 0, 0xf000000);
00979 stop = TRUE;
00980 }
00981
00982 if ((pODlist->Entries + n) > EC_MAXODLIST)
00983 n = EC_MAXODLIST - pODlist->Entries;
00984 pODlist->Entries += n;
00985
00986 for (i = 0; i < n; i++)
00987 pODlist->Index[sp + i] = etohs(aSDOp->wdata[i + offset]);
00988 sp += n;
00989
00990 if (aSDOp->Fragments > 0)
00991 stop = FALSE;
00992 First = FALSE;
00993 offset = 0;
00994 }
00995
00996 else
00997 {
00998 if ((aSDOp->Opcode & 0x7f) == ECT_SDOINFO_ERROR)
00999 {
01000 ec_SDOinfoerror(Slave, 0, 0, etohl(aSDOp->ldata[0]));
01001 stop = TRUE;
01002 }
01003 else
01004 ec_packeterror(Slave, 0, 0, 1);
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
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
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);
01047 SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOINFO << 12));
01048 SDOp->Opcode = ECT_GET_OD_REQ;
01049 SDOp->Reserved = 0;
01050 SDOp->Fragments = 0;
01051 SDOp->wdata[0] = htoes(pODlist->Index[Item]);
01052
01053 wkc = ec_mbxsend(Slave, &MbxOut, EC_TIMEOUTTXM);
01054
01055 if (wkc > 0)
01056 {
01057 ec_clearmbx(&MbxIn);
01058
01059 wkc = ec_mbxreceive(Slave, &MbxIn, EC_TIMEOUTRXM);
01060
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);
01066 if (n > EC_MAXNAME)
01067 n = EC_MAXNAME;
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;
01074 }
01075
01076 else
01077 {
01078 if (((aSDOp->Opcode & 0x7f) == ECT_SDOINFO_ERROR))
01079 ec_SDOinfoerror(Slave, pODlist->Index[Item], 0, etohl(aSDOp->ldata[0]));
01080 else
01081 ec_packeterror(Slave,pODlist->Index[Item], 0, 1);
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
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
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);
01122 SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOINFO << 12));
01123 SDOp->Opcode = ECT_GET_OE_REQ;
01124 SDOp->Reserved = 0;
01125 SDOp->Fragments = 0;
01126 SDOp->wdata[0] = htoes(Index);
01127 SDOp->bdata[2] = SubI;
01128 SDOp->bdata[3] = 1 + 2 + 4;
01129
01130 wkc = ec_mbxsend(Slave, &MbxOut, EC_TIMEOUTTXM);
01131
01132 if (wkc > 0)
01133 {
01134 ec_clearmbx(&MbxIn);
01135
01136 wkc = ec_mbxreceive(Slave, &MbxIn, EC_TIMEOUTRXM);
01137
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);
01144 if (n > EC_MAXNAME)
01145 n = EC_MAXNAME;
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;
01155 }
01156
01157 else
01158 {
01159 if (((aSDOp->Opcode & 0x7f) == ECT_SDOINFO_ERROR))
01160 ec_SDOinfoerror(Slave, Index, SubI, etohl(aSDOp->ldata[0]));
01161 else
01162 ec_packeterror(Slave, Index, SubI, 1);
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
01187 for (SubCount = 0; SubCount <= (SubI); SubCount++)
01188
01189 wkc = ec_readOEsingle(Item, (uint8)SubCount, pODlist, pOElist);
01190 return wkc;
01191 }