75 static int ec_master_idle_thread(void *); |
75 static int ec_master_idle_thread(void *); |
76 static int ec_master_operation_thread(void *); |
76 static int ec_master_operation_thread(void *); |
77 #ifdef EC_EOE |
77 #ifdef EC_EOE |
78 void ec_master_eoe_run(unsigned long); |
78 void ec_master_eoe_run(unsigned long); |
79 #endif |
79 #endif |
|
80 void ec_master_find_dc_ref_clock(ec_master_t *); |
80 |
81 |
81 /*****************************************************************************/ |
82 /*****************************************************************************/ |
82 |
83 |
83 /** Static variables initializer. |
84 /** Static variables initializer. |
84 */ |
85 */ |
1355 */ |
1358 */ |
1356 void ec_master_find_dc_ref_clock( |
1359 void ec_master_find_dc_ref_clock( |
1357 ec_master_t *master /**< EtherCAT master. */ |
1360 ec_master_t *master /**< EtherCAT master. */ |
1358 ) |
1361 ) |
1359 { |
1362 { |
1360 ec_slave_t *slave; |
1363 ec_slave_t *slave, *ref = NULL; |
1361 uint16_t ref_clock_addr = 0xffff; |
|
1362 |
1364 |
1363 for (slave = master->slaves; |
1365 for (slave = master->slaves; |
1364 slave < master->slaves + master->slave_count; |
1366 slave < master->slaves + master->slave_count; |
1365 slave++) { |
1367 slave++) { |
1366 if (slave->base_dc_supported && slave->has_dc_system_time) { |
1368 if (slave->base_dc_supported && slave->has_dc_system_time) { |
1367 ref_clock_addr = slave->station_address; |
1369 ref = slave; |
1368 break; |
1370 break; |
1369 } |
1371 } |
1370 } |
1372 } |
1371 |
1373 |
1372 // This call always succeeds, because the datagram has been pre-allocated. |
1374 master->dc_ref_clock = ref; |
1373 ec_datagram_frmw(&master->sync_datagram, ref_clock_addr, 0x0910, 4); |
1375 |
|
1376 // This call always succeeds, because the datagram has been pre-allocated. |
|
1377 ec_datagram_frmw(&master->sync_datagram, |
|
1378 ref ? ref->station_address : 0xffff, 0x0910, 4); |
1374 } |
1379 } |
1375 |
1380 |
1376 /*****************************************************************************/ |
1381 /*****************************************************************************/ |
1377 |
1382 |
1378 /** Calculates the bus topology; recursion function. |
1383 /** Calculates the bus topology; recursion function. |
1385 { |
1390 { |
1386 ec_slave_t *slave = master->slaves + *slave_position; |
1391 ec_slave_t *slave = master->slaves + *slave_position; |
1387 unsigned int i; |
1392 unsigned int i; |
1388 int ret; |
1393 int ret; |
1389 |
1394 |
1390 slave->next_slave[0] = port0_slave; |
1395 slave->ports[0].next_slave = port0_slave; |
1391 |
1396 |
1392 for (i = 1; i < EC_MAX_PORTS; i++) { |
1397 for (i = 1; i < EC_MAX_PORTS; i++) { |
1393 if (!slave->ports[i].dl_loop) { |
1398 if (!slave->ports[i].link.loop_closed) { |
1394 *slave_position = *slave_position + 1; |
1399 *slave_position = *slave_position + 1; |
1395 if (*slave_position < master->slave_count) { |
1400 if (*slave_position < master->slave_count) { |
1396 slave->next_slave[i] = master->slaves + *slave_position; |
1401 slave->ports[i].next_slave = master->slaves + *slave_position; |
1397 ret = ec_master_calc_topology_rec(master, |
1402 ret = ec_master_calc_topology_rec(master, |
1398 slave, slave_position); |
1403 slave, slave_position); |
1399 if (ret) |
1404 if (ret) |
1400 return ret; |
1405 return ret; |
1401 } else { |
1406 } else { |
1420 if (master->slave_count == 0) |
1425 if (master->slave_count == 0) |
1421 return; |
1426 return; |
1422 |
1427 |
1423 if (ec_master_calc_topology_rec(master, NULL, &slave_position)) |
1428 if (ec_master_calc_topology_rec(master, NULL, &slave_position)) |
1424 EC_ERR("Failed to calculate bus topology.\n"); |
1429 EC_ERR("Failed to calculate bus topology.\n"); |
|
1430 } |
|
1431 |
|
1432 /*****************************************************************************/ |
|
1433 |
|
1434 /** Calculates the bus transition delays. |
|
1435 */ |
|
1436 void ec_master_calc_transition_delays( |
|
1437 ec_master_t *master /**< EtherCAT master. */ |
|
1438 ) |
|
1439 { |
|
1440 ec_slave_t *slave; |
|
1441 |
|
1442 for (slave = master->slaves; |
|
1443 slave < master->slaves + master->slave_count; |
|
1444 slave++) { |
|
1445 ec_slave_calc_port_delays(slave); |
|
1446 } |
|
1447 |
|
1448 if (master->dc_ref_clock) { |
|
1449 uint32_t delay = 0; |
|
1450 ec_slave_calc_transition_delays_rec(master->dc_ref_clock, &delay); |
|
1451 } |
|
1452 } |
|
1453 |
|
1454 /*****************************************************************************/ |
|
1455 |
|
1456 /** Distributed-clocks calculations. |
|
1457 */ |
|
1458 void ec_master_calc_dc( |
|
1459 ec_master_t *master /**< EtherCAT master. */ |
|
1460 ) |
|
1461 { |
|
1462 // find DC reference clock |
|
1463 ec_master_find_dc_ref_clock(master); |
|
1464 |
|
1465 // calculate bus topology |
|
1466 ec_master_calc_topology(master); |
|
1467 |
|
1468 ec_master_calc_transition_delays(master); |
1425 } |
1469 } |
1426 |
1470 |
1427 /****************************************************************************** |
1471 /****************************************************************************** |
1428 * Application interface |
1472 * Application interface |
1429 *****************************************************************************/ |
1473 *****************************************************************************/ |