diff --git a/soem/ethercatcoe.c b/soem/ethercatcoe.c index 4bc2ed9..86667b5 100644 --- a/soem/ethercatcoe.c +++ b/soem/ethercatcoe.c @@ -856,13 +856,11 @@ int ecx_readPDOmap(ecx_contextt *context, uint16 Slave, int *Osize, int *Isize) /* positive result from slave ? */ if ((wkc > 0) && (nSM > 2)) { - /* make nSM equal to number of defined SM */ - nSM--; /* limit to maximum number of SM defined, if true the slave can't be configured */ if (nSM > EC_MAXSM) nSM = EC_MAXSM; /* iterate for every SM type defined */ - for (iSM = 2 ; iSM <= nSM ; iSM++) + for (iSM = 2 ; iSM < nSM ; iSM++) { rdl = sizeof(tSM); tSM = 0; /* read SyncManager Communication Type */ @@ -958,8 +956,7 @@ int ecx_readPDOmapCA(ecx_contextt *context, uint16 Slave, int *Osize, int *Isize /* positive result from slave ? */ if ((wkc > 0) && (context->SMcommtype->n > 2)) { - /* make nSM equal to number of defined SM */ - nSM = context->SMcommtype->n - 1; + nSM = context->SMcommtype->n; /* limit to maximum number of SM defined, if true the slave can't be configured */ if (nSM > EC_MAXSM) { @@ -967,7 +964,7 @@ int ecx_readPDOmapCA(ecx_contextt *context, uint16 Slave, int *Osize, int *Isize ecx_packeterror(context, Slave, 0, 0, 10); /* #SM larger than EC_MAXSM */ } /* iterate for every SM type defined */ - for (iSM = 2 ; iSM <= nSM ; iSM++) + for (iSM = 2 ; iSM < nSM ; iSM++) { tSM = context->SMcommtype->SMtype[iSM]; @@ -1235,7 +1232,8 @@ int ecx_readODdescription(ecx_contextt *context, uint16 Item, ec_ODlistt *pODlis int ecx_readOEsingle(ecx_contextt *context, uint16 Item, uint8 SubI, ec_ODlistt *pODlist, ec_OElistt *pOElist) { ec_SDOservicet *SDOp, *aSDOp; - uint16 wkc, Index, Slave; + int wkc; + uint16 Index, Slave; int16 n; ec_mbxbuft MbxIn, MbxOut; uint8 cnt; diff --git a/soem/ethercatconfig.c b/soem/ethercatconfig.c index 12cf717..62f78a8 100644 --- a/soem/ethercatconfig.c +++ b/soem/ethercatconfig.c @@ -176,7 +176,17 @@ int ecx_detect_slaves(ecx_contextt *context) wkc = ecx_BRD(context->port, 0x0000, ECT_REG_TYPE, sizeof(w), &w, EC_TIMEOUTSAFE); /* detect number of slaves */ if (wkc > 0) { - *(context->slavecount) = wkc; + /* this is strictly "less than" since the master is "slave 0" */ + if (wkc < EC_MAXSLAVE) + { + *(context->slavecount) = wkc; + } + else + { + EC_PRINT("Error: too many slaves on network: num_slaves=%d, EC_MAXSLAVE=%d\n", + wkc, EC_MAXSLAVE); + return -2; + } } return wkc; } @@ -1273,7 +1283,8 @@ int ecx_config_map_group(ecx_contextt *context, void *pIOmap, uint8 group) int ecx_recover_slave(ecx_contextt *context, uint16 slave, int timeout) { int rval; - uint16 ADPh, configadr, readadr, wkc; + int wkc; + uint16 ADPh, configadr, readadr; rval = 0; configadr = context->slavelist[slave].configadr; diff --git a/soem/ethercatdc.c b/soem/ethercatdc.c index 98ccbf4..f3883d0 100644 --- a/soem/ethercatdc.c +++ b/soem/ethercatdc.c @@ -292,8 +292,10 @@ boolean ecx_configdc(ecx_contextt *context) context->slavelist[0].hasdc = FALSE; context->grouplist[0].hasdc = FALSE; ht = 0; - mastertime = osal_current_time(); + ecx_BWR(context->port, 0, ECT_REG_DCTIME0, sizeof(ht), &ht, EC_TIMEOUTRET); /* latch DCrecvTimeA of all slaves */ + mastertime = osal_current_time(); + mastertime.sec -= 946684800UL; /* EtherCAT uses 2000-01-01 as epoch start instead of 1970-01-01 */ mastertime64 = (((uint64)mastertime.sec * 1000000) + (uint64)mastertime.usec) * 1000; for (i = 1; i <= *(context->slavecount); i++) { diff --git a/soem/ethercatmain.c b/soem/ethercatmain.c index e8314dd..bdb3b73 100644 --- a/soem/ethercatmain.c +++ b/soem/ethercatmain.c @@ -784,9 +784,9 @@ int ecx_readstate(ecx_contextt *context) configadr = context->slavelist[slave].configadr; rval = etohs(sl[slave - fslave].alstatus); context->slavelist[slave].ALstatuscode = etohs(sl[slave - fslave].alstatuscode); - if (rval < lowest) + if ((rval & 0xf) < lowest) { - lowest = rval; + lowest = (rval & 0xf); } context->slavelist[slave].state = rval; context->slavelist[0].ALstatuscode |= context->slavelist[slave].ALstatuscode; @@ -800,26 +800,29 @@ int ecx_readstate(ecx_contextt *context) /** Write slave state, if slave = 0 then write to all slaves. * The function does not check if the actual state is changed. - * @param[in] context = context struct + * @param[in] context = context struct * @param[in] slave = Slave number, 0 = master - * @return 0 + * @return Workcounter or EC_NOFRAME */ int ecx_writestate(ecx_contextt *context, uint16 slave) { + int ret; uint16 configadr, slstate; if (slave == 0) { slstate = htoes(context->slavelist[slave].state); - ecx_BWR(context->port, 0, ECT_REG_ALCTL, sizeof(slstate), &slstate, EC_TIMEOUTRET3); /* write slave status */ + ret = ecx_BWR(context->port, 0, ECT_REG_ALCTL, sizeof(slstate), + &slstate, EC_TIMEOUTRET3); } else { configadr = context->slavelist[slave].configadr; - ecx_FPWRw(context->port, configadr, ECT_REG_ALCTL, htoes(context->slavelist[slave].state), EC_TIMEOUTRET3); /* write slave status */ + ret = ecx_FPWRw(context->port, configadr, ECT_REG_ALCTL, + htoes(context->slavelist[slave].state), EC_TIMEOUTRET3); } - return 0; + return ret; } /** Check actual slave state. diff --git a/soem/ethercatprint.h b/soem/ethercatprint.h index 3e22113..688012f 100644 --- a/soem/ethercatprint.h +++ b/soem/ethercatprint.h @@ -52,7 +52,7 @@ extern "C" { #endif -char* ec_sdoerror2string( uint16 sdoerrorcode); +char* ec_sdoerror2string( uint32 sdoerrorcode); char* ec_ALstatuscode2string( uint16 ALstatuscode); char* ec_soeerror2string( uint16 errorcode); char* ecx_elist2string(ecx_contextt *context);