00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include <stdio.h>
00050 #include <string.h>
00051 #include <sys/time.h>
00052 #include <unistd.h>
00053 #include "ethercattype.h"
00054 #include "nicdrv.h"
00055 #include "ethercatbase.h"
00056 #include "ethercatmain.h"
00057 #include "ethercatcoe.h"
00058 #include "ethercatsoe.h"
00059 #include "ethercatconfig.h"
00060
00061
00062
00063
00064 #ifdef EC_DEBUG
00065 #define EC_PRINT printf
00066 #else
00067 #define EC_PRINT(...) do {} while (0)
00068 #endif
00069
00070
00071 typedef const struct
00072 {
00073
00074 uint32 man;
00075
00076 uint32 id;
00077
00078 char name[EC_MAXNAME + 1];
00079
00080 uint8 Dtype;
00081
00082 uint16 Ibits;
00083
00084 uint16 Obits;
00085
00086 uint16 SM2a;
00087
00088 uint32 SM2f;
00089
00090 uint16 SM3a;
00091
00092 uint32 SM3f;
00093
00094 uint8 FM0ac;
00095
00096 uint8 FM1ac;
00097 } ec_configlist_t;
00098
00099 #include "ethercatconfiglist.h"
00100
00101
00102 #define EC_DEFAULTMBXSM0 0x00010026
00103
00104 #define EC_DEFAULTMBXSM1 0x00010022
00105
00106 #define EC_DEFAULTDOSM0 0x00010044
00107
00108
00109 static ec_eepromSMt ec_SM;
00110
00111 static ec_eepromFMMUt ec_FMMU;
00112
00113
00114
00115
00116
00117
00118
00119 int ec_findconfig( uint32 man, uint32 id)
00120 {
00121 int i = 0;
00122
00123 do
00124 {
00125 i++;
00126 } while ( (ec_configlist[i].man != EC_CONFIGEND) &&
00127 ((ec_configlist[i].man != man) || (ec_configlist[i].id != id)) );
00128 if (ec_configlist[i].man == EC_CONFIGEND)
00129 i = 0;
00130
00131 return i;
00132 }
00133
00134
00135
00136
00137
00138
00139 int ec_config_init(uint8 usetable)
00140 {
00141 uint16 w, slave, ADPh, configadr, mbx_wo, mbx_ro, mbx_l, mbx_rl, ssigen;
00142 uint16 topology, estat;
00143 int16 topoc, slavec;
00144 uint8 b,h;
00145 uint8 zbuf[64];
00146 uint8 SMc;
00147 uint32 eedat;
00148 int wkc, cindex, nSM, lp;
00149
00150 EC_PRINT("ec_config_init %d\n",usetable);
00151 ec_slavecount = 0;
00152
00153 memset(&ec_slave, 0x00, sizeof(ec_slave));
00154 memset(&zbuf, 0x00, sizeof(zbuf));
00155 memset(&ec_group, 0x00, sizeof(ec_group));
00156 for(lp = 0; lp < EC_MAXGROUP; lp++)
00157 {
00158 ec_group[lp].logstartaddr = lp << 16;
00159 }
00160 w = 0x0000;
00161 wkc = ec_BRD(0x0000, ECT_REG_TYPE, sizeof(w), &w, EC_TIMEOUTSAFE);
00162 if (wkc > 0)
00163 {
00164 ec_slavecount = wkc;
00165 b = 0x00;
00166 ec_BWR(0x0000, ECT_REG_DLPORT, sizeof(b), &b, EC_TIMEOUTRET);
00167 w = htoes(0x0004);
00168 ec_BWR(0x0000, ECT_REG_IRQMASK, sizeof(w), &w, EC_TIMEOUTRET);
00169 ec_BWR(0x0000, ECT_REG_RXERR, 8, &zbuf, EC_TIMEOUTRET);
00170 ec_BWR(0x0000, ECT_REG_FMMU0, 16 * 3, &zbuf, EC_TIMEOUTRET);
00171 ec_BWR(0x0000, ECT_REG_SM0, 8 * 4, &zbuf, EC_TIMEOUTRET);
00172 ec_BWR(0x0000, ECT_REG_DCSYSTIME, 4, &zbuf, EC_TIMEOUTRET);
00173 w = htoes(0x1000);
00174 ec_BWR(0x0000, ECT_REG_DCSPEEDCNT, sizeof(w), &w, EC_TIMEOUTRET);
00175 w = htoes(0x0c00);
00176 ec_BWR(0x0000, ECT_REG_DCTIMEFILT, sizeof(w), &w, EC_TIMEOUTRET);
00177 b = 0x00;
00178 ec_BWR(0x0000, ECT_REG_DLALIAS, sizeof(b), &b, EC_TIMEOUTRET);
00179 b = EC_STATE_INIT | EC_STATE_ACK;
00180 ec_BWR(0x0000, ECT_REG_ALCTL, sizeof(b), &b, EC_TIMEOUTRET);
00181 b = 2;
00182 ec_BWR(0x0000, ECT_REG_EEPCFG, sizeof(b), &b , EC_TIMEOUTRET);
00183 b = 0;
00184 ec_BWR(0x0000, ECT_REG_EEPCFG, sizeof(b), &b , EC_TIMEOUTRET);
00185
00186 for (slave = 1; slave <= ec_slavecount; slave++)
00187 {
00188 ADPh = (uint16)(1 - slave);
00189 ec_slave[slave].Itype = etohs(ec_APRDw(ADPh, ECT_REG_PDICTL, EC_TIMEOUTRET));
00190
00191
00192 ec_APWRw(ADPh, ECT_REG_STADR, htoes(slave + EC_NODEOFFSET) , EC_TIMEOUTRET);
00193 if (slave == 1)
00194 b = 1;
00195 else
00196 b = 0;
00197 ec_APWRw(ADPh, ECT_REG_DLCTL, htoes(b), EC_TIMEOUTRET);
00198 configadr = etohs(ec_APRDw(ADPh, ECT_REG_STADR, EC_TIMEOUTRET));
00199 ec_slave[slave].configadr = configadr;
00200 ec_FPRD(configadr, ECT_REG_ALIAS, sizeof(ec_slave[slave].aliasadr), &ec_slave[slave].aliasadr, EC_TIMEOUTRET);
00201 ec_FPRD(configadr, ECT_REG_EEPSTAT, sizeof(estat), &estat, EC_TIMEOUTRET);
00202 estat = etohs(estat);
00203 if (estat & EC_ESTAT_R64)
00204 ec_slave[slave].eep_8byte = 1;
00205 ec_readeeprom1(slave, ECT_SII_MANUF);
00206 }
00207 for (slave = 1; slave <= ec_slavecount; slave++)
00208 {
00209 ec_slave[slave].eep_man = etohl(ec_readeeprom2(slave, EC_TIMEOUTEEP));
00210 ec_readeeprom1(slave, ECT_SII_ID);
00211 }
00212 for (slave = 1; slave <= ec_slavecount; slave++)
00213 {
00214 ec_slave[slave].eep_id = etohl(ec_readeeprom2(slave, EC_TIMEOUTEEP));
00215 ec_readeeprom1(slave, ECT_SII_REV);
00216 }
00217 for (slave = 1; slave <= ec_slavecount; slave++)
00218 {
00219 ec_slave[slave].eep_rev = etohl(ec_readeeprom2(slave, EC_TIMEOUTEEP));
00220 ec_readeeprom1(slave, ECT_SII_RXMBXADR);
00221 }
00222 for (slave = 1; slave <= ec_slavecount; slave++)
00223 {
00224 eedat = etohl(ec_readeeprom2(slave, EC_TIMEOUTEEP));
00225 ec_slave[slave].mbx_wo = (uint16)LO_WORD(eedat);
00226 ec_slave[slave].mbx_l = (uint16)HI_WORD(eedat);
00227 if (ec_slave[slave].mbx_l > 0)
00228 ec_readeeprom1(slave, ECT_SII_TXMBXADR);
00229 }
00230 for (slave = 1; slave <= ec_slavecount; slave++)
00231 {
00232 if (ec_slave[slave].mbx_l > 0)
00233 {
00234 eedat = etohl(ec_readeeprom2(slave, EC_TIMEOUTEEP));
00235 ec_slave[slave].mbx_ro = (uint16)LO_WORD(eedat);
00236 ec_slave[slave].mbx_rl = (uint16)HI_WORD(eedat);
00237 if (ec_slave[slave].mbx_rl == 0)
00238 ec_slave[slave].mbx_rl = ec_slave[slave].mbx_l;
00239 }
00240 configadr = ec_slave[slave].configadr;
00241 mbx_ro = ec_slave[slave].mbx_ro;
00242 mbx_wo = ec_slave[slave].mbx_wo;
00243 mbx_l = ec_slave[slave].mbx_l;
00244 mbx_rl = ec_slave[slave].mbx_rl;
00245 if ((etohs(ec_FPRDw(configadr, ECT_REG_ESCSUP, EC_TIMEOUTRET)) & 0x04) > 0)
00246 ec_slave[slave].hasdc = TRUE;
00247 else
00248 ec_slave[slave].hasdc = FALSE;
00249 topology = etohs(ec_FPRDw(configadr, ECT_REG_DLSTAT, EC_TIMEOUTRET));
00250 h = 0;
00251 b = 0;
00252 if ((topology & 0x0300) == 0x0200)
00253 {
00254 h++;
00255 b |= 0x01;
00256 }
00257 if ((topology & 0x0c00) == 0x0800)
00258 {
00259 h++;
00260 b |= 0x02;
00261 }
00262 if ((topology & 0x3000) == 0x2000)
00263 {
00264 h++;
00265 b |= 0x04;
00266 }
00267 if ((topology & 0xc000) == 0x8000)
00268 {
00269 h++;
00270 b |= 0x08;
00271 }
00272
00273 ec_slave[slave].ptype = LO_BYTE(etohs(ec_FPRDw(configadr, ECT_REG_PORTDES, EC_TIMEOUTRET)));
00274 ec_slave[slave].topology = h;
00275 ec_slave[slave].activeports = b;
00276
00277
00278
00279
00280
00281
00282 ec_slave[slave].parent = 0;
00283 if (slave > 1)
00284 {
00285 topoc = 0;
00286 slavec = slave - 1;
00287 do
00288 {
00289 topology = ec_slave[slavec].topology;
00290 if (topology == 1)
00291 topoc--;
00292 if (topology == 3)
00293 topoc++;
00294 if (topology == 4)
00295 topoc+=2;
00296 if (((topoc >= 0) && (topology > 1)) ||
00297 (slavec == 1))
00298 {
00299 ec_slave[slave].parent = slavec;
00300 slavec = 1;
00301 }
00302 slavec--;
00303 }
00304 while (slavec > 0);
00305 }
00306
00307 w = ec_statecheck(slave, EC_STATE_INIT, EC_TIMEOUTSTATE);
00308
00309
00310 if (ec_slave[slave].mbx_l>0)
00311 {
00312 ec_slave[slave].SMtype[0] = 1;
00313 ec_slave[slave].SMtype[1] = 2;
00314 ec_slave[slave].SMtype[2] = 3;
00315 ec_slave[slave].SMtype[3] = 4;
00316 ec_slave[slave].SM[0].StartAddr = htoes(ec_slave[slave].mbx_wo);
00317 ec_slave[slave].SM[0].SMlength = htoes(ec_slave[slave].mbx_l);
00318 ec_slave[slave].SM[0].SMflags = htoel(EC_DEFAULTMBXSM0);
00319 ec_slave[slave].SM[1].StartAddr = htoes(ec_slave[slave].mbx_ro);
00320 ec_slave[slave].SM[1].SMlength = htoes(ec_slave[slave].mbx_rl);
00321 ec_slave[slave].SM[1].SMflags = htoel(EC_DEFAULTMBXSM1);
00322 ec_slave[slave].mbx_proto = ec_readeeprom (slave, ECT_SII_MBXPROTO, EC_TIMEOUTEEP);
00323 }
00324 cindex = 0;
00325
00326 if (usetable)
00327 {
00328 cindex = ec_findconfig( ec_slave[slave].eep_man, ec_slave[slave].eep_id );
00329 ec_slave[slave].configindex= cindex;
00330 }
00331
00332 if (cindex)
00333 {
00334 ec_slave[slave].Dtype = ec_configlist[cindex].Dtype;
00335 strcpy( ec_slave[slave].name ,ec_configlist[cindex].name);
00336 ec_slave[slave].Ibits = ec_configlist[cindex].Ibits;
00337 ec_slave[slave].Obits = ec_configlist[cindex].Obits;
00338 if (ec_slave[slave].Obits)
00339 ec_slave[slave].FMMU0func = 1;
00340 if (ec_slave[slave].Ibits)
00341 ec_slave[slave].FMMU1func = 2;
00342 ec_slave[slave].FMMU[0].FMMUactive = ec_configlist[cindex].FM0ac;
00343 ec_slave[slave].FMMU[1].FMMUactive = ec_configlist[cindex].FM1ac;
00344 ec_slave[slave].SM[2].StartAddr = htoes(ec_configlist[cindex].SM2a);
00345 ec_slave[slave].SM[2].SMflags = htoel(ec_configlist[cindex].SM2f);
00346
00347 if (ec_slave[slave].Obits && !ec_slave[slave].SM[2].StartAddr)
00348 {
00349 ec_slave[slave].SM[0].StartAddr = htoes(0x0f00);
00350 ec_slave[slave].SM[0].SMlength = htoes((ec_slave[slave].Obits + 7) / 8);
00351 ec_slave[slave].SM[0].SMflags = htoel(EC_DEFAULTDOSM0);
00352 ec_slave[slave].FMMU[0].FMMUactive = 1;
00353 ec_slave[slave].FMMU[0].FMMUtype = 2;
00354 ec_slave[slave].SMtype[0] = 3;
00355 }
00356
00357 else
00358 {
00359 ec_slave[slave].SM[2].SMlength = htoes((ec_slave[slave].Obits + 7) / 8);
00360 ec_slave[slave].SMtype[2] = 3;
00361 }
00362 ec_slave[slave].SM[3].StartAddr = htoes(ec_configlist[cindex].SM3a);
00363 ec_slave[slave].SM[3].SMflags = htoel(ec_configlist[cindex].SM3f);
00364
00365 if (ec_slave[slave].Ibits && !ec_slave[slave].SM[3].StartAddr)
00366 {
00367 ec_slave[slave].SM[1].StartAddr = htoes(0x1000);
00368 ec_slave[slave].SM[1].SMlength = htoes((ec_slave[slave].Ibits + 7) / 8);
00369 ec_slave[slave].SM[1].SMflags = htoel(0x00000000);
00370 ec_slave[slave].FMMU[1].FMMUactive = 1;
00371 ec_slave[slave].FMMU[1].FMMUtype = 1;
00372 ec_slave[slave].SMtype[1] = 4;
00373 }
00374
00375 else
00376 {
00377 ec_slave[slave].SM[3].SMlength = htoes((ec_slave[slave].Ibits + 7) / 8);
00378 ec_slave[slave].SMtype[3] = 4;
00379 }
00380 }
00381
00382 else
00383 {
00384 ssigen = ec_siifind(slave, ECT_SII_GENERAL);
00385
00386 if (ssigen)
00387 {
00388 ec_slave[slave].CoEdetails = ec_siigetbyte(slave, ssigen + 0x07);
00389 ec_slave[slave].FoEdetails = ec_siigetbyte(slave, ssigen + 0x08);
00390 ec_slave[slave].EoEdetails = ec_siigetbyte(slave, ssigen + 0x09);
00391 ec_slave[slave].SoEdetails = ec_siigetbyte(slave, ssigen + 0x0a);
00392 if((ec_siigetbyte(slave, ssigen + 0x0d) & 0x02) > 0)
00393 {
00394 ec_slave[slave].blockLRW = 1;
00395 ec_slave[0].blockLRW++;
00396 }
00397 ec_slave[slave].Ebuscurrent = ec_siigetbyte(slave, ssigen + 0x0e);
00398 ec_slave[slave].Ebuscurrent += ec_siigetbyte(slave, ssigen + 0x0f) << 8;
00399 ec_slave[0].Ebuscurrent += ec_slave[slave].Ebuscurrent;
00400 }
00401
00402 if (ec_siifind(slave, ECT_SII_STRING) > 0)
00403 ec_siistring(ec_slave[slave].name, slave, 1);
00404
00405 else
00406 {
00407 sprintf(ec_slave[slave].name, "? M:%8.8x I:%8.8x",
00408 (unsigned int)ec_slave[slave].eep_man, (unsigned int)ec_slave[slave].eep_id);
00409 }
00410
00411 nSM = ec_siiSM (slave,&ec_SM);
00412 if (nSM>0)
00413 {
00414 ec_slave[slave].SM[0].StartAddr = htoes(ec_SM.PhStart);
00415 ec_slave[slave].SM[0].SMlength = htoes(ec_SM.Plength);
00416 ec_slave[slave].SM[0].SMflags = htoel((ec_SM.Creg) + (ec_SM.Activate << 16));
00417 SMc = 1;
00418 while ((SMc < EC_MAXSM) && ec_siiSMnext(slave, &ec_SM, SMc))
00419 {
00420 ec_slave[slave].SM[SMc].StartAddr = htoes(ec_SM.PhStart);
00421 ec_slave[slave].SM[SMc].SMlength = htoes(ec_SM.Plength);
00422 ec_slave[slave].SM[SMc].SMflags = htoel((ec_SM.Creg) + (ec_SM.Activate << 16));
00423 SMc++;
00424 }
00425 }
00426
00427 if (ec_siiFMMU(slave, &ec_FMMU))
00428 {
00429 if (ec_FMMU.FMMU0 !=0xff)
00430 ec_slave[slave].FMMU0func = ec_FMMU.FMMU0;
00431 if (ec_FMMU.FMMU1 !=0xff)
00432 ec_slave[slave].FMMU1func = ec_FMMU.FMMU1;
00433 if (ec_FMMU.FMMU2 !=0xff)
00434 ec_slave[slave].FMMU2func = ec_FMMU.FMMU2;
00435 if (ec_FMMU.FMMU3 !=0xff)
00436 ec_slave[slave].FMMU3func = ec_FMMU.FMMU3;
00437 }
00438 }
00439
00440 if (ec_slave[slave].mbx_l > 0)
00441 {
00442 if (ec_slave[slave].SM[0].StartAddr == 0x0000)
00443 {
00444 ec_slave[slave].SM[0].StartAddr = htoes(0x1000);
00445 ec_slave[slave].SM[0].SMlength = htoes(0x0080);
00446 ec_slave[slave].SM[0].SMflags = htoel(EC_DEFAULTMBXSM0);
00447 ec_slave[slave].SMtype[0] = 1;
00448 }
00449 if (ec_slave[slave].SM[1].StartAddr == 0x0000)
00450 {
00451 ec_slave[slave].SM[1].StartAddr = htoes(0x1080);
00452 ec_slave[slave].SM[1].SMlength = htoes(0x0080);
00453 ec_slave[slave].SM[1].SMflags = htoel(EC_DEFAULTMBXSM1);
00454 ec_slave[slave].SMtype[1] = 2;
00455 }
00456
00457 ec_FPWR (configadr, ECT_REG_SM0, sizeof(ec_smt), &ec_slave[slave].SM[0], EC_TIMEOUTRET);
00458
00459
00460 ec_FPWR (configadr, ECT_REG_SM1, sizeof(ec_smt), &ec_slave[slave].SM[1], EC_TIMEOUTRET);
00461 }
00462 ec_FPWRw(configadr, ECT_REG_ALCTL, htoes(EC_STATE_PRE_OP | EC_STATE_ACK) , EC_TIMEOUTRET);
00463 }
00464 }
00465 return wkc;
00466 }
00467
00468
00469
00470
00471
00472
00473
00474 int ec_config_map_group(void *pIOmap, uint8 group)
00475 {
00476 uint16 slave, configadr;
00477 int Isize, Osize, BitCount, ByteCount, FMMUsize, FMMUdone;
00478 uint16 SMlength;
00479 uint8 BitPos, EndAddr;
00480 uint8 SMc, FMMUc;
00481 uint32 LogAddr = 0;
00482 uint32 oLogAddr = 0;
00483 uint32 diff;
00484 int nSM, rval;
00485 ec_eepromPDOt eepPDO;
00486 uint16 currentsegment = 0;
00487 uint32 segmentsize = 0;
00488
00489 if ((ec_slavecount > 0) && (group < EC_MAXGROUP))
00490 {
00491 EC_PRINT("ec_config_map_group IOmap:%p group:%d\n", pIOmap, group);
00492 LogAddr = ec_group[group].logstartaddr;
00493 oLogAddr = LogAddr;
00494 BitPos = 0;
00495 ec_group[group].nsegments = 0;
00496 ec_group[group].expectedWKC = 0;
00497
00498
00499 for (slave = 1; slave <= ec_slavecount; slave++)
00500 {
00501 configadr = ec_slave[slave].configadr;
00502
00503 ec_statecheck(slave, EC_STATE_PRE_OP, EC_TIMEOUTSTATE);
00504
00505 EC_PRINT(" >Slave %d, configadr %x, state %2.2x\n",
00506 slave, ec_slave[slave].configadr, ec_slave[slave].state);
00507
00508 if (!group || (group == ec_slave[slave].group))
00509 {
00510
00511
00512 if (!ec_slave[slave].configindex)
00513 {
00514 Isize = 0;
00515 Osize = 0;
00516 if (ec_slave[slave].mbx_proto & ECT_MBXPROT_COE)
00517 {
00518 if (ec_slave[slave].CoEdetails & ECT_COEDET_SDOCA)
00519
00520 rval = ec_readPDOmapCA(slave, &Osize, &Isize);
00521 else
00522
00523 rval = ec_readPDOmap(slave, &Osize, &Isize);
00524 EC_PRINT(" CoE Osize:%d Isize:%d\n", Osize, Isize);
00525 }
00526 if ((!Isize && !Osize) && (ec_slave[slave].mbx_proto & ECT_MBXPROT_SOE))
00527 {
00528
00529 rval = ec_readIDNmap(slave, &Osize, &Isize);
00530 ec_slave[slave].SM[2].SMlength = htoes((Osize + 7) / 8);
00531 ec_slave[slave].SM[3].SMlength = htoes((Isize + 7) / 8);
00532 EC_PRINT(" SoE Osize:%d Isize:%d\n", Osize, Isize);
00533 }
00534 if (!Isize && !Osize)
00535 {
00536 memset(&eepPDO, 0, sizeof(eepPDO));
00537 Isize = (int)ec_siiPDO (slave, &eepPDO, 0);
00538 EC_PRINT(" SII Isize:%d\n", Isize);
00539 for( nSM=0 ; nSM < EC_MAXSM ; nSM++ )
00540 {
00541 if (eepPDO.SMbitsize[nSM] > 0)
00542 {
00543 ec_slave[slave].SM[nSM].SMlength = htoes((eepPDO.SMbitsize[nSM] + 7) / 8);
00544 ec_slave[slave].SMtype[nSM] = 4;
00545 EC_PRINT(" SM%d length %d\n", nSM, eepPDO.SMbitsize[nSM]);
00546 }
00547 }
00548 Osize = (int)ec_siiPDO (slave, &eepPDO, 1);
00549 EC_PRINT(" SII Osize:%d\n", Osize);
00550 for( nSM=0 ; nSM < EC_MAXSM ; nSM++ )
00551 {
00552 if (eepPDO.SMbitsize[nSM] > 0)
00553 {
00554 ec_slave[slave].SM[nSM].SMlength = htoes((eepPDO.SMbitsize[nSM] + 7) / 8);
00555 ec_slave[slave].SMtype[nSM] = 3;
00556 EC_PRINT(" SM%d length %d\n", nSM, eepPDO.SMbitsize[nSM]);
00557 }
00558 }
00559 }
00560 ec_slave[slave].Obits = Osize;
00561 ec_slave[slave].Ibits = Isize;
00562 EC_PRINT(" ISIZE:%d %d OSIZE:%d\n", ec_slave[slave].Ibits, Isize,ec_slave[slave].Obits);
00563
00564 }
00565
00566 EC_PRINT(" SM programming\n");
00567 if (!ec_slave[slave].mbx_l && ec_slave[slave].SM[0].StartAddr)
00568 {
00569 ec_FPWR (configadr, ECT_REG_SM0, sizeof(ec_smt), &ec_slave[slave].SM[0], EC_TIMEOUTRET);
00570 EC_PRINT(" SM0 Type:%d StartAddr:%4.4x Flags:%8.8x\n",
00571 ec_slave[slave].SMtype[0], ec_slave[slave].SM[0].StartAddr, ec_slave[slave].SM[0].SMflags);
00572 }
00573 if (!ec_slave[slave].mbx_l && ec_slave[slave].SM[1].StartAddr)
00574 {
00575 ec_FPWR (configadr, ECT_REG_SM1, sizeof(ec_smt), &ec_slave[slave].SM[1], EC_TIMEOUTRET);
00576 EC_PRINT(" SM1 Type:%d StartAddr:%4.4x Flags:%8.8x\n",
00577 ec_slave[slave].SMtype[1], ec_slave[slave].SM[1].StartAddr, ec_slave[slave].SM[1].SMflags);
00578 }
00579
00580 for( nSM = 2 ; nSM < EC_MAXSM ; nSM++ )
00581 {
00582 if (ec_slave[slave].SM[nSM].StartAddr)
00583 {
00584
00585 if( ec_slave[slave].SM[nSM].SMlength == 0)
00586 ec_slave[slave].SM[nSM].SMflags = htoel( etohl(ec_slave[slave].SM[nSM].SMflags) & EC_SMENABLEMASK);
00587 ec_FPWR (configadr, ECT_REG_SM0 + (nSM * sizeof(ec_smt)), sizeof(ec_smt), &ec_slave[slave].SM[nSM], EC_TIMEOUTRET);
00588 EC_PRINT(" SM%d Type:%d StartAddr:%4.4x Flags:%8.8x\n", nSM,
00589 ec_slave[slave].SMtype[nSM], ec_slave[slave].SM[nSM].StartAddr, ec_slave[slave].SM[nSM].SMflags);
00590 }
00591 }
00592 if (ec_slave[slave].Ibits > 7)
00593 ec_slave[slave].Ibytes = (ec_slave[slave].Ibits + 7) / 8;
00594 if (ec_slave[slave].Obits > 7)
00595 ec_slave[slave].Obytes = (ec_slave[slave].Obits + 7) / 8;
00596
00597 FMMUc = ec_slave[slave].FMMUunused;
00598 SMc = 0;
00599 BitCount = 0;
00600 ByteCount = 0;
00601 EndAddr = 0;
00602 FMMUsize = 0;
00603 FMMUdone = 0;
00604
00605 if (ec_slave[slave].Obits)
00606 {
00607 EC_PRINT(" OUTPUT MAPPING\n");
00608
00609 while ( (SMc < (EC_MAXSM - 1)) && (FMMUdone < ((ec_slave[slave].Obits + 7) / 8)))
00610 {
00611 EC_PRINT(" FMMU %d\n", FMMUc);
00612 while ( (SMc < (EC_MAXSM - 1)) && (ec_slave[slave].SMtype[SMc] != 3)) SMc++;
00613 EC_PRINT(" SM%d\n", SMc);
00614 ec_slave[slave].FMMU[FMMUc].PhysStart = ec_slave[slave].SM[SMc].StartAddr;
00615 SMlength = etohs(ec_slave[slave].SM[SMc].SMlength);
00616 ByteCount += SMlength;
00617 BitCount += SMlength * 8;
00618 EndAddr = etohs(ec_slave[slave].SM[SMc].StartAddr) + SMlength;
00619 while ( (BitCount < ec_slave[slave].Obits) && (SMc < (EC_MAXSM - 1)) )
00620 {
00621 SMc++;
00622 while ( (SMc < (EC_MAXSM - 1)) && (ec_slave[slave].SMtype[SMc] != 3)) SMc++;
00623
00624 if ( etohs(ec_slave[slave].SM[SMc].StartAddr) > EndAddr ) break;
00625 EC_PRINT(" SM%d\n", SMc);
00626 SMlength = etohs(ec_slave[slave].SM[SMc].SMlength);
00627 ByteCount += SMlength;
00628 BitCount += SMlength * 8;
00629 EndAddr = etohs(ec_slave[slave].SM[SMc].StartAddr) + SMlength;
00630 }
00631
00632
00633 if (!ec_slave[slave].Obytes)
00634 {
00635 ec_slave[slave].FMMU[FMMUc].LogStart = htoel(LogAddr);
00636 ec_slave[slave].FMMU[FMMUc].LogStartbit = BitPos;
00637 BitPos += ec_slave[slave].Obits - 1;
00638 if (BitPos > 7)
00639 {
00640 LogAddr++;
00641 BitPos -= 8;
00642 }
00643 FMMUsize = LogAddr - etohl(ec_slave[slave].FMMU[FMMUc].LogStart) + 1;
00644 ec_slave[slave].FMMU[FMMUc].LogLength = htoes(FMMUsize);
00645 ec_slave[slave].FMMU[FMMUc].LogEndbit = BitPos;
00646 BitPos ++;
00647 if (BitPos > 7)
00648 {
00649 LogAddr++;
00650 BitPos -= 8;
00651 }
00652 }
00653
00654 else
00655 {
00656 if (BitPos)
00657 {
00658 LogAddr++;
00659 BitPos = 0;
00660 }
00661 ec_slave[slave].FMMU[FMMUc].LogStart = htoel(LogAddr);
00662 ec_slave[slave].FMMU[FMMUc].LogStartbit = BitPos;
00663 BitPos = 7;
00664 FMMUsize = ByteCount;
00665 if ((FMMUsize + FMMUdone)> ec_slave[slave].Obytes)
00666 FMMUsize = ec_slave[slave].Obytes - FMMUdone;
00667 LogAddr += FMMUsize;
00668 ec_slave[slave].FMMU[FMMUc].LogLength = htoes(FMMUsize);
00669 ec_slave[slave].FMMU[FMMUc].LogEndbit = BitPos;
00670 BitPos = 0;
00671 }
00672 FMMUdone += FMMUsize;
00673 ec_slave[slave].FMMU[FMMUc].PhysStartBit = 0;
00674 ec_slave[slave].FMMU[FMMUc].FMMUtype = 2;
00675 ec_slave[slave].FMMU[FMMUc].FMMUactive = 1;
00676
00677 ec_FPWR (configadr, ECT_REG_FMMU0 + (sizeof(ec_fmmut) * FMMUc), sizeof(ec_fmmut),
00678 &ec_slave[slave].FMMU[FMMUc], EC_TIMEOUTRET);
00679
00680 ec_group[group].expectedWKC += 2;
00681 if (!ec_slave[slave].outputs)
00682 {
00683 ec_slave[slave].outputs = pIOmap + etohl(ec_slave[slave].FMMU[FMMUc].LogStart);
00684 ec_slave[slave].Ostartbit = ec_slave[slave].FMMU[FMMUc].LogStartbit;
00685 EC_PRINT(" slave %d Outputs %p startbit %d\n", slave, ec_slave[slave].outputs, ec_slave[slave].Ostartbit);
00686 }
00687 FMMUc++;
00688 }
00689 ec_slave[slave].FMMUunused = FMMUc;
00690 diff = LogAddr - oLogAddr;
00691 oLogAddr = LogAddr;
00692 if ((segmentsize + diff) > (EC_MAXLRWDATA - EC_FIRSTDCDATAGRAM))
00693 {
00694 ec_group[group].IOsegment[currentsegment] = segmentsize;
00695 if (currentsegment < (EC_MAXIOSEGMENTS - 1))
00696 {
00697 currentsegment++;
00698 segmentsize = diff;
00699 }
00700 }
00701 else
00702 segmentsize += diff;
00703 }
00704 }
00705 }
00706 if (BitPos)
00707 {
00708 LogAddr++;
00709 oLogAddr = LogAddr;
00710 BitPos = 0;
00711 if ((segmentsize + 1) > (EC_MAXLRWDATA - EC_FIRSTDCDATAGRAM))
00712 {
00713 ec_group[group].IOsegment[currentsegment] = segmentsize;
00714 if (currentsegment < (EC_MAXIOSEGMENTS - 1))
00715 {
00716 currentsegment++;
00717 segmentsize = 1;
00718 }
00719 }
00720 else
00721 segmentsize += 1;
00722 }
00723 ec_group[group].outputs = pIOmap;
00724 ec_group[group].Obytes = LogAddr;
00725 ec_group[group].nsegments = currentsegment + 1;
00726 ec_group[group].Isegment = currentsegment;
00727 ec_group[group].Ioffset = segmentsize;
00728 if (!group)
00729 {
00730 ec_slave[0].outputs = pIOmap;
00731 ec_slave[0].Obytes = LogAddr;
00732 }
00733
00734
00735 for (slave = 1; slave <= ec_slavecount; slave++)
00736 {
00737 configadr = ec_slave[slave].configadr;
00738 FMMUc = ec_slave[slave].FMMUunused;
00739 if (ec_slave[slave].Obits)
00740 while ( ec_slave[slave].FMMU[FMMUc].LogStart ) FMMUc++;
00741 SMc = 0;
00742 BitCount = 0;
00743 ByteCount = 0;
00744 EndAddr = 0;
00745 FMMUsize = 0;
00746 FMMUdone = 0;
00747
00748 if (ec_slave[slave].Ibits)
00749 {
00750 EC_PRINT(" =Slave %d, INPUT MAPPING\n", slave);
00751
00752 while ( (SMc < (EC_MAXSM - 1)) && (FMMUdone < ((ec_slave[slave].Ibits + 7) / 8)))
00753 {
00754 EC_PRINT(" FMMU %d\n", FMMUc);
00755 while ( (SMc < (EC_MAXSM - 1)) && (ec_slave[slave].SMtype[SMc] != 4)) SMc++;
00756 EC_PRINT(" SM%d\n", SMc);
00757 ec_slave[slave].FMMU[FMMUc].PhysStart = ec_slave[slave].SM[SMc].StartAddr;
00758 SMlength = etohs(ec_slave[slave].SM[SMc].SMlength);
00759 ByteCount += SMlength;
00760 BitCount += SMlength * 8;
00761 EndAddr = etohs(ec_slave[slave].SM[SMc].StartAddr) + SMlength;
00762 while ( (BitCount < ec_slave[slave].Ibits) && (SMc < (EC_MAXSM - 1)) )
00763 {
00764 SMc++;
00765 while ( (SMc < (EC_MAXSM - 1)) && (ec_slave[slave].SMtype[SMc] != 4)) SMc++;
00766
00767 if ( etohs(ec_slave[slave].SM[SMc].StartAddr) > EndAddr ) break;
00768 EC_PRINT(" SM%d\n", SMc);
00769 SMlength = etohs(ec_slave[slave].SM[SMc].SMlength);
00770 ByteCount += SMlength;
00771 BitCount += SMlength * 8;
00772 EndAddr = etohs(ec_slave[slave].SM[SMc].StartAddr) + SMlength;
00773 }
00774
00775
00776 if (!ec_slave[slave].Ibytes)
00777 {
00778 ec_slave[slave].FMMU[FMMUc].LogStart = htoel(LogAddr);
00779 ec_slave[slave].FMMU[FMMUc].LogStartbit = BitPos;
00780 BitPos += ec_slave[slave].Ibits - 1;
00781 if (BitPos > 7)
00782 {
00783 LogAddr++;
00784 BitPos -= 8;
00785 }
00786 FMMUsize = LogAddr - etohl(ec_slave[slave].FMMU[FMMUc].LogStart) + 1;
00787 ec_slave[slave].FMMU[FMMUc].LogLength = htoes(FMMUsize);
00788 ec_slave[slave].FMMU[FMMUc].LogEndbit = BitPos;
00789 BitPos ++;
00790 if (BitPos > 7)
00791 {
00792 LogAddr++;
00793 BitPos -= 8;
00794 }
00795 }
00796
00797 else
00798 {
00799 if (BitPos)
00800 {
00801 LogAddr++;
00802 BitPos = 0;
00803 }
00804 ec_slave[slave].FMMU[FMMUc].LogStart = htoel(LogAddr);
00805 ec_slave[slave].FMMU[FMMUc].LogStartbit = BitPos;
00806 BitPos = 7;
00807 FMMUsize = ByteCount;
00808 if ((FMMUsize + FMMUdone)> ec_slave[slave].Ibytes)
00809 FMMUsize = ec_slave[slave].Ibytes - FMMUdone;
00810 LogAddr += FMMUsize;
00811 ec_slave[slave].FMMU[FMMUc].LogLength = htoes(FMMUsize);
00812 ec_slave[slave].FMMU[FMMUc].LogEndbit = BitPos;
00813 BitPos = 0;
00814 }
00815 FMMUdone += FMMUsize;
00816 if (ec_slave[slave].FMMU[FMMUc].LogLength)
00817 {
00818 ec_slave[slave].FMMU[FMMUc].PhysStartBit = 0;
00819 ec_slave[slave].FMMU[FMMUc].FMMUtype = 1;
00820 ec_slave[slave].FMMU[FMMUc].FMMUactive = 1;
00821
00822 ec_FPWR (configadr, ECT_REG_FMMU0 + (sizeof(ec_fmmut) * FMMUc), sizeof(ec_fmmut),
00823 &ec_slave[slave].FMMU[FMMUc], EC_TIMEOUTRET);
00824
00825 ec_group[group].expectedWKC += 1;
00826 }
00827 if (!ec_slave[slave].inputs)
00828 {
00829 ec_slave[slave].inputs = pIOmap + etohl(ec_slave[slave].FMMU[FMMUc].LogStart);
00830 ec_slave[slave].Istartbit = ec_slave[slave].FMMU[FMMUc].LogStartbit;
00831 EC_PRINT(" Inputs %p startbit %d\n", ec_slave[slave].inputs, ec_slave[slave].Istartbit);
00832 }
00833 FMMUc++;
00834 }
00835 ec_slave[slave].FMMUunused = FMMUc;
00836 diff = LogAddr - oLogAddr;
00837 oLogAddr = LogAddr;
00838 if ((segmentsize + diff) > (EC_MAXLRWDATA - EC_FIRSTDCDATAGRAM))
00839 {
00840 ec_group[group].IOsegment[currentsegment] = segmentsize;
00841 if (currentsegment < (EC_MAXIOSEGMENTS - 1))
00842 {
00843 currentsegment++;
00844 segmentsize = diff;
00845 }
00846 }
00847 else
00848 segmentsize += diff;
00849 }
00850
00851 ec_eeprom2pdi(slave);
00852 ec_FPWRw(configadr, ECT_REG_ALCTL, htoes(EC_STATE_SAFE_OP) , EC_TIMEOUTRET);
00853
00854 }
00855 if (BitPos)
00856 {
00857 LogAddr++;
00858 oLogAddr = LogAddr;
00859 BitPos = 0;
00860 if ((segmentsize + 1) > (EC_MAXLRWDATA - EC_FIRSTDCDATAGRAM))
00861 {
00862 ec_group[group].IOsegment[currentsegment] = segmentsize;
00863 if (currentsegment < (EC_MAXIOSEGMENTS - 1))
00864 {
00865 currentsegment++;
00866 segmentsize = 1;
00867 }
00868 }
00869 else
00870 segmentsize += 1;
00871 }
00872 ec_group[group].IOsegment[currentsegment] = segmentsize;
00873 ec_group[group].nsegments = currentsegment + 1;
00874 ec_group[group].inputs = pIOmap + ec_group[group].Obytes;
00875 ec_group[group].Ibytes = LogAddr - ec_group[group].Obytes;
00876 if (ec_slave[slave].blockLRW)
00877 ec_group[group].blockLRW++;
00878 ec_group[group].Ebuscurrent += ec_slave[slave].Ebuscurrent;
00879 if (!group)
00880 {
00881 ec_slave[0].inputs = pIOmap + ec_slave[0].Obytes;
00882 ec_slave[0].Ibytes = LogAddr - ec_slave[0].Obytes;
00883 }
00884
00885 EC_PRINT("IOmapSize %d\n", LogAddr - ec_group[group].logstartaddr);
00886 return (LogAddr - ec_group[group].logstartaddr);
00887 }
00888 return 0;
00889 }
00890
00891
00892
00893
00894
00895
00896 int ec_config_map(void *pIOmap)
00897 {
00898 return ec_config_map_group(pIOmap, 0);
00899 }
00900
00901
00902
00903
00904
00905
00906
00907 int ec_config(uint8 usetable, void *pIOmap)
00908 {
00909 int wkc;
00910 wkc = ec_config_init(usetable);
00911 if (wkc)
00912 ec_config_map(pIOmap);
00913 return wkc;
00914 }
00915
00916
00917
00918
00919
00920
00921 int ec_recover_slave(uint16 slave)
00922 {
00923 int rval;
00924 uint16 ADPh, configadr;
00925
00926 rval = 0;
00927 configadr = ec_slave[slave].configadr;
00928
00929 ec_FPWRw(EC_TEMPNODE, ECT_REG_STADR, htoes(0) , 0);
00930 ADPh = (uint16)(1 - slave);
00931
00932 if(ec_APWRw(ADPh, ECT_REG_STADR, htoes(EC_TEMPNODE) , EC_TIMEOUTRET) <= 0)
00933 return 0;
00934
00935 ec_slave[slave].configadr = EC_TEMPNODE;
00936 ec_eeprom2master(slave);
00937
00938
00939 if ((ec_FPRDw(EC_TEMPNODE, ECT_REG_ALIAS, EC_TIMEOUTRET) == ec_slave[slave].aliasadr) &&
00940 (ec_readeeprom(slave, ECT_SII_ID, EC_TIMEOUTEEP) == ec_slave[slave].eep_id) &&
00941 (ec_readeeprom(slave, ECT_SII_MANUF, EC_TIMEOUTEEP) == ec_slave[slave].eep_man) &&
00942 (ec_readeeprom(slave, ECT_SII_REV, EC_TIMEOUTEEP) == ec_slave[slave].eep_rev))
00943 {
00944 rval = ec_FPWRw(EC_TEMPNODE, ECT_REG_STADR, htoes(configadr) , EC_TIMEOUTRET);
00945 ec_slave[slave].configadr = configadr;
00946 }
00947 else
00948 {
00949
00950 ec_FPWRw(EC_TEMPNODE, ECT_REG_STADR, htoes(0) , EC_TIMEOUTRET);
00951 ec_slave[slave].configadr = configadr;
00952 }
00953
00954 return rval;
00955 }
00956
00957
00958
00959
00960
00961
00962 int ec_reconfig_slave(uint16 slave)
00963 {
00964 int state, nSM, FMMUc;
00965 uint16 configadr;
00966
00967 configadr = ec_slave[slave].configadr;
00968 if (ec_FPWRw(configadr, ECT_REG_ALCTL, htoes(EC_STATE_INIT) , EC_TIMEOUTRET) <= 0)
00969 return 0;
00970 state = 0;
00971 ec_eeprom2pdi(slave);
00972
00973 state = ec_statecheck(slave, EC_STATE_INIT, EC_TIMEOUTSTATE);
00974 if(state == EC_STATE_INIT)
00975 {
00976
00977 for( nSM = 0 ; nSM < EC_MAXSM ; nSM++ )
00978 {
00979 if (ec_slave[slave].SM[nSM].StartAddr)
00980 ec_FPWR (configadr, ECT_REG_SM0 + (nSM * sizeof(ec_smt)), sizeof(ec_smt),
00981 &ec_slave[slave].SM[nSM], EC_TIMEOUTRET);
00982 }
00983
00984 for( FMMUc = 0 ; FMMUc < ec_slave[slave].FMMUunused ; FMMUc++ )
00985 {
00986 ec_FPWR (configadr, ECT_REG_FMMU0 + (sizeof(ec_fmmut) * FMMUc), sizeof(ec_fmmut),
00987 &ec_slave[slave].FMMU[FMMUc], EC_TIMEOUTRET);
00988 }
00989 ec_FPWRw(configadr, ECT_REG_ALCTL, htoes(EC_STATE_PRE_OP) , EC_TIMEOUTRET);
00990 state = ec_statecheck(slave, EC_STATE_PRE_OP, EC_TIMEOUTSTATE);
00991 if( state == EC_STATE_PRE_OP)
00992 {
00993 ec_FPWRw(configadr, ECT_REG_ALCTL, htoes(EC_STATE_SAFE_OP) , EC_TIMEOUTRET);
00994 state = ec_statecheck(slave, EC_STATE_SAFE_OP, EC_TIMEOUTSTATE);
00995 }
00996 }
00997 return state;
00998 }