1 /****************************************************************************** |
1 /****************************************************************************** |
2 * |
2 * |
3 * $Id$ |
3 * $Id$ |
4 * |
4 * |
5 * Copyright (C) 2006-2009 Florian Pose, Ingenieurgemeinschaft IgH |
5 * Copyright (C) 2006-2012 Florian Pose, Ingenieurgemeinschaft IgH |
6 * |
6 * |
7 * This file is part of the IgH EtherCAT master userspace library. |
7 * This file is part of the IgH EtherCAT master userspace library. |
8 * |
8 * |
9 * The IgH EtherCAT master userspace library is free software; you can |
9 * The IgH EtherCAT master userspace library is free software; you can |
10 * redistribute it and/or modify it under the terms of the GNU Lesser General |
10 * redistribute it and/or modify it under the terms of the GNU Lesser General |
11 * Public License as published by the Free Software Foundation; version 2.1 |
11 * Public License as published by the Free Software Foundation; version 2.1 |
12 * of the License. |
12 * of the License. |
13 * |
13 * |
17 * GNU Lesser General Public License for more details. |
17 * GNU Lesser General Public License for more details. |
18 * |
18 * |
19 * You should have received a copy of the GNU Lesser General Public License |
19 * You should have received a copy of the GNU Lesser General Public License |
20 * along with the IgH EtherCAT master userspace library. If not, see |
20 * along with the IgH EtherCAT master userspace library. If not, see |
21 * <http://www.gnu.org/licenses/>. |
21 * <http://www.gnu.org/licenses/>. |
22 * |
22 * |
23 * --- |
23 * --- |
24 * |
24 * |
25 * The license mentioned above concerns the source code only. Using the |
25 * The license mentioned above concerns the source code only. Using the |
26 * EtherCAT technology and brand is only permitted in compliance with the |
26 * EtherCAT technology and brand is only permitted in compliance with the |
27 * industrial property and similar rights of Beckhoff Automation GmbH. |
27 * industrial property and similar rights of Beckhoff Automation GmbH. |
28 * |
28 * |
29 *****************************************************************************/ |
29 *****************************************************************************/ |
33 EtherCAT domain methods. |
33 EtherCAT domain methods. |
34 */ |
34 */ |
35 |
35 |
36 /*****************************************************************************/ |
36 /*****************************************************************************/ |
37 |
37 |
38 #include <sys/ioctl.h> |
|
39 #include <sys/mman.h> |
|
40 #include <stdio.h> |
38 #include <stdio.h> |
41 #include <errno.h> |
|
42 #include <string.h> |
39 #include <string.h> |
|
40 #include <errno.h> /* ENOENT */ |
43 |
41 |
|
42 #include "ioctl.h" |
44 #include "domain.h" |
43 #include "domain.h" |
45 #include "master.h" |
44 #include "master.h" |
46 #include "master/ioctl.h" |
|
47 |
45 |
48 /*****************************************************************************/ |
46 /*****************************************************************************/ |
49 |
47 |
50 void ec_domain_clear(ec_domain_t *domain) |
48 void ec_domain_clear(ec_domain_t *domain) |
51 { |
49 { |
52 // nothing to do |
50 // nothing to do |
53 } |
|
54 |
|
55 |
|
56 /*****************************************************************************/ |
|
57 unsigned int ecrt_domain_index(ec_domain_t *domain) |
|
58 { |
|
59 return domain->index; |
|
60 } |
51 } |
61 |
52 |
62 /*****************************************************************************/ |
53 /*****************************************************************************/ |
63 |
54 |
64 int ecrt_domain_reg_pdo_entry_list(ec_domain_t *domain, |
55 int ecrt_domain_reg_pdo_entry_list(ec_domain_t *domain, |
65 const ec_pdo_entry_reg_t *regs) |
56 const ec_pdo_entry_reg_t *regs) |
66 { |
57 { |
67 const ec_pdo_entry_reg_t *reg; |
58 const ec_pdo_entry_reg_t *reg; |
68 ec_slave_config_t *sc; |
59 ec_slave_config_t *sc; |
69 int ret; |
60 int ret; |
70 |
61 |
71 for (reg = regs; reg->index; reg++) { |
62 for (reg = regs; reg->index; reg++) { |
72 if (!(sc = ecrt_master_slave_config(domain->master, reg->alias, |
63 if (!(sc = ecrt_master_slave_config(domain->master, reg->alias, |
73 reg->position, reg->vendor_id, reg->product_code))) |
64 reg->position, reg->vendor_id, reg->product_code))) |
74 return -1; // FIXME |
65 return -ENOENT; |
75 |
66 |
76 if ((ret = ecrt_slave_config_reg_pdo_entry(sc, reg->index, |
67 if ((ret = ecrt_slave_config_reg_pdo_entry(sc, reg->index, |
77 reg->subindex, domain, reg->bit_position)) < 0) |
68 reg->subindex, domain, reg->bit_position)) < 0) |
78 return -1; // FIXME |
69 return ret; |
79 |
70 |
80 *reg->offset = ret; |
71 *reg->offset = ret; |
81 } |
72 } |
82 |
73 |
83 return 0; |
74 return 0; |
|
75 } |
|
76 |
|
77 /*****************************************************************************/ |
|
78 |
|
79 size_t ecrt_domain_size(const ec_domain_t *domain) |
|
80 { |
|
81 int ret; |
|
82 |
|
83 ret = ioctl(domain->master->fd, EC_IOCTL_DOMAIN_SIZE, domain->index); |
|
84 if (EC_IOCTL_IS_ERROR(ret)) { |
|
85 fprintf(stderr, "Failed to get domain size: %s\n", |
|
86 strerror(EC_IOCTL_ERRNO(ret))); |
|
87 } |
|
88 |
|
89 return ret; |
84 } |
90 } |
85 |
91 |
86 /*****************************************************************************/ |
92 /*****************************************************************************/ |
87 |
93 |
88 uint8_t *ecrt_domain_data(ec_domain_t *domain) |
94 uint8_t *ecrt_domain_data(ec_domain_t *domain) |
90 if (!domain->process_data) { |
96 if (!domain->process_data) { |
91 int offset = 0; |
97 int offset = 0; |
92 |
98 |
93 offset = ioctl(domain->master->fd, EC_IOCTL_DOMAIN_OFFSET, |
99 offset = ioctl(domain->master->fd, EC_IOCTL_DOMAIN_OFFSET, |
94 domain->index); |
100 domain->index); |
95 if (offset == -1) { |
101 if (EC_IOCTL_IS_ERROR(offset)) { |
96 fprintf(stderr, "Failed to get domain offset: %s\n", |
102 fprintf(stderr, "Failed to get domain offset: %s\n", |
97 strerror(errno)); |
103 strerror(EC_IOCTL_ERRNO(offset))); |
98 return NULL; |
104 return NULL; |
99 } |
105 } |
100 |
106 |
101 domain->process_data = domain->master->process_data + offset; |
107 domain->process_data = domain->master->process_data + offset; |
102 } |
108 } |
103 |
109 |
104 return domain->process_data; |
110 return domain->process_data; |
105 } |
111 } |
106 |
112 |
107 /*****************************************************************************/ |
113 /*****************************************************************************/ |
108 |
114 |
109 void ecrt_domain_process(ec_domain_t *domain) |
115 void ecrt_domain_process(ec_domain_t *domain) |
110 { |
116 { |
111 if (ioctl(domain->master->fd, EC_IOCTL_DOMAIN_PROCESS, |
117 int ret; |
112 domain->index) == -1) { |
118 |
113 fprintf(stderr, "Failed to process domain: %s\n", strerror(errno)); |
119 ret = ioctl(domain->master->fd, EC_IOCTL_DOMAIN_PROCESS, domain->index); |
|
120 if (EC_IOCTL_IS_ERROR(ret)) { |
|
121 fprintf(stderr, "Failed to process domain: %s\n", |
|
122 strerror(EC_IOCTL_ERRNO(ret))); |
114 } |
123 } |
115 } |
124 } |
116 |
125 |
117 /*****************************************************************************/ |
126 /*****************************************************************************/ |
118 |
127 |
119 void ecrt_domain_queue(ec_domain_t *domain) |
128 void ecrt_domain_queue(ec_domain_t *domain) |
120 { |
129 { |
121 if (ioctl(domain->master->fd, EC_IOCTL_DOMAIN_QUEUE, |
130 int ret; |
122 domain->index) == -1) { |
131 |
123 fprintf(stderr, "Failed to queue domain: %s\n", strerror(errno)); |
132 ret = ioctl(domain->master->fd, EC_IOCTL_DOMAIN_QUEUE, domain->index); |
|
133 if (EC_IOCTL_IS_ERROR(ret)) { |
|
134 fprintf(stderr, "Failed to queue domain: %s\n", |
|
135 strerror(EC_IOCTL_ERRNO(ret))); |
124 } |
136 } |
125 } |
137 } |
126 |
138 |
127 /*****************************************************************************/ |
139 /*****************************************************************************/ |
128 |
140 |
129 void ecrt_domain_state(const ec_domain_t *domain, ec_domain_state_t *state) |
141 void ecrt_domain_state(const ec_domain_t *domain, ec_domain_state_t *state) |
130 { |
142 { |
131 ec_ioctl_domain_state_t data; |
143 ec_ioctl_domain_state_t data; |
|
144 int ret; |
132 |
145 |
133 data.domain_index = domain->index; |
146 data.domain_index = domain->index; |
134 data.state = state; |
147 data.state = state; |
135 |
148 |
136 if (ioctl(domain->master->fd, EC_IOCTL_DOMAIN_STATE, &data) == -1) { |
149 ret = ioctl(domain->master->fd, EC_IOCTL_DOMAIN_STATE, &data); |
|
150 if (EC_IOCTL_IS_ERROR(ret)) { |
137 fprintf(stderr, "Failed to get domain state: %s\n", |
151 fprintf(stderr, "Failed to get domain state: %s\n", |
138 strerror(errno)); |
152 strerror(EC_IOCTL_ERRNO(ret))); |
139 } |
153 } |
140 } |
154 } |
141 |
155 |
142 /*****************************************************************************/ |
156 /*****************************************************************************/ |