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
This commit is contained in:
parent
3be652a0e0
commit
298397bcc3
@ -756,45 +756,96 @@ int ecx_FPRD_multi(ecx_contextt *context, int n, uint16 *configlst, ec_alstatust
|
|||||||
*/
|
*/
|
||||||
int ecx_readstate(ecx_contextt *context)
|
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];
|
ec_alstatust sl[MAX_FPRD_MULTI];
|
||||||
uint16 slca[MAX_FPRD_MULTI];
|
uint16 slca[MAX_FPRD_MULTI];
|
||||||
|
boolean noerrorflag, allslavessamestate;
|
||||||
|
|
||||||
lowest = 0xff;
|
/* Try to establish the state of all slaves sending only one broadcast datargam.
|
||||||
context->slavelist[0].ALstatuscode = 0;
|
* This way a number of datagrams equal to the number of slaves will be sent only if needed.*/
|
||||||
fslave = 1;
|
rval = 0;
|
||||||
do
|
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);
|
noerrorflag = TRUE;
|
||||||
if ((lslave - fslave) >= MAX_FPRD_MULTI)
|
context->slavelist[0].ALstatuscode = 0;
|
||||||
{
|
}
|
||||||
lslave = fslave + MAX_FPRD_MULTI - 1;
|
else
|
||||||
}
|
{
|
||||||
for (slave = fslave; slave <= lslave; slave++)
|
noerrorflag = FALSE;
|
||||||
{
|
}
|
||||||
const ec_alstatust zero = {0, 0, 0};
|
|
||||||
|
|
||||||
configadr = context->slavelist[slave].configadr;
|
switch (bitwisestate)
|
||||||
slca[slave - fslave] = configadr;
|
{
|
||||||
sl[slave - fslave] = zero;
|
case EC_STATE_INIT:
|
||||||
}
|
case EC_STATE_PRE_OP:
|
||||||
ecx_FPRD_multi(context, (lslave - fslave) + 1, &(slca[0]), &(sl[0]), EC_TIMEOUTRET3);
|
case EC_STATE_BOOT:
|
||||||
for (slave = fslave; slave <= lslave; slave++)
|
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;
|
context->slavelist[slave].ALstatuscode = 0x0000;
|
||||||
rval = etohs(sl[slave - fslave].alstatus);
|
context->slavelist[slave].state = bitwisestate;
|
||||||
context->slavelist[slave].ALstatuscode = etohs(sl[slave - fslave].alstatuscode);
|
}
|
||||||
if ((rval & 0xf) < lowest)
|
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;
|
for (slave = fslave; slave <= lslave; slave++)
|
||||||
context->slavelist[0].ALstatuscode |= context->slavelist[slave].ALstatuscode;
|
{
|
||||||
}
|
const ec_alstatust zero = { 0, 0, 0 };
|
||||||
fslave = lslave + 1;
|
|
||||||
} while(lslave < *(context->slavecount));
|
|
||||||
context->slavelist[0].state = lowest;
|
|
||||||
|
|
||||||
|
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;
|
return lowest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -851,37 +902,71 @@ uint16 ecx_statecheck(ecx_contextt *context, uint16 slave, uint16 reqstate, int
|
|||||||
{
|
{
|
||||||
uint16 bitwisestate;
|
uint16 bitwisestate;
|
||||||
uint16 slaveindex;
|
uint16 slaveindex;
|
||||||
|
boolean allslavessamestate;
|
||||||
|
boolean noerrorflag;
|
||||||
|
|
||||||
rval = 0;
|
rval = 0;
|
||||||
ecx_BRD(context->port, 0, ECT_REG_ALSTAT, sizeof(rval), &rval , EC_TIMEOUTRET);
|
ecx_BRD(context->port, 0, ECT_REG_ALSTAT, sizeof(rval), &rval , EC_TIMEOUTRET);
|
||||||
rval = etohs(rval);
|
rval = etohs(rval);
|
||||||
bitwisestate = (rval & 0x0f);
|
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 */
|
noerrorflag = TRUE;
|
||||||
for(slaveindex = 1; slaveindex <= *(context->slavecount); slaveindex++)
|
context->slavelist[0].ALstatuscode = 0;
|
||||||
{
|
}
|
||||||
context->slavelist[slaveindex].ALstatuscode = 0x0000;
|
else
|
||||||
}
|
{
|
||||||
|
noerrorflag = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(bitwisestate)
|
switch (bitwisestate)
|
||||||
{
|
{
|
||||||
case EC_STATE_INIT:
|
case EC_STATE_INIT:
|
||||||
case EC_STATE_PRE_OP:
|
case EC_STATE_PRE_OP:
|
||||||
case EC_STATE_BOOT:
|
case EC_STATE_BOOT:
|
||||||
case EC_STATE_SAFE_OP:
|
case EC_STATE_SAFE_OP:
|
||||||
case EC_STATE_OPERATIONAL:
|
case EC_STATE_OPERATIONAL:
|
||||||
/* All the slaves have reached the same state so we can update the state of every slave */
|
allslavessamestate = TRUE;
|
||||||
for(slaveindex = 1; slaveindex <= *(context->slavecount); slaveindex++)
|
|
||||||
{
|
|
||||||
context->slavelist[slaveindex].state = bitwisestate;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
allslavessamestate = FALSE;
|
||||||
break;
|
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
|
else
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user