master/master.c
changeset 1507 68e89abadd19
parent 1500 ed1a733efbc5
child 1513 60ca68d853b8
child 1579 326d47aa986c
equal deleted inserted replaced
1506:41ca84fb6bb2 1507:68e89abadd19
   127     master->slaves = NULL;
   127     master->slaves = NULL;
   128     master->slave_count = 0;
   128     master->slave_count = 0;
   129     
   129     
   130     INIT_LIST_HEAD(&master->configs);
   130     INIT_LIST_HEAD(&master->configs);
   131 
   131 
   132 	master->app_time = 0ULL;
   132     master->app_time = 0ULL;
   133 	master->app_start_time = 0ULL;
   133     master->app_start_time = 0ULL;
   134 	master->has_start_time = 0;
   134     master->has_start_time = 0;
   135 
   135 
   136     master->scan_busy = 0;
   136     master->scan_busy = 0;
   137     master->allow_scan = 1;
   137     master->allow_scan = 1;
   138     init_MUTEX(&master->scan_sem);
   138     init_MUTEX(&master->scan_sem);
   139     init_waitqueue_head(&master->scan_queue);
   139     init_waitqueue_head(&master->scan_queue);
   222     if (ret < 0) {
   222     if (ret < 0) {
   223         ec_datagram_clear(&master->sync_datagram);
   223         ec_datagram_clear(&master->sync_datagram);
   224         EC_ERR("Failed to allocate synchronisation datagram.\n");
   224         EC_ERR("Failed to allocate synchronisation datagram.\n");
   225         goto out_clear_ref_sync;
   225         goto out_clear_ref_sync;
   226     }
   226     }
   227 	ec_master_find_dc_ref_clock(master);
   227     ec_master_find_dc_ref_clock(master);
   228 
   228 
   229     // init character device
   229     // init character device
   230     ret = ec_cdev_init(&master->cdev, master, device_number);
   230     ret = ec_cdev_init(&master->cdev, master, device_number);
   231     if (ret)
   231     if (ret)
   232         goto out_clear_sync;
   232         goto out_clear_sync;
  1255 /** Get the number of slave configurations provided by the application.
  1255 /** Get the number of slave configurations provided by the application.
  1256  *
  1256  *
  1257  * \return Number of configurations.
  1257  * \return Number of configurations.
  1258  */
  1258  */
  1259 unsigned int ec_master_config_count(
  1259 unsigned int ec_master_config_count(
  1260 		const ec_master_t *master /**< EtherCAT master. */
  1260         const ec_master_t *master /**< EtherCAT master. */
  1261 		)
  1261         )
  1262 {
  1262 {
  1263 	const ec_slave_config_t *sc;
  1263     const ec_slave_config_t *sc;
  1264 	unsigned int count = 0;
  1264     unsigned int count = 0;
  1265 
  1265 
  1266 	list_for_each_entry(sc, &master->configs, list) {
  1266     list_for_each_entry(sc, &master->configs, list) {
  1267 		count++;
  1267         count++;
  1268 	}
  1268     }
  1269 
  1269 
  1270 	return count;
  1270     return count;
  1271 }
  1271 }
  1272 
  1272 
  1273 /*****************************************************************************/
  1273 /*****************************************************************************/
  1274 
  1274 
  1275 /** Common implementation for ec_master_get_config()
  1275 /** Common implementation for ec_master_get_config()
  1276  * and ec_master_get_config_const().
  1276  * and ec_master_get_config_const().
  1277  */
  1277  */
  1278 #define EC_FIND_CONFIG \
  1278 #define EC_FIND_CONFIG \
  1279     do { \
  1279     do { \
  1280 		list_for_each_entry(sc, &master->configs, list) { \
  1280         list_for_each_entry(sc, &master->configs, list) { \
  1281 			if (pos--) \
  1281             if (pos--) \
  1282 				continue; \
  1282                 continue; \
  1283 			return sc; \
  1283             return sc; \
  1284 		} \
  1284         } \
  1285 		return NULL; \
  1285         return NULL; \
  1286     } while (0)
  1286     } while (0)
  1287 
  1287 
  1288 /** Get a slave configuration via its position in the list.
  1288 /** Get a slave configuration via its position in the list.
  1289  *
  1289  *
  1290  * \return Slave configuration or \a NULL.
  1290  * \return Slave configuration or \a NULL.
  1291  */
  1291  */
  1292 ec_slave_config_t *ec_master_get_config(
  1292 ec_slave_config_t *ec_master_get_config(
  1293 		const ec_master_t *master, /**< EtherCAT master. */
  1293         const ec_master_t *master, /**< EtherCAT master. */
  1294 		unsigned int pos /**< List position. */
  1294         unsigned int pos /**< List position. */
  1295 		)
  1295         )
  1296 {
  1296 {
  1297 	ec_slave_config_t *sc;
  1297     ec_slave_config_t *sc;
  1298 	EC_FIND_CONFIG;
  1298     EC_FIND_CONFIG;
  1299 }
  1299 }
  1300 
  1300 
  1301 /** Get a slave configuration via its position in the list.
  1301 /** Get a slave configuration via its position in the list.
  1302  *
  1302  *
  1303  * Const version.
  1303  * Const version.
  1304  *
  1304  *
  1305  * \return Slave configuration or \a NULL.
  1305  * \return Slave configuration or \a NULL.
  1306  */
  1306  */
  1307 const ec_slave_config_t *ec_master_get_config_const(
  1307 const ec_slave_config_t *ec_master_get_config_const(
  1308 		const ec_master_t *master, /**< EtherCAT master. */
  1308         const ec_master_t *master, /**< EtherCAT master. */
  1309 		unsigned int pos /**< List position. */
  1309         unsigned int pos /**< List position. */
  1310 		)
  1310         )
  1311 {
  1311 {
  1312 	const ec_slave_config_t *sc;
  1312     const ec_slave_config_t *sc;
  1313 	EC_FIND_CONFIG;
  1313     EC_FIND_CONFIG;
  1314 }
  1314 }
  1315 
  1315 
  1316 /*****************************************************************************/
  1316 /*****************************************************************************/
  1317 
  1317 
  1318 /** Get the number of domains.
  1318 /** Get the number of domains.
  1319  *
  1319  *
  1320  * \return Number of domains.
  1320  * \return Number of domains.
  1321  */
  1321  */
  1322 unsigned int ec_master_domain_count(
  1322 unsigned int ec_master_domain_count(
  1323 		const ec_master_t *master /**< EtherCAT master. */
  1323         const ec_master_t *master /**< EtherCAT master. */
  1324 		)
  1324         )
  1325 {
  1325 {
  1326 	const ec_domain_t *domain;
  1326     const ec_domain_t *domain;
  1327 	unsigned int count = 0;
  1327     unsigned int count = 0;
  1328 
  1328 
  1329 	list_for_each_entry(domain, &master->domains, list) {
  1329     list_for_each_entry(domain, &master->domains, list) {
  1330 		count++;
  1330         count++;
  1331 	}
  1331     }
  1332 
  1332 
  1333 	return count;
  1333     return count;
  1334 }
  1334 }
  1335 
  1335 
  1336 /*****************************************************************************/
  1336 /*****************************************************************************/
  1337 
  1337 
  1338 /** Common implementation for ec_master_find_domain() and
  1338 /** Common implementation for ec_master_find_domain() and
  1352 /** Get a domain via its position in the list.
  1352 /** Get a domain via its position in the list.
  1353  *
  1353  *
  1354  * \return Domain pointer, or \a NULL if not found.
  1354  * \return Domain pointer, or \a NULL if not found.
  1355  */
  1355  */
  1356 ec_domain_t *ec_master_find_domain(
  1356 ec_domain_t *ec_master_find_domain(
  1357 		ec_master_t *master, /**< EtherCAT master. */
  1357         ec_master_t *master, /**< EtherCAT master. */
  1358 		unsigned int index /**< Domain index. */
  1358         unsigned int index /**< Domain index. */
  1359 		)
  1359         )
  1360 {
  1360 {
  1361 	ec_domain_t *domain;
  1361     ec_domain_t *domain;
  1362     EC_FIND_DOMAIN;
  1362     EC_FIND_DOMAIN;
  1363 }
  1363 }
  1364 
  1364 
  1365 /** Get a domain via its position in the list.
  1365 /** Get a domain via its position in the list.
  1366  *
  1366  *
  1367  * Const version.
  1367  * Const version.
  1368  *
  1368  *
  1369  * \return Domain pointer, or \a NULL if not found.
  1369  * \return Domain pointer, or \a NULL if not found.
  1370  */
  1370  */
  1371 const ec_domain_t *ec_master_find_domain_const(
  1371 const ec_domain_t *ec_master_find_domain_const(
  1372 		const ec_master_t *master, /**< EtherCAT master. */
  1372         const ec_master_t *master, /**< EtherCAT master. */
  1373 		unsigned int index /**< Domain index. */
  1373         unsigned int index /**< Domain index. */
  1374 		)
  1374         )
  1375 {
  1375 {
  1376 	const ec_domain_t *domain;
  1376     const ec_domain_t *domain;
  1377     EC_FIND_DOMAIN;
  1377     EC_FIND_DOMAIN;
  1378 }
  1378 }
  1379 
  1379 
  1380 /*****************************************************************************/
  1380 /*****************************************************************************/
  1381 
  1381 
  1382 /** Get the number of EoE handlers.
  1382 /** Get the number of EoE handlers.
  1383  *
  1383  *
  1384  * \return Number of EoE handlers.
  1384  * \return Number of EoE handlers.
  1385  */
  1385  */
  1386 uint16_t ec_master_eoe_handler_count(
  1386 uint16_t ec_master_eoe_handler_count(
  1387 		const ec_master_t *master /**< EtherCAT master. */
  1387         const ec_master_t *master /**< EtherCAT master. */
  1388 		)
  1388         )
  1389 {
  1389 {
  1390 	const ec_eoe_t *eoe;
  1390     const ec_eoe_t *eoe;
  1391 	unsigned int count = 0;
  1391     unsigned int count = 0;
  1392 
  1392 
  1393 	list_for_each_entry(eoe, &master->eoe_handlers, list) {
  1393     list_for_each_entry(eoe, &master->eoe_handlers, list) {
  1394 		count++;
  1394         count++;
  1395 	}
  1395     }
  1396 
  1396 
  1397 	return count;
  1397     return count;
  1398 }
  1398 }
  1399 
  1399 
  1400 /*****************************************************************************/
  1400 /*****************************************************************************/
  1401 
  1401 
  1402 /** Get an EoE handler via its position in the list.
  1402 /** Get an EoE handler via its position in the list.
  1404  * Const version.
  1404  * Const version.
  1405  *
  1405  *
  1406  * \return EoE handler pointer, or \a NULL if not found.
  1406  * \return EoE handler pointer, or \a NULL if not found.
  1407  */
  1407  */
  1408 const ec_eoe_t *ec_master_get_eoe_handler_const(
  1408 const ec_eoe_t *ec_master_get_eoe_handler_const(
  1409 		const ec_master_t *master, /**< EtherCAT master. */
  1409         const ec_master_t *master, /**< EtherCAT master. */
  1410 		uint16_t index /**< EoE handler index. */
  1410         uint16_t index /**< EoE handler index. */
  1411 		)
  1411         )
  1412 {
  1412 {
  1413 	const ec_eoe_t *eoe;
  1413     const ec_eoe_t *eoe;
  1414 
  1414 
  1415 	list_for_each_entry(eoe, &master->eoe_handlers, list) {
  1415     list_for_each_entry(eoe, &master->eoe_handlers, list) {
  1416 		if (index--)
  1416         if (index--)
  1417 			continue;
  1417             continue;
  1418 		return eoe;
  1418         return eoe;
  1419 	}
  1419     }
  1420 
  1420 
  1421 	return NULL;
  1421     return NULL;
  1422 }
  1422 }
  1423 
  1423 
  1424 /*****************************************************************************/
  1424 /*****************************************************************************/
  1425 
  1425 
  1426 /** Set the debug level.
  1426 /** Set the debug level.
  1450 
  1450 
  1451 /** Finds the DC reference clock.
  1451 /** Finds the DC reference clock.
  1452  */
  1452  */
  1453 void ec_master_find_dc_ref_clock(
  1453 void ec_master_find_dc_ref_clock(
  1454         ec_master_t *master /**< EtherCAT master. */
  1454         ec_master_t *master /**< EtherCAT master. */
  1455 		)
  1455         )
  1456 {
  1456 {
  1457 	ec_slave_t *slave, *ref = NULL;
  1457     ec_slave_t *slave, *ref = NULL;
  1458 
  1458 
  1459     for (slave = master->slaves;
  1459     for (slave = master->slaves;
  1460             slave < master->slaves + master->slave_count;
  1460             slave < master->slaves + master->slave_count;
  1461             slave++) {
  1461             slave++) {
  1462         if (slave->base_dc_supported && slave->has_dc_system_time) {
  1462         if (slave->base_dc_supported && slave->has_dc_system_time) {
  1478  */
  1478  */
  1479 int ec_master_calc_topology_rec(
  1479 int ec_master_calc_topology_rec(
  1480         ec_master_t *master, /**< EtherCAT master. */
  1480         ec_master_t *master, /**< EtherCAT master. */
  1481         ec_slave_t *port0_slave, /**< Slave at port 0. */
  1481         ec_slave_t *port0_slave, /**< Slave at port 0. */
  1482         unsigned int *slave_position /**< Slave position. */
  1482         unsigned int *slave_position /**< Slave position. */
  1483 		)
  1483         )
  1484 {
  1484 {
  1485     ec_slave_t *slave = master->slaves + *slave_position;
  1485     ec_slave_t *slave = master->slaves + *slave_position;
  1486     unsigned int i;
  1486     unsigned int i;
  1487     int ret;
  1487     int ret;
  1488 
  1488 
  1510 
  1510 
  1511 /** Calculates the bus topology.
  1511 /** Calculates the bus topology.
  1512  */
  1512  */
  1513 void ec_master_calc_topology(
  1513 void ec_master_calc_topology(
  1514         ec_master_t *master /**< EtherCAT master. */
  1514         ec_master_t *master /**< EtherCAT master. */
  1515 		)
  1515         )
  1516 {
  1516 {
  1517     unsigned int slave_position = 0;
  1517     unsigned int slave_position = 0;
  1518 
  1518 
  1519     if (master->slave_count == 0)
  1519     if (master->slave_count == 0)
  1520         return;
  1520         return;
  1527 
  1527 
  1528 /** Calculates the bus transmission delays.
  1528 /** Calculates the bus transmission delays.
  1529  */
  1529  */
  1530 void ec_master_calc_transmission_delays(
  1530 void ec_master_calc_transmission_delays(
  1531         ec_master_t *master /**< EtherCAT master. */
  1531         ec_master_t *master /**< EtherCAT master. */
  1532 		)
  1532         )
  1533 {
  1533 {
  1534 	ec_slave_t *slave;
  1534     ec_slave_t *slave;
  1535 
  1535 
  1536     for (slave = master->slaves;
  1536     for (slave = master->slaves;
  1537             slave < master->slaves + master->slave_count;
  1537             slave < master->slaves + master->slave_count;
  1538             slave++) {
  1538             slave++) {
  1539         ec_slave_calc_port_delays(slave);
  1539         ec_slave_calc_port_delays(slave);
  1549 
  1549 
  1550 /** Distributed-clocks calculations.
  1550 /** Distributed-clocks calculations.
  1551  */
  1551  */
  1552 void ec_master_calc_dc(
  1552 void ec_master_calc_dc(
  1553         ec_master_t *master /**< EtherCAT master. */
  1553         ec_master_t *master /**< EtherCAT master. */
  1554 		)
  1554         )
  1555 {
  1555 {
  1556 	// find DC reference clock
  1556     // find DC reference clock
  1557 	ec_master_find_dc_ref_clock(master);
  1557     ec_master_find_dc_ref_clock(master);
  1558 
  1558 
  1559     // calculate bus topology
  1559     // calculate bus topology
  1560     ec_master_calc_topology(master);
  1560     ec_master_calc_topology(master);
  1561 
  1561 
  1562     ec_master_calc_transmission_delays(master);
  1562     ec_master_calc_transmission_delays(master);