From 28927aab87d70dc428dd8a6121bc6de3af568c3a Mon Sep 17 00:00:00 2001 From: Luca Date: Tue, 18 Oct 2016 00:35:54 +0200 Subject: [PATCH 1/6] minor_improvement/ ecx_statecheck() improved ecx_statecheck() when called with the first argument set to 0 automatically updates the state of all the slaves in the slavelist structure when possible, --- soem/ethercatmain.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/soem/ethercatmain.c b/soem/ethercatmain.c index f270dba..5d81c36 100644 --- a/soem/ethercatmain.c +++ b/soem/ethercatmain.c @@ -849,9 +849,39 @@ uint16 ecx_statecheck(ecx_contextt *context, uint16 slave, uint16 reqstate, int { if (slave < 1) { + uint16 bitWiseState; + uint16 slaveIndex; + rval = 0; ecx_BRD(context->port, 0, ECT_REG_ALSTAT, sizeof(rval), &rval , EC_TIMEOUTRET); rval = etohs(rval); + bitWiseState = (rval & 0x0f); + + if((rval & 0xf0) == 0) + { + /* No slave has toggled the error flag so the alstatuscode (even if different from 0) should be ignored */ + for(slaveIndex = 0; slaveIndex < *(context->slavecount); slaveIndex++) + { + ec_slave[slaveIndex].ALstatuscode = 0x0000; + } + } + + switch(bitWiseState) + { + case EC_STATE_INIT: + case EC_STATE_PRE_OP: + case EC_STATE_BOOT: + case EC_STATE_SAFE_OP: + case EC_STATE_OPERATIONAL: + /* All the slaves have reached the same state so we can update the state of every slave */ + for(slaveIndex = 0; slaveIndex < *(context->slavecount); slaveIndex++) + { + ec_slave[slaveIndex].state = bitWiseState; + } + break; + default: + break; + } } else { From 74b76da66851e7b0354647e1d058dee78c537804 Mon Sep 17 00:00:00 2001 From: Luca Date: Tue, 18 Oct 2016 17:54:58 +0200 Subject: [PATCH 2/6] fixed for pr --- soem/ethercatmain.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/soem/ethercatmain.c b/soem/ethercatmain.c index 5d81c36..8f1d5d2 100644 --- a/soem/ethercatmain.c +++ b/soem/ethercatmain.c @@ -849,24 +849,24 @@ uint16 ecx_statecheck(ecx_contextt *context, uint16 slave, uint16 reqstate, int { if (slave < 1) { - uint16 bitWiseState; - uint16 slaveIndex; + uint16 bitwisestate; + uint16 slaveindex; rval = 0; ecx_BRD(context->port, 0, ECT_REG_ALSTAT, sizeof(rval), &rval , EC_TIMEOUTRET); rval = etohs(rval); - bitWiseState = (rval & 0x0f); + bitwisestate = (rval & 0x0f); if((rval & 0xf0) == 0) { /* No slave has toggled the error flag so the alstatuscode (even if different from 0) should be ignored */ - for(slaveIndex = 0; slaveIndex < *(context->slavecount); slaveIndex++) + for(slaveindex = 0; slaveindex < *(context->slavecount); slaveindex++) { - ec_slave[slaveIndex].ALstatuscode = 0x0000; + context->slavelist[slaveindex].ALstatuscode = 0x0000; } } - switch(bitWiseState) + switch(bitwisestate) { case EC_STATE_INIT: case EC_STATE_PRE_OP: @@ -874,9 +874,9 @@ uint16 ecx_statecheck(ecx_contextt *context, uint16 slave, uint16 reqstate, int case EC_STATE_SAFE_OP: case EC_STATE_OPERATIONAL: /* All the slaves have reached the same state so we can update the state of every slave */ - for(slaveIndex = 0; slaveIndex < *(context->slavecount); slaveIndex++) + for(slaveindex = 0; slaveindex < *(context->slavecount); slaveindex++) { - ec_slave[slaveIndex].state = bitWiseState; + context->slavelist[slaveindex].state = bitwisestate; } break; default: From 47d28458612fb3d64901d5c9fa99343542028cc8 Mon Sep 17 00:00:00 2001 From: Luca Date: Tue, 18 Oct 2016 18:00:31 +0200 Subject: [PATCH 3/6] tabs removes --- soem/ethercatmain.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/soem/ethercatmain.c b/soem/ethercatmain.c index 8f1d5d2..465e905 100644 --- a/soem/ethercatmain.c +++ b/soem/ethercatmain.c @@ -849,9 +849,9 @@ uint16 ecx_statecheck(ecx_contextt *context, uint16 slave, uint16 reqstate, int { if (slave < 1) { - uint16 bitwisestate; - uint16 slaveindex; - + uint16 bitwisestate; + uint16 slaveindex; + rval = 0; ecx_BRD(context->port, 0, ECT_REG_ALSTAT, sizeof(rval), &rval , EC_TIMEOUTRET); rval = etohs(rval); From 3be652a0e01c71c0accae7e0c01602c36029aa57 Mon Sep 17 00:00:00 2001 From: Luca Date: Thu, 20 Oct 2016 15:21:29 +0200 Subject: [PATCH 4/6] Bug fix --- soem/ethercatmain.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/soem/ethercatmain.c b/soem/ethercatmain.c index 465e905..9379236 100644 --- a/soem/ethercatmain.c +++ b/soem/ethercatmain.c @@ -860,7 +860,7 @@ uint16 ecx_statecheck(ecx_contextt *context, uint16 slave, uint16 reqstate, int if((rval & 0xf0) == 0) { /* No slave has toggled the error flag so the alstatuscode (even if different from 0) should be ignored */ - for(slaveindex = 0; slaveindex < *(context->slavecount); slaveindex++) + for(slaveindex = 1; slaveindex <= *(context->slavecount); slaveindex++) { context->slavelist[slaveindex].ALstatuscode = 0x0000; } @@ -874,7 +874,7 @@ uint16 ecx_statecheck(ecx_contextt *context, uint16 slave, uint16 reqstate, int case EC_STATE_SAFE_OP: case EC_STATE_OPERATIONAL: /* All the slaves have reached the same state so we can update the state of every slave */ - for(slaveindex = 0; slaveindex < *(context->slavecount); slaveindex++) + for(slaveindex = 1; slaveindex <= *(context->slavecount); slaveindex++) { context->slavelist[slaveindex].state = bitwisestate; } From 298397bcc3cead55eaf65ea278e9ca27be964bd2 Mon Sep 17 00:00:00 2001 From: MagnaboscoAndrea Date: Sun, 23 Oct 2016 13:18:34 +0200 Subject: [PATCH 5/6] improve both ecx_statecheck and ecx_readstate - in ecx_statecheck only one iteration is done through the slave list if needed - in ecx_readstate only one datagram is used if possible --- soem/ethercatmain.c | 171 +++++++++++++++++++++++++++++++++----------- 1 file changed, 128 insertions(+), 43 deletions(-) diff --git a/soem/ethercatmain.c b/soem/ethercatmain.c index 9379236..1970f3d 100644 --- a/soem/ethercatmain.c +++ b/soem/ethercatmain.c @@ -756,45 +756,96 @@ int ecx_FPRD_multi(ecx_contextt *context, int n, uint16 *configlst, ec_alstatust */ int ecx_readstate(ecx_contextt *context) { - uint16 slave, fslave, lslave, configadr, lowest, rval; + uint16 slave, fslave, lslave, configadr, lowest, rval, bitwisestate; ec_alstatust sl[MAX_FPRD_MULTI]; uint16 slca[MAX_FPRD_MULTI]; + boolean noerrorflag, allslavessamestate; - lowest = 0xff; - context->slavelist[0].ALstatuscode = 0; - fslave = 1; - do + /* Try to establish the state of all slaves sending only one broadcast datargam. + * This way a number of datagrams equal to the number of slaves will be sent only if needed.*/ + rval = 0; + ecx_BRD(context->port, 0, ECT_REG_ALSTAT, sizeof(rval), &rval, EC_TIMEOUTRET); + rval = etohs(rval); + bitwisestate = (rval & 0x0f); + + if ((rval & EC_STATE_ERROR) == 0) { - lslave = *(context->slavecount); - if ((lslave - fslave) >= MAX_FPRD_MULTI) - { - lslave = fslave + MAX_FPRD_MULTI - 1; - } - for (slave = fslave; slave <= lslave; slave++) - { - const ec_alstatust zero = {0, 0, 0}; + noerrorflag = TRUE; + context->slavelist[0].ALstatuscode = 0; + } + else + { + noerrorflag = FALSE; + } - configadr = context->slavelist[slave].configadr; - slca[slave - fslave] = configadr; - sl[slave - fslave] = zero; - } - ecx_FPRD_multi(context, (lslave - fslave) + 1, &(slca[0]), &(sl[0]), EC_TIMEOUTRET3); - for (slave = fslave; slave <= lslave; slave++) + switch (bitwisestate) + { + case EC_STATE_INIT: + case EC_STATE_PRE_OP: + case EC_STATE_BOOT: + case EC_STATE_SAFE_OP: + case EC_STATE_OPERATIONAL: + allslavessamestate = TRUE; + context->slavelist[0].state = bitwisestate; + break; + default: + allslavessamestate = FALSE; + break; + } + + if (noerrorflag && allslavessamestate) + { + /* No slave has toggled the error flag so the alstatuscode + * (even if different from 0) should be ignored and + * the slaves have reached the same state so the internal state + * can be updated without sending any datagram. */ + for (slave = 1; slave <= *(context->slavecount); slave++) { - configadr = context->slavelist[slave].configadr; - rval = etohs(sl[slave - fslave].alstatus); - context->slavelist[slave].ALstatuscode = etohs(sl[slave - fslave].alstatuscode); - if ((rval & 0xf) < lowest) + context->slavelist[slave].ALstatuscode = 0x0000; + context->slavelist[slave].state = bitwisestate; + } + lowest = bitwisestate; + } + else + { + /* Not all slaves have the same state or at least one is in error so one datagram per slave + * is needed. */ + context->slavelist[0].ALstatuscode = 0; + lowest = 0xff; + fslave = 1; + do + { + lslave = *(context->slavecount); + if ((lslave - fslave) >= MAX_FPRD_MULTI) { - lowest = (rval & 0xf); + lslave = fslave + MAX_FPRD_MULTI - 1; } - context->slavelist[slave].state = rval; - context->slavelist[0].ALstatuscode |= context->slavelist[slave].ALstatuscode; - } - fslave = lslave + 1; - } while(lslave < *(context->slavecount)); - context->slavelist[0].state = lowest; + for (slave = fslave; slave <= lslave; slave++) + { + const ec_alstatust zero = { 0, 0, 0 }; + configadr = context->slavelist[slave].configadr; + slca[slave - fslave] = configadr; + sl[slave - fslave] = zero; + } + ecx_FPRD_multi(context, (lslave - fslave) + 1, &(slca[0]), &(sl[0]), EC_TIMEOUTRET3); + for (slave = fslave; slave <= lslave; slave++) + { + configadr = context->slavelist[slave].configadr; + rval = etohs(sl[slave - fslave].alstatus); + context->slavelist[slave].ALstatuscode = etohs(sl[slave - fslave].alstatuscode); + if ((rval & 0xf) < lowest) + { + lowest = (rval & 0xf); + } + context->slavelist[slave].state = rval; + context->slavelist[0].ALstatuscode |= context->slavelist[slave].ALstatuscode; + } + fslave = lslave + 1; + } while (lslave < *(context->slavecount)); + context->slavelist[0].state = lowest; + } + return lowest; } @@ -851,37 +902,71 @@ uint16 ecx_statecheck(ecx_contextt *context, uint16 slave, uint16 reqstate, int { uint16 bitwisestate; uint16 slaveindex; + boolean allslavessamestate; + boolean noerrorflag; rval = 0; ecx_BRD(context->port, 0, ECT_REG_ALSTAT, sizeof(rval), &rval , EC_TIMEOUTRET); rval = etohs(rval); bitwisestate = (rval & 0x0f); - if((rval & 0xf0) == 0) + if ((rval & EC_STATE_ERROR) == 0) { - /* No slave has toggled the error flag so the alstatuscode (even if different from 0) should be ignored */ - for(slaveindex = 1; slaveindex <= *(context->slavecount); slaveindex++) - { - context->slavelist[slaveindex].ALstatuscode = 0x0000; - } + noerrorflag = TRUE; + context->slavelist[0].ALstatuscode = 0; + } + else + { + noerrorflag = FALSE; } - switch(bitwisestate) + switch (bitwisestate) { case EC_STATE_INIT: case EC_STATE_PRE_OP: case EC_STATE_BOOT: case EC_STATE_SAFE_OP: case EC_STATE_OPERATIONAL: - /* All the slaves have reached the same state so we can update the state of every slave */ - for(slaveindex = 1; slaveindex <= *(context->slavecount); slaveindex++) - { - context->slavelist[slaveindex].state = bitwisestate; - } + allslavessamestate = TRUE; break; default: + allslavessamestate = FALSE; break; - } + } + + if (noerrorflag || allslavessamestate) + { + if (noerrorflag && allslavessamestate) + { + /* No slave has toggled the error flag so the alstatuscode + * (even if different from 0) should be ignored and + * the slaves have reached the same state so the internal state + * can be updated without sending any datagram. */ + for (slaveindex = 1; slaveindex <= *(context->slavecount); slaveindex++) + { + context->slavelist[slaveindex].ALstatuscode = 0x0000; + context->slavelist[slaveindex].state = bitwisestate; + } + } + else if (noerrorflag) + { + /* No slave has toggled the error flag so the alstatuscode + * (even if different from 0) should be ignored. */ + for (slaveindex = 1; slaveindex <= *(context->slavecount); slaveindex++) + { + context->slavelist[slaveindex].ALstatuscode = 0x0000; + } + } + else + { + /* All the slaves have reached the same state therefore + * the internal state can be updated without sending any datagram. */ + for (slaveindex = 1; slaveindex <= *(context->slavecount); slaveindex++) + { + context->slavelist[slaveindex].state = bitwisestate; + } + } + } } else { From c97e92e4ec750546b89b5ee12b39074c5e89490b Mon Sep 17 00:00:00 2001 From: MagnaboscoL Date: Tue, 25 Oct 2016 20:25:10 +0200 Subject: [PATCH 6/6] revert ecx_statecheck() to original --- soem/ethercatmain.c | 67 ++------------------------------------------- 1 file changed, 2 insertions(+), 65 deletions(-) diff --git a/soem/ethercatmain.c b/soem/ethercatmain.c index 1970f3d..78e43dc 100644 --- a/soem/ethercatmain.c +++ b/soem/ethercatmain.c @@ -878,8 +878,9 @@ int ecx_writestate(ecx_contextt *context, uint16 slave) /** Check actual slave state. * This is a blocking function. + * To refresh the state of all slaves ecx_readstate()should be called * @param[in] context = context struct - * @param[in] slave = Slave number, 0 = all slaves + * @param[in] slave = Slave number, 0 = all slaves (only the "slavelist[0].state" is refreshed) * @param[in] reqstate = Requested state * @param[in] timeout = Timout value in us * @return Requested state, or found state after timeout. @@ -900,73 +901,9 @@ uint16 ecx_statecheck(ecx_contextt *context, uint16 slave, uint16 reqstate, int { if (slave < 1) { - uint16 bitwisestate; - uint16 slaveindex; - boolean allslavessamestate; - boolean noerrorflag; - rval = 0; ecx_BRD(context->port, 0, ECT_REG_ALSTAT, sizeof(rval), &rval , EC_TIMEOUTRET); rval = etohs(rval); - bitwisestate = (rval & 0x0f); - - if ((rval & EC_STATE_ERROR) == 0) - { - noerrorflag = TRUE; - context->slavelist[0].ALstatuscode = 0; - } - else - { - noerrorflag = FALSE; - } - - switch (bitwisestate) - { - case EC_STATE_INIT: - case EC_STATE_PRE_OP: - case EC_STATE_BOOT: - case EC_STATE_SAFE_OP: - case EC_STATE_OPERATIONAL: - allslavessamestate = TRUE; - break; - default: - allslavessamestate = FALSE; - break; - } - - if (noerrorflag || allslavessamestate) - { - if (noerrorflag && allslavessamestate) - { - /* No slave has toggled the error flag so the alstatuscode - * (even if different from 0) should be ignored and - * the slaves have reached the same state so the internal state - * can be updated without sending any datagram. */ - for (slaveindex = 1; slaveindex <= *(context->slavecount); slaveindex++) - { - context->slavelist[slaveindex].ALstatuscode = 0x0000; - context->slavelist[slaveindex].state = bitwisestate; - } - } - else if (noerrorflag) - { - /* No slave has toggled the error flag so the alstatuscode - * (even if different from 0) should be ignored. */ - for (slaveindex = 1; slaveindex <= *(context->slavecount); slaveindex++) - { - context->slavelist[slaveindex].ALstatuscode = 0x0000; - } - } - else - { - /* All the slaves have reached the same state therefore - * the internal state can be updated without sending any datagram. */ - for (slaveindex = 1; slaveindex <= *(context->slavecount); slaveindex++) - { - context->slavelist[slaveindex].state = bitwisestate; - } - } - } } else {