#include <stdio.h>
#include <string.h>
#include "osal.h"
#include "oshw.h"
#include "ethercattype.h"
#include "ethercatbase.h"
#include "ethercatmain.h"
#include "ethercatcoe.h"
PACKED_BEGIN
typedef struct PACKED
{
ec_mbxheadert MbxHeader;
uint16 CANOpen;
uint8 Command;
uint16 Index;
uint8 SubIndex;
union
{
uint8 bdata[0x200];
uint16 wdata[0x100];
uint32 ldata[0x80];
};
} ec_SDOt;
PACKED_END
PACKED_BEGIN
typedef struct PACKED
{
ec_mbxheadert MbxHeader;
uint16 CANOpen;
uint8 Opcode;
uint8 Reserved;
uint16 Fragments;
union
{
uint8 bdata[0x200];
uint16 wdata[0x100];
uint32 ldata[0x80];
};
} ec_SDOservicet;
PACKED_END
void ecx_SDOerror(ecx_contextt *context, uint16 Slave, uint16 Index, uint8 SubIdx, int32 AbortCode)
{
ec_errort Ec;
memset(&Ec, 0, sizeof(Ec));
Ec.Time = osal_current_time();
Ec.Slave = Slave;
Ec.Index = Index;
Ec.SubIdx = SubIdx;
*(context->ecaterror) = TRUE;
Ec.Etype = EC_ERR_TYPE_SDO_ERROR;
Ec.AbortCode = AbortCode;
ecx_pusherror(context, &Ec);
}
static void ecx_SDOinfoerror(ecx_contextt *context, uint16 Slave, uint16 Index, uint8 SubIdx, int32 AbortCode)
{
ec_errort Ec;
memset(&Ec, 0, sizeof(Ec));
Ec.Slave = Slave;
Ec.Index = Index;
Ec.SubIdx = SubIdx;
*(context->ecaterror) = TRUE;
Ec.Etype = EC_ERR_TYPE_SDOINFO_ERROR;
Ec.AbortCode = AbortCode;
ecx_pusherror(context, &Ec);
}
int ecx_SDOread(ecx_contextt *context, uint16 slave, uint16 index, uint8 subindex,
boolean CA, int *psize, void *p, int timeout)
{
ec_SDOt *SDOp, *aSDOp;
uint16 bytesize, Framedatasize;
int wkc;
int32 SDOlen;
uint8 *bp;
uint8 *hp;
ec_mbxbuft MbxIn, MbxOut;
uint8 cnt, toggle;
boolean NotLast;
ec_clearmbx(&MbxIn);
wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, 0);
ec_clearmbx(&MbxOut);
aSDOp = (ec_SDOt *)&MbxIn;
SDOp = (ec_SDOt *)&MbxOut;
SDOp->MbxHeader.length = htoes(0x000a);
SDOp->MbxHeader.address = htoes(0x0000);
SDOp->MbxHeader.priority = 0x00;
cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt);
context->slavelist[slave].mbx_cnt = cnt;
SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4);
SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12));
if (CA)
{
SDOp->Command = ECT_SDO_UP_REQ_CA;
}
else
{
SDOp->Command = ECT_SDO_UP_REQ;
}
SDOp->Index = htoes(index);
if (CA && (subindex > 1))
{
subindex = 1;
}
SDOp->SubIndex = subindex;
SDOp->ldata[0] = 0;
wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
if (wkc > 0)
{
ec_clearmbx(&MbxIn);
wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, timeout);
if (wkc > 0)
{
if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_SDORES) &&
(aSDOp->Index == SDOp->Index))
{
if ((aSDOp->Command & 0x02) > 0)
{
bytesize = 4 - ((aSDOp->Command >> 2) & 0x03);
if (*psize >= bytesize)
{
memcpy(p, &aSDOp->ldata[0], bytesize);
*psize = bytesize;
}
else
{
wkc = 0;
ecx_packeterror(context, slave, index, subindex, 3);
}
}
else
{
SDOlen = etohl(aSDOp->ldata[0]);
if (SDOlen <= *psize)
{
bp = p;
hp = p;
Framedatasize = (etohs(aSDOp->MbxHeader.length) - 10);
if (Framedatasize < SDOlen)
{
memcpy(hp, &aSDOp->ldata[1], Framedatasize);
hp += Framedatasize;
*psize = Framedatasize;
NotLast = TRUE;
toggle= 0x00;
while (NotLast)
{
SDOp = (ec_SDOt *)&MbxOut;
SDOp->MbxHeader.length = htoes(0x000a);
SDOp->MbxHeader.address = htoes(0x0000);
SDOp->MbxHeader.priority = 0x00;
cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt);
context->slavelist[slave].mbx_cnt = cnt;
SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4);
SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12));
SDOp->Command = ECT_SDO_SEG_UP_REQ + toggle;
SDOp->Index = htoes(index);
SDOp->SubIndex = subindex;
SDOp->ldata[0] = 0;
wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
if (wkc > 0)
{
ec_clearmbx(&MbxIn);
wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, timeout);
if (wkc > 0)
{
if ((((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_SDORES) &&
((aSDOp->Command & 0xe0) == 0x00)))
{
Framedatasize = etohs(aSDOp->MbxHeader.length) - 3;
if ((aSDOp->Command & 0x01) > 0)
{
NotLast = FALSE;
if (Framedatasize == 7)
Framedatasize = Framedatasize - ((aSDOp->Command & 0x0e) >> 1);
memcpy(hp, &(aSDOp->Index), Framedatasize);
}
else
{
memcpy(hp, &(aSDOp->Index), Framedatasize);
hp += Framedatasize;
}
*psize += Framedatasize;
}
else
{
NotLast = FALSE;
if ((aSDOp->Command) == ECT_SDO_ABORT)
ecx_SDOerror(context, slave, index, subindex, etohl(aSDOp->ldata[0]));
else
ecx_packeterror(context, slave, index, subindex, 1);
wkc = 0;
}
}
}
toggle = toggle ^ 0x10;
}
}
else
{
memcpy(bp, &aSDOp->ldata[1], SDOlen);
*psize = SDOlen;
}
}
else
{
wkc = 0;
ecx_packeterror(context, slave, index, subindex, 3);
}
}
}
else
{
if ((aSDOp->Command) == ECT_SDO_ABORT)
{
ecx_SDOerror(context, slave, index, subindex, etohl(aSDOp->ldata[0]));
}
else
{
ecx_packeterror(context, slave, index, subindex, 1);
}
wkc = 0;
}
}
}
return wkc;
}
int ecx_SDOwrite(ecx_contextt *context, uint16 Slave, uint16 Index, uint8 SubIndex,
boolean CA, int psize, void *p, int Timeout)
{
ec_SDOt *SDOp, *aSDOp;
int wkc, maxdata;
ec_mbxbuft MbxIn, MbxOut;
uint8 cnt, toggle;
uint16 framedatasize;
boolean NotLast;
uint8 *hp;
ec_clearmbx(&MbxIn);
wkc = ecx_mbxreceive(context, Slave, (ec_mbxbuft *)&MbxIn, 0);
ec_clearmbx(&MbxOut);
aSDOp = (ec_SDOt *)&MbxIn;
SDOp = (ec_SDOt *)&MbxOut;
maxdata = context->slavelist[Slave].mbx_l - 0x10;
if ((psize <= 4) && !CA)
{
SDOp->MbxHeader.length = htoes(0x000a);
SDOp->MbxHeader.address = htoes(0x0000);
SDOp->MbxHeader.priority = 0x00;
cnt = ec_nextmbxcnt(context->slavelist[Slave].mbx_cnt);
context->slavelist[Slave].mbx_cnt = cnt;
SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4);
SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12));
SDOp->Command = ECT_SDO_DOWN_EXP | (((4 - psize) << 2) & 0x0c);
SDOp->Index = htoes(Index);
SDOp->SubIndex = SubIndex;
hp = p;
memcpy(&SDOp->ldata[0], hp, psize);
wkc = ecx_mbxsend(context, Slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
if (wkc > 0)
{
ec_clearmbx(&MbxIn);
wkc = ecx_mbxreceive(context, Slave, (ec_mbxbuft *)&MbxIn, Timeout);
if (wkc > 0)
{
if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_SDORES) &&
(aSDOp->Index == SDOp->Index) &&
(aSDOp->SubIndex == SDOp->SubIndex))
{
}
else
{
if (aSDOp->Command == ECT_SDO_ABORT)
{
ecx_SDOerror(context, Slave, Index, SubIndex, etohl(aSDOp->ldata[0]));
}
else
{
ecx_packeterror(context, Slave, Index, SubIndex, 1);
}
wkc = 0;
}
}
}
}
else
{
framedatasize = psize;
NotLast = FALSE;
if (framedatasize > maxdata)
{
framedatasize = maxdata;
NotLast = TRUE;
}
SDOp->MbxHeader.length = htoes(0x0a + framedatasize);
SDOp->MbxHeader.address = htoes(0x0000);
SDOp->MbxHeader.priority = 0x00;
cnt = ec_nextmbxcnt(context->slavelist[Slave].mbx_cnt);
context->slavelist[Slave].mbx_cnt = cnt;
SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4);
SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12));
if (CA)
{
SDOp->Command = ECT_SDO_DOWN_INIT_CA;
}
else
{
SDOp->Command = ECT_SDO_DOWN_INIT;
}
SDOp->Index = htoes(Index);
SDOp->SubIndex = SubIndex;
if (CA && (SubIndex > 1))
{
SDOp->SubIndex = 1;
}
SDOp->ldata[0] = htoel(psize);
hp = p;
memcpy(&SDOp->ldata[1], hp, framedatasize);
hp += framedatasize;
psize -= framedatasize;
wkc = ecx_mbxsend(context, Slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
if (wkc > 0)
{
ec_clearmbx(&MbxIn);
wkc = ecx_mbxreceive(context, Slave, (ec_mbxbuft *)&MbxIn, Timeout);
if (wkc > 0)
{
if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_SDORES) &&
(aSDOp->Index == SDOp->Index) &&
(aSDOp->SubIndex == SDOp->SubIndex))
{
maxdata += 7;
toggle = 0;
while (NotLast)
{
SDOp = (ec_SDOt *)&MbxOut;
framedatasize = psize;
NotLast = FALSE;
SDOp->Command = 0x01;
if (framedatasize > maxdata)
{
framedatasize = maxdata;
NotLast = TRUE;
SDOp->Command = 0x00;
}
if (!NotLast && (framedatasize < 7))
{
SDOp->MbxHeader.length = htoes(0x0a);
SDOp->Command = 0x01 + ((7 - framedatasize) << 1);
}
else
{
SDOp->MbxHeader.length = htoes(framedatasize + 3);
}
SDOp->MbxHeader.address = htoes(0x0000);
SDOp->MbxHeader.priority = 0x00;
cnt = ec_nextmbxcnt(context->slavelist[Slave].mbx_cnt);
context->slavelist[Slave].mbx_cnt = cnt;
SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4);
SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12));
SDOp->Command = SDOp->Command + toggle;
memcpy(&SDOp->Index, hp, framedatasize);
hp += framedatasize;
psize -= framedatasize;
wkc = ecx_mbxsend(context, Slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
if (wkc > 0)
{
ec_clearmbx(&MbxIn);
wkc = ecx_mbxreceive(context, Slave, (ec_mbxbuft *)&MbxIn, Timeout);
if (wkc > 0)
{
if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_SDORES) &&
((aSDOp->Command & 0xe0) == 0x20))
{
}
else
{
if (aSDOp->Command == ECT_SDO_ABORT)
{
ecx_SDOerror(context, Slave, Index, SubIndex, etohl(aSDOp->ldata[0]));
}
else
{
ecx_packeterror(context, Slave, Index, SubIndex, 1);
}
wkc = 0;
NotLast = FALSE;
}
}
}
toggle = toggle ^ 0x10;
}
}
else
{
if (aSDOp->Command == ECT_SDO_ABORT)
{
ecx_SDOerror(context, Slave, Index, SubIndex, etohl(aSDOp->ldata[0]));
}
else
{
ecx_packeterror(context, Slave, Index, SubIndex, 1);
}
wkc = 0;
}
}
}
}
return wkc;
}
int ecx_RxPDO(ecx_contextt *context, uint16 Slave, uint16 RxPDOnumber, int psize, void *p)
{
ec_SDOt *SDOp;
int wkc, maxdata;
ec_mbxbuft MbxIn, MbxOut;
uint8 cnt;
uint16 framedatasize;
ec_clearmbx(&MbxIn);
wkc = ecx_mbxreceive(context, Slave, (ec_mbxbuft *)&MbxIn, 0);
ec_clearmbx(&MbxOut);
SDOp = (ec_SDOt *)&MbxOut;
maxdata = context->slavelist[Slave].mbx_l - 0x08;
framedatasize = psize;
if (framedatasize > maxdata)
{
framedatasize = maxdata;
}
SDOp->MbxHeader.length = htoes(0x02 + framedatasize);
SDOp->MbxHeader.address = htoes(0x0000);
SDOp->MbxHeader.priority = 0x00;
cnt = ec_nextmbxcnt(context->slavelist[Slave].mbx_cnt);
context->slavelist[Slave].mbx_cnt = cnt;
SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4);
SDOp->CANOpen = htoes((RxPDOnumber & 0x01ff) + (ECT_COES_RXPDO << 12));
memcpy(&SDOp->Command, p, framedatasize);
wkc = ecx_mbxsend(context, Slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
return wkc;
}
int ecx_TxPDO(ecx_contextt *context, uint16 slave, uint16 TxPDOnumber , int *psize, void *p, int timeout)
{
ec_SDOt *SDOp, *aSDOp;
int wkc;
ec_mbxbuft MbxIn, MbxOut;
uint8 cnt;
uint16 framedatasize;
ec_clearmbx(&MbxIn);
wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, 0);
ec_clearmbx(&MbxOut);
aSDOp = (ec_SDOt *)&MbxIn;
SDOp = (ec_SDOt *)&MbxOut;
SDOp->MbxHeader.length = htoes(0x02);
SDOp->MbxHeader.address = htoes(0x0000);
SDOp->MbxHeader.priority = 0x00;
cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt);
context->slavelist[slave].mbx_cnt = cnt;
SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4);
SDOp->CANOpen = htoes((TxPDOnumber & 0x01ff) + (ECT_COES_TXPDO_RR << 12));
wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
if (wkc > 0)
{
ec_clearmbx(&MbxIn);
wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, timeout);
if (wkc > 0)
{
if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_TXPDO))
{
framedatasize = (aSDOp->MbxHeader.length - 2);
if (*psize >= framedatasize)
{
memcpy(p, &aSDOp->Command, framedatasize);
*psize = framedatasize;
}
else
{
wkc = 0;
ecx_packeterror(context, slave, 0, 0, 3);
}
}
else
{
if ((aSDOp->Command) == ECT_SDO_ABORT)
{
ecx_SDOerror(context, slave, 0, 0, etohl(aSDOp->ldata[0]));
}
else
{
ecx_packeterror(context, slave, 0, 0, 1);
}
wkc = 0;
}
}
}
return wkc;
}
int ecx_readPDOassign(ecx_contextt *context, uint16 Slave, uint16 PDOassign)
{
uint16 idxloop, nidx, subidxloop, rdat, idx, subidx;
uint8 subcnt;
int wkc, bsize = 0, rdl;
int32 rdat2;
rdl = sizeof(rdat); rdat = 0;
wkc = ecx_SDOread(context, Slave, PDOassign, 0x00, FALSE, &rdl, &rdat, EC_TIMEOUTRXM);
rdat = etohs(rdat);
if ((wkc > 0) && (rdat > 0))
{
nidx = rdat;
bsize = 0;
for (idxloop = 1; idxloop <= nidx; idxloop++)
{
rdl = sizeof(rdat); rdat = 0;
wkc = ecx_SDOread(context, Slave, PDOassign, (uint8)idxloop, FALSE, &rdl, &rdat, EC_TIMEOUTRXM);
idx = etohs(rdat);
if (idx > 0)
{
rdl = sizeof(subcnt); subcnt = 0;
wkc = ecx_SDOread(context, Slave,idx, 0x00, FALSE, &rdl, &subcnt, EC_TIMEOUTRXM);
subidx = subcnt;
for (subidxloop = 1; subidxloop <= subidx; subidxloop++)
{
rdl = sizeof(rdat2); rdat2 = 0;
wkc = ecx_SDOread(context, Slave, idx, (uint8)subidxloop, FALSE, &rdl, &rdat2, EC_TIMEOUTRXM);
rdat2 = etohl(rdat2);
if (LO_BYTE(rdat2) < 0xff)
{
bsize += LO_BYTE(rdat2);
}
else
{
rdl = sizeof(rdat); rdat = htoes(0xff);
bsize += etohs(rdat);
}
}
}
}
}
return bsize;
}
int ecx_readPDOassignCA(ecx_contextt *context, uint16 Slave, int Thread_n,
uint16 PDOassign)
{
uint16 idxloop, nidx, subidxloop, idx, subidx;
int wkc, bsize = 0, rdl;
rdl = sizeof(ec_PDOassignt);
context->PDOassign[Thread_n].n=0;
wkc = ecx_SDOread(context, Slave, PDOassign, 0x00, TRUE, &rdl,
&(context->PDOassign[Thread_n]), EC_TIMEOUTRXM);
if ((wkc > 0) && (context->PDOassign[Thread_n].n > 0))
{
nidx = context->PDOassign[Thread_n].n;
bsize = 0;
for (idxloop = 1; idxloop <= nidx; idxloop++)
{
idx = etohs(context->PDOassign[Thread_n].index[idxloop - 1]);
if (idx > 0)
{
rdl = sizeof(ec_PDOdesct); context->PDOdesc[Thread_n].n = 0;
wkc = ecx_SDOread(context, Slave,idx, 0x00, TRUE, &rdl,
&(context->PDOdesc[Thread_n]), EC_TIMEOUTRXM);
subidx = context->PDOdesc[Thread_n].n;
for (subidxloop = 1; subidxloop <= subidx; subidxloop++)
{
bsize += LO_BYTE(etohl(context->PDOdesc[Thread_n].PDO[subidxloop -1]));
}
}
}
}
return bsize;
}
int ecx_readPDOmap(ecx_contextt *context, uint16 Slave, int *Osize, int *Isize)
{
int wkc, rdl;
int retVal = 0;
uint8 nSM, iSM, tSM;
int Tsize;
uint8 SMt_bug_add;
*Isize = 0;
*Osize = 0;
SMt_bug_add = 0;
rdl = sizeof(nSM); nSM = 0;
wkc = ecx_SDOread(context, Slave, ECT_SDO_SMCOMMTYPE, 0x00, FALSE, &rdl, &nSM, EC_TIMEOUTRXM);
if ((wkc > 0) && (nSM > 2))
{
if (nSM > EC_MAXSM)
nSM = EC_MAXSM;
for (iSM = 2 ; iSM < nSM ; iSM++)
{
rdl = sizeof(tSM); tSM = 0;
wkc = ecx_SDOread(context, Slave, ECT_SDO_SMCOMMTYPE, iSM + 1, FALSE, &rdl, &tSM, EC_TIMEOUTRXM);
if (wkc > 0)
{
if((iSM == 2) && (tSM == 2)) {
SMt_bug_add = 1; }
if(tSM)
{
tSM += SMt_bug_add; }
if((iSM == 2) && (tSM == 0)) {
tSM = 3;
}
if((iSM == 3) && (tSM == 0)) {
tSM = 4;
}
context->slavelist[Slave].SMtype[iSM] = tSM;
if (tSM == 0)
{
context->slavelist[Slave].SM[iSM].SMflags =
htoel( etohl(context->slavelist[Slave].SM[iSM].SMflags) & EC_SMENABLEMASK);
}
if ((tSM == 3) || (tSM == 4))
{
Tsize = ecx_readPDOassign(context, Slave, ECT_SDO_PDOASSIGN + iSM );
if (Tsize)
{
context->slavelist[Slave].SM[iSM].SMlength = htoes((Tsize + 7) / 8);
if (tSM == 3)
{
*Osize += Tsize;
}
else
{
*Isize += Tsize;
}
}
}
}
}
}
if ((*Isize > 0) || (*Osize > 0))
{
retVal = 1;
}
return retVal;
}
int ecx_readPDOmapCA(ecx_contextt *context, uint16 Slave, int Thread_n, int *Osize, int *Isize)
{
int wkc, rdl;
int retVal = 0;
uint8 nSM, iSM, tSM;
int Tsize;
uint8 SMt_bug_add;
*Isize = 0;
*Osize = 0;
SMt_bug_add = 0;
rdl = sizeof(ec_SMcommtypet);
context->SMcommtype[Thread_n].n = 0;
wkc = ecx_SDOread(context, Slave, ECT_SDO_SMCOMMTYPE, 0x00, TRUE, &rdl,
&(context->SMcommtype[Thread_n]), EC_TIMEOUTRXM);
if ((wkc > 0) && (context->SMcommtype[Thread_n].n > 2))
{
nSM = context->SMcommtype[Thread_n].n;
if (nSM > EC_MAXSM)
{
nSM = EC_MAXSM;
ecx_packeterror(context, Slave, 0, 0, 10);
}
for (iSM = 2 ; iSM < nSM ; iSM++)
{
tSM = context->SMcommtype[Thread_n].SMtype[iSM];
if((iSM == 2) && (tSM == 2)) {
SMt_bug_add = 1; }
if(tSM)
{
tSM += SMt_bug_add; }
context->slavelist[Slave].SMtype[iSM] = tSM;
if (tSM == 0)
{
context->slavelist[Slave].SM[iSM].SMflags =
htoel( etohl(context->slavelist[Slave].SM[iSM].SMflags) & EC_SMENABLEMASK);
}
if ((tSM == 3) || (tSM == 4))
{
Tsize = ecx_readPDOassignCA(context, Slave, Thread_n,
ECT_SDO_PDOASSIGN + iSM );
if (Tsize)
{
context->slavelist[Slave].SM[iSM].SMlength = htoes((Tsize + 7) / 8);
if (tSM == 3)
{
*Osize += Tsize;
}
else
{
*Isize += Tsize;
}
}
}
}
}
if ((*Isize > 0) || (*Osize > 0))
{
retVal = 1;
}
return retVal;
}
int ecx_readODlist(ecx_contextt *context, uint16 Slave, ec_ODlistt *pODlist)
{
ec_SDOservicet *SDOp, *aSDOp;
ec_mbxbuft MbxIn, MbxOut;
int wkc;
uint16 x, n, i, sp, offset;
boolean stop;
uint8 cnt;
boolean First;
pODlist->Slave = Slave;
pODlist->Entries = 0;
ec_clearmbx(&MbxIn);
wkc = ecx_mbxreceive(context, Slave, &MbxIn, 0);
ec_clearmbx(&MbxOut);
aSDOp = (ec_SDOservicet*)&MbxIn;
SDOp = (ec_SDOservicet*)&MbxOut;
SDOp->MbxHeader.length = htoes(0x0008);
SDOp->MbxHeader.address = htoes(0x0000);
SDOp->MbxHeader.priority = 0x00;
cnt = ec_nextmbxcnt(context->slavelist[Slave].mbx_cnt);
context->slavelist[Slave].mbx_cnt = cnt;
SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4);
SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOINFO << 12));
SDOp->Opcode = ECT_GET_ODLIST_REQ;
SDOp->Reserved = 0;
SDOp->Fragments = 0;
SDOp->wdata[0] = htoes(0x01);
wkc = ecx_mbxsend(context, Slave, &MbxOut, EC_TIMEOUTTXM);
if (wkc > 0)
{
x = 0;
sp = 0;
First = TRUE;
offset = 1;
do
{
stop = TRUE;
ec_clearmbx(&MbxIn);
wkc = ecx_mbxreceive(context, Slave, &MbxIn, EC_TIMEOUTRXM);
if (wkc > 0)
{
if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
((aSDOp->Opcode & 0x7f) == ECT_GET_ODLIST_RES))
{
if (First)
{
n = (etohs(aSDOp->MbxHeader.length) - (6 + 2)) / 2;
}
else
{
n = (etohs(aSDOp->MbxHeader.length) - 6) / 2;
}
if ((sp + n) > EC_MAXODLIST)
{
n = EC_MAXODLIST + 1 - sp;
ecx_SDOinfoerror(context, Slave, 0, 0, 0xf000000);
stop = TRUE;
}
if ((pODlist->Entries + n) > EC_MAXODLIST)
{
n = EC_MAXODLIST - pODlist->Entries;
}
pODlist->Entries += n;
for (i = 0; i < n; i++)
{
pODlist->Index[sp + i] = etohs(aSDOp->wdata[i + offset]);
}
sp += n;
if (aSDOp->Fragments > 0)
{
stop = FALSE;
}
First = FALSE;
offset = 0;
}
else
{
if ((aSDOp->Opcode & 0x7f) == ECT_SDOINFO_ERROR)
{
ecx_SDOinfoerror(context, Slave, 0, 0, etohl(aSDOp->ldata[0]));
stop = TRUE;
}
else
{
ecx_packeterror(context, Slave, 0, 0, 1);
}
wkc = 0;
x += 20;
}
}
x++;
}
while ((x <= 128) && !stop);
}
return wkc;
}
int ecx_readODdescription(ecx_contextt *context, uint16 Item, ec_ODlistt *pODlist)
{
ec_SDOservicet *SDOp, *aSDOp;
int wkc;
uint16 n, Slave;
ec_mbxbuft MbxIn, MbxOut;
uint8 cnt;
Slave = pODlist->Slave;
pODlist->DataType[Item] = 0;
pODlist->ObjectCode[Item] = 0;
pODlist->MaxSub[Item] = 0;
pODlist->Name[Item][0] = 0;
ec_clearmbx(&MbxIn);
wkc = ecx_mbxreceive(context, Slave, &MbxIn, 0);
ec_clearmbx(&MbxOut);
aSDOp = (ec_SDOservicet*)&MbxIn;
SDOp = (ec_SDOservicet*)&MbxOut;
SDOp->MbxHeader.length = htoes(0x0008);
SDOp->MbxHeader.address = htoes(0x0000);
SDOp->MbxHeader.priority = 0x00;
cnt = ec_nextmbxcnt(context->slavelist[Slave].mbx_cnt);
context->slavelist[Slave].mbx_cnt = cnt;
SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4);
SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOINFO << 12));
SDOp->Opcode = ECT_GET_OD_REQ;
SDOp->Reserved = 0;
SDOp->Fragments = 0;
SDOp->wdata[0] = htoes(pODlist->Index[Item]);
wkc = ecx_mbxsend(context, Slave, &MbxOut, EC_TIMEOUTTXM);
if (wkc > 0)
{
ec_clearmbx(&MbxIn);
wkc = ecx_mbxreceive(context, Slave, &MbxIn, EC_TIMEOUTRXM);
if (wkc > 0)
{
if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
((aSDOp->Opcode & 0x7f) == ECT_GET_OD_RES))
{
n = (etohs(aSDOp->MbxHeader.length) - 12);
if (n > EC_MAXNAME)
{
n = EC_MAXNAME;
}
pODlist->DataType[Item] = etohs(aSDOp->wdata[1]);
pODlist->ObjectCode[Item] = aSDOp->bdata[5];
pODlist->MaxSub[Item] = aSDOp->bdata[4];
strncpy(pODlist->Name[Item] , (char *)&aSDOp->bdata[6], n);
pODlist->Name[Item][n] = 0x00;
}
else
{
if (((aSDOp->Opcode & 0x7f) == ECT_SDOINFO_ERROR))
{
ecx_SDOinfoerror(context, Slave,pODlist->Index[Item], 0, etohl(aSDOp->ldata[0]));
}
else
{
ecx_packeterror(context, Slave,pODlist->Index[Item], 0, 1);
}
wkc = 0;
}
}
}
return wkc;
}
int ecx_readOEsingle(ecx_contextt *context, uint16 Item, uint8 SubI, ec_ODlistt *pODlist, ec_OElistt *pOElist)
{
ec_SDOservicet *SDOp, *aSDOp;
int wkc;
uint16 Index, Slave;
int16 n;
ec_mbxbuft MbxIn, MbxOut;
uint8 cnt;
wkc = 0;
Slave = pODlist->Slave;
Index = pODlist->Index[Item];
ec_clearmbx(&MbxIn);
wkc = ecx_mbxreceive(context, Slave, &MbxIn, 0);
ec_clearmbx(&MbxOut);
aSDOp = (ec_SDOservicet*)&MbxIn;
SDOp = (ec_SDOservicet*)&MbxOut;
SDOp->MbxHeader.length = htoes(0x000a);
SDOp->MbxHeader.address = htoes(0x0000);
SDOp->MbxHeader.priority = 0x00;
cnt = ec_nextmbxcnt(context->slavelist[Slave].mbx_cnt);
context->slavelist[Slave].mbx_cnt = cnt;
SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4);
SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOINFO << 12));
SDOp->Opcode = ECT_GET_OE_REQ;
SDOp->Reserved = 0;
SDOp->Fragments = 0;
SDOp->wdata[0] = htoes(Index);
SDOp->bdata[2] = SubI;
SDOp->bdata[3] = 1 + 2 + 4;
wkc = ecx_mbxsend(context, Slave, &MbxOut, EC_TIMEOUTTXM);
if (wkc > 0)
{
ec_clearmbx(&MbxIn);
wkc = ecx_mbxreceive(context, Slave, &MbxIn, EC_TIMEOUTRXM);
if (wkc > 0)
{
if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
((aSDOp->Opcode & 0x7f) == ECT_GET_OE_RES))
{
pOElist->Entries++;
n = (etohs(aSDOp->MbxHeader.length) - 16);
if (n > EC_MAXNAME)
{
n = EC_MAXNAME;
}
if (n < 0 )
{
n = 0;
}
pOElist->ValueInfo[SubI] = aSDOp->bdata[3];
pOElist->DataType[SubI] = etohs(aSDOp->wdata[2]);
pOElist->BitLength[SubI] = etohs(aSDOp->wdata[3]);
pOElist->ObjAccess[SubI] = etohs(aSDOp->wdata[4]);
strncpy(pOElist->Name[SubI] , (char *)&aSDOp->wdata[5], n);
pOElist->Name[SubI][n] = 0x00;
}
else
{
if (((aSDOp->Opcode & 0x7f) == ECT_SDOINFO_ERROR))
{
ecx_SDOinfoerror(context, Slave, Index, SubI, etohl(aSDOp->ldata[0]));
}
else
{
ecx_packeterror(context, Slave, Index, SubI, 1);
}
wkc = 0;
}
}
}
return wkc;
}
int ecx_readOE(ecx_contextt *context, uint16 Item, ec_ODlistt *pODlist, ec_OElistt *pOElist)
{
uint16 SubCount;
int wkc;
uint8 SubI;
wkc = 0;
pOElist->Entries = 0;
SubI = pODlist->MaxSub[Item];
for (SubCount = 0; SubCount <= SubI; SubCount++)
{
wkc = ecx_readOEsingle(context, Item, (uint8)SubCount, pODlist, pOElist);
}
return wkc;
}
#ifdef EC_VER1
void ec_SDOerror(uint16 Slave, uint16 Index, uint8 SubIdx, int32 AbortCode)
{
ecx_SDOerror(&ecx_context, Slave, Index, SubIdx, AbortCode);
}
int ec_SDOread(uint16 slave, uint16 index, uint8 subindex,
boolean CA, int *psize, void *p, int timeout)
{
return ecx_SDOread(&ecx_context, slave, index, subindex, CA, psize, p, timeout);
}
int ec_SDOwrite(uint16 Slave, uint16 Index, uint8 SubIndex,
boolean CA, int psize, void *p, int Timeout)
{
return ecx_SDOwrite(&ecx_context, Slave, Index, SubIndex, CA, psize, p, Timeout);
}
int ec_RxPDO(uint16 Slave, uint16 RxPDOnumber, int psize, void *p)
{
return ecx_RxPDO(&ecx_context, Slave, RxPDOnumber, psize, p);
}
int ec_TxPDO(uint16 slave, uint16 TxPDOnumber , int *psize, void *p, int timeout)
{
return ecx_TxPDO(&ecx_context, slave, TxPDOnumber, psize, p, timeout);
}
int ec_readPDOassign(uint16 Slave, uint16 PDOassign)
{
return ecx_readPDOassign(&ecx_context, Slave, PDOassign);
}
int ec_readPDOassignCA(uint16 Slave, uint16 PDOassign, int Thread_n)
{
return ecx_readPDOassignCA(&ecx_context, Slave, Thread_n, PDOassign);
}
int ec_readPDOmap(uint16 Slave, int *Osize, int *Isize)
{
return ecx_readPDOmap(&ecx_context, Slave, Osize, Isize);
}
int ec_readPDOmapCA(uint16 Slave, int Thread_n, int *Osize, int *Isize)
{
return ecx_readPDOmapCA(&ecx_context, Slave, Thread_n, Osize, Isize);
}
int ec_readODlist(uint16 Slave, ec_ODlistt *pODlist)
{
return ecx_readODlist(&ecx_context, Slave, pODlist);
}
int ec_readODdescription(uint16 Item, ec_ODlistt *pODlist)
{
return ecx_readODdescription(&ecx_context, Item, pODlist);
}
int ec_readOEsingle(uint16 Item, uint8 SubI, ec_ODlistt *pODlist, ec_OElistt *pOElist)
{
return ecx_readOEsingle(&ecx_context, Item, SubI, pODlist, pOElist);
}
int ec_readOE(uint16 Item, ec_ODlistt *pODlist, ec_OElistt *pOElist)
{
return ecx_readOE(&ecx_context, Item, pODlist, pOElist);
}
#endif