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
00046 #include <youbot_driver/soem/ethercattype.h>
00047 #include <youbot_driver/soem/nicdrv.h>
00048 #include <youbot_driver/soem/ethercatbase.h>
00049 #include <youbot_driver/soem/ethercatmain.h>
00050 #include <youbot_driver/soem/ethercatdc.h>
00051
00052 #define PORTM0 0x01
00053 #define PORTM1 0x02
00054 #define PORTM2 0x04
00055 #define PORTM3 0x08
00056
00058 #define SyncDelay ((int32)100000000)
00059
00068 void ec_dcsync0(uint16 slave, boolean act, uint32 CyclTime, uint32 CyclShift)
00069 {
00070 uint8 h, RA;
00071 uint16 slaveh;
00072 int64 t, t1;
00073 int32 tc;
00074
00075 slaveh = ec_slave[slave].configadr;
00076 RA = 0;
00077
00078
00079 ec_FPWR(slaveh, ECT_REG_DCSYNCACT, sizeof(RA), &RA, EC_TIMEOUTRET);
00080 if (act)
00081 {
00082 RA = 1 + 2;
00083 }
00084 h = 0;
00085 ec_FPWR(slaveh, ECT_REG_DCCUC, sizeof(h), &h, EC_TIMEOUTRET);
00086 ec_FPRD(slaveh, ECT_REG_DCSYSTIME, sizeof(t1), &t1, EC_TIMEOUTRET);
00087 t1 = etohll(t1);
00088
00089
00090
00091
00092
00093 if (CyclTime > 0)
00094 {
00095 t = ((t1 + SyncDelay )/ CyclTime) * CyclTime + CyclTime + CyclShift;
00096 }
00097 else
00098 {
00099 t = t1 + SyncDelay + CyclShift;
00100
00101 }
00102 t = htoell(t);
00103 ec_FPWR(slaveh, ECT_REG_DCSTART0, sizeof(t), &t, EC_TIMEOUTRET);
00104 tc = htoel(CyclTime);
00105 ec_FPWR(slaveh, ECT_REG_DCCYCLE0, sizeof(tc), &tc, EC_TIMEOUTRET);
00106 ec_FPWR(slaveh, ECT_REG_DCSYNCACT, sizeof(RA), &RA, EC_TIMEOUTRET);
00107 }
00108
00120 void ec_dcsync01(uint16 slave, boolean act, uint32 CyclTime0, uint32 CyclTime1, uint32 CyclShift)
00121 {
00122 uint8 h, RA;
00123 uint16 slaveh;
00124 int64 t, t1;
00125 int32 tc;
00126
00127 slaveh = ec_slave[slave].configadr;
00128 RA = 0;
00129
00130
00131 ec_FPWR(slaveh, ECT_REG_DCSYNCACT, sizeof(RA), &RA, EC_TIMEOUTRET);
00132 if (act)
00133 {
00134 RA = 1 + 2 + 4;
00135 }
00136 h = 0;
00137 ec_FPWR(slaveh, ECT_REG_DCCUC, sizeof(h), &h, EC_TIMEOUTRET);
00138 ec_FPRD(slaveh, ECT_REG_DCSYSTIME, sizeof(t1), &t1, EC_TIMEOUTRET);
00139 t1 = etohll(t1);
00140
00141
00142
00143
00144
00145 if (CyclTime0 > 0)
00146 {
00147 t = ((t1 + SyncDelay )/ CyclTime0) * CyclTime0 + CyclTime0 + CyclShift;
00148 }
00149 else
00150 {
00151 t = t1 + SyncDelay + CyclShift;
00152
00153 }
00154 t = htoell(t);
00155 ec_FPWR(slaveh, ECT_REG_DCSTART0, sizeof(t), &t, EC_TIMEOUTRET);
00156 tc = htoel(CyclTime0);
00157 ec_FPWR(slaveh, ECT_REG_DCCYCLE0, sizeof(tc), &tc, EC_TIMEOUTRET);
00158 tc = htoel(CyclTime1);
00159 ec_FPWR(slaveh, ECT_REG_DCCYCLE1, sizeof(tc), &tc, EC_TIMEOUTRET);
00160 ec_FPWR(slaveh, ECT_REG_DCSYNCACT, sizeof(RA), &RA, EC_TIMEOUTRET);
00161 }
00162
00163
00164 int32 ec_porttime(uint16 slave, uint8 port)
00165 {
00166 int32 ts;
00167 switch (port)
00168 {
00169 case 0:
00170 ts = ec_slave[slave].DCrtA;
00171 break;
00172 case 1:
00173 ts = ec_slave[slave].DCrtB;
00174 break;
00175 case 2:
00176 ts = ec_slave[slave].DCrtC;
00177 break;
00178 case 3:
00179 ts = ec_slave[slave].DCrtD;
00180 break;
00181 default:
00182 ts = 0;
00183 }
00184 return ts;
00185 }
00186
00187
00188 uint8 ec_prevport(uint16 slave, uint8 port)
00189 {
00190 uint8 pport = port;
00191 uint8 aport = ec_slave[slave].activeports;
00192 switch (port)
00193 {
00194 case 0:
00195 if (aport & PORTM2)
00196 pport = 2;
00197 else if (aport & PORTM1)
00198 pport = 1;
00199 else if (aport & PORTM2)
00200 pport = 3;
00201 break;
00202 case 1:
00203 if (aport & PORTM3)
00204 pport = 3;
00205 else if (aport & PORTM0)
00206 pport = 0;
00207 else if (aport & PORTM2)
00208 pport = 2;
00209 break;
00210 case 2:
00211 if (aport & PORTM1)
00212 pport = 1;
00213 else if (aport & PORTM3)
00214 pport = 3;
00215 else if (aport & PORTM0)
00216 pport = 0;
00217 break;
00218 case 3:
00219 if (aport & PORTM0)
00220 pport = 0;
00221 else if (aport & PORTM2)
00222 pport = 2;
00223 else if (aport & PORTM1)
00224 pport = 1;
00225 break;
00226 }
00227 return pport;
00228 }
00229
00230
00231 uint8 ec_parentport(uint16 parent)
00232 {
00233 uint8 parentport = 0;
00234 uint8 b;
00235
00236 b = ec_slave[parent].consumedports;
00237 if (b & PORTM3)
00238 {
00239 parentport = 3;
00240 b &= (uint8)~PORTM3;
00241 }
00242 else if (b & PORTM1)
00243 {
00244 parentport = 1;
00245 b &= (uint8)~PORTM1;
00246 }
00247 else if (b & PORTM2)
00248 {
00249 parentport = 2;
00250 b &= (uint8)~PORTM2;
00251 }
00252 else if (b & PORTM0)
00253 {
00254 parentport = 0;
00255 b &= (uint8)~PORTM0;
00256 }
00257 ec_slave[parent].consumedports = b;
00258 return parentport;
00259 }
00260
00266 boolean ec_configdc(void)
00267 {
00268 uint16 i, slaveh, parent, child;
00269 uint16 parenthold = 0;
00270 uint16 prevDCslave = 0;
00271 int32 ht, dt1, dt2, dt3;
00272 int64 hrt;
00273 uint8 entryport;
00274 int8 nlist;
00275 int8 plist[4];
00276 int32 tlist[4];
00277
00278 ec_slave[0].hasdc = FALSE;
00279 ec_group[0].hasdc = FALSE;
00280 ht = 0;
00281 ec_BWR(0, ECT_REG_DCTIME0, sizeof(ht), &ht, EC_TIMEOUTRET);
00282 for (i = 1; i <= ec_slavecount; i++)
00283 {
00284 ec_slave[i].consumedports = ec_slave[i].activeports;
00285 if (ec_slave[i].hasdc)
00286 {
00287 if (!ec_slave[0].hasdc)
00288 {
00289 ec_slave[0].hasdc = TRUE;
00290 ec_slave[0].DCnext = i;
00291 ec_slave[i].DCprevious = 0;
00292 ec_group[0].hasdc = TRUE;
00293 ec_group[0].DCnext = i;
00294 }
00295 else
00296 {
00297 ec_slave[prevDCslave].DCnext = i;
00298 ec_slave[i].DCprevious = prevDCslave;
00299 }
00300
00301 parenthold = 0;
00302 prevDCslave = i;
00303 slaveh = ec_slave[i].configadr;
00304 ec_FPRD(slaveh, ECT_REG_DCTIME0, sizeof(ht), &ht, EC_TIMEOUTRET);
00305 ec_slave[i].DCrtA = etohl(ht);
00306
00307 ec_FPRD(slaveh, ECT_REG_DCSOF, sizeof(hrt), &hrt, EC_TIMEOUTRET);
00308
00309 hrt = htoell(-etohll(hrt));
00310
00311 ec_FPWR(slaveh, ECT_REG_DCSYSOFFSET, sizeof(hrt), &hrt, EC_TIMEOUTRET);
00312 ec_FPRD(slaveh, ECT_REG_DCTIME1, sizeof(ht), &ht, EC_TIMEOUTRET);
00313 ec_slave[i].DCrtB = etohl(ht);
00314 ec_FPRD(slaveh, ECT_REG_DCTIME2, sizeof(ht), &ht, EC_TIMEOUTRET);
00315 ec_slave[i].DCrtC = etohl(ht);
00316 ec_FPRD(slaveh, ECT_REG_DCTIME3, sizeof(ht), &ht, EC_TIMEOUTRET);
00317 ec_slave[i].DCrtD = etohl(ht);
00318
00319
00320 nlist = 0;
00321 if (ec_slave[i].activeports & PORTM0)
00322 {
00323 plist[nlist] = 0;
00324 tlist[nlist] = ec_slave[i].DCrtA;
00325 nlist++;
00326 }
00327 if (ec_slave[i].activeports & PORTM3)
00328 {
00329 plist[nlist] = 3;
00330 tlist[nlist] = ec_slave[i].DCrtD;
00331 nlist++;
00332 }
00333 if (ec_slave[i].activeports & PORTM1)
00334 {
00335 plist[nlist] = 1;
00336 tlist[nlist] = ec_slave[i].DCrtB;
00337 nlist++;
00338 }
00339 if (ec_slave[i].activeports & PORTM2)
00340 {
00341 plist[nlist] = 2;
00342 tlist[nlist] = ec_slave[i].DCrtC;
00343 nlist++;
00344 }
00345
00346 entryport = 0;
00347 if ((nlist > 1) && (tlist[1] < tlist[entryport]))
00348 {
00349 entryport = 1;
00350 }
00351 if ((nlist > 2) && (tlist[2] < tlist[entryport]))
00352 {
00353 entryport = 2;
00354 }
00355 if ((nlist > 3) && (tlist[3] < tlist[entryport]))
00356 {
00357 entryport = 3;
00358 }
00359 entryport = plist[entryport];
00360 ec_slave[i].entryport = entryport;
00361
00362 ec_slave[i].consumedports &= (uint8)~(1 << entryport);
00363
00364
00365 parent = i;
00366 do
00367 {
00368 child = parent;
00369 parent = ec_slave[parent].parent;
00370 } while (!((parent == 0) || (ec_slave[parent].hasdc)));
00371
00372 if (parent > 0)
00373 {
00374
00375 ec_slave[i].parentport = ec_parentport(parent);
00376 if (ec_slave[parent].topology == 1)
00377 {
00378 ec_slave[i].parentport = ec_slave[parent].entryport;
00379 }
00380
00381 dt1 = 0;
00382 dt2 = 0;
00383
00384
00385
00386 dt3 = ec_porttime(parent, ec_slave[i].parentport)
00387 - ec_porttime(parent, ec_prevport(parent, ec_slave[i].parentport));
00388
00389
00390 if (ec_slave[i].topology > 1)
00391 {
00392 dt1 = ec_porttime(i, ec_prevport(i, ec_slave[i].entryport)) - ec_porttime(i, ec_slave[i].entryport);
00393 }
00394
00395 if (dt1 > dt3)
00396 dt1 = -dt1;
00397
00398
00399 if ((child - parent) > 1)
00400 {
00401 dt2 = ec_porttime(parent, ec_prevport(parent, ec_slave[i].parentport))
00402 - ec_porttime(parent, ec_slave[parent].entryport);
00403 }
00404 if (dt2 < 0)
00405 dt2 = -dt2;
00406
00407
00408
00409 ec_slave[i].pdelay = ((dt3 - dt1) / 2) + dt2 + ec_slave[parent].pdelay;
00410 ht = htoel(ec_slave[i].pdelay);
00411
00412
00413 ec_FPWR(slaveh, ECT_REG_DCSYSDELAY, sizeof(ht), &ht, EC_TIMEOUTRET);
00414 }
00415 }
00416 else
00417 {
00418 ec_slave[i].DCrtA = 0;
00419 ec_slave[i].DCrtB = 0;
00420 ec_slave[i].DCrtC = 0;
00421 ec_slave[i].DCrtD = 0;
00422 parent = ec_slave[i].parent;
00423
00424 if ((parent > 0) && (ec_slave[parent].topology > 2))
00425 parenthold = parent;
00426
00427 if (parenthold && (ec_slave[i].topology == 1))
00428 {
00429 ec_parentport(parenthold);
00430 parenthold = 0;
00431 }
00432 }
00433 }
00434
00435 return ec_slave[0].hasdc;
00436 }