1 /****************************************************************************** |
1 /****************************************************************************** |
2 * |
|
3 * m a s t e r . c |
|
4 * |
|
5 * EtherCAT master methods. |
|
6 * |
2 * |
7 * $Id$ |
3 * $Id$ |
8 * |
4 * |
|
5 * Copyright (C) 2006 Florian Pose, Ingenieurgemeinschaft IgH |
|
6 * |
|
7 * This file is part of the IgH EtherCAT Master. |
|
8 * |
|
9 * The IgH EtherCAT Master is free software; you can redistribute it |
|
10 * and/or modify it under the terms of the GNU General Public License |
|
11 * as published by the Free Software Foundation; version 2 of the License. |
|
12 * |
|
13 * The IgH EtherCAT Master is distributed in the hope that it will be |
|
14 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
16 * GNU General Public License for more details. |
|
17 * |
|
18 * You should have received a copy of the GNU General Public License |
|
19 * along with the IgH EtherCAT Master; if not, write to the Free Software |
|
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|
21 * |
9 *****************************************************************************/ |
22 *****************************************************************************/ |
|
23 |
|
24 /** |
|
25 \file |
|
26 EtherCAT master methods. |
|
27 */ |
|
28 |
|
29 /*****************************************************************************/ |
10 |
30 |
11 #include <linux/module.h> |
31 #include <linux/module.h> |
12 #include <linux/kernel.h> |
32 #include <linux/kernel.h> |
13 #include <linux/string.h> |
33 #include <linux/string.h> |
14 #include <linux/slab.h> |
34 #include <linux/slab.h> |
676 } |
700 } |
677 |
701 |
678 /*****************************************************************************/ |
702 /*****************************************************************************/ |
679 |
703 |
680 /** |
704 /** |
681 Translates an ASCII coded bus-address to a slave pointer. |
|
682 These are the valid addressing schemes: |
|
683 - \a "X" = the X. slave on the bus, |
|
684 - \a "X:Y" = the Y. slave after the X. branch (bus coupler), |
|
685 - \a "#X" = the slave with alias X, |
|
686 - \a "#X:Y" = the Y. slave after the branch (bus coupler) with alias X. |
|
687 X and Y are zero-based indices and may be provided in hexadecimal or octal |
|
688 notation (with respective prefix). |
|
689 \return pointer to the slave on success, else NULL |
|
690 */ |
|
691 |
|
692 ec_slave_t *ecrt_master_get_slave(const ec_master_t *master, /**< Master */ |
|
693 const char *address /**< address string */ |
|
694 ) |
|
695 { |
|
696 unsigned long first, second; |
|
697 char *remainder, *remainder2; |
|
698 unsigned int alias_requested, alias_found; |
|
699 ec_slave_t *alias_slave = NULL, *slave; |
|
700 |
|
701 if (!address || address[0] == 0) return NULL; |
|
702 |
|
703 alias_requested = 0; |
|
704 if (address[0] == '#') { |
|
705 alias_requested = 1; |
|
706 address++; |
|
707 } |
|
708 |
|
709 first = simple_strtoul(address, &remainder, 0); |
|
710 if (remainder == address) { |
|
711 EC_ERR("Slave address \"%s\" - First number empty!\n", address); |
|
712 return NULL; |
|
713 } |
|
714 |
|
715 if (alias_requested) { |
|
716 alias_found = 0; |
|
717 list_for_each_entry(alias_slave, &master->slaves, list) { |
|
718 if (alias_slave->sii_alias == first) { |
|
719 alias_found = 1; |
|
720 break; |
|
721 } |
|
722 } |
|
723 if (!alias_found) { |
|
724 EC_ERR("Slave address \"%s\" - Alias not found!\n", address); |
|
725 return NULL; |
|
726 } |
|
727 } |
|
728 |
|
729 if (!remainder[0]) { // absolute position |
|
730 if (alias_requested) { |
|
731 return alias_slave; |
|
732 } |
|
733 else { |
|
734 list_for_each_entry(slave, &master->slaves, list) { |
|
735 if (slave->ring_position == first) return slave; |
|
736 } |
|
737 EC_ERR("Slave address \"%s\" - Absolute position invalid!\n", |
|
738 address); |
|
739 } |
|
740 } |
|
741 else if (remainder[0] == ':') { // field position |
|
742 remainder++; |
|
743 second = simple_strtoul(remainder, &remainder2, 0); |
|
744 |
|
745 if (remainder2 == remainder) { |
|
746 EC_ERR("Slave address \"%s\" - Second number empty!\n", address); |
|
747 return NULL; |
|
748 } |
|
749 |
|
750 if (remainder2[0]) { |
|
751 EC_ERR("Slave address \"%s\" - Invalid trailer!\n", address); |
|
752 return NULL; |
|
753 } |
|
754 |
|
755 if (alias_requested) { |
|
756 if (!alias_slave->type || |
|
757 alias_slave->type->special != EC_TYPE_BUS_COUPLER) { |
|
758 EC_ERR("Slave address \"%s\": Alias slave must be bus coupler" |
|
759 " in colon mode.\n", address); |
|
760 return NULL; |
|
761 } |
|
762 list_for_each_entry(slave, &master->slaves, list) { |
|
763 if (slave->coupler_index == alias_slave->coupler_index |
|
764 && slave->coupler_subindex == second) |
|
765 return slave; |
|
766 } |
|
767 EC_ERR("Slave address \"%s\" - Bus coupler %i has no %lu. slave" |
|
768 " following!\n", address, alias_slave->ring_position, |
|
769 second); |
|
770 return NULL; |
|
771 } |
|
772 else { |
|
773 list_for_each_entry(slave, &master->slaves, list) { |
|
774 if (slave->coupler_index == first |
|
775 && slave->coupler_subindex == second) return slave; |
|
776 } |
|
777 } |
|
778 } |
|
779 else |
|
780 EC_ERR("Slave address \"%s\" - Invalid format!\n", address); |
|
781 |
|
782 return NULL; |
|
783 } |
|
784 |
|
785 /*****************************************************************************/ |
|
786 |
|
787 /** |
|
788 Initializes a sync manager configuration page. |
705 Initializes a sync manager configuration page. |
789 The referenced memory (\a data) must be at least EC_SYNC_SIZE bytes. |
706 The referenced memory (\a data) must be at least EC_SYNC_SIZE bytes. |
790 */ |
707 */ |
791 |
708 |
792 void ec_sync_config(const ec_sync_t *sync, /**< sync manager */ |
709 void ec_sync_config(const ec_sync_t *sync, /**< sync manager */ |
916 } |
833 } |
917 printk(")\n"); |
834 printk(")\n"); |
918 } |
835 } |
919 } |
836 } |
920 |
837 |
|
838 /*****************************************************************************/ |
|
839 |
|
840 /** |
|
841 Does the Ethernet-over-EtherCAT processing. |
|
842 */ |
|
843 |
|
844 void ec_master_run_eoe(ec_master_t *master /**< EtherCAT master */) |
|
845 { |
|
846 ec_eoe_t *eoe; |
|
847 |
|
848 list_for_each_entry(eoe, &master->eoe_slaves, list) { |
|
849 ec_eoe_run(eoe); |
|
850 } |
|
851 } |
|
852 |
921 /****************************************************************************** |
853 /****************************************************************************** |
922 * Realtime interface |
854 * Realtime interface |
923 *****************************************************************************/ |
855 *****************************************************************************/ |
924 |
856 |
925 /** |
857 /** |
926 Creates a domain. |
858 Creates a domain. |
927 \return pointer to new domain on success, else NULL |
859 \return pointer to new domain on success, else NULL |
|
860 \ingroup RealtimeInterface |
928 */ |
861 */ |
929 |
862 |
930 ec_domain_t *ecrt_master_create_domain(ec_master_t *master /**< master */) |
863 ec_domain_t *ecrt_master_create_domain(ec_master_t *master /**< master */) |
931 { |
864 { |
932 ec_domain_t *domain, *last_domain; |
865 ec_domain_t *domain, *last_domain; |
1351 ec_master_process_watch_command(master); |
1292 ec_master_process_watch_command(master); |
1352 ec_master_queue_command(master, &master->watch_command); |
1293 ec_master_queue_command(master, &master->watch_command); |
1353 |
1294 |
1354 // Ethernet-over-EtherCAT |
1295 // Ethernet-over-EtherCAT |
1355 ec_master_run_eoe(master); |
1296 ec_master_run_eoe(master); |
|
1297 } |
|
1298 |
|
1299 /*****************************************************************************/ |
|
1300 |
|
1301 /** |
|
1302 Translates an ASCII coded bus-address to a slave pointer. |
|
1303 These are the valid addressing schemes: |
|
1304 - \a "X" = the X. slave on the bus, |
|
1305 - \a "X:Y" = the Y. slave after the X. branch (bus coupler), |
|
1306 - \a "#X" = the slave with alias X, |
|
1307 - \a "#X:Y" = the Y. slave after the branch (bus coupler) with alias X. |
|
1308 X and Y are zero-based indices and may be provided in hexadecimal or octal |
|
1309 notation (with respective prefix). |
|
1310 \return pointer to the slave on success, else NULL |
|
1311 \ingroup RealtimeInterface |
|
1312 */ |
|
1313 |
|
1314 ec_slave_t *ecrt_master_get_slave(const ec_master_t *master, /**< Master */ |
|
1315 const char *address /**< address string */ |
|
1316 ) |
|
1317 { |
|
1318 unsigned long first, second; |
|
1319 char *remainder, *remainder2; |
|
1320 unsigned int alias_requested, alias_found; |
|
1321 ec_slave_t *alias_slave = NULL, *slave; |
|
1322 |
|
1323 if (!address || address[0] == 0) return NULL; |
|
1324 |
|
1325 alias_requested = 0; |
|
1326 if (address[0] == '#') { |
|
1327 alias_requested = 1; |
|
1328 address++; |
|
1329 } |
|
1330 |
|
1331 first = simple_strtoul(address, &remainder, 0); |
|
1332 if (remainder == address) { |
|
1333 EC_ERR("Slave address \"%s\" - First number empty!\n", address); |
|
1334 return NULL; |
|
1335 } |
|
1336 |
|
1337 if (alias_requested) { |
|
1338 alias_found = 0; |
|
1339 list_for_each_entry(alias_slave, &master->slaves, list) { |
|
1340 if (alias_slave->sii_alias == first) { |
|
1341 alias_found = 1; |
|
1342 break; |
|
1343 } |
|
1344 } |
|
1345 if (!alias_found) { |
|
1346 EC_ERR("Slave address \"%s\" - Alias not found!\n", address); |
|
1347 return NULL; |
|
1348 } |
|
1349 } |
|
1350 |
|
1351 if (!remainder[0]) { // absolute position |
|
1352 if (alias_requested) { |
|
1353 return alias_slave; |
|
1354 } |
|
1355 else { |
|
1356 list_for_each_entry(slave, &master->slaves, list) { |
|
1357 if (slave->ring_position == first) return slave; |
|
1358 } |
|
1359 EC_ERR("Slave address \"%s\" - Absolute position invalid!\n", |
|
1360 address); |
|
1361 } |
|
1362 } |
|
1363 else if (remainder[0] == ':') { // field position |
|
1364 remainder++; |
|
1365 second = simple_strtoul(remainder, &remainder2, 0); |
|
1366 |
|
1367 if (remainder2 == remainder) { |
|
1368 EC_ERR("Slave address \"%s\" - Second number empty!\n", address); |
|
1369 return NULL; |
|
1370 } |
|
1371 |
|
1372 if (remainder2[0]) { |
|
1373 EC_ERR("Slave address \"%s\" - Invalid trailer!\n", address); |
|
1374 return NULL; |
|
1375 } |
|
1376 |
|
1377 if (alias_requested) { |
|
1378 if (!alias_slave->type || |
|
1379 alias_slave->type->special != EC_TYPE_BUS_COUPLER) { |
|
1380 EC_ERR("Slave address \"%s\": Alias slave must be bus coupler" |
|
1381 " in colon mode.\n", address); |
|
1382 return NULL; |
|
1383 } |
|
1384 list_for_each_entry(slave, &master->slaves, list) { |
|
1385 if (slave->coupler_index == alias_slave->coupler_index |
|
1386 && slave->coupler_subindex == second) |
|
1387 return slave; |
|
1388 } |
|
1389 EC_ERR("Slave address \"%s\" - Bus coupler %i has no %lu. slave" |
|
1390 " following!\n", address, alias_slave->ring_position, |
|
1391 second); |
|
1392 return NULL; |
|
1393 } |
|
1394 else { |
|
1395 list_for_each_entry(slave, &master->slaves, list) { |
|
1396 if (slave->coupler_index == first |
|
1397 && slave->coupler_subindex == second) return slave; |
|
1398 } |
|
1399 } |
|
1400 } |
|
1401 else |
|
1402 EC_ERR("Slave address \"%s\" - Invalid format!\n", address); |
|
1403 |
|
1404 return NULL; |
1356 } |
1405 } |
1357 |
1406 |
1358 /*****************************************************************************/ |
1407 /*****************************************************************************/ |
1359 |
1408 |
1360 /** |
1409 /** |
1361 Sets the debug level of the master. |
1410 Sets the debug level of the master. |
1362 The following levels are valid: |
1411 The following levels are valid: |
1363 - 1: only output positions marks and basic data |
1412 - 1: only output positions marks and basic data |
1364 - 2: additional frame data output |
1413 - 2: additional frame data output |
|
1414 \ingroup RealtimeInterface |
1365 */ |
1415 */ |
1366 |
1416 |
1367 void ecrt_master_debug(ec_master_t *master, /**< EtherCAT master */ |
1417 void ecrt_master_debug(ec_master_t *master, /**< EtherCAT master */ |
1368 int level /**< debug level */ |
1418 int level /**< debug level */ |
1369 ) |
1419 ) |