/** Reconfigure slave. * * @param[in] context = context struct * @param[in] slave = slave to reconfigure * @param[in] timeout = local timeout f.e. EC_TIMEOUTRET3 * @return Slave state */ int ecx_reconfig_slave(ecx_contextt *context, uint16 slave, int timeout) { int state, nSM, FMMUc; uint16 configadr; configadr = context->slavelist[slave].configadr; if (ecx_FPWRw(context->port, configadr, ECT_REG_ALCTL, htoes(EC_STATE_INIT) , timeout) <= 0) { return 0; } state = 0; ecx_eeprom2pdi(context, slave); /* set Eeprom control to PDI */ /* check state change init */ state = ecx_statecheck(context, slave, EC_STATE_INIT, EC_TIMEOUTSTATE); if(state == EC_STATE_INIT) { /* program all enabled SM */ for( nSM = 0 ; nSM < EC_MAXSM ; nSM++ ) { if (context->slavelist[slave].SM[nSM].StartAddr) { ecx_FPWR(context->port, configadr, ECT_REG_SM0 + (nSM * sizeof(ec_smt)), sizeof(ec_smt), &context->slavelist[slave].SM[nSM], timeout); } } ecx_FPWRw(context->port, configadr, ECT_REG_ALCTL, htoes(EC_STATE_PRE_OP) , timeout); state = ecx_statecheck(context, slave, EC_STATE_PRE_OP, EC_TIMEOUTSTATE); /* check state change pre-op */ if( state == EC_STATE_PRE_OP) { /* execute special slave configuration hook Pre-Op to Safe-OP */ if(context->slavelist[slave].PO2SOconfig) /* only if registered */ { context->slavelist[slave].PO2SOconfig(slave); } ecx_FPWRw(context->port, configadr, ECT_REG_ALCTL, htoes(EC_STATE_SAFE_OP) , timeout); /* set safeop status */ state = ecx_statecheck(context, slave, EC_STATE_SAFE_OP, EC_TIMEOUTSTATE); /* check state change safe-op */ /* program configured FMMU */ for( FMMUc = 0 ; FMMUc < context->slavelist[slave].FMMUunused ; FMMUc++ ) { ecx_FPWR(context->port, configadr, ECT_REG_FMMU0 + (sizeof(ec_fmmut) * FMMUc), sizeof(ec_fmmut), &context->slavelist[slave].FMMU[FMMUc], timeout); } } } return state; }
/** Map all PDOs in one group of slaves to IOmap. * * @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_map_group(ecx_contextt *context, void *pIOmap, uint8 group) { uint16 slave, configadr; int Isize, Osize, BitCount, ByteCount, FMMUsize, FMMUdone; uint16 SMlength, EndAddr; uint8 BitPos; uint8 SMc, FMMUc; uint32 LogAddr = 0; uint32 oLogAddr = 0; uint32 diff; int nSM, rval; ec_eepromPDOt eepPDO; 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); LogAddr = context->grouplist[group].logstartaddr; oLogAddr = LogAddr; BitPos = 0; context->grouplist[group].nsegments = 0; context->grouplist[group].outputsWKC = 0; context->grouplist[group].inputsWKC = 0; /* find output mapping of slave and program FMMU */ for (slave = 1; slave <= *(context->slavecount); slave++) { configadr = context->slavelist[slave].configadr; ecx_statecheck(context, slave, EC_STATE_PRE_OP, EC_TIMEOUTSTATE); /* check state change pre-op */ EC_PRINT(" >Slave %d, configadr %x, state %2.2x\n", slave, context->slavelist[slave].configadr, context->slavelist[slave].state); /* execute special slave configuration hook Pre-Op to Safe-OP */ if(context->slavelist[slave].PO2SOconfig) /* only if registered */ { context->slavelist[slave].PO2SOconfig(slave); } if (!group || (group == context->slavelist[slave].group)) { /* if slave not found in configlist find IO mapping in slave self */ if (!context->slavelist[slave].configindex) { Isize = 0; Osize = 0; if (context->slavelist[slave].mbx_proto & ECT_MBXPROT_COE) /* has CoE */ { rval = 0; if (context->slavelist[slave].CoEdetails & ECT_COEDET_SDOCA) /* has Complete Access */ /* read PDO mapping via CoE and use Complete Access */ { rval = ecx_readPDOmapCA(context, slave, &Osize, &Isize); } if (!rval) /* CA not available or not succeeded */ { /* read PDO mapping via CoE */ rval = ecx_readPDOmap(context, slave, &Osize, &Isize); } EC_PRINT(" CoE Osize:%d Isize:%d\n", Osize, Isize); } if ((!Isize && !Osize) && (context->slavelist[slave].mbx_proto & ECT_MBXPROT_SOE)) /* has SoE */ { /* read AT / MDT mapping via SoE */ rval = ecx_readIDNmap(context, slave, &Osize, &Isize); context->slavelist[slave].SM[2].SMlength = htoes((Osize + 7) / 8); context->slavelist[slave].SM[3].SMlength = htoes((Isize + 7) / 8); EC_PRINT(" SoE Osize:%d Isize:%d\n", Osize, Isize); } if (!Isize && !Osize) /* find PDO mapping by SII */ { memset(&eepPDO, 0, sizeof(eepPDO)); Isize = (int)ecx_siiPDO(context, slave, &eepPDO, 0); EC_PRINT(" SII Isize:%d\n", Isize); for( nSM=0 ; nSM < EC_MAXSM ; nSM++ ) { if (eepPDO.SMbitsize[nSM] > 0) { context->slavelist[slave].SM[nSM].SMlength = htoes((eepPDO.SMbitsize[nSM] + 7) / 8); context->slavelist[slave].SMtype[nSM] = 4; EC_PRINT(" SM%d length %d\n", nSM, eepPDO.SMbitsize[nSM]); } } Osize = (int)ecx_siiPDO(context, slave, &eepPDO, 1); EC_PRINT(" SII Osize:%d\n", Osize); for( nSM=0 ; nSM < EC_MAXSM ; nSM++ ) { if (eepPDO.SMbitsize[nSM] > 0) { context->slavelist[slave].SM[nSM].SMlength = htoes((eepPDO.SMbitsize[nSM] + 7) / 8); context->slavelist[slave].SMtype[nSM] = 3; EC_PRINT(" SM%d length %d\n", nSM, eepPDO.SMbitsize[nSM]); } } } context->slavelist[slave].Obits = Osize; context->slavelist[slave].Ibits = Isize; EC_PRINT(" ISIZE:%d %d OSIZE:%d\n", context->slavelist[slave].Ibits, Isize,context->slavelist[slave].Obits); } EC_PRINT(" SM programming\n"); if (!context->slavelist[slave].mbx_l && context->slavelist[slave].SM[0].StartAddr) { ecx_FPWR(context->port, configadr, ECT_REG_SM0, sizeof(ec_smt), &(context->slavelist[slave].SM[0]), EC_TIMEOUTRET3); EC_PRINT(" SM0 Type:%d StartAddr:%4.4x Flags:%8.8x\n", context->slavelist[slave].SMtype[0], context->slavelist[slave].SM[0].StartAddr, context->slavelist[slave].SM[0].SMflags); } if (!context->slavelist[slave].mbx_l && context->slavelist[slave].SM[1].StartAddr) { ecx_FPWR(context->port, configadr, ECT_REG_SM1, sizeof(ec_smt), &context->slavelist[slave].SM[1], EC_TIMEOUTRET3); EC_PRINT(" SM1 Type:%d StartAddr:%4.4x Flags:%8.8x\n", context->slavelist[slave].SMtype[1], context->slavelist[slave].SM[1].StartAddr, context->slavelist[slave].SM[1].SMflags); } /* program SM2 to SMx */ for( nSM = 2 ; nSM < EC_MAXSM ; nSM++ ) { if (context->slavelist[slave].SM[nSM].StartAddr) { /* check if SM length is zero -> clear enable flag */ if( context->slavelist[slave].SM[nSM].SMlength == 0) { context->slavelist[slave].SM[nSM].SMflags = htoel( etohl(context->slavelist[slave].SM[nSM].SMflags) & EC_SMENABLEMASK); } ecx_FPWR(context->port, configadr, ECT_REG_SM0 + (nSM * sizeof(ec_smt)), sizeof(ec_smt), &context->slavelist[slave].SM[nSM], EC_TIMEOUTRET3); EC_PRINT(" SM%d Type:%d StartAddr:%4.4x Flags:%8.8x\n", nSM, context->slavelist[slave].SMtype[nSM], context->slavelist[slave].SM[nSM].StartAddr, context->slavelist[slave].SM[nSM].SMflags); } } if (context->slavelist[slave].Ibits > 7) { context->slavelist[slave].Ibytes = (context->slavelist[slave].Ibits + 7) / 8; } if (context->slavelist[slave].Obits > 7) { context->slavelist[slave].Obytes = (context->slavelist[slave].Obits + 7) / 8; } FMMUc = context->slavelist[slave].FMMUunused; SMc = 0; BitCount = 0; ByteCount = 0; EndAddr = 0; FMMUsize = 0; FMMUdone = 0; /* create output mapping */ if (context->slavelist[slave].Obits) { EC_PRINT(" OUTPUT MAPPING\n"); /* 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; oLogAddr = LogAddr; if ((segmentsize + diff) > (EC_MAXLRWDATA - EC_FIRSTDCDATAGRAM)) { context->grouplist[group].IOsegment[currentsegment] = segmentsize; if (currentsegment < (EC_MAXIOSEGMENTS - 1)) { currentsegment++; segmentsize = diff; } } else { segmentsize += diff; } } } } if (BitPos) { LogAddr++; oLogAddr = LogAddr; BitPos = 0; if ((segmentsize + 1) > (EC_MAXLRWDATA - EC_FIRSTDCDATAGRAM)) { context->grouplist[group].IOsegment[currentsegment] = segmentsize; if (currentsegment < (EC_MAXIOSEGMENTS - 1)) { currentsegment++; segmentsize = 1; } } else { segmentsize += 1; } } context->grouplist[group].outputs = pIOmap; context->grouplist[group].Obytes = LogAddr; context->grouplist[group].nsegments = currentsegment + 1; context->grouplist[group].Isegment = currentsegment; context->grouplist[group].Ioffset = segmentsize; if (!group) { context->slavelist[0].outputs = pIOmap; context->slavelist[0].Obytes = LogAddr; /* store output bytes in master record */ } /* do input mapping of slave and program FMMUs */ for (slave = 1; slave <= *(context->slavecount); 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++; } SMc = 0; BitCount = 0; ByteCount = 0; EndAddr = 0; FMMUsize = 0; FMMUdone = 0; /* create input mapping */ if (context->slavelist[slave].Ibits) { EC_PRINT(" =Slave %d, INPUT MAPPING\n", slave); /* 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++; 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; oLogAddr = LogAddr; 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; } if (BitPos) { LogAddr++; oLogAddr = LogAddr; BitPos = 0; if ((segmentsize + 1) > (EC_MAXLRWDATA - EC_FIRSTDCDATAGRAM)) { context->grouplist[group].IOsegment[currentsegment] = segmentsize; if (currentsegment < (EC_MAXIOSEGMENTS - 1)) { currentsegment++; segmentsize = 1; } } else { segmentsize += 1; } } context->grouplist[group].IOsegment[currentsegment] = segmentsize; context->grouplist[group].nsegments = currentsegment + 1; context->grouplist[group].inputs = (uint8 *)(pIOmap) + context->grouplist[group].Obytes; context->grouplist[group].Ibytes = LogAddr - context->grouplist[group].Obytes; if (!group) { context->slavelist[0].inputs = (uint8 *)(pIOmap) + context->slavelist[0].Obytes; context->slavelist[0].Ibytes = LogAddr - context->slavelist[0].Obytes; /* store input bytes in master record */ } EC_PRINT("IOmapSize %d\n", LogAddr - context->grouplist[group].logstartaddr); return (LogAddr - context->grouplist[group].logstartaddr); } return 0; }
/** Enumerate and init all slaves. * * @param[in] context = context struct * @param[in] usetable = TRUE when using configtable to init slaves, FALSE otherwise * @return Workcounter of slave discover datagram = number of slaves found */ int ecx_config_init(ecx_contextt *context, uint8 usetable) { uint16 w, slave, ADPh, configadr, ssigen; uint16 topology, estat; int16 topoc, slavec, aliasadr; uint8 b,h; uint8 zbuf[64]; uint8 SMc; uint32 eedat; int wkc, cindex, nSM, lp; EC_PRINT("ec_config_init %d\n",usetable); *(context->slavecount) = 0; /* clean ec_slave array */ memset(context->slavelist, 0x00, sizeof(ec_slavet) * context->maxslave); memset(&zbuf, 0x00, sizeof(zbuf)); memset(context->grouplist, 0x00, sizeof(ec_groupt) * context->maxgroup); /* clear slave eeprom cache */ ecx_siigetbyte(context, 0, EC_MAXEEPBUF); for(lp = 0; lp < context->maxgroup; lp++) { context->grouplist[lp].logstartaddr = lp << 16; /* default start address per group entry */ } /* make special pre-init register writes to enable MAC[1] local administered bit * * setting for old netX100 slaves */ b = 0x00; ecx_BWR(context->port, 0x0000, ECT_REG_DLALIAS, sizeof(b), &b, EC_TIMEOUTRET3); /* Ignore Alias register */ b = EC_STATE_INIT | EC_STATE_ACK; ecx_BWR(context->port, 0x0000, ECT_REG_ALCTL, sizeof(b), &b, EC_TIMEOUTRET3); /* Reset all slaves to Init */ /* netX100 should now be happy */ wkc = ecx_BWR(context->port, 0x0000, ECT_REG_ALCTL, sizeof(b), &b, EC_TIMEOUTRET3); /* Reset all slaves to Init */ printf("wkc = %d\n",wkc); w = 0x0000; wkc = ecx_BRD(context->port, 0x0000, ECT_REG_TYPE, sizeof(w), &w, EC_TIMEOUTSAFE); /* detect number of slaves */ if (wkc > 0) { *(context->slavecount) = wkc; b = 0x00; ecx_BWR(context->port, 0x0000, ECT_REG_DLPORT, sizeof(b), &b, EC_TIMEOUTRET3); /* deact loop manual */ w = htoes(0x0004); ecx_BWR(context->port, 0x0000, ECT_REG_IRQMASK, sizeof(w), &w, EC_TIMEOUTRET3); /* set IRQ mask */ ecx_BWR(context->port, 0x0000, ECT_REG_RXERR, 8, &zbuf, EC_TIMEOUTRET3); /* reset CRC counters */ ecx_BWR(context->port, 0x0000, ECT_REG_FMMU0, 16 * 3, &zbuf, EC_TIMEOUTRET3); /* reset FMMU's */ ecx_BWR(context->port, 0x0000, ECT_REG_SM0, 8 * 4, &zbuf, EC_TIMEOUTRET3); /* reset SyncM */ ecx_BWR(context->port, 0x0000, ECT_REG_DCSYSTIME, 4, &zbuf, EC_TIMEOUTRET3); /* reset system time+ofs */ w = htoes(0x1000); ecx_BWR(context->port, 0x0000, ECT_REG_DCSPEEDCNT, sizeof(w), &w, EC_TIMEOUTRET3); /* DC speedstart */ w = htoes(0x0c00); ecx_BWR(context->port, 0x0000, ECT_REG_DCTIMEFILT, sizeof(w), &w, EC_TIMEOUTRET3); /* DC filt expr */ b = 0x00; ecx_BWR(context->port, 0x0000, ECT_REG_DLALIAS, sizeof(b), &b, EC_TIMEOUTRET3); /* Ignore Alias register */ b = EC_STATE_INIT | EC_STATE_ACK; ecx_BWR(context->port, 0x0000, ECT_REG_ALCTL, sizeof(b), &b, EC_TIMEOUTRET3); /* Reset all slaves to Init */ b = 2; ecx_BWR(context->port, 0x0000, ECT_REG_EEPCFG, sizeof(b), &b , EC_TIMEOUTRET3); /* force Eeprom from PDI */ b = 0; ecx_BWR(context->port, 0x0000, ECT_REG_EEPCFG, sizeof(b), &b , EC_TIMEOUTRET3); /* set Eeprom to master */ for (slave = 1; slave <= *(context->slavecount); slave++) { ADPh = (uint16)(1 - slave); context->slavelist[slave].Itype = etohs(ecx_APRDw(context->port, ADPh, ECT_REG_PDICTL, EC_TIMEOUTRET3)); /* read interface type of slave */ /* a node offset is used to improve readibility of network frames */ /* this has no impact on the number of addressable slaves (auto wrap around) */ ecx_APWRw(context->port, ADPh, ECT_REG_STADR, htoes(slave + EC_NODEOFFSET) , EC_TIMEOUTRET3); /* set node address of slave */ if (slave == 1) { b = 1; /* kill non ecat frames for first slave */ } else { b = 0; /* pass all frames for following slaves */ } ecx_APWRw(context->port, ADPh, ECT_REG_DLCTL, htoes(b), EC_TIMEOUTRET3); /* set non ecat frame behaviour */ configadr = etohs(ecx_APRDw(context->port, ADPh, ECT_REG_STADR, EC_TIMEOUTRET3)); context->slavelist[slave].configadr = configadr; ecx_FPRD(context->port, configadr, ECT_REG_ALIAS, sizeof(aliasadr), &aliasadr, EC_TIMEOUTRET3); context->slavelist[slave].aliasadr = etohs(aliasadr); ecx_FPRD(context->port, configadr, ECT_REG_EEPSTAT, sizeof(estat), &estat, EC_TIMEOUTRET3); estat = etohs(estat); if (estat & EC_ESTAT_R64) /* check if slave can read 8 byte chunks */ { context->slavelist[slave].eep_8byte = 1; } ecx_readeeprom1(context, slave, ECT_SII_MANUF); /* Manuf */ } for (slave = 1; slave <= *(context->slavecount); slave++) { context->slavelist[slave].eep_man = etohl(ecx_readeeprom2(context, slave, EC_TIMEOUTEEP)); /* Manuf */ ecx_readeeprom1(context, slave, ECT_SII_ID); /* ID */ } for (slave = 1; slave <= *(context->slavecount); slave++) { context->slavelist[slave].eep_id = etohl(ecx_readeeprom2(context, slave, EC_TIMEOUTEEP)); /* ID */ ecx_readeeprom1(context, slave, ECT_SII_REV); /* revision */ } for (slave = 1; slave <= *(context->slavecount); slave++) { context->slavelist[slave].eep_rev = etohl(ecx_readeeprom2(context, slave, EC_TIMEOUTEEP)); /* revision */ ecx_readeeprom1(context, slave, ECT_SII_RXMBXADR); /* write mailbox address + mailboxsize */ } for (slave = 1; slave <= *(context->slavecount); slave++) { eedat = etohl(ecx_readeeprom2(context, slave, EC_TIMEOUTEEP)); /* write mailbox address and mailboxsize */ context->slavelist[slave].mbx_wo = (uint16)LO_WORD(eedat); context->slavelist[slave].mbx_l = (uint16)HI_WORD(eedat); if (context->slavelist[slave].mbx_l > 0) { ecx_readeeprom1(context, slave, ECT_SII_TXMBXADR); /* read mailbox offset */ } } for (slave = 1; slave <= *(context->slavecount); slave++) { if (context->slavelist[slave].mbx_l > 0) { eedat = etohl(ecx_readeeprom2(context, slave, EC_TIMEOUTEEP)); /* read mailbox offset */ context->slavelist[slave].mbx_ro = (uint16)LO_WORD(eedat); /* read mailbox offset */ context->slavelist[slave].mbx_rl = (uint16)HI_WORD(eedat); /*read mailbox length */ if (context->slavelist[slave].mbx_rl == 0) { context->slavelist[slave].mbx_rl = context->slavelist[slave].mbx_l; } } configadr = context->slavelist[slave].configadr; if ((etohs(ecx_FPRDw(context->port, configadr, ECT_REG_ESCSUP, EC_TIMEOUTRET3)) & 0x04) > 0) /* Support DC? */ { context->slavelist[slave].hasdc = TRUE; } else { context->slavelist[slave].hasdc = FALSE; } topology = etohs(ecx_FPRDw(context->port, configadr, ECT_REG_DLSTAT, EC_TIMEOUTRET3)); /* extract topology from DL status */ h = 0; b = 0; if ((topology & 0x0300) == 0x0200) /* port0 open and communication established */ { h++; b |= 0x01; } if ((topology & 0x0c00) == 0x0800) /* port1 open and communication established */ { h++; b |= 0x02; } if ((topology & 0x3000) == 0x2000) /* port2 open and communication established */ { h++; b |= 0x04; } if ((topology & 0xc000) == 0x8000) /* port3 open and communication established */ { h++; b |= 0x08; } /* ptype = Physical type*/ context->slavelist[slave].ptype = LO_BYTE(etohs(ecx_FPRDw(context->port, configadr, ECT_REG_PORTDES, EC_TIMEOUTRET3))); context->slavelist[slave].topology = h; context->slavelist[slave].activeports = b; /* 0=no links, not possible */ /* 1=1 link , end of line */ /* 2=2 links , one before and one after */ /* 3=3 links , split point */ /* 4=4 links , cross point */ /* search for parent */ context->slavelist[slave].parent = 0; /* parent is master */ if (slave > 1) { topoc = 0; slavec = slave - 1; do { topology = context->slavelist[slavec].topology; if (topology == 1) { topoc--; /* endpoint found */ } if (topology == 3) { topoc++; /* split found */ } if (topology == 4) { topoc += 2; /* cross found */ } if (((topoc >= 0) && (topology > 1)) || (slavec == 1)) /* parent found */ { context->slavelist[slave].parent = slavec; slavec = 1; } slavec--; } while (slavec > 0); } w = ecx_statecheck(context, slave, EC_STATE_INIT, EC_TIMEOUTSTATE); //* check state change Init */ /* set default mailbox configuration if slave has mailbox */ if (context->slavelist[slave].mbx_l>0) { context->slavelist[slave].SMtype[0] = 1; context->slavelist[slave].SMtype[1] = 2; context->slavelist[slave].SMtype[2] = 3; context->slavelist[slave].SMtype[3] = 4; context->slavelist[slave].SM[0].StartAddr = htoes(context->slavelist[slave].mbx_wo); context->slavelist[slave].SM[0].SMlength = htoes(context->slavelist[slave].mbx_l); context->slavelist[slave].SM[0].SMflags = htoel(EC_DEFAULTMBXSM0); context->slavelist[slave].SM[1].StartAddr = htoes(context->slavelist[slave].mbx_ro); context->slavelist[slave].SM[1].SMlength = htoes(context->slavelist[slave].mbx_rl); context->slavelist[slave].SM[1].SMflags = htoel(EC_DEFAULTMBXSM1); context->slavelist[slave].mbx_proto = ecx_readeeprom(context, slave, ECT_SII_MBXPROTO, EC_TIMEOUTEEP); } cindex = 0; #ifdef EC_VER1 /* use configuration table ? */ if (usetable) { cindex = ec_findconfig( context->slavelist[slave].eep_man, context->slavelist[slave].eep_id ); context->slavelist[slave].configindex= cindex; } /* slave found in configuration table ? */ if (cindex) { context->slavelist[slave].Dtype = ec_configlist[cindex].Dtype; strcpy(context->slavelist[slave].name ,ec_configlist[cindex].name); context->slavelist[slave].Ibits = ec_configlist[cindex].Ibits; context->slavelist[slave].Obits = ec_configlist[cindex].Obits; if (context->slavelist[slave].Obits) { context->slavelist[slave].FMMU0func = 1; } if (context->slavelist[slave].Ibits) { context->slavelist[slave].FMMU1func = 2; } context->slavelist[slave].FMMU[0].FMMUactive = ec_configlist[cindex].FM0ac; context->slavelist[slave].FMMU[1].FMMUactive = ec_configlist[cindex].FM1ac; context->slavelist[slave].SM[2].StartAddr = htoes(ec_configlist[cindex].SM2a); context->slavelist[slave].SM[2].SMflags = htoel(ec_configlist[cindex].SM2f); /* simple (no mailbox) output slave found ? */ if (context->slavelist[slave].Obits && !context->slavelist[slave].SM[2].StartAddr) { context->slavelist[slave].SM[0].StartAddr = htoes(0x0f00); context->slavelist[slave].SM[0].SMlength = htoes((context->slavelist[slave].Obits + 7) / 8); context->slavelist[slave].SM[0].SMflags = htoel(EC_DEFAULTDOSM0); context->slavelist[slave].FMMU[0].FMMUactive = 1; context->slavelist[slave].FMMU[0].FMMUtype = 2; context->slavelist[slave].SMtype[0] = 3; } /* complex output slave */ else { context->slavelist[slave].SM[2].SMlength = htoes((context->slavelist[slave].Obits + 7) / 8); context->slavelist[slave].SMtype[2] = 3; } context->slavelist[slave].SM[3].StartAddr = htoes(ec_configlist[cindex].SM3a); context->slavelist[slave].SM[3].SMflags = htoel(ec_configlist[cindex].SM3f); /* simple (no mailbox) input slave found ? */ if (context->slavelist[slave].Ibits && !context->slavelist[slave].SM[3].StartAddr) { context->slavelist[slave].SM[1].StartAddr = htoes(0x1000); context->slavelist[slave].SM[1].SMlength = htoes((context->slavelist[slave].Ibits + 7) / 8); context->slavelist[slave].SM[1].SMflags = htoel(0x00000000); context->slavelist[slave].FMMU[1].FMMUactive = 1; context->slavelist[slave].FMMU[1].FMMUtype = 1; context->slavelist[slave].SMtype[1] = 4; } /* complex input slave */ else { context->slavelist[slave].SM[3].SMlength = htoes((context->slavelist[slave].Ibits + 7) / 8); context->slavelist[slave].SMtype[3] = 4; } } /* slave not in configuration table, find out via SII */ else #endif { ssigen = ecx_siifind(context, slave, ECT_SII_GENERAL); /* SII general section */ if (ssigen) { context->slavelist[slave].CoEdetails = ecx_siigetbyte(context, slave, ssigen + 0x07); context->slavelist[slave].FoEdetails = ecx_siigetbyte(context, slave, ssigen + 0x08); context->slavelist[slave].EoEdetails = ecx_siigetbyte(context, slave, ssigen + 0x09); context->slavelist[slave].SoEdetails = ecx_siigetbyte(context, slave, ssigen + 0x0a); if((ecx_siigetbyte(context, slave, ssigen + 0x0d) & 0x02) > 0) { context->slavelist[slave].blockLRW = 1; context->slavelist[0].blockLRW++; } context->slavelist[slave].Ebuscurrent = ecx_siigetbyte(context, slave, ssigen + 0x0e); context->slavelist[slave].Ebuscurrent += ecx_siigetbyte(context, slave, ssigen + 0x0f) << 8; context->slavelist[0].Ebuscurrent += context->slavelist[slave].Ebuscurrent; } /* SII strings section */ if (ecx_siifind(context, slave, ECT_SII_STRING) > 0) { ecx_siistring(context, context->slavelist[slave].name, slave, 1); } /* no name for slave found, use constructed name */ else { sprintf(context->slavelist[slave].name, "? M:%8.8x I:%8.8x", (unsigned int)context->slavelist[slave].eep_man, (unsigned int)context->slavelist[slave].eep_id); } /* SII SM section */ nSM = ecx_siiSM(context, slave, context->eepSM); if (nSM>0) { context->slavelist[slave].SM[0].StartAddr = htoes(context->eepSM->PhStart); context->slavelist[slave].SM[0].SMlength = htoes(context->eepSM->Plength); context->slavelist[slave].SM[0].SMflags = htoel((context->eepSM->Creg) + (context->eepSM->Activate << 16)); SMc = 1; while ((SMc < EC_MAXSM) && ecx_siiSMnext(context, slave, context->eepSM, SMc)) { context->slavelist[slave].SM[SMc].StartAddr = htoes(context->eepSM->PhStart); context->slavelist[slave].SM[SMc].SMlength = htoes(context->eepSM->Plength); context->slavelist[slave].SM[SMc].SMflags = htoel((context->eepSM->Creg) + (context->eepSM->Activate << 16)); SMc++; } } /* SII FMMU section */ if (ecx_siiFMMU(context, slave, context->eepFMMU)) { if (context->eepFMMU->FMMU0 !=0xff) { context->slavelist[slave].FMMU0func = context->eepFMMU->FMMU0; } if (context->eepFMMU->FMMU1 !=0xff) { context->slavelist[slave].FMMU1func = context->eepFMMU->FMMU1; } if (context->eepFMMU->FMMU2 !=0xff) { context->slavelist[slave].FMMU2func = context->eepFMMU->FMMU2; } if (context->eepFMMU->FMMU3 !=0xff) { context->slavelist[slave].FMMU3func = context->eepFMMU->FMMU3; } } } if (context->slavelist[slave].mbx_l > 0) { if (context->slavelist[slave].SM[0].StartAddr == 0x0000) /* should never happen */ { EC_PRINT("Slave %d has no proper mailbox in configuration, try default.\n", slave); context->slavelist[slave].SM[0].StartAddr = htoes(0x1000); context->slavelist[slave].SM[0].SMlength = htoes(0x0080); context->slavelist[slave].SM[0].SMflags = htoel(EC_DEFAULTMBXSM0); context->slavelist[slave].SMtype[0] = 1; } if (context->slavelist[slave].SM[1].StartAddr == 0x0000) /* should never happen */ { EC_PRINT("Slave %d has no proper mailbox out configuration, try default.\n", slave); context->slavelist[slave].SM[1].StartAddr = htoes(0x1080); context->slavelist[slave].SM[1].SMlength = htoes(0x0080); context->slavelist[slave].SM[1].SMflags = htoel(EC_DEFAULTMBXSM1); context->slavelist[slave].SMtype[1] = 2; } /* program SM0 mailbox in and SM1 mailbox out for slave */ /* writing both SM in one datagram will solve timing issue in old NETX */ ecx_FPWR(context->port, configadr, ECT_REG_SM0, sizeof(ec_smt) * 2, &(context->slavelist[slave].SM[0]), EC_TIMEOUTRET3); } /* request pre_op for slave */ ecx_FPWRw(context->port, configadr, ECT_REG_ALCTL, htoes(EC_STATE_PRE_OP | EC_STATE_ACK) , EC_TIMEOUTRET3); /* set preop status */ } } return wkc; }
void slaveinfo(char *ifname) { int cnt, i, j, nSM; int ctx_count; uint16 ssigen; int expectedWKC[2]; int wkc_count; int chk; volatile int wkc[2]; boolean inOP; printf("Starting slaveinfo\n"); /* initialise SOEM, bind socket to ifname */ if (ecx_init(&ctx[0],"ie1g1") && ecx_init(&ctx[1],"ie1g0")) { printf("ec_init on %s succeeded.\n",ifname); /* find and auto-config slaves */ if ( ecx_config_init(&ctx[0],FALSE) > 0 && ecx_config_init(&ctx[1],FALSE) > 0 ) { for (ctx_count = 0; ctx_count < 2; ctx_count++) { ecx_config_map_group(&ctx[ctx_count], IOmap, 0); ecx_configdc(&ctx[ctx_count]); while(*(ctx[ctx_count].ecaterror)) printf("%s", ecx_elist2string(&ctx[ctx_count])); printf("%d slaves found and configured.\n",*(ctx[ctx_count].slavecount)); expectedWKC[ctx_count] = ( ctx[ctx_count].grouplist[0].outputsWKC * 2) + ctx[ctx_count].grouplist[0].inputsWKC; printf("Calculated workcounter %d\n", expectedWKC[ctx_count]); /* wait for all slaves to reach SAFE_OP state */ ecx_statecheck(&ctx[ctx_count],0, EC_STATE_SAFE_OP, EC_TIMEOUTSTATE * 3); if (ctx[ctx_count].slavelist[ctx_count].state != EC_STATE_SAFE_OP ) { printf("Not all slaves reached safe operational state.\n"); ecx_readstate(&ctx[ctx_count]); for(i = 1; i <= *(ctx[ctx_count].slavecount) ; i++) { if(ctx[ctx_count].slavelist[i].state != EC_STATE_SAFE_OP) { printf("Slave %d State=%2x StatusCode=%4x : %s\n", i, ctx[ctx_count].slavelist[i].state, ctx[ctx_count].slavelist[i].ALstatuscode, ec_ALstatuscode2string(ctx[ctx_count].slavelist[i].ALstatuscode)); } } } ecx_readstate(&ctx[ctx_count]); for( cnt = 1 ; cnt <= *(ctx[ctx_count].slavecount) ; cnt++) { printf("\nSlave:%d\n Name:%s\n Output size: %dbits\n Input size: %dbits\n State: %d\n Delay: %d[ns]\n Has DC: %d\n", cnt, ctx[ctx_count].slavelist[cnt].name, ctx[ctx_count].slavelist[cnt].Obits, ctx[ctx_count].slavelist[cnt].Ibits, ctx[ctx_count].slavelist[cnt].state, ctx[ctx_count].slavelist[cnt].pdelay, ctx[ctx_count].slavelist[cnt].hasdc); if (ctx[ctx_count].slavelist[cnt].hasdc) { printf(" DCParentport:%d\n", ctx[ctx_count].slavelist[cnt].parentport); } printf(" Activeports:%d.%d.%d.%d\n", (ctx[ctx_count].slavelist[cnt].activeports & 0x01) > 0 , (ctx[ctx_count].slavelist[cnt].activeports & 0x02) > 0 , (ctx[ctx_count].slavelist[cnt].activeports & 0x04) > 0 , (ctx[ctx_count].slavelist[cnt].activeports & 0x08) > 0 ); printf(" Configured address: %4.4x\n", ctx[ctx_count].slavelist[cnt].configadr); printf(" Man: %8.8x ID: %8.8x Rev: %8.8x\n", (int)ctx[ctx_count].slavelist[cnt].eep_man, (int)ctx[ctx_count].slavelist[cnt].eep_id, (int)ctx[ctx_count].slavelist[cnt].eep_rev); for(nSM = 0 ; nSM < EC_MAXSM ; nSM++) { if(ctx[ctx_count].slavelist[cnt].SM[nSM].StartAddr > 0) printf(" SM%1d A:%4.4x L:%4d F:%8.8x Type:%d\n",nSM, ctx[ctx_count].slavelist[cnt].SM[nSM].StartAddr, ctx[ctx_count].slavelist[cnt].SM[nSM].SMlength,(int)ctx[ctx_count].slavelist[cnt].SM[nSM].SMflags, ctx[ctx_count].slavelist[cnt].SMtype[nSM]); } for(j = 0 ; j < ctx[ctx_count].slavelist[cnt].FMMUunused ; j++) { printf(" FMMU%1d Ls:%8.8x Ll:%4d Lsb:%d Leb:%d Ps:%4.4x Psb:%d Ty:%2.2x Act:%2.2x\n", j, (int)ctx[ctx_count].slavelist[cnt].FMMU[j].LogStart, ctx[ctx_count].slavelist[cnt].FMMU[j].LogLength, ctx[ctx_count].slavelist[cnt].FMMU[j].LogStartbit, ctx[ctx_count].slavelist[cnt].FMMU[j].LogEndbit, ctx[ctx_count].slavelist[cnt].FMMU[j].PhysStart, ctx[ctx_count].slavelist[cnt].FMMU[j].PhysStartBit, ctx[ctx_count].slavelist[cnt].FMMU[j].FMMUtype, ctx[ctx_count].slavelist[cnt].FMMU[j].FMMUactive); } printf(" FMMUfunc 0:%d 1:%d 2:%d 3:%d\n", ctx[ctx_count].slavelist[cnt].FMMU0func, ctx[ctx_count].slavelist[cnt].FMMU2func, ctx[ctx_count].slavelist[cnt].FMMU2func, ctx[ctx_count].slavelist[cnt].FMMU3func); printf(" MBX length wr: %d rd: %d MBX protocols : %2.2x\n", ctx[ctx_count].slavelist[cnt].mbx_l, ctx[ctx_count].slavelist[cnt].mbx_rl, ctx[ctx_count].slavelist[cnt].mbx_proto); ssigen = ecx_siifind(&ctx[ctx_count], cnt, ECT_SII_GENERAL); /* SII general section */ if (ssigen) { ctx[ctx_count].slavelist[cnt].CoEdetails = ecx_siigetbyte(&ctx[ctx_count], cnt, ssigen + 0x07); ctx[ctx_count].slavelist[cnt].FoEdetails = ecx_siigetbyte(&ctx[ctx_count], cnt, ssigen + 0x08); ctx[ctx_count].slavelist[cnt].EoEdetails = ecx_siigetbyte(&ctx[ctx_count], cnt, ssigen + 0x09); ctx[ctx_count].slavelist[cnt].SoEdetails = ecx_siigetbyte(&ctx[ctx_count], cnt, ssigen + 0x0a); if((ecx_siigetbyte(&ctx[ctx_count], cnt, ssigen + 0x0d) & 0x02) > 0) { ctx[ctx_count].slavelist[cnt].blockLRW = 1; ctx[ctx_count].slavelist[0].blockLRW++; } ctx[ctx_count].slavelist[cnt].Ebuscurrent = ecx_siigetbyte(&ctx[ctx_count], cnt, ssigen + 0x0e); ctx[ctx_count].slavelist[cnt].Ebuscurrent += ecx_siigetbyte(&ctx[ctx_count], cnt, ssigen + 0x0f) << 8; ctx[ctx_count].slavelist[0].Ebuscurrent += ctx[ctx_count].slavelist[cnt].Ebuscurrent; } printf(" CoE details: %2.2x FoE details: %2.2x EoE details: %2.2x SoE details: %2.2x\n", ctx[ctx_count].slavelist[cnt].CoEdetails, ctx[ctx_count].slavelist[cnt].FoEdetails, ctx[ctx_count].slavelist[cnt].EoEdetails, ctx[ctx_count].slavelist[cnt].SoEdetails); printf(" Ebus current: %d[mA]\n only LRD/LWR:%d\n", ctx[ctx_count].slavelist[cnt].Ebuscurrent, ctx[ctx_count].slavelist[cnt].blockLRW); } } inOP = FALSE; printf("Request operational state for all slaves\n"); expectedWKC[0] = (ctx[0].grouplist[0].outputsWKC * 2) + ctx[0].grouplist[0].inputsWKC; expectedWKC[1] = (ctx[1].grouplist[0].outputsWKC * 2) + ctx[1].grouplist[0].inputsWKC; printf("Calculated workcounter master 1 %d\n", expectedWKC[0]); printf("Calculated workcounter master 2 %d\n", expectedWKC[1]); ctx[0].slavelist[0].state = EC_STATE_OPERATIONAL; ctx[1].slavelist[0].state = EC_STATE_OPERATIONAL; /* send one valid process data to make outputs in slaves happy*/ ecx_send_processdata(&ctx[0]); ecx_send_processdata(&ctx[1]); ecx_receive_processdata(&ctx[0],EC_TIMEOUTRET); ecx_receive_processdata(&ctx[1],EC_TIMEOUTRET); /* request OP state for all slaves */ ecx_writestate(&ctx[0], 0); ecx_writestate(&ctx[1], 0); chk = 40; /* wait for all slaves to reach OP state */ do { ecx_send_processdata(&ctx[0]); ecx_send_processdata(&ctx[1]); ecx_receive_processdata(&ctx[0],EC_TIMEOUTRET); ecx_receive_processdata(&ctx[1],EC_TIMEOUTRET); ecx_statecheck(&ctx[0],0, EC_STATE_OPERATIONAL, 50000); ecx_statecheck(&ctx[1],0, EC_STATE_OPERATIONAL, 50000); } while (chk-- && (ctx[0].slavelist[0].state != EC_STATE_OPERATIONAL) && (ctx[1].slavelist[0].state != EC_STATE_OPERATIONAL)); *(ctx[0].slavelist[6].outputs) = 0xFF; *(ctx[1].slavelist[1].outputs) = 0x0F; if (ctx[0].slavelist[0].state == EC_STATE_OPERATIONAL && ctx[1].slavelist[0].state == EC_STATE_OPERATIONAL ) { printf("Operational state reached for all slaves.\n"); /* cyclic loop */ start_RT_trace (1); wkc_count = 0; inOP = TRUE; for(i = 1; i <= 10000; i++) { for (ctx_count = 0; ctx_count < 2; ctx_count++) { /* Receive processdata */ log_RT_event('R',(WORD)(1 + ctx_count * 10)); wkc[ctx_count] = ecx_receive_processdata(&ctx[ctx_count], 0); log_RT_event('R',(WORD)(99 + ctx_count * 100)); } for (ctx_count = 0; ctx_count < 2; ctx_count++) { /* Send processdata */ log_RT_event('S',(WORD)(1 + ctx_count * 10)); if (!ecx_send_processdata(&ctx[ctx_count])) { printf (" Frame no: %d on master %d,Not sentOK\n", i,ctx_count); } log_RT_event('S',(WORD)(99 + ctx_count * 100)); } knRtSleep(1); for (ctx_count = 0; ctx_count < 2; ctx_count++) { if(wkc[ctx_count] >= expectedWKC[ctx_count]) { } else { printf (" Frame no: %d on master %d , wc not wkc >= expectedWKC, %d\n",i, ctx_count, wkc[ctx_count]); } } } stop_RT_trace (); inOP = FALSE; } } else { printf("No slaves found!\n"); } printf("End slaveinfo, close socket\n"); /* stop SOEM, close socket */ ecx_close(&ctx[0]); ecx_close(&ctx[1]); } else { printf("No socket connection on %s\nExcecute as root\n",ifname); } }