45 #include "ecrt.h" |
45 #include "ecrt.h" |
46 |
46 |
47 /****************************************************************************/ |
47 /****************************************************************************/ |
48 |
48 |
49 // Application parameters |
49 // Application parameters |
|
50 #define FREQUENCY 100 |
50 #define PRIORITY 1 |
51 #define PRIORITY 1 |
51 |
52 |
52 // Optional features |
53 // Optional features |
53 #define CONFIGURE_PDOS 1 |
54 #define CONFIGURE_PDOS 1 |
54 |
55 |
55 /****************************************************************************/ |
56 /****************************************************************************/ |
56 |
57 |
57 // EtherCAT |
58 // EtherCAT |
58 static ec_master_t *master = NULL; |
59 static ec_master_t *master = NULL; |
|
60 static ec_master_state_t master_state = {}; |
59 |
61 |
60 static ec_domain_t *domain1 = NULL; |
62 static ec_domain_t *domain1 = NULL; |
|
63 static ec_domain_state_t domain1_state = {}; |
61 |
64 |
62 static ec_slave_config_t *sc_ana_in = NULL; |
65 static ec_slave_config_t *sc_ana_in = NULL; |
|
66 static ec_slave_config_state_t sc_ana_in_state = {}; |
63 |
67 |
64 // Timer |
68 // Timer |
65 static unsigned int sig_alarms = 0; |
69 static unsigned int sig_alarms = 0; |
66 static unsigned int user_alarms = 0; |
70 static unsigned int user_alarms = 0; |
67 |
71 |
73 #define BusCouplerPos 0, 0 |
77 #define BusCouplerPos 0, 0 |
74 #define AnaOutSlavePos 0, 1 |
78 #define AnaOutSlavePos 0, 1 |
75 #define AnaInSlavePos 0, 2 |
79 #define AnaInSlavePos 0, 2 |
76 #define DigOutSlavePos 0, 3 |
80 #define DigOutSlavePos 0, 3 |
77 |
81 |
78 #define Beckhoff_EK1100 0x00000002, 0x044C2C52 |
82 #define Beckhoff_EK1100 0x00000002, 0x044c2c52 |
79 #define Beckhoff_EL2004 0x00000002, 0x07D43052 |
83 #define Beckhoff_EL2004 0x00000002, 0x07d43052 |
|
84 #define Beckhoff_EL2032 0x00000002, 0x07f03052 |
80 #define Beckhoff_EL3152 0x00000002, 0x0c503052 |
85 #define Beckhoff_EL3152 0x00000002, 0x0c503052 |
81 #define Beckhoff_EL4102 0x00000002, 0x10063052 |
86 #define Beckhoff_EL4102 0x00000002, 0x10063052 |
82 |
87 |
83 // offsets for Pdo entries |
88 // offsets for Pdo entries |
84 static unsigned int off_ana_in_status; |
89 static unsigned int off_ana_in_status; |
88 |
93 |
89 const static ec_pdo_entry_reg_t domain1_regs[] = { |
94 const static ec_pdo_entry_reg_t domain1_regs[] = { |
90 {AnaInSlavePos, Beckhoff_EL3152, 0x3101, 1, &off_ana_in_status}, |
95 {AnaInSlavePos, Beckhoff_EL3152, 0x3101, 1, &off_ana_in_status}, |
91 {AnaInSlavePos, Beckhoff_EL3152, 0x3101, 2, &off_ana_in_value}, |
96 {AnaInSlavePos, Beckhoff_EL3152, 0x3101, 2, &off_ana_in_value}, |
92 {AnaOutSlavePos, Beckhoff_EL4102, 0x3001, 1, &off_ana_out}, |
97 {AnaOutSlavePos, Beckhoff_EL4102, 0x3001, 1, &off_ana_out}, |
93 {DigOutSlavePos, Beckhoff_EL2004, 0x3001, 1, &off_dig_out}, |
98 {DigOutSlavePos, Beckhoff_EL2032, 0x3001, 1, &off_dig_out}, |
94 {} |
99 {} |
95 }; |
100 }; |
|
101 |
|
102 static unsigned int counter = 0; |
|
103 static unsigned int blink = 0; |
96 |
104 |
97 /*****************************************************************************/ |
105 /*****************************************************************************/ |
98 |
106 |
99 #if CONFIGURE_PDOS |
107 #if CONFIGURE_PDOS |
100 |
108 |
159 {1, EC_DIR_INPUT}, |
167 {1, EC_DIR_INPUT}, |
160 {0xff} |
168 {0xff} |
161 }; |
169 }; |
162 #endif |
170 #endif |
163 |
171 |
|
172 /*****************************************************************************/ |
|
173 |
|
174 void check_domain1_state(void) |
|
175 { |
|
176 ec_domain_state_t ds; |
|
177 |
|
178 ecrt_domain_state(domain1, &ds); |
|
179 |
|
180 if (ds.working_counter != domain1_state.working_counter) |
|
181 printf("Domain1: WC %u.\n", ds.working_counter); |
|
182 if (ds.wc_state != domain1_state.wc_state) |
|
183 printf("Domain1: State %u.\n", ds.wc_state); |
|
184 |
|
185 domain1_state = ds; |
|
186 } |
|
187 |
|
188 /*****************************************************************************/ |
|
189 |
|
190 void check_master_state(void) |
|
191 { |
|
192 ec_master_state_t ms; |
|
193 |
|
194 ecrt_master_state(master, &ms); |
|
195 |
|
196 if (ms.slaves_responding != master_state.slaves_responding) |
|
197 printf("%u slave(s).\n", ms.slaves_responding); |
|
198 if (ms.al_states != master_state.al_states) |
|
199 printf("AL states: 0x%02X.\n", ms.al_states); |
|
200 if (ms.link_up != master_state.link_up) |
|
201 printf("Link is %s.\n", ms.link_up ? "up" : "down"); |
|
202 |
|
203 master_state = ms; |
|
204 } |
|
205 |
|
206 /*****************************************************************************/ |
|
207 |
|
208 void check_slave_config_states(void) |
|
209 { |
|
210 ec_slave_config_state_t s; |
|
211 |
|
212 ecrt_slave_config_state(sc_ana_in, &s); |
|
213 |
|
214 if (s.al_state != sc_ana_in_state.al_state) |
|
215 printf("AnaIn: State 0x%02X.\n", s.al_state); |
|
216 if (s.online != sc_ana_in_state.online) |
|
217 printf("AnaIn: %s.\n", s.online ? "online" : "offline"); |
|
218 if (s.operational != sc_ana_in_state.operational) |
|
219 printf("AnaIn: %soperational.\n", |
|
220 s.operational ? "" : "Not "); |
|
221 |
|
222 sc_ana_in_state = s; |
|
223 } |
|
224 |
164 /****************************************************************************/ |
225 /****************************************************************************/ |
165 |
226 |
166 void cyclic_task() |
227 void cyclic_task() |
167 { |
228 { |
|
229 int i; |
|
230 |
|
231 // receive process data |
168 ecrt_master_receive(master); |
232 ecrt_master_receive(master); |
169 ecrt_domain_process(domain1); |
233 ecrt_domain_process(domain1); |
170 |
234 |
|
235 // check process data state (optional) |
|
236 check_domain1_state(); |
|
237 |
|
238 if (counter) { |
|
239 counter--; |
|
240 } else { // do this at 1 Hz |
|
241 counter = FREQUENCY; |
|
242 |
|
243 // calculate new process data |
|
244 blink = !blink; |
|
245 |
|
246 // check for master state (optional) |
|
247 check_master_state(); |
|
248 |
|
249 // check for islave configuration state(s) (optional) |
|
250 check_slave_config_states(); |
|
251 } |
|
252 |
171 #if 0 |
253 #if 0 |
172 #if EL3152_ALT_PDOS |
254 // read process data |
173 printf("AnaIn: value %u\n", |
|
174 EC_READ_U16(domain1_pd + off_ana_in_value)); |
|
175 #else |
|
176 printf("AnaIn: state %u value %u\n", |
255 printf("AnaIn: state %u value %u\n", |
177 EC_READ_U8(domain1_pd + off_ana_in_status), |
256 EC_READ_U8(domain1_pd + off_ana_in_status), |
178 EC_READ_U16(domain1_pd + off_ana_in_value)); |
257 EC_READ_U16(domain1_pd + off_ana_in_value)); |
179 #endif |
258 #endif |
180 #endif |
259 |
181 |
260 #if 1 |
|
261 // write process data |
|
262 EC_WRITE_U8(domain1_pd + off_dig_out, blink ? 0x06 : 0x09); |
|
263 #endif |
|
264 |
|
265 // send process data |
182 ecrt_domain_queue(domain1); |
266 ecrt_domain_queue(domain1); |
183 ecrt_master_send(master); |
267 ecrt_master_send(master); |
184 } |
268 } |
185 |
269 |
186 /****************************************************************************/ |
270 /****************************************************************************/ |
232 fprintf(stderr, "Failed to configure Pdos.\n"); |
316 fprintf(stderr, "Failed to configure Pdos.\n"); |
233 return -1; |
317 return -1; |
234 } |
318 } |
235 |
319 |
236 if (!(sc = ecrt_master_slave_config( |
320 if (!(sc = ecrt_master_slave_config( |
237 master, DigOutSlavePos, Beckhoff_EL2004))) { |
321 master, DigOutSlavePos, Beckhoff_EL2032))) { |
238 fprintf(stderr, "Failed to get slave configuration.\n"); |
322 fprintf(stderr, "Failed to get slave configuration.\n"); |
239 return -1; |
323 return -1; |
240 } |
324 } |
241 |
325 |
242 if (ecrt_slave_config_pdos(sc, EC_END, el2004_syncs)) { |
326 if (ecrt_slave_config_pdos(sc, EC_END, el2004_syncs)) { |
278 return -1; |
362 return -1; |
279 } |
363 } |
280 |
364 |
281 printf("Starting timer...\n"); |
365 printf("Starting timer...\n"); |
282 tv.it_interval.tv_sec = 0; |
366 tv.it_interval.tv_sec = 0; |
283 tv.it_interval.tv_usec = 10000; |
367 tv.it_interval.tv_usec = 1000000 / FREQUENCY; |
284 tv.it_value.tv_sec = 0; |
368 tv.it_value.tv_sec = 0; |
285 tv.it_value.tv_usec = 1000; |
369 tv.it_value.tv_usec = 1000; |
286 if (setitimer(ITIMER_REAL, &tv, NULL)) { |
370 if (setitimer(ITIMER_REAL, &tv, NULL)) { |
287 fprintf(stderr, "Failed to start timer: %s\n", strerror(errno)); |
371 fprintf(stderr, "Failed to start timer: %s\n", strerror(errno)); |
288 return 1; |
372 return 1; |