69 0x0000, 6); |
69 0x0000, 6); |
70 |
70 |
71 if (unlikely(ec_frame_send_receive(&frame))) return -1; |
71 if (unlikely(ec_frame_send_receive(&frame))) return -1; |
72 |
72 |
73 if (unlikely(frame.working_counter != 1)) { |
73 if (unlikely(frame.working_counter != 1)) { |
74 printk(KERN_ERR "EtherCAT: Slave %i did not respond while reading base" |
74 EC_ERR("Slave %i did not respond while reading base data!\n", |
75 " data!\n", slave->ring_position); |
75 slave->ring_position); |
76 return -1; |
76 return -1; |
77 } |
77 } |
78 |
78 |
79 slave->base_type = EC_READ_U8 (frame.data); |
79 slave->base_type = EC_READ_U8 (frame.data); |
80 slave->base_revision = EC_READ_U8 (frame.data + 1); |
80 slave->base_revision = EC_READ_U8 (frame.data + 1); |
86 slave->base_fmmu_count = EC_MAX_FMMUS; |
86 slave->base_fmmu_count = EC_MAX_FMMUS; |
87 |
87 |
88 // Read identification from "Slave Information Interface" (SII) |
88 // Read identification from "Slave Information Interface" (SII) |
89 |
89 |
90 if (unlikely(ec_slave_sii_read(slave, 0x0008, &slave->sii_vendor_id))) { |
90 if (unlikely(ec_slave_sii_read(slave, 0x0008, &slave->sii_vendor_id))) { |
91 printk(KERN_ERR "EtherCAT: Could not read SII vendor id!\n"); |
91 EC_ERR("Could not read SII vendor id!\n"); |
92 return -1; |
92 return -1; |
93 } |
93 } |
94 |
94 |
95 if (unlikely(ec_slave_sii_read(slave, 0x000A, &slave->sii_product_code))) { |
95 if (unlikely(ec_slave_sii_read(slave, 0x000A, &slave->sii_product_code))) { |
96 printk(KERN_ERR "EtherCAT: Could not read SII product code!\n"); |
96 EC_ERR("Could not read SII product code!\n"); |
97 return -1; |
97 return -1; |
98 } |
98 } |
99 |
99 |
100 if (unlikely(ec_slave_sii_read(slave, 0x000C, |
100 if (unlikely(ec_slave_sii_read(slave, 0x000C, |
101 &slave->sii_revision_number))) { |
101 &slave->sii_revision_number))) { |
102 printk(KERN_ERR "EtherCAT: Could not read SII revision number!\n"); |
102 EC_ERR("Could not read SII revision number!\n"); |
103 return -1; |
103 return -1; |
104 } |
104 } |
105 |
105 |
106 if (unlikely(ec_slave_sii_read(slave, 0x000E, |
106 if (unlikely(ec_slave_sii_read(slave, 0x000E, |
107 &slave->sii_serial_number))) { |
107 &slave->sii_serial_number))) { |
108 printk(KERN_ERR "EtherCAT: Could not read SII serial number!\n"); |
108 EC_ERR("Could not read SII serial number!\n"); |
109 return -1; |
109 return -1; |
110 } |
110 } |
111 |
111 |
112 return 0; |
112 return 0; |
113 } |
113 } |
145 data); |
145 data); |
146 |
146 |
147 if (unlikely(ec_frame_send_receive(&frame))) return -1; |
147 if (unlikely(ec_frame_send_receive(&frame))) return -1; |
148 |
148 |
149 if (unlikely(frame.working_counter != 1)) { |
149 if (unlikely(frame.working_counter != 1)) { |
150 printk(KERN_ERR "EtherCAT: SII-read - Slave %i did not respond!\n", |
150 EC_ERR("SII-read - Slave %i did not respond!\n", slave->ring_position); |
151 slave->ring_position); |
|
152 return -1; |
151 return -1; |
153 } |
152 } |
154 |
153 |
155 // Der Slave legt die Informationen des Slave-Information-Interface |
154 // Der Slave legt die Informationen des Slave-Information-Interface |
156 // in das Datenregister und löscht daraufhin ein Busy-Bit. Solange |
155 // in das Datenregister und löscht daraufhin ein Busy-Bit. Solange |
165 10); |
164 10); |
166 |
165 |
167 if (unlikely(ec_frame_send_receive(&frame))) return -1; |
166 if (unlikely(ec_frame_send_receive(&frame))) return -1; |
168 |
167 |
169 if (unlikely(frame.working_counter != 1)) { |
168 if (unlikely(frame.working_counter != 1)) { |
170 printk(KERN_ERR "EtherCAT: SII-read status -" |
169 EC_ERR("SII-read status - Slave %i did not respond!\n", |
171 " Slave %i did not respond!\n", slave->ring_position); |
170 slave->ring_position); |
172 return -1; |
171 return -1; |
173 } |
172 } |
174 |
173 |
175 if (likely((EC_READ_U8(frame.data + 1) & 0x81) == 0)) { |
174 if (likely((EC_READ_U8(frame.data + 1) & 0x81) == 0)) { |
176 memcpy(target, frame.data + 6, 4); |
175 memcpy(target, frame.data + 6, 4); |
211 |
209 |
212 ec_frame_init_npwr(&frame, slave->master, slave->station_address, 0x0120, |
210 ec_frame_init_npwr(&frame, slave->master, slave->station_address, 0x0120, |
213 2, data); |
211 2, data); |
214 |
212 |
215 if (unlikely(ec_frame_send_receive(&frame) != 0)) { |
213 if (unlikely(ec_frame_send_receive(&frame) != 0)) { |
216 printk(KERN_ERR "EtherCAT: Could no acknowledge state %02X - Unable to" |
214 EC_WARN("Could no acknowledge state %02X - Unable to send!\n", state); |
217 " send!\n", state); |
|
218 return; |
215 return; |
219 } |
216 } |
220 |
217 |
221 if (unlikely(frame.working_counter != 1)) { |
218 if (unlikely(frame.working_counter != 1)) { |
222 printk(KERN_ERR "EtherCAT: Could not acknowledge state %02X - Slave" |
219 EC_WARN("Could not acknowledge state %02X - Slave %i did not" |
223 " %i did not respond!\n", state, slave->ring_position); |
220 " respond!\n", state, slave->ring_position); |
224 return; |
221 return; |
225 } |
222 } |
226 |
223 |
227 tries_left = 100; |
224 tries_left = 100; |
228 while (likely(tries_left)) |
225 while (likely(tries_left)) |
231 |
228 |
232 ec_frame_init_nprd(&frame, slave->master, slave->station_address, |
229 ec_frame_init_nprd(&frame, slave->master, slave->station_address, |
233 0x0130, 2); |
230 0x0130, 2); |
234 |
231 |
235 if (unlikely(ec_frame_send_receive(&frame) != 0)) { |
232 if (unlikely(ec_frame_send_receive(&frame) != 0)) { |
236 printk(KERN_ERR "EtherCAT: Could not check state acknowledgement" |
233 EC_WARN("Could not check state acknowledgement %02X - Unable to" |
237 " %02X - Unable to send!\n", state); |
234 " send!\n", state); |
238 return; |
235 return; |
239 } |
236 } |
240 |
237 |
241 if (unlikely(frame.working_counter != 1)) { |
238 if (unlikely(frame.working_counter != 1)) { |
242 printk(KERN_ERR "EtherCAT: Could not check state acknowledgement" |
239 EC_WARN("Could not check state acknowledgement %02X - Slave %i did" |
243 " %02X - Slave %i did not respond!\n", state, |
240 " not respond!\n", state, slave->ring_position); |
244 slave->ring_position); |
|
245 return; |
241 return; |
246 } |
242 } |
247 |
243 |
248 if (unlikely(EC_READ_U8(frame.data) != state)) { |
244 if (unlikely(EC_READ_U8(frame.data) != state)) { |
249 printk(KERN_ERR "EtherCAT: Could not acknowledge state %02X on" |
245 EC_WARN("Could not acknowledge state %02X on slave %i (code" |
250 " slave %i (code %02X)!\n", state, slave->ring_position, |
246 " %02X)!\n", state, slave->ring_position, |
251 EC_READ_U8(frame.data)); |
247 EC_READ_U8(frame.data)); |
252 return; |
248 return; |
253 } |
249 } |
254 |
250 |
255 if (likely(EC_READ_U8(frame.data) == state)) { |
251 if (likely(EC_READ_U8(frame.data) == state)) { |
256 printk(KERN_INFO "EtherCAT: Acknowleged state %02X on slave %i.\n", |
252 EC_INFO("Acknowleged state %02X on slave %i.\n", state, |
257 state, slave->ring_position); |
253 slave->ring_position); |
258 return; |
254 return; |
259 } |
255 } |
260 |
256 |
261 tries_left--; |
257 tries_left--; |
262 } |
258 } |
263 |
259 |
264 if (unlikely(!tries_left)) { |
260 if (unlikely(!tries_left)) { |
265 printk(KERN_ERR "EtherCAT: Could not check state acknowledgement %02X" |
261 EC_WARN("Could not check state acknowledgement %02X of slave %i -" |
266 " of slave %i - Timeout while checking!\n", state, |
262 " Timeout while checking!\n", state, slave->ring_position); |
267 slave->ring_position); |
|
268 return; |
263 return; |
269 } |
264 } |
270 } |
265 } |
271 |
266 |
272 /*****************************************************************************/ |
267 /*****************************************************************************/ |
291 |
286 |
292 ec_frame_init_npwr(&frame, slave->master, slave->station_address, 0x0120, |
287 ec_frame_init_npwr(&frame, slave->master, slave->station_address, 0x0120, |
293 2, data); |
288 2, data); |
294 |
289 |
295 if (unlikely(ec_frame_send_receive(&frame) != 0)) { |
290 if (unlikely(ec_frame_send_receive(&frame) != 0)) { |
296 printk(KERN_ERR "EtherCAT: Could not set state %02X - Unable to" |
291 EC_ERR("Could not set state %02X - Unable to send!\n", state); |
297 " send!\n", state); |
292 return -1; |
298 return -1; |
293 } |
299 } |
294 |
300 |
295 if (unlikely(frame.working_counter != 1)) { |
301 if (unlikely(frame.working_counter != 1)) { |
296 EC_ERR("Could not set state %02X - Slave %i did not respond!\n", state, |
302 printk(KERN_ERR "EtherCAT: Could not set state %02X - Slave %i did not" |
297 slave->ring_position); |
303 " respond!\n", state, slave->ring_position); |
|
304 return -1; |
298 return -1; |
305 } |
299 } |
306 |
300 |
307 tries_left = 100; |
301 tries_left = 100; |
308 while (likely(tries_left)) |
302 while (likely(tries_left)) |
311 |
305 |
312 ec_frame_init_nprd(&frame, slave->master, slave->station_address, |
306 ec_frame_init_nprd(&frame, slave->master, slave->station_address, |
313 0x0130, 2); |
307 0x0130, 2); |
314 |
308 |
315 if (unlikely(ec_frame_send_receive(&frame) != 0)) { |
309 if (unlikely(ec_frame_send_receive(&frame) != 0)) { |
316 printk(KERN_ERR "EtherCAT: Could not check state %02X - Unable to" |
310 EC_ERR("Could not check state %02X - Unable to send!\n", state); |
317 " send!\n", state); |
|
318 return -1; |
311 return -1; |
319 } |
312 } |
320 |
313 |
321 if (unlikely(frame.working_counter != 1)) { |
314 if (unlikely(frame.working_counter != 1)) { |
322 printk(KERN_ERR "EtherCAT: Could not check state %02X - Slave %i" |
315 EC_ERR("Could not check state %02X - Slave %i did not respond!\n", |
323 " did not respond!\n", state, slave->ring_position); |
316 state, slave->ring_position); |
324 return -1; |
317 return -1; |
325 } |
318 } |
326 |
319 |
327 if (unlikely(EC_READ_U8(frame.data) & 0x10)) { // State change error |
320 if (unlikely(EC_READ_U8(frame.data) & 0x10)) { // State change error |
328 printk(KERN_ERR "EtherCAT: Could not set state %02X - Slave %i" |
321 EC_ERR("Could not set state %02X - Slave %i refused state change" |
329 " refused state change (code %02X)!\n", state, |
322 " (code %02X)!\n", state, slave->ring_position, |
330 slave->ring_position, EC_READ_U8(frame.data)); |
323 EC_READ_U8(frame.data)); |
331 ec_slave_state_ack(slave, EC_READ_U8(frame.data) & 0x0F); |
324 ec_slave_state_ack(slave, EC_READ_U8(frame.data) & 0x0F); |
332 return -1; |
325 return -1; |
333 } |
326 } |
334 |
327 |
335 if (likely(EC_READ_U8(frame.data) == (state & 0x0F))) { |
328 if (likely(EC_READ_U8(frame.data) == (state & 0x0F))) { |
376 for (i = 0; i < slave->fmmu_count; i++) |
368 for (i = 0; i < slave->fmmu_count; i++) |
377 if (slave->fmmus[i].domain == domain && slave->fmmus[i].sync == sync) |
369 if (slave->fmmus[i].domain == domain && slave->fmmus[i].sync == sync) |
378 return 0; |
370 return 0; |
379 |
371 |
380 if (slave->fmmu_count >= slave->base_fmmu_count) { |
372 if (slave->fmmu_count >= slave->base_fmmu_count) { |
381 printk(KERN_ERR "EtherCAT: Slave %i supports only %i FMMUs.\n", |
373 EC_ERR("Slave %i FMMU limit reached!\n", slave->ring_position); |
382 slave->ring_position, slave->base_fmmu_count); |
|
383 return -1; |
374 return -1; |
384 } |
375 } |
385 |
376 |
386 slave->fmmus[slave->fmmu_count].domain = domain; |
377 slave->fmmus[slave->fmmu_count].domain = domain; |
387 slave->fmmus[slave->fmmu_count].sync = sync; |
378 slave->fmmus[slave->fmmu_count].sync = sync; |
398 Gibt alle Informationen über einen EtherCAT-Slave aus. |
389 Gibt alle Informationen über einen EtherCAT-Slave aus. |
399 */ |
390 */ |
400 |
391 |
401 void ec_slave_print(const ec_slave_t *slave /**< EtherCAT-Slave */) |
392 void ec_slave_print(const ec_slave_t *slave /**< EtherCAT-Slave */) |
402 { |
393 { |
403 printk(KERN_INFO "--- EtherCAT slave information ---\n"); |
394 EC_INFO("--- EtherCAT slave information ---\n"); |
404 |
395 |
405 if (slave->type) { |
396 if (slave->type) { |
406 printk(KERN_INFO " Vendor \"%s\", Product \"%s\": %s\n", |
397 EC_INFO(" Vendor \"%s\", Product \"%s\": %s\n", |
407 slave->type->vendor_name, slave->type->product_name, |
398 slave->type->vendor_name, slave->type->product_name, |
408 slave->type->description); |
399 slave->type->description); |
409 } |
400 } |
410 else { |
401 else { |
411 printk(KERN_INFO " *** This slave has no type information! ***\n"); |
402 EC_INFO(" *** This slave has no type information! ***\n"); |
412 } |
403 } |
413 |
404 |
414 printk(KERN_INFO " Ring position: %i, Station address: 0x%04X\n", |
405 EC_INFO(" Ring position: %i, Station address: 0x%04X\n", |
415 slave->ring_position, slave->station_address); |
406 slave->ring_position, slave->station_address); |
416 |
407 |
417 printk(KERN_INFO " Base information:\n"); |
408 EC_INFO(" Base information:\n"); |
418 printk(KERN_INFO " Type %u, Revision %i, Build %i\n", |
409 EC_INFO(" Type %u, Revision %i, Build %i\n", |
419 slave->base_type, slave->base_revision, slave->base_build); |
410 slave->base_type, slave->base_revision, slave->base_build); |
420 printk(KERN_INFO " Supported FMMUs: %i, Sync managers: %i\n", |
411 EC_INFO(" Supported FMMUs: %i, Sync managers: %i\n", |
421 slave->base_fmmu_count, slave->base_sync_count); |
412 slave->base_fmmu_count, slave->base_sync_count); |
422 |
413 |
423 printk(KERN_INFO " Slave information interface:\n"); |
414 EC_INFO(" Slave information interface:\n"); |
424 printk(KERN_INFO " Vendor-ID: 0x%08X, Product code: 0x%08X\n", |
415 EC_INFO(" Vendor-ID: 0x%08X, Product code: 0x%08X\n", |
425 slave->sii_vendor_id, slave->sii_product_code); |
416 slave->sii_vendor_id, slave->sii_product_code); |
426 printk(KERN_INFO " Revision number: 0x%08X, Serial number: 0x%08X\n", |
417 EC_INFO(" Revision number: 0x%08X, Serial number: 0x%08X\n", |
427 slave->sii_revision_number, slave->sii_serial_number); |
418 slave->sii_revision_number, slave->sii_serial_number); |
428 } |
419 } |
429 |
420 |
430 /*****************************************************************************/ |
421 /*****************************************************************************/ |
431 |
422 |
432 /** |
423 /** |
442 |
433 |
443 ec_frame_init_nprd(&frame, slave->master, slave->station_address, 0x0300, |
434 ec_frame_init_nprd(&frame, slave->master, slave->station_address, 0x0300, |
444 4); |
435 4); |
445 |
436 |
446 if (unlikely(ec_frame_send_receive(&frame))) { |
437 if (unlikely(ec_frame_send_receive(&frame))) { |
447 printk(KERN_WARNING "EtherCAT: Reading CRC fault counters failed" |
438 EC_WARN("Reading CRC fault counters failed on slave %i - Could not" |
448 " on slave %i - Could not send command!\n", |
439 " send command!\n", slave->ring_position); |
449 slave->ring_position); |
440 return -1; |
450 return -1; |
441 } |
451 } |
442 |
452 |
443 if (unlikely(frame.working_counter != 1)) { |
453 if (unlikely(frame.working_counter != 1)) { |
444 EC_WARN("Reading CRC fault counters - Slave %i did not respond!\n", |
454 printk(KERN_WARNING "EtherCAT: Reading CRC fault counters -" |
445 slave->ring_position); |
455 " Slave %i did not respond!\n", slave->ring_position); |
|
456 return -1; |
446 return -1; |
457 } |
447 } |
458 |
448 |
459 // No CRC faults. |
449 // No CRC faults. |
460 if (!EC_READ_U16(frame.data) && !EC_READ_U16(frame.data + 2)) return 0; |
450 if (!EC_READ_U16(frame.data) && !EC_READ_U16(frame.data + 2)) return 0; |
461 |
451 |
462 printk(KERN_INFO "EtherCAT: CRC faults on slave %i. A: %i, B: %i\n", |
452 EC_WARN("CRC faults on slave %i. A: %i, B: %i\n", slave->ring_position, |
463 slave->ring_position, EC_READ_U16(frame.data), |
453 EC_READ_U16(frame.data), EC_READ_U16(frame.data + 2)); |
464 EC_READ_U16(frame.data + 2)); |
|
465 |
454 |
466 // Reset CRC counters |
455 // Reset CRC counters |
467 EC_WRITE_U16(data, 0x0000); |
456 EC_WRITE_U16(data, 0x0000); |
468 EC_WRITE_U16(data + 2, 0x0000); |
457 EC_WRITE_U16(data + 2, 0x0000); |
469 ec_frame_init_npwr(&frame, slave->master, slave->station_address, 0x0300, |
458 ec_frame_init_npwr(&frame, slave->master, slave->station_address, 0x0300, |
470 4, data); |
459 4, data); |
471 |
460 |
472 if (unlikely(ec_frame_send_receive(&frame))) return -1; |
461 if (unlikely(ec_frame_send_receive(&frame))) return -1; |
473 |
462 |
474 if (unlikely(frame.working_counter != 1)) { |
463 if (unlikely(frame.working_counter != 1)) { |
475 printk(KERN_ERR "EtherCAT: Resetting CRC fault counters - Slave" |
464 EC_WARN("Resetting CRC fault counters - Slave %i did not respond!\n", |
476 " %i did not respond!\n", slave->ring_position); |
465 slave->ring_position); |
477 return -1; |
466 return -1; |
478 } |
467 } |
479 |
468 |
480 return 0; |
469 return 0; |
481 } |
470 } |