Merge pull request #156 from nakarlsson/master
Add functions to configure and send an overlapping IOmap
This commit is contained in:
commit
0adfb0025b
@ -820,7 +820,309 @@ static int ecx_get_threadcount(void)
|
|||||||
return thrc;
|
return thrc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Map all PDOs in one group of slaves to IOmap.
|
static void ecx_config_find_mappings(ecx_contextt *context, uint8 group)
|
||||||
|
{
|
||||||
|
int thrn, thrc;
|
||||||
|
uint16 slave;
|
||||||
|
|
||||||
|
for (thrn = 0; thrn < EC_MAX_MAPT; thrn++)
|
||||||
|
{
|
||||||
|
ecx_mapt[thrn].running = 0;
|
||||||
|
}
|
||||||
|
/* find CoE and SoE mapping of slaves in multiple threads */
|
||||||
|
for (slave = 1; slave <= *(context->slavecount); slave++)
|
||||||
|
{
|
||||||
|
if (!group || (group == context->slavelist[slave].group))
|
||||||
|
{
|
||||||
|
if (EC_MAX_MAPT <= 1)
|
||||||
|
{
|
||||||
|
/* serialised version */
|
||||||
|
ecx_map_coe_soe(context, slave, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* multi-threaded version */
|
||||||
|
while ((thrn = ecx_find_mapt()) < 0)
|
||||||
|
{
|
||||||
|
osal_usleep(1000);
|
||||||
|
}
|
||||||
|
ecx_mapt[thrn].context = context;
|
||||||
|
ecx_mapt[thrn].slave = slave;
|
||||||
|
ecx_mapt[thrn].thread_n = thrn;
|
||||||
|
ecx_mapt[thrn].running = 1;
|
||||||
|
osal_thread_create(&(ecx_threadh[thrn]), 128000,
|
||||||
|
&ecx_mapper_thread, &(ecx_mapt[thrn]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* wait for all threads to finish */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
thrc = ecx_get_threadcount();
|
||||||
|
if (thrc)
|
||||||
|
{
|
||||||
|
osal_usleep(1000);
|
||||||
|
}
|
||||||
|
} while (thrc);
|
||||||
|
/* find SII mapping of slave and program SM */
|
||||||
|
for (slave = 1; slave <= *(context->slavecount); slave++)
|
||||||
|
{
|
||||||
|
if (!group || (group == context->slavelist[slave].group))
|
||||||
|
{
|
||||||
|
ecx_map_sii(context, slave);
|
||||||
|
ecx_map_sm(context, slave);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ecx_config_create_input_mappings(ecx_contextt *context, void *pIOmap,
|
||||||
|
uint8 group, int16 slave, uint32 * LogAddr, uint8 * BitPos)
|
||||||
|
{
|
||||||
|
int BitCount = 0;
|
||||||
|
int ByteCount = 0;
|
||||||
|
int FMMUsize = 0;
|
||||||
|
int FMMUdone = 0;
|
||||||
|
uint8 SMc = 0;
|
||||||
|
uint16 EndAddr;
|
||||||
|
uint16 SMlength;
|
||||||
|
uint16 configadr;
|
||||||
|
uint8 FMMUc;
|
||||||
|
|
||||||
|
EC_PRINT(" =Slave %d, INPUT MAPPING\n", slave);
|
||||||
|
|
||||||
|
configadr = context->slavelist[slave].configadr;
|
||||||
|
FMMUc = context->slavelist[slave].FMMUunused;
|
||||||
|
if (context->slavelist[slave].Obits) /* find free FMMU */
|
||||||
|
{
|
||||||
|
while (context->slavelist[slave].FMMU[FMMUc].LogStart)
|
||||||
|
{
|
||||||
|
FMMUc++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* search for SM that contribute to the input mapping */
|
||||||
|
while ((SMc < (EC_MAXSM - 1)) && (FMMUdone < ((context->slavelist[slave].Ibits + 7) / 8)))
|
||||||
|
{
|
||||||
|
EC_PRINT(" FMMU %d\n", FMMUc);
|
||||||
|
while ((SMc < (EC_MAXSM - 1)) && (context->slavelist[slave].SMtype[SMc] != 4))
|
||||||
|
{
|
||||||
|
SMc++;
|
||||||
|
}
|
||||||
|
EC_PRINT(" SM%d\n", SMc);
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].PhysStart =
|
||||||
|
context->slavelist[slave].SM[SMc].StartAddr;
|
||||||
|
SMlength = etohs(context->slavelist[slave].SM[SMc].SMlength);
|
||||||
|
ByteCount += SMlength;
|
||||||
|
BitCount += SMlength * 8;
|
||||||
|
EndAddr = etohs(context->slavelist[slave].SM[SMc].StartAddr) + SMlength;
|
||||||
|
while ((BitCount < context->slavelist[slave].Ibits) && (SMc < (EC_MAXSM - 1))) /* more SM for input */
|
||||||
|
{
|
||||||
|
SMc++;
|
||||||
|
while ((SMc < (EC_MAXSM - 1)) && (context->slavelist[slave].SMtype[SMc] != 4))
|
||||||
|
{
|
||||||
|
SMc++;
|
||||||
|
}
|
||||||
|
/* if addresses from more SM connect use one FMMU otherwise break up in mutiple FMMU */
|
||||||
|
if (etohs(context->slavelist[slave].SM[SMc].StartAddr) > EndAddr)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
EC_PRINT(" SM%d\n", SMc);
|
||||||
|
SMlength = etohs(context->slavelist[slave].SM[SMc].SMlength);
|
||||||
|
ByteCount += SMlength;
|
||||||
|
BitCount += SMlength * 8;
|
||||||
|
EndAddr = etohs(context->slavelist[slave].SM[SMc].StartAddr) + SMlength;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bit oriented slave */
|
||||||
|
if (!context->slavelist[slave].Ibytes)
|
||||||
|
{
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].LogStart = htoel(*LogAddr);
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].LogStartbit = *BitPos;
|
||||||
|
*BitPos += context->slavelist[slave].Ibits - 1;
|
||||||
|
if (*BitPos > 7)
|
||||||
|
{
|
||||||
|
*LogAddr += 1;
|
||||||
|
*BitPos -= 8;
|
||||||
|
}
|
||||||
|
FMMUsize = *LogAddr - etohl(context->slavelist[slave].FMMU[FMMUc].LogStart) + 1;
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].LogLength = htoes(FMMUsize);
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].LogEndbit = *BitPos;
|
||||||
|
*BitPos += 1;
|
||||||
|
if (*BitPos > 7)
|
||||||
|
{
|
||||||
|
*LogAddr += 1;
|
||||||
|
*BitPos -= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* byte oriented slave */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (*BitPos)
|
||||||
|
{
|
||||||
|
*LogAddr += 1;
|
||||||
|
*BitPos = 0;
|
||||||
|
}
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].LogStart = htoel(*LogAddr);
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].LogStartbit = *BitPos;
|
||||||
|
*BitPos = 7;
|
||||||
|
FMMUsize = ByteCount;
|
||||||
|
if ((FMMUsize + FMMUdone)> (int)context->slavelist[slave].Ibytes)
|
||||||
|
{
|
||||||
|
FMMUsize = context->slavelist[slave].Ibytes - FMMUdone;
|
||||||
|
}
|
||||||
|
*LogAddr += FMMUsize;
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].LogLength = htoes(FMMUsize);
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].LogEndbit = *BitPos;
|
||||||
|
*BitPos = 0;
|
||||||
|
}
|
||||||
|
FMMUdone += FMMUsize;
|
||||||
|
if (context->slavelist[slave].FMMU[FMMUc].LogLength)
|
||||||
|
{
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].PhysStartBit = 0;
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].FMMUtype = 1;
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].FMMUactive = 1;
|
||||||
|
/* program FMMU for input */
|
||||||
|
ecx_FPWR(context->port, configadr, ECT_REG_FMMU0 + (sizeof(ec_fmmut) * FMMUc),
|
||||||
|
sizeof(ec_fmmut), &(context->slavelist[slave].FMMU[FMMUc]), EC_TIMEOUTRET3);
|
||||||
|
/* add one for an input FMMU */
|
||||||
|
context->grouplist[group].inputsWKC++;
|
||||||
|
}
|
||||||
|
if (!context->slavelist[slave].inputs)
|
||||||
|
{
|
||||||
|
context->slavelist[slave].inputs =
|
||||||
|
(uint8 *)(pIOmap)+etohl(context->slavelist[slave].FMMU[FMMUc].LogStart);
|
||||||
|
context->slavelist[slave].Istartbit =
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].LogStartbit;
|
||||||
|
EC_PRINT(" Inputs %p startbit %d\n",
|
||||||
|
context->slavelist[slave].inputs,
|
||||||
|
context->slavelist[slave].Istartbit);
|
||||||
|
}
|
||||||
|
FMMUc++;
|
||||||
|
}
|
||||||
|
context->slavelist[slave].FMMUunused = FMMUc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ecx_config_create_output_mappings(ecx_contextt *context, void *pIOmap,
|
||||||
|
uint8 group, int16 slave, uint32 * LogAddr, uint8 * BitPos)
|
||||||
|
{
|
||||||
|
int BitCount = 0;
|
||||||
|
int ByteCount = 0;
|
||||||
|
int FMMUsize = 0;
|
||||||
|
int FMMUdone = 0;
|
||||||
|
uint8 SMc = 0;
|
||||||
|
uint16 EndAddr;
|
||||||
|
uint16 SMlength;
|
||||||
|
uint16 configadr;
|
||||||
|
uint8 FMMUc;
|
||||||
|
|
||||||
|
EC_PRINT(" OUTPUT MAPPING\n");
|
||||||
|
|
||||||
|
FMMUc = context->slavelist[slave].FMMUunused;
|
||||||
|
configadr = context->slavelist[slave].configadr;
|
||||||
|
|
||||||
|
/* search for SM that contribute to the output mapping */
|
||||||
|
while ((SMc < (EC_MAXSM - 1)) && (FMMUdone < ((context->slavelist[slave].Obits + 7) / 8)))
|
||||||
|
{
|
||||||
|
EC_PRINT(" FMMU %d\n", FMMUc);
|
||||||
|
while ((SMc < (EC_MAXSM - 1)) && (context->slavelist[slave].SMtype[SMc] != 3))
|
||||||
|
{
|
||||||
|
SMc++;
|
||||||
|
}
|
||||||
|
EC_PRINT(" SM%d\n", SMc);
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].PhysStart =
|
||||||
|
context->slavelist[slave].SM[SMc].StartAddr;
|
||||||
|
SMlength = etohs(context->slavelist[slave].SM[SMc].SMlength);
|
||||||
|
ByteCount += SMlength;
|
||||||
|
BitCount += SMlength * 8;
|
||||||
|
EndAddr = etohs(context->slavelist[slave].SM[SMc].StartAddr) + SMlength;
|
||||||
|
while ((BitCount < context->slavelist[slave].Obits) && (SMc < (EC_MAXSM - 1))) /* more SM for output */
|
||||||
|
{
|
||||||
|
SMc++;
|
||||||
|
while ((SMc < (EC_MAXSM - 1)) && (context->slavelist[slave].SMtype[SMc] != 3))
|
||||||
|
{
|
||||||
|
SMc++;
|
||||||
|
}
|
||||||
|
/* if addresses from more SM connect use one FMMU otherwise break up in mutiple FMMU */
|
||||||
|
if (etohs(context->slavelist[slave].SM[SMc].StartAddr) > EndAddr)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
EC_PRINT(" SM%d\n", SMc);
|
||||||
|
SMlength = etohs(context->slavelist[slave].SM[SMc].SMlength);
|
||||||
|
ByteCount += SMlength;
|
||||||
|
BitCount += SMlength * 8;
|
||||||
|
EndAddr = etohs(context->slavelist[slave].SM[SMc].StartAddr) + SMlength;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bit oriented slave */
|
||||||
|
if (!context->slavelist[slave].Obytes)
|
||||||
|
{
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].LogStart = htoel(*LogAddr);
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].LogStartbit = *BitPos;
|
||||||
|
*BitPos += context->slavelist[slave].Obits - 1;
|
||||||
|
if (*BitPos > 7)
|
||||||
|
{
|
||||||
|
*LogAddr += 1;
|
||||||
|
*BitPos -= 8;
|
||||||
|
}
|
||||||
|
FMMUsize = *LogAddr - etohl(context->slavelist[slave].FMMU[FMMUc].LogStart) + 1;
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].LogLength = htoes(FMMUsize);
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].LogEndbit = *BitPos;
|
||||||
|
*BitPos += 1;
|
||||||
|
if (*BitPos > 7)
|
||||||
|
{
|
||||||
|
*LogAddr += 1;
|
||||||
|
*BitPos -= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* byte oriented slave */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (*BitPos)
|
||||||
|
{
|
||||||
|
*LogAddr += 1;
|
||||||
|
*BitPos = 0;
|
||||||
|
}
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].LogStart = htoel(*LogAddr);
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].LogStartbit = *BitPos;
|
||||||
|
*BitPos = 7;
|
||||||
|
FMMUsize = ByteCount;
|
||||||
|
if ((FMMUsize + FMMUdone)> (int)context->slavelist[slave].Obytes)
|
||||||
|
{
|
||||||
|
FMMUsize = context->slavelist[slave].Obytes - FMMUdone;
|
||||||
|
}
|
||||||
|
*LogAddr += FMMUsize;
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].LogLength = htoes(FMMUsize);
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].LogEndbit = *BitPos;
|
||||||
|
*BitPos = 0;
|
||||||
|
}
|
||||||
|
FMMUdone += FMMUsize;
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].PhysStartBit = 0;
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].FMMUtype = 2;
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].FMMUactive = 1;
|
||||||
|
/* program FMMU for output */
|
||||||
|
ecx_FPWR(context->port, configadr, ECT_REG_FMMU0 + (sizeof(ec_fmmut) * FMMUc),
|
||||||
|
sizeof(ec_fmmut), &(context->slavelist[slave].FMMU[FMMUc]), EC_TIMEOUTRET3);
|
||||||
|
context->grouplist[group].outputsWKC++;
|
||||||
|
if (!context->slavelist[slave].outputs)
|
||||||
|
{
|
||||||
|
context->slavelist[slave].outputs =
|
||||||
|
(uint8 *)(pIOmap)+etohl(context->slavelist[slave].FMMU[FMMUc].LogStart);
|
||||||
|
context->slavelist[slave].Ostartbit =
|
||||||
|
context->slavelist[slave].FMMU[FMMUc].LogStartbit;
|
||||||
|
EC_PRINT(" slave %d Outputs %p startbit %d\n",
|
||||||
|
slave,
|
||||||
|
context->slavelist[slave].outputs,
|
||||||
|
context->slavelist[slave].Ostartbit);
|
||||||
|
}
|
||||||
|
FMMUc++;
|
||||||
|
}
|
||||||
|
context->slavelist[slave].FMMUunused = FMMUc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Map all PDOs in one group of slaves to IOmap with Outputs/Inputs
|
||||||
|
* in sequential order (legacy SOEM way).
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* @param[in] context = context struct
|
* @param[in] context = context struct
|
||||||
* @param[out] pIOmap = pointer to IOmap
|
* @param[out] pIOmap = pointer to IOmap
|
||||||
@ -830,16 +1132,12 @@ static int ecx_get_threadcount(void)
|
|||||||
int ecx_config_map_group(ecx_contextt *context, void *pIOmap, uint8 group)
|
int ecx_config_map_group(ecx_contextt *context, void *pIOmap, uint8 group)
|
||||||
{
|
{
|
||||||
uint16 slave, configadr;
|
uint16 slave, configadr;
|
||||||
int BitCount, ByteCount, FMMUsize, FMMUdone;
|
|
||||||
uint16 SMlength, EndAddr;
|
|
||||||
uint8 BitPos;
|
uint8 BitPos;
|
||||||
uint8 SMc, FMMUc;
|
|
||||||
uint32 LogAddr = 0;
|
uint32 LogAddr = 0;
|
||||||
uint32 oLogAddr = 0;
|
uint32 oLogAddr = 0;
|
||||||
uint32 diff;
|
uint32 diff;
|
||||||
uint16 currentsegment = 0;
|
uint16 currentsegment = 0;
|
||||||
uint32 segmentsize = 0;
|
uint32 segmentsize = 0;
|
||||||
int thrn, thrc;
|
|
||||||
|
|
||||||
if ((*(context->slavecount) > 0) && (group < context->maxgroup))
|
if ((*(context->slavecount) > 0) && (group < context->maxgroup))
|
||||||
{
|
{
|
||||||
@ -851,165 +1149,20 @@ int ecx_config_map_group(ecx_contextt *context, void *pIOmap, uint8 group)
|
|||||||
context->grouplist[group].outputsWKC = 0;
|
context->grouplist[group].outputsWKC = 0;
|
||||||
context->grouplist[group].inputsWKC = 0;
|
context->grouplist[group].inputsWKC = 0;
|
||||||
|
|
||||||
for(thrn = 0 ; thrn < EC_MAX_MAPT ; thrn++)
|
/* Find mappings and program syncmanagers */
|
||||||
{
|
ecx_config_find_mappings(context, group);
|
||||||
ecx_mapt[thrn].running = 0;
|
|
||||||
}
|
|
||||||
/* find CoE and SoE mapping of slaves in multiple threads */
|
|
||||||
for (slave = 1; slave <= *(context->slavecount); slave++)
|
|
||||||
{
|
|
||||||
if (!group || (group == context->slavelist[slave].group))
|
|
||||||
{
|
|
||||||
if(EC_MAX_MAPT <= 1)
|
|
||||||
{
|
|
||||||
/* serialised version */
|
|
||||||
ecx_map_coe_soe(context, slave, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* multi-threaded version */
|
|
||||||
while((thrn = ecx_find_mapt()) < 0)
|
|
||||||
{
|
|
||||||
osal_usleep(1000);
|
|
||||||
}
|
|
||||||
ecx_mapt[thrn].context = context;
|
|
||||||
ecx_mapt[thrn].slave = slave;
|
|
||||||
ecx_mapt[thrn].thread_n = thrn;
|
|
||||||
ecx_mapt[thrn].running = 1;
|
|
||||||
osal_thread_create(&(ecx_threadh[thrn]), 128000,
|
|
||||||
&ecx_mapper_thread, &(ecx_mapt[thrn]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* wait for all threads to finish */
|
|
||||||
do
|
|
||||||
{
|
|
||||||
thrc = ecx_get_threadcount();
|
|
||||||
if(thrc)
|
|
||||||
{
|
|
||||||
osal_usleep(1000);
|
|
||||||
}
|
|
||||||
} while(thrc);
|
|
||||||
/* find SII mapping of slave and program SM */
|
|
||||||
for (slave = 1; slave <= *(context->slavecount); slave++)
|
|
||||||
{
|
|
||||||
if (!group || (group == context->slavelist[slave].group))
|
|
||||||
{
|
|
||||||
ecx_map_sii(context, slave);
|
|
||||||
ecx_map_sm(context, slave);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* do input mapping of slave and program FMMUs */
|
/* do output mapping of slave and program FMMUs */
|
||||||
for (slave = 1; slave <= *(context->slavecount); slave++)
|
for (slave = 1; slave <= *(context->slavecount); slave++)
|
||||||
{
|
{
|
||||||
configadr = context->slavelist[slave].configadr;
|
configadr = context->slavelist[slave].configadr;
|
||||||
|
|
||||||
if (!group || (group == context->slavelist[slave].group))
|
if (!group || (group == context->slavelist[slave].group))
|
||||||
{
|
{
|
||||||
FMMUc = context->slavelist[slave].FMMUunused;
|
|
||||||
SMc = 0;
|
|
||||||
BitCount = 0;
|
|
||||||
ByteCount = 0;
|
|
||||||
EndAddr = 0;
|
|
||||||
FMMUsize = 0;
|
|
||||||
FMMUdone = 0;
|
|
||||||
/* create output mapping */
|
/* create output mapping */
|
||||||
if (context->slavelist[slave].Obits)
|
if (context->slavelist[slave].Obits)
|
||||||
{
|
{
|
||||||
EC_PRINT(" OUTPUT MAPPING\n");
|
ecx_config_create_output_mappings (context, pIOmap, group, slave, &LogAddr, &BitPos);
|
||||||
/* search for SM that contribute to the output mapping */
|
|
||||||
while ( (SMc < (EC_MAXSM - 1)) && (FMMUdone < ((context->slavelist[slave].Obits + 7) / 8)))
|
|
||||||
{
|
|
||||||
EC_PRINT(" FMMU %d\n", FMMUc);
|
|
||||||
while ( (SMc < (EC_MAXSM - 1)) && (context->slavelist[slave].SMtype[SMc] != 3)) SMc++;
|
|
||||||
EC_PRINT(" SM%d\n", SMc);
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].PhysStart =
|
|
||||||
context->slavelist[slave].SM[SMc].StartAddr;
|
|
||||||
SMlength = etohs(context->slavelist[slave].SM[SMc].SMlength);
|
|
||||||
ByteCount += SMlength;
|
|
||||||
BitCount += SMlength * 8;
|
|
||||||
EndAddr = etohs(context->slavelist[slave].SM[SMc].StartAddr) + SMlength;
|
|
||||||
while ( (BitCount < context->slavelist[slave].Obits) && (SMc < (EC_MAXSM - 1)) ) /* more SM for output */
|
|
||||||
{
|
|
||||||
SMc++;
|
|
||||||
while ( (SMc < (EC_MAXSM - 1)) && (context->slavelist[slave].SMtype[SMc] != 3)) SMc++;
|
|
||||||
/* if addresses from more SM connect use one FMMU otherwise break up in mutiple FMMU */
|
|
||||||
if ( etohs(context->slavelist[slave].SM[SMc].StartAddr) > EndAddr )
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
EC_PRINT(" SM%d\n", SMc);
|
|
||||||
SMlength = etohs(context->slavelist[slave].SM[SMc].SMlength);
|
|
||||||
ByteCount += SMlength;
|
|
||||||
BitCount += SMlength * 8;
|
|
||||||
EndAddr = etohs(context->slavelist[slave].SM[SMc].StartAddr) + SMlength;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* bit oriented slave */
|
|
||||||
if (!context->slavelist[slave].Obytes)
|
|
||||||
{
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].LogStart = htoel(LogAddr);
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].LogStartbit = BitPos;
|
|
||||||
BitPos += context->slavelist[slave].Obits - 1;
|
|
||||||
if (BitPos > 7)
|
|
||||||
{
|
|
||||||
LogAddr++;
|
|
||||||
BitPos -= 8;
|
|
||||||
}
|
|
||||||
FMMUsize = LogAddr - etohl(context->slavelist[slave].FMMU[FMMUc].LogStart) + 1;
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].LogLength = htoes(FMMUsize);
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].LogEndbit = BitPos;
|
|
||||||
BitPos ++;
|
|
||||||
if (BitPos > 7)
|
|
||||||
{
|
|
||||||
LogAddr++;
|
|
||||||
BitPos -= 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* byte oriented slave */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (BitPos)
|
|
||||||
{
|
|
||||||
LogAddr++;
|
|
||||||
BitPos = 0;
|
|
||||||
}
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].LogStart = htoel(LogAddr);
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].LogStartbit = BitPos;
|
|
||||||
BitPos = 7;
|
|
||||||
FMMUsize = ByteCount;
|
|
||||||
if ((FMMUsize + FMMUdone)> (int)context->slavelist[slave].Obytes)
|
|
||||||
{
|
|
||||||
FMMUsize = context->slavelist[slave].Obytes - FMMUdone;
|
|
||||||
}
|
|
||||||
LogAddr += FMMUsize;
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].LogLength = htoes(FMMUsize);
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].LogEndbit = BitPos;
|
|
||||||
BitPos = 0;
|
|
||||||
}
|
|
||||||
FMMUdone += FMMUsize;
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].PhysStartBit = 0;
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].FMMUtype = 2;
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].FMMUactive = 1;
|
|
||||||
/* program FMMU for output */
|
|
||||||
ecx_FPWR(context->port, configadr, ECT_REG_FMMU0 + (sizeof(ec_fmmut) * FMMUc),
|
|
||||||
sizeof(ec_fmmut), &(context->slavelist[slave].FMMU[FMMUc]), EC_TIMEOUTRET3);
|
|
||||||
context->grouplist[group].outputsWKC++;
|
|
||||||
if (!context->slavelist[slave].outputs)
|
|
||||||
{
|
|
||||||
context->slavelist[slave].outputs =
|
|
||||||
(uint8 *)(pIOmap) + etohl(context->slavelist[slave].FMMU[FMMUc].LogStart);
|
|
||||||
context->slavelist[slave].Ostartbit =
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].LogStartbit;
|
|
||||||
EC_PRINT(" slave %d Outputs %p startbit %d\n",
|
|
||||||
slave,
|
|
||||||
context->slavelist[slave].outputs,
|
|
||||||
context->slavelist[slave].Ostartbit);
|
|
||||||
}
|
|
||||||
FMMUc++;
|
|
||||||
}
|
|
||||||
context->slavelist[slave].FMMUunused = FMMUc;
|
|
||||||
diff = LogAddr - oLogAddr;
|
diff = LogAddr - oLogAddr;
|
||||||
oLogAddr = LogAddr;
|
oLogAddr = LogAddr;
|
||||||
if ((segmentsize + diff) > (EC_MAXLRWDATA - EC_FIRSTDCDATAGRAM))
|
if ((segmentsize + diff) > (EC_MAXLRWDATA - EC_FIRSTDCDATAGRAM))
|
||||||
@ -1064,116 +1217,11 @@ int ecx_config_map_group(ecx_contextt *context, void *pIOmap, uint8 group)
|
|||||||
configadr = context->slavelist[slave].configadr;
|
configadr = context->slavelist[slave].configadr;
|
||||||
if (!group || (group == context->slavelist[slave].group))
|
if (!group || (group == context->slavelist[slave].group))
|
||||||
{
|
{
|
||||||
FMMUc = context->slavelist[slave].FMMUunused;
|
|
||||||
if (context->slavelist[slave].Obits) /* find free FMMU */
|
|
||||||
{
|
|
||||||
while ( context->slavelist[slave].FMMU[FMMUc].LogStart ) FMMUc++;
|
|
||||||
}
|
|
||||||
SMc = 0;
|
|
||||||
BitCount = 0;
|
|
||||||
ByteCount = 0;
|
|
||||||
EndAddr = 0;
|
|
||||||
FMMUsize = 0;
|
|
||||||
FMMUdone = 0;
|
|
||||||
/* create input mapping */
|
/* create input mapping */
|
||||||
if (context->slavelist[slave].Ibits)
|
if (context->slavelist[slave].Ibits)
|
||||||
{
|
{
|
||||||
EC_PRINT(" =Slave %d, INPUT MAPPING\n", slave);
|
|
||||||
/* search for SM that contribute to the input mapping */
|
ecx_config_create_input_mappings(context, pIOmap, group, slave, &LogAddr, &BitPos);
|
||||||
while ( (SMc < (EC_MAXSM - 1)) && (FMMUdone < ((context->slavelist[slave].Ibits + 7) / 8)))
|
|
||||||
{
|
|
||||||
EC_PRINT(" FMMU %d\n", FMMUc);
|
|
||||||
while ( (SMc < (EC_MAXSM - 1)) && (context->slavelist[slave].SMtype[SMc] != 4)) SMc++;
|
|
||||||
EC_PRINT(" SM%d\n", SMc);
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].PhysStart =
|
|
||||||
context->slavelist[slave].SM[SMc].StartAddr;
|
|
||||||
SMlength = etohs(context->slavelist[slave].SM[SMc].SMlength);
|
|
||||||
ByteCount += SMlength;
|
|
||||||
BitCount += SMlength * 8;
|
|
||||||
EndAddr = etohs(context->slavelist[slave].SM[SMc].StartAddr) + SMlength;
|
|
||||||
while ( (BitCount < context->slavelist[slave].Ibits) && (SMc < (EC_MAXSM - 1)) ) /* more SM for input */
|
|
||||||
{
|
|
||||||
SMc++;
|
|
||||||
while ( (SMc < (EC_MAXSM - 1)) && (context->slavelist[slave].SMtype[SMc] != 4)) SMc++;
|
|
||||||
/* if addresses from more SM connect use one FMMU otherwise break up in mutiple FMMU */
|
|
||||||
if ( etohs(context->slavelist[slave].SM[SMc].StartAddr) > EndAddr )
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
EC_PRINT(" SM%d\n", SMc);
|
|
||||||
SMlength = etohs(context->slavelist[slave].SM[SMc].SMlength);
|
|
||||||
ByteCount += SMlength;
|
|
||||||
BitCount += SMlength * 8;
|
|
||||||
EndAddr = etohs(context->slavelist[slave].SM[SMc].StartAddr) + SMlength;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* bit oriented slave */
|
|
||||||
if (!context->slavelist[slave].Ibytes)
|
|
||||||
{
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].LogStart = htoel(LogAddr);
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].LogStartbit = BitPos;
|
|
||||||
BitPos += context->slavelist[slave].Ibits - 1;
|
|
||||||
if (BitPos > 7)
|
|
||||||
{
|
|
||||||
LogAddr++;
|
|
||||||
BitPos -= 8;
|
|
||||||
}
|
|
||||||
FMMUsize = LogAddr - etohl(context->slavelist[slave].FMMU[FMMUc].LogStart) + 1;
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].LogLength = htoes(FMMUsize);
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].LogEndbit = BitPos;
|
|
||||||
BitPos ++;
|
|
||||||
if (BitPos > 7)
|
|
||||||
{
|
|
||||||
LogAddr++;
|
|
||||||
BitPos -= 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* byte oriented slave */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (BitPos)
|
|
||||||
{
|
|
||||||
LogAddr++;
|
|
||||||
BitPos = 0;
|
|
||||||
}
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].LogStart = htoel(LogAddr);
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].LogStartbit = BitPos;
|
|
||||||
BitPos = 7;
|
|
||||||
FMMUsize = ByteCount;
|
|
||||||
if ((FMMUsize + FMMUdone)> (int)context->slavelist[slave].Ibytes)
|
|
||||||
{
|
|
||||||
FMMUsize = context->slavelist[slave].Ibytes - FMMUdone;
|
|
||||||
}
|
|
||||||
LogAddr += FMMUsize;
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].LogLength = htoes(FMMUsize);
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].LogEndbit = BitPos;
|
|
||||||
BitPos = 0;
|
|
||||||
}
|
|
||||||
FMMUdone += FMMUsize;
|
|
||||||
if (context->slavelist[slave].FMMU[FMMUc].LogLength)
|
|
||||||
{
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].PhysStartBit = 0;
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].FMMUtype = 1;
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].FMMUactive = 1;
|
|
||||||
/* program FMMU for input */
|
|
||||||
ecx_FPWR(context->port, configadr, ECT_REG_FMMU0 + (sizeof(ec_fmmut) * FMMUc),
|
|
||||||
sizeof(ec_fmmut), &(context->slavelist[slave].FMMU[FMMUc]), EC_TIMEOUTRET3);
|
|
||||||
/* add one for an input FMMU */
|
|
||||||
context->grouplist[group].inputsWKC++;
|
|
||||||
}
|
|
||||||
if (!context->slavelist[slave].inputs)
|
|
||||||
{
|
|
||||||
context->slavelist[slave].inputs =
|
|
||||||
(uint8 *)(pIOmap) + etohl(context->slavelist[slave].FMMU[FMMUc].LogStart);
|
|
||||||
context->slavelist[slave].Istartbit =
|
|
||||||
context->slavelist[slave].FMMU[FMMUc].LogStartbit;
|
|
||||||
EC_PRINT(" Inputs %p startbit %d\n",
|
|
||||||
context->slavelist[slave].inputs,
|
|
||||||
context->slavelist[slave].Istartbit);
|
|
||||||
}
|
|
||||||
FMMUc++;
|
|
||||||
}
|
|
||||||
context->slavelist[slave].FMMUunused = FMMUc;
|
|
||||||
diff = LogAddr - oLogAddr;
|
diff = LogAddr - oLogAddr;
|
||||||
oLogAddr = LogAddr;
|
oLogAddr = LogAddr;
|
||||||
if ((segmentsize + diff) > (EC_MAXLRWDATA - EC_FIRSTDCDATAGRAM))
|
if ((segmentsize + diff) > (EC_MAXLRWDATA - EC_FIRSTDCDATAGRAM))
|
||||||
@ -1238,6 +1286,136 @@ int ecx_config_map_group(ecx_contextt *context, void *pIOmap, uint8 group)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Map all PDOs in one group of slaves to IOmap with Outputs/Inputs
|
||||||
|
* overlapping. NOTE: Must use this for TI ESC when using LRW.
|
||||||
|
*
|
||||||
|
* @param[in] context = context struct
|
||||||
|
* @param[out] pIOmap = pointer to IOmap
|
||||||
|
* @param[in] group = group to map, 0 = all groups
|
||||||
|
* @return IOmap size
|
||||||
|
*/
|
||||||
|
int ecx_config_overlap_map_group(ecx_contextt *context, void *pIOmap, uint8 group)
|
||||||
|
{
|
||||||
|
uint16 slave, configadr;
|
||||||
|
uint8 BitPos;
|
||||||
|
uint32 mLogAddr = 0;
|
||||||
|
uint32 siLogAddr = 0;
|
||||||
|
uint32 soLogAddr = 0;
|
||||||
|
uint32 tempLogAddr;
|
||||||
|
uint32 diff;
|
||||||
|
uint16 currentsegment = 0;
|
||||||
|
uint32 segmentsize = 0;
|
||||||
|
|
||||||
|
if ((*(context->slavecount) > 0) && (group < context->maxgroup))
|
||||||
|
{
|
||||||
|
EC_PRINT("ec_config_map_group IOmap:%p group:%d\n", pIOmap, group);
|
||||||
|
mLogAddr = context->grouplist[group].logstartaddr;
|
||||||
|
siLogAddr = mLogAddr;
|
||||||
|
soLogAddr = mLogAddr;
|
||||||
|
BitPos = 0;
|
||||||
|
context->grouplist[group].nsegments = 0;
|
||||||
|
context->grouplist[group].outputsWKC = 0;
|
||||||
|
context->grouplist[group].inputsWKC = 0;
|
||||||
|
|
||||||
|
/* Find mappings and program syncmanagers */
|
||||||
|
ecx_config_find_mappings(context, group);
|
||||||
|
|
||||||
|
/* do IO mapping of slave and program FMMUs */
|
||||||
|
for (slave = 1; slave <= *(context->slavecount); slave++)
|
||||||
|
{
|
||||||
|
configadr = context->slavelist[slave].configadr;
|
||||||
|
siLogAddr = soLogAddr = mLogAddr;
|
||||||
|
|
||||||
|
if (!group || (group == context->slavelist[slave].group))
|
||||||
|
{
|
||||||
|
/* create output mapping */
|
||||||
|
if (context->slavelist[slave].Obits)
|
||||||
|
{
|
||||||
|
|
||||||
|
ecx_config_create_output_mappings(context, pIOmap, group,
|
||||||
|
slave, &soLogAddr, &BitPos);
|
||||||
|
if (BitPos)
|
||||||
|
{
|
||||||
|
soLogAddr++;
|
||||||
|
BitPos = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create input mapping */
|
||||||
|
if (context->slavelist[slave].Ibits)
|
||||||
|
{
|
||||||
|
ecx_config_create_input_mappings(context, pIOmap, group,
|
||||||
|
slave, &siLogAddr, &BitPos);
|
||||||
|
if (BitPos)
|
||||||
|
{
|
||||||
|
siLogAddr++;
|
||||||
|
BitPos = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tempLogAddr = (siLogAddr > soLogAddr) ? siLogAddr : soLogAddr;
|
||||||
|
diff = tempLogAddr - mLogAddr;
|
||||||
|
mLogAddr = tempLogAddr;
|
||||||
|
|
||||||
|
if ((segmentsize + diff) > (EC_MAXLRWDATA - EC_FIRSTDCDATAGRAM))
|
||||||
|
{
|
||||||
|
context->grouplist[group].IOsegment[currentsegment] = segmentsize;
|
||||||
|
if (currentsegment < (EC_MAXIOSEGMENTS - 1))
|
||||||
|
{
|
||||||
|
currentsegment++;
|
||||||
|
segmentsize = diff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
segmentsize += diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
ecx_eeprom2pdi(context, slave); /* set Eeprom control to PDI */
|
||||||
|
ecx_FPWRw(context->port, configadr, ECT_REG_ALCTL, htoes(EC_STATE_SAFE_OP), EC_TIMEOUTRET3); /* set safeop status */
|
||||||
|
|
||||||
|
if (context->slavelist[slave].blockLRW)
|
||||||
|
{
|
||||||
|
context->grouplist[group].blockLRW++;
|
||||||
|
}
|
||||||
|
context->grouplist[group].Ebuscurrent += context->slavelist[slave].Ebuscurrent;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
context->grouplist[group].IOsegment[currentsegment] = segmentsize;
|
||||||
|
context->grouplist[group].nsegments = currentsegment + 1;
|
||||||
|
context->grouplist[group].Isegment = 0;
|
||||||
|
context->grouplist[group].Ioffset = 0;
|
||||||
|
|
||||||
|
context->grouplist[group].Obytes = soLogAddr;
|
||||||
|
context->grouplist[group].Ibytes = siLogAddr;
|
||||||
|
context->grouplist[group].outputs = pIOmap;
|
||||||
|
context->grouplist[group].inputs = (uint8 *)pIOmap + context->grouplist[group].Obytes;
|
||||||
|
|
||||||
|
/* Move calculated inputs with OBytes offset*/
|
||||||
|
for (slave = 1; slave <= *(context->slavecount); slave++)
|
||||||
|
{
|
||||||
|
context->slavelist[slave].inputs += context->grouplist[group].Obytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!group)
|
||||||
|
{
|
||||||
|
context->slavelist[0].outputs = pIOmap;
|
||||||
|
context->slavelist[0].Obytes = soLogAddr; /* store output bytes in master record */
|
||||||
|
context->slavelist[0].inputs = (uint8 *)pIOmap + context->slavelist[0].Obytes;
|
||||||
|
context->slavelist[0].Ibytes = siLogAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
EC_PRINT("IOmapSize %d\n", context->grouplist[group].Obytes + context->grouplist[group].Ibytes);
|
||||||
|
|
||||||
|
return (context->grouplist[group].Obytes + context->grouplist[group].Ibytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Recover slave.
|
/** Recover slave.
|
||||||
*
|
*
|
||||||
* @param[in] context = context struct
|
* @param[in] context = context struct
|
||||||
@ -1368,7 +1546,8 @@ int ec_config_init(uint8 usetable)
|
|||||||
return ecx_config_init(&ecx_context, usetable);
|
return ecx_config_init(&ecx_context, usetable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Map all PDOs in one group of slaves to IOmap.
|
/** Map all PDOs in one group of slaves to IOmap with Outputs/Inputs
|
||||||
|
* in sequential order (legacy SOEM way).
|
||||||
*
|
*
|
||||||
* @param[out] pIOmap = pointer to IOmap
|
* @param[out] pIOmap = pointer to IOmap
|
||||||
* @param[in] group = group to map, 0 = all groups
|
* @param[in] group = group to map, 0 = all groups
|
||||||
@ -1380,7 +1559,21 @@ int ec_config_map_group(void *pIOmap, uint8 group)
|
|||||||
return ecx_config_map_group(&ecx_context, pIOmap, group);
|
return ecx_config_map_group(&ecx_context, pIOmap, group);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Map all PDOs from slaves to IOmap.
|
/** Map all PDOs in one group of slaves to IOmap with Outputs/Inputs
|
||||||
|
* overlapping. NOTE: Must use this for TI ESC when using LRW.
|
||||||
|
*
|
||||||
|
* @param[out] pIOmap = pointer to IOmap
|
||||||
|
* @param[in] group = group to map, 0 = all groups
|
||||||
|
* @return IOmap size
|
||||||
|
* @see ecx_config_overlap_map_group
|
||||||
|
*/
|
||||||
|
int ec_config_overlap_map_group(void *pIOmap, uint8 group)
|
||||||
|
{
|
||||||
|
return ecx_config_overlap_map_group(&ecx_context, pIOmap, group);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Map all PDOs from slaves to IOmap with Outputs/Inputs
|
||||||
|
* in sequential order (legacy SOEM way).
|
||||||
*
|
*
|
||||||
* @param[out] pIOmap = pointer to IOmap
|
* @param[out] pIOmap = pointer to IOmap
|
||||||
* @return IOmap size
|
* @return IOmap size
|
||||||
@ -1390,6 +1583,17 @@ int ec_config_map(void *pIOmap)
|
|||||||
return ec_config_map_group(pIOmap, 0);
|
return ec_config_map_group(pIOmap, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Map all PDOs from slaves to IOmap with Outputs/Inputs
|
||||||
|
* overlapping. NOTE: Must use this for TI ESC when using LRW.
|
||||||
|
*
|
||||||
|
* @param[out] pIOmap = pointer to IOmap
|
||||||
|
* @return IOmap size
|
||||||
|
*/
|
||||||
|
int ec_config_overlap_map(void *pIOmap)
|
||||||
|
{
|
||||||
|
return ec_config_overlap_map_group(pIOmap, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/** Enumerate / map and init all slaves.
|
/** Enumerate / map and init all slaves.
|
||||||
*
|
*
|
||||||
* @param[in] usetable = TRUE when using configtable to init slaves, FALSE otherwise
|
* @param[in] usetable = TRUE when using configtable to init slaves, FALSE otherwise
|
||||||
@ -1407,6 +1611,23 @@ int ec_config(uint8 usetable, void *pIOmap)
|
|||||||
return wkc;
|
return wkc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Enumerate / map and init all slaves.
|
||||||
|
*
|
||||||
|
* @param[in] usetable = TRUE when using configtable to init slaves, FALSE otherwise
|
||||||
|
* @param[out] pIOmap = pointer to IOmap
|
||||||
|
* @return Workcounter of slave discover datagram = number of slaves found
|
||||||
|
*/
|
||||||
|
int ec_config_overlap(uint8 usetable, void *pIOmap)
|
||||||
|
{
|
||||||
|
int wkc;
|
||||||
|
wkc = ec_config_init(usetable);
|
||||||
|
if (wkc)
|
||||||
|
{
|
||||||
|
ec_config_overlap_map(pIOmap);
|
||||||
|
}
|
||||||
|
return wkc;
|
||||||
|
}
|
||||||
|
|
||||||
/** Recover slave.
|
/** Recover slave.
|
||||||
*
|
*
|
||||||
* @param[in] slave = slave to recover
|
* @param[in] slave = slave to recover
|
||||||
|
@ -22,14 +22,18 @@ extern "C"
|
|||||||
#ifdef EC_VER1
|
#ifdef EC_VER1
|
||||||
int ec_config_init(uint8 usetable);
|
int ec_config_init(uint8 usetable);
|
||||||
int ec_config_map(void *pIOmap);
|
int ec_config_map(void *pIOmap);
|
||||||
|
int ec_config_overlap_map(void *pIOmap);
|
||||||
int ec_config_map_group(void *pIOmap, uint8 group);
|
int ec_config_map_group(void *pIOmap, uint8 group);
|
||||||
|
int ec_config_overlap_map_group(void *pIOmap, uint8 group);
|
||||||
int ec_config(uint8 usetable, void *pIOmap);
|
int ec_config(uint8 usetable, void *pIOmap);
|
||||||
|
int ec_config_overlap(uint8 usetable, void *pIOmap);
|
||||||
int ec_recover_slave(uint16 slave, int timeout);
|
int ec_recover_slave(uint16 slave, int timeout);
|
||||||
int ec_reconfig_slave(uint16 slave, int timeout);
|
int ec_reconfig_slave(uint16 slave, int timeout);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int ecx_config_init(ecx_contextt *context, uint8 usetable);
|
int ecx_config_init(ecx_contextt *context, uint8 usetable);
|
||||||
int ecx_config_map_group(ecx_contextt *context, void *pIOmap, uint8 group);
|
int ecx_config_map_group(ecx_contextt *context, void *pIOmap, uint8 group);
|
||||||
|
int ecx_config_overlap_map_group(ecx_contextt *context, void *pIOmap, uint8 group);
|
||||||
int ecx_recover_slave(ecx_contextt *context, uint16 slave, int timeout);
|
int ecx_recover_slave(ecx_contextt *context, uint16 slave, int timeout);
|
||||||
int ecx_reconfig_slave(ecx_contextt *context, uint16 slave, int timeout);
|
int ecx_reconfig_slave(ecx_contextt *context, uint16 slave, int timeout);
|
||||||
|
|
||||||
|
@ -1671,7 +1671,7 @@ static void ecx_clearindex(ecx_contextt *context) {
|
|||||||
* @param[in] group = group number
|
* @param[in] group = group number
|
||||||
* @return >0 if processdata is transmitted.
|
* @return >0 if processdata is transmitted.
|
||||||
*/
|
*/
|
||||||
int ecx_send_processdata_group(ecx_contextt *context, uint8 group)
|
static int ecx_main_send_processdata(ecx_contextt *context, uint8 group, boolean use_overlap_io)
|
||||||
{
|
{
|
||||||
uint32 LogAdr;
|
uint32 LogAdr;
|
||||||
uint16 w1, w2;
|
uint16 w1, w2;
|
||||||
@ -1681,20 +1681,36 @@ int ecx_send_processdata_group(ecx_contextt *context, uint8 group)
|
|||||||
uint8* data;
|
uint8* data;
|
||||||
boolean first=FALSE;
|
boolean first=FALSE;
|
||||||
uint16 currentsegment = 0;
|
uint16 currentsegment = 0;
|
||||||
|
uint32 iomapinputoffset;
|
||||||
|
|
||||||
wkc = 0;
|
wkc = 0;
|
||||||
if(context->grouplist[group].hasdc)
|
if(context->grouplist[group].hasdc)
|
||||||
{
|
{
|
||||||
first = TRUE;
|
first = TRUE;
|
||||||
}
|
}
|
||||||
length = context->grouplist[group].Obytes + context->grouplist[group].Ibytes;
|
|
||||||
|
/* For overlapping IO map use the biggest */
|
||||||
|
if(use_overlap_io == TRUE)
|
||||||
|
{
|
||||||
|
/* For overlap IOmap make the frame EQ big to biggest part */
|
||||||
|
length = (context->grouplist[group].Obytes > context->grouplist[group].Ibytes) ?
|
||||||
|
context->grouplist[group].Obytes : context->grouplist[group].Ibytes;
|
||||||
|
/* Save the offset used to compensate where to save inputs when frame returns */
|
||||||
|
iomapinputoffset = context->grouplist[group].Obytes;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
length = context->grouplist[group].Obytes + context->grouplist[group].Ibytes;
|
||||||
|
iomapinputoffset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
LogAdr = context->grouplist[group].logstartaddr;
|
LogAdr = context->grouplist[group].logstartaddr;
|
||||||
if (length)
|
if(length)
|
||||||
{
|
{
|
||||||
|
|
||||||
wkc = 1;
|
wkc = 1;
|
||||||
/* LRW blocked by one or more slaves ? */
|
/* LRW blocked by one or more slaves ? */
|
||||||
if (context->grouplist[group].blockLRW)
|
if(context->grouplist[group].blockLRW)
|
||||||
{
|
{
|
||||||
/* if inputs available generate LRD */
|
/* if inputs available generate LRD */
|
||||||
if(context->grouplist[group].Ibytes)
|
if(context->grouplist[group].Ibytes)
|
||||||
@ -1786,6 +1802,8 @@ int ecx_send_processdata_group(ecx_contextt *context, uint8 group)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
data = context->grouplist[group].inputs;
|
data = context->grouplist[group].inputs;
|
||||||
|
/* Clear offset, don't compensate for overlapping IOmap if we only got inputs */
|
||||||
|
iomapinputoffset = 0;
|
||||||
}
|
}
|
||||||
/* segment transfer if needed */
|
/* segment transfer if needed */
|
||||||
do
|
do
|
||||||
@ -1807,8 +1825,12 @@ int ecx_send_processdata_group(ecx_contextt *context, uint8 group)
|
|||||||
}
|
}
|
||||||
/* send frame */
|
/* send frame */
|
||||||
ecx_outframe_red(context->port, idx);
|
ecx_outframe_red(context->port, idx);
|
||||||
/* push index and data pointer on stack */
|
/* push index and data pointer on stack.
|
||||||
ecx_pushindex(context, idx, data, sublength);
|
* the iomapinputoffset compensate for where the inputs are stored
|
||||||
|
* in the IOmap if we use an overlapping IOmap. If a regular IOmap
|
||||||
|
* is used it should always be 0.
|
||||||
|
*/
|
||||||
|
ecx_pushindex(context, idx, (data + iomapinputoffset), sublength);
|
||||||
length -= sublength;
|
length -= sublength;
|
||||||
LogAdr += sublength;
|
LogAdr += sublength;
|
||||||
data += sublength;
|
data += sublength;
|
||||||
@ -1819,6 +1841,40 @@ int ecx_send_processdata_group(ecx_contextt *context, uint8 group)
|
|||||||
return wkc;
|
return wkc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Transmit processdata to slaves.
|
||||||
|
* Uses LRW, or LRD/LWR if LRW is not allowed (blockLRW).
|
||||||
|
* Both the input and output processdata are transmitted in the overlapped IOmap.
|
||||||
|
* The outputs with the actual data, the inputs replace the output data in the
|
||||||
|
* returning frame. The inputs are gathered with the receive processdata function.
|
||||||
|
* In contrast to the base LRW function this function is non-blocking.
|
||||||
|
* If the processdata does not fit in one datagram, multiple are used.
|
||||||
|
* In order to recombine the slave response, a stack is used.
|
||||||
|
* @param[in] context = context struct
|
||||||
|
* @param[in] group = group number
|
||||||
|
* @return >0 if processdata is transmitted.
|
||||||
|
*/
|
||||||
|
int ecx_send_overlap_processdata_group(ecx_contextt *context, uint8 group)
|
||||||
|
{
|
||||||
|
return ecx_main_send_processdata(context, group, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Transmit processdata to slaves.
|
||||||
|
* Uses LRW, or LRD/LWR if LRW is not allowed (blockLRW).
|
||||||
|
* Both the input and output processdata are transmitted.
|
||||||
|
* The outputs with the actual data, the inputs have a placeholder.
|
||||||
|
* The inputs are gathered with the receive processdata function.
|
||||||
|
* In contrast to the base LRW function this function is non-blocking.
|
||||||
|
* If the processdata does not fit in one datagram, multiple are used.
|
||||||
|
* In order to recombine the slave response, a stack is used.
|
||||||
|
* @param[in] context = context struct
|
||||||
|
* @param[in] group = group number
|
||||||
|
* @return >0 if processdata is transmitted.
|
||||||
|
*/
|
||||||
|
int ecx_send_processdata_group(ecx_contextt *context, uint8 group)
|
||||||
|
{
|
||||||
|
return ecx_main_send_processdata(context, group, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
/** Receive processdata from slaves.
|
/** Receive processdata from slaves.
|
||||||
* Second part from ec_send_processdata().
|
* Second part from ec_send_processdata().
|
||||||
* Received datagrams are recombined with the processdata with help from the stack.
|
* Received datagrams are recombined with the processdata with help from the stack.
|
||||||
@ -1911,6 +1967,11 @@ int ecx_send_processdata(ecx_contextt *context)
|
|||||||
return ecx_send_processdata_group(context, 0);
|
return ecx_send_processdata_group(context, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ecx_send_overlap_processdata(ecx_contextt *context)
|
||||||
|
{
|
||||||
|
return ecx_send_overlap_processdata_group(context, 0);
|
||||||
|
}
|
||||||
|
|
||||||
int ecx_receive_processdata(ecx_contextt *context, int timeout)
|
int ecx_receive_processdata(ecx_contextt *context, int timeout)
|
||||||
{
|
{
|
||||||
return ecx_receive_processdata_group(context, 0, timeout);
|
return ecx_receive_processdata_group(context, 0, timeout);
|
||||||
@ -2265,6 +2326,24 @@ int ec_send_processdata_group(uint8 group)
|
|||||||
return ecx_send_processdata_group (&ecx_context, group);
|
return ecx_send_processdata_group (&ecx_context, group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Transmit processdata to slaves.
|
||||||
|
* Uses LRW, or LRD/LWR if LRW is not allowed (blockLRW).
|
||||||
|
* Both the input and output processdata are transmitted in the overlapped IOmap.
|
||||||
|
* The outputs with the actual data, the inputs replace the output data in the
|
||||||
|
* returning frame. The inputs are gathered with the receive processdata function.
|
||||||
|
* In contrast to the base LRW function this function is non-blocking.
|
||||||
|
* If the processdata does not fit in one datagram, multiple are used.
|
||||||
|
* In order to recombine the slave response, a stack is used.
|
||||||
|
* @param[in] context = context struct
|
||||||
|
* @param[in] group = group number
|
||||||
|
* @return >0 if processdata is transmitted.
|
||||||
|
* @see ecx_send_overlap_processdata_group
|
||||||
|
*/
|
||||||
|
int ec_send_overlap_processdata_group(uint8 group)
|
||||||
|
{
|
||||||
|
return ecx_send_overlap_processdata_group(&ecx_context, group);
|
||||||
|
}
|
||||||
|
|
||||||
/** Receive processdata from slaves.
|
/** Receive processdata from slaves.
|
||||||
* Second part from ec_send_processdata().
|
* Second part from ec_send_processdata().
|
||||||
* Received datagrams are recombined with the processdata with help from the stack.
|
* Received datagrams are recombined with the processdata with help from the stack.
|
||||||
@ -2284,6 +2363,11 @@ int ec_send_processdata(void)
|
|||||||
return ec_send_processdata_group(0);
|
return ec_send_processdata_group(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ec_send_overlap_processdata(void)
|
||||||
|
{
|
||||||
|
return ec_send_overlap_processdata_group(0);
|
||||||
|
}
|
||||||
|
|
||||||
int ec_receive_processdata(int timeout)
|
int ec_receive_processdata(int timeout)
|
||||||
{
|
{
|
||||||
return ec_receive_processdata_group(0, timeout);
|
return ec_receive_processdata_group(0, timeout);
|
||||||
|
@ -467,8 +467,10 @@ int ec_writeeepromFP(uint16 configadr, uint16 eeproma, uint16 data, int timeout)
|
|||||||
void ec_readeeprom1(uint16 slave, uint16 eeproma);
|
void ec_readeeprom1(uint16 slave, uint16 eeproma);
|
||||||
uint32 ec_readeeprom2(uint16 slave, int timeout);
|
uint32 ec_readeeprom2(uint16 slave, int timeout);
|
||||||
int ec_send_processdata_group(uint8 group);
|
int ec_send_processdata_group(uint8 group);
|
||||||
|
int ec_send_overlap_processdata_group(uint8 group);
|
||||||
int ec_receive_processdata_group(uint8 group, int timeout);
|
int ec_receive_processdata_group(uint8 group, int timeout);
|
||||||
int ec_send_processdata(void);
|
int ec_send_processdata(void);
|
||||||
|
int ec_send_overlap_processdata(void);
|
||||||
int ec_receive_processdata(int timeout);
|
int ec_receive_processdata(int timeout);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -507,9 +509,10 @@ uint64 ecx_readeepromFP(ecx_contextt *context, uint16 configadr, uint16 eeproma,
|
|||||||
int ecx_writeeepromFP(ecx_contextt *context, uint16 configadr, uint16 eeproma, uint16 data, int timeout);
|
int ecx_writeeepromFP(ecx_contextt *context, uint16 configadr, uint16 eeproma, uint16 data, int timeout);
|
||||||
void ecx_readeeprom1(ecx_contextt *context, uint16 slave, uint16 eeproma);
|
void ecx_readeeprom1(ecx_contextt *context, uint16 slave, uint16 eeproma);
|
||||||
uint32 ecx_readeeprom2(ecx_contextt *context, uint16 slave, int timeout);
|
uint32 ecx_readeeprom2(ecx_contextt *context, uint16 slave, int timeout);
|
||||||
int ecx_send_processdata_group(ecx_contextt *context, uint8 group);
|
int ecx_send_overlap_processdata_group(ecx_contextt *context, uint8 group);
|
||||||
int ecx_receive_processdata_group(ecx_contextt *context, uint8 group, int timeout);
|
int ecx_receive_processdata_group(ecx_contextt *context, uint8 group, int timeout);
|
||||||
int ecx_send_processdata(ecx_contextt *context);
|
int ecx_send_processdata(ecx_contextt *context);
|
||||||
|
int ecx_send_overlap_processdata(ecx_contextt *context);
|
||||||
int ecx_receive_processdata(ecx_contextt *context, int timeout);
|
int ecx_receive_processdata(ecx_contextt *context, int timeout);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
Loading…
x
Reference in New Issue
Block a user