master/master.c
changeset 1425 c1322a8793c0
parent 1421 043a518831b2
child 1426 af45bba80d85
equal deleted inserted replaced
1424:cb02dbe4076f 1425:c1322a8793c0
    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 */
   340  */
   341  */
   341 void ec_master_clear_slaves(ec_master_t *master)
   342 void ec_master_clear_slaves(ec_master_t *master)
   342 {
   343 {
   343     ec_slave_t *slave;
   344     ec_slave_t *slave;
   344 
   345 
       
   346     master->dc_ref_clock = NULL;
       
   347 
   345     for (slave = master->slaves;
   348     for (slave = master->slaves;
   346             slave < master->slaves + master->slave_count;
   349             slave < master->slaves + master->slave_count;
   347             slave++) {
   350             slave++) {
   348         ec_slave_clear(slave);
   351         ec_slave_clear(slave);
   349     }
   352     }
  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  *****************************************************************************/