15 #include <linux/delay.h> |
15 #include <linux/delay.h> |
16 |
16 |
17 #include "ec_globals.h" |
17 #include "ec_globals.h" |
18 #include "ec_master.h" |
18 #include "ec_master.h" |
19 #include "ec_dbg.h" |
19 #include "ec_dbg.h" |
20 |
|
21 // FIXME: Klappt nur solange, wie es nur einen Master gibt! fp |
|
22 static int ASYNC = 0; |
|
23 |
20 |
24 /***************************************************************/ |
21 /***************************************************************/ |
25 |
22 |
26 /** |
23 /** |
27 Konstruktor des EtherCAT-Masters. |
24 Konstruktor des EtherCAT-Masters. |
157 |
154 |
158 return -1; |
155 return -1; |
159 } |
156 } |
160 else |
157 else |
161 { |
158 { |
162 EC_DBG("EtherCAT: Slave count on bus: %i. Found: %i.\n", |
159 EC_DBG("EtherCAT: Found all %i slaves.\n", slave_count); |
163 cmd->working_counter, slave_count); |
|
164 } |
160 } |
165 |
161 |
166 EtherCAT_remove_command(master, cmd); |
162 EtherCAT_remove_command(master, cmd); |
167 |
163 |
168 // For every slave in the list |
164 // For every slave in the list |
169 for (i = 0; i < slave_count; i++) |
165 for (i = 0; i < slave_count; i++) |
170 { |
166 { |
171 cur = &slaves[i]; |
167 cur = &slaves[i]; |
172 |
168 |
173 if (!cur->desc) |
169 if (!cur->desc) |
237 // Read identification from "Slave Information Interface" (SII) |
233 // Read identification from "Slave Information Interface" (SII) |
238 |
234 |
239 if (EtherCAT_read_slave_information(master, cur->station_address, |
235 if (EtherCAT_read_slave_information(master, cur->station_address, |
240 0x0008, &cur->vendor_id) != 0) |
236 0x0008, &cur->vendor_id) != 0) |
241 { |
237 { |
242 EC_DBG(KERN_ERR "EtherCAT: Could not read SII!\n"); |
238 EC_DBG(KERN_ERR "EtherCAT: Could not read SII vendor id!\n"); |
243 return -1; |
239 return -1; |
244 } |
240 } |
245 |
241 |
246 if (EtherCAT_read_slave_information(master, cur->station_address, |
242 if (EtherCAT_read_slave_information(master, cur->station_address, |
247 0x000A, &cur->product_code) != 0) |
243 0x000A, &cur->product_code) != 0) |
248 { |
244 { |
249 EC_DBG(KERN_ERR "EtherCAT: Could not read SII!\n"); |
245 EC_DBG(KERN_ERR "EtherCAT: Could not read SII product code!\n"); |
250 return -1; |
246 return -1; |
251 } |
247 } |
252 |
248 |
253 if (EtherCAT_read_slave_information(master, cur->station_address, |
249 if (EtherCAT_read_slave_information(master, cur->station_address, |
254 0x000E, &cur->revision_number) != 0) |
250 0x000E, &cur->revision_number) != 0) |
255 { |
251 { |
256 EC_DBG(KERN_ERR "EtherCAT: Could not read SII!\n"); |
252 EC_DBG(KERN_ERR "EtherCAT: Could not read SII revision number!\n"); |
|
253 return -1; |
|
254 } |
|
255 |
|
256 if (EtherCAT_read_slave_information(master, cur->station_address, |
|
257 0x0012, &cur->serial_number) != 0) |
|
258 { |
|
259 EC_DBG(KERN_ERR "EtherCAT: Could not read SII serial number!\n"); |
257 return -1; |
260 return -1; |
258 } |
261 } |
259 |
262 |
260 // Search for identification in "database" |
263 // Search for identification in "database" |
261 |
264 |
310 for (i = 0; i < slave_count; i++) |
314 for (i = 0; i < slave_count; i++) |
311 { |
315 { |
312 slaves[i].process_data = master->process_data + pos; |
316 slaves[i].process_data = master->process_data + pos; |
313 slaves[i].logical_address0 = pos; |
317 slaves[i].logical_address0 = pos; |
314 |
318 |
315 EC_DBG(KERN_DEBUG "EtherCAT: Slave %i - \"%s %s\" - Logical Address 0x%08X\n", |
319 EC_DBG(KERN_DEBUG "EtherCAT: Slave %i - Address 0x%X, \"%s %s\", s/n %u\n", |
316 i, slaves[i].desc->vendor_name, slaves[i].desc->product_name, pos); |
320 i, pos, slaves[i].desc->vendor_name, slaves[i].desc->product_name, |
|
321 slaves[i].serial_number); |
317 |
322 |
318 pos += slaves[i].desc->data_length; |
323 pos += slaves[i].desc->data_length; |
319 } |
324 } |
320 |
325 |
321 master->slaves = slaves; |
326 master->slaves = slaves; |
449 |
454 |
450 Sendet alle wartenden Kommandos und wartet auf die |
455 Sendet alle wartenden Kommandos und wartet auf die |
451 entsprechenden Antworten. |
456 entsprechenden Antworten. |
452 |
457 |
453 @param master EtherCAT-Master |
458 @param master EtherCAT-Master |
454 |
459 |
455 @return 0 bei Erfolg, sonst < 0 |
460 @return 0 bei Erfolg, sonst < 0 |
456 */ |
461 */ |
457 |
462 |
458 int EtherCAT_async_send_receive(EtherCAT_master_t *master) |
463 int EtherCAT_async_send_receive(EtherCAT_master_t *master) |
459 { |
464 { |
460 unsigned int wait_cycles; |
465 unsigned int wait_cycles; |
461 int i; |
466 int i; |
462 |
467 |
463 // Send all commands |
468 // Send all commands |
464 |
469 |
465 for (i = 0; i < ECAT_NUM_RETRIES; i++) |
470 for (i = 0; i < ECAT_NUM_RETRIES; i++) |
466 { |
471 { |
467 ASYNC = 1; |
|
468 if (EtherCAT_send(master) < 0) |
472 if (EtherCAT_send(master) < 0) |
469 { |
473 { |
470 return -1; |
474 return -1; |
471 } |
475 } |
472 ASYNC = 0; |
|
473 |
476 |
474 // Wait until something is received or an error has occurred |
477 // Wait until something is received or an error has occurred |
|
478 |
475 wait_cycles = 10; |
479 wait_cycles = 10; |
|
480 EtherCAT_device_call_isr(master->dev); |
|
481 |
476 while (master->dev->state == ECAT_DS_SENT && wait_cycles) |
482 while (master->dev->state == ECAT_DS_SENT && wait_cycles) |
477 { |
483 { |
478 udelay(1000); |
484 udelay(1000); |
479 wait_cycles--; |
485 wait_cycles--; |
480 } |
486 EtherCAT_device_call_isr(master->dev); |
481 |
487 } |
|
488 |
482 //EC_DBG("Master async send: tries %d",tries_left); |
489 //EC_DBG("Master async send: tries %d",tries_left); |
483 |
490 |
484 if (!wait_cycles) |
491 if (!wait_cycles) |
485 { |
492 { |
486 EC_DBG(KERN_ERR "EtherCAT: Asynchronous receive timeout.\n"); |
493 EC_DBG(KERN_ERR "EtherCAT: Asynchronous receive timeout.\n"); |
487 continue; |
494 continue; |
488 } |
495 } |
490 if (master->dev->state != ECAT_DS_RECEIVED) |
497 if (master->dev->state != ECAT_DS_RECEIVED) |
491 { |
498 { |
492 EC_DBG(KERN_ERR "EtherCAT: Asyncronous send error. State %i\n", master->dev->state); |
499 EC_DBG(KERN_ERR "EtherCAT: Asyncronous send error. State %i\n", master->dev->state); |
493 continue; |
500 continue; |
494 } |
501 } |
495 |
502 |
496 // Receive all commands |
503 // Receive all commands |
497 if (EtherCAT_receive(master) < 0) |
504 if (EtherCAT_receive(master) < 0) |
498 { |
505 { |
499 // Noch mal versuchen |
506 // Noch mal versuchen |
500 master->dev->state = ECAT_DS_READY; |
507 master->dev->state = ECAT_DS_READY; |
516 Errechnet erst die benötigte Gesamt-Rahmenlänge, und erstellt |
523 Errechnet erst die benötigte Gesamt-Rahmenlänge, und erstellt |
517 dann alle Kommando-Bytefolgen im statischen Sendespeicher. |
524 dann alle Kommando-Bytefolgen im statischen Sendespeicher. |
518 Danach wird die Sendefunktion des EtherCAT-Gerätes aufgerufen. |
525 Danach wird die Sendefunktion des EtherCAT-Gerätes aufgerufen. |
519 |
526 |
520 @param master EtherCAT-Master |
527 @param master EtherCAT-Master |
521 |
528 |
522 @return 0 bei Erfolg, sonst < 0 |
529 @return 0 bei Erfolg, sonst < 0 |
523 */ |
530 */ |
524 |
531 |
525 int EtherCAT_send(EtherCAT_master_t *master) |
532 int EtherCAT_send(EtherCAT_master_t *master) |
526 { |
533 { |
612 pos += 12 + cmd->data_length; |
619 pos += 12 + cmd->data_length; |
613 } |
620 } |
614 |
621 |
615 // Pad with zeros |
622 // Pad with zeros |
616 while (pos < 46) master->tx_data[pos++] = 0x00; |
623 while (pos < 46) master->tx_data[pos++] = 0x00; |
617 |
624 |
618 master->tx_data_length = framelength; |
625 master->tx_data_length = framelength; |
619 |
626 |
620 #ifdef DEBUG_SEND_RECEIVE |
627 #ifdef DEBUG_SEND_RECEIVE |
621 EC_DBG(KERN_DEBUG "\n"); |
628 EC_DBG(KERN_DEBUG "\n"); |
622 EC_DBG(KERN_DEBUG ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); |
629 EC_DBG(KERN_DEBUG ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); |
633 |
640 |
634 if (master->debug_level > 0) |
641 if (master->debug_level > 0) |
635 { |
642 { |
636 EC_DBG(KERN_DEBUG "device send...\n"); |
643 EC_DBG(KERN_DEBUG "device send...\n"); |
637 } |
644 } |
638 |
645 |
639 // Send frame |
646 // Send frame |
640 if (EtherCAT_device_send(master->dev, master->tx_data, framelength) != 0) |
647 if (EtherCAT_device_send(master->dev, master->tx_data, framelength) != 0) |
641 { |
648 { |
642 EC_DBG(KERN_ERR "EtherCAT: Could not send!\n"); |
649 EC_DBG(KERN_ERR "EtherCAT: Could not send!\n"); |
643 EC_DBG(KERN_DEBUG "EtherCAT: tx_data content:\n"); |
650 EC_DBG(KERN_DEBUG "EtherCAT: tx_data content:\n"); |
644 EC_DBG(KERN_DEBUG); |
651 EC_DBG(KERN_DEBUG); |
645 for (i = 0; i < framelength; i++) |
652 for (i = 0; i < framelength; i++) |
646 { |
653 { |
647 EC_DBG("%02X ", master->tx_data[i]); |
654 EC_DBG("%02X ", master->tx_data[i]); |
648 if ((i + 1) % 16 == 0) EC_DBG("\n" KERN_DEBUG); |
655 if ((i + 1) % 16 == 0) EC_DBG("\n" KERN_DEBUG); |
649 } |
656 } |
650 EC_DBG("\n"); |
657 EC_DBG("\n"); |
651 return -1; |
658 return -1; |
652 } |
659 } |
667 Kopiert einen empfangenen Rahmen vom EtherCAT-Gerät |
674 Kopiert einen empfangenen Rahmen vom EtherCAT-Gerät |
668 in den Statischen Empfangsspeicher und ordnet dann |
675 in den Statischen Empfangsspeicher und ordnet dann |
669 allen gesendeten Kommandos ihre Antworten zu. |
676 allen gesendeten Kommandos ihre Antworten zu. |
670 |
677 |
671 @param master EtherCAT-Master |
678 @param master EtherCAT-Master |
672 |
679 |
673 @return 0 bei Erfolg, sonst < 0 |
680 @return 0 bei Erfolg, sonst < 0 |
674 */ |
681 */ |
675 |
682 |
676 int EtherCAT_receive(EtherCAT_master_t *master) |
683 int EtherCAT_receive(EtherCAT_master_t *master) |
677 { |
684 { |