33 master->slaves = NULL; |
34 master->slaves = NULL; |
34 master->device = NULL; |
35 master->device = NULL; |
35 |
36 |
36 INIT_LIST_HEAD(&master->command_queue); |
37 INIT_LIST_HEAD(&master->command_queue); |
37 INIT_LIST_HEAD(&master->domains); |
38 INIT_LIST_HEAD(&master->domains); |
|
39 INIT_LIST_HEAD(&master->eoe_slaves); |
38 |
40 |
39 ec_command_init(&master->simple_command); |
41 ec_command_init(&master->simple_command); |
40 ec_command_init(&master->watch_command); |
42 ec_command_init(&master->watch_command); |
41 |
43 |
42 ec_master_reset(master); |
44 ec_master_reset(master); |
78 ) |
80 ) |
79 { |
81 { |
80 unsigned int i; |
82 unsigned int i; |
81 ec_command_t *command, *next_c; |
83 ec_command_t *command, *next_c; |
82 ec_domain_t *domain, *next_d; |
84 ec_domain_t *domain, *next_d; |
|
85 ec_eoe_t *eoe, *next_eoe; |
83 |
86 |
84 // Alle Slaves entfernen |
87 // Alle Slaves entfernen |
85 if (master->slaves) { |
88 if (master->slaves) { |
86 for (i = 0; i < master->slave_count; i++) { |
89 for (i = 0; i < master->slave_count; i++) { |
87 ec_slave_clear(master->slaves + i); |
90 ec_slave_clear(master->slaves + i); |
100 // Domain-Liste leeren |
103 // Domain-Liste leeren |
101 list_for_each_entry_safe(domain, next_d, &master->domains, list) { |
104 list_for_each_entry_safe(domain, next_d, &master->domains, list) { |
102 list_del(&domain->list); |
105 list_del(&domain->list); |
103 ec_domain_clear(domain); |
106 ec_domain_clear(domain); |
104 kfree(domain); |
107 kfree(domain); |
|
108 } |
|
109 |
|
110 // EOE-Liste leeren |
|
111 list_for_each_entry_safe(eoe, next_eoe, &master->domains, list) { |
|
112 list_del(&eoe->list); |
|
113 ec_eoe_clear(eoe); |
|
114 kfree(eoe); |
105 } |
115 } |
106 |
116 |
107 master->command_index = 0; |
117 master->command_index = 0; |
108 master->debug_level = 0; |
118 master->debug_level = 0; |
109 master->timeout = 100; // us |
119 master->timeout = 100; // us |
370 nochmals gesendet. |
380 nochmals gesendet. |
371 |
381 |
372 \return 0 bei Erfolg, sonst < 0 |
382 \return 0 bei Erfolg, sonst < 0 |
373 */ |
383 */ |
374 |
384 |
375 int ec_master_simple_io(ec_master_t *master /**< EtherCAT-Master */) |
385 int ec_master_simple_io(ec_master_t *master, /**< EtherCAT-Master */ |
|
386 ec_command_t *command /**< Kommando */ |
|
387 ) |
376 { |
388 { |
377 unsigned int response_tries_left; |
389 unsigned int response_tries_left; |
378 ec_command_t *command; |
|
379 |
390 |
380 response_tries_left = 10; |
391 response_tries_left = 10; |
381 command = &master->simple_command; |
|
382 |
392 |
383 while (1) |
393 while (1) |
384 { |
394 { |
385 ec_master_queue_command(master, command); |
395 ec_master_queue_command(master, command); |
386 ecrt_master_sync_io(master); |
396 ecrt_master_sync_io(master); |
423 { |
433 { |
424 ec_slave_t *slave; |
434 ec_slave_t *slave; |
425 ec_slave_ident_t *ident; |
435 ec_slave_ident_t *ident; |
426 unsigned int i; |
436 unsigned int i; |
427 ec_command_t *command; |
437 ec_command_t *command; |
|
438 ec_eoe_t *eoe; |
428 |
439 |
429 if (master->slaves || master->slave_count) { |
440 if (master->slaves || master->slave_count) { |
430 EC_ERR("Slave scan already done!\n"); |
441 EC_ERR("Slave scan already done!\n"); |
431 return -1; |
442 return -1; |
432 } |
443 } |
433 |
444 |
434 command = &master->simple_command; |
445 command = &master->simple_command; |
435 |
446 |
436 // Determine number of slaves on bus |
447 // Determine number of slaves on bus |
437 if (ec_command_brd(command, 0x0000, 4)) return -1; |
448 if (ec_command_brd(command, 0x0000, 4)) return -1; |
438 if (unlikely(ec_master_simple_io(master))) return -1; |
449 if (unlikely(ec_master_simple_io(master, command))) return -1; |
439 master->slave_count = command->working_counter; |
450 master->slave_count = command->working_counter; |
440 EC_INFO("Found %i slaves on bus.\n", master->slave_count); |
451 EC_INFO("Found %i slaves on bus.\n", master->slave_count); |
441 |
452 |
442 if (!master->slave_count) return 0; |
453 if (!master->slave_count) return 0; |
443 |
454 |
463 |
474 |
464 // Write station address |
475 // Write station address |
465 if (ec_command_apwr(command, slave->ring_position, |
476 if (ec_command_apwr(command, slave->ring_position, |
466 0x0010, sizeof(uint16_t))) return -1; |
477 0x0010, sizeof(uint16_t))) return -1; |
467 EC_WRITE_U16(command->data, slave->station_address); |
478 EC_WRITE_U16(command->data, slave->station_address); |
468 if (unlikely(ec_master_simple_io(master))) { |
479 if (unlikely(ec_master_simple_io(master, command))) { |
469 EC_ERR("Writing station address failed on slave %i!\n", i); |
480 EC_ERR("Writing station address failed on slave %i!\n", i); |
470 return -1; |
481 return -1; |
471 } |
482 } |
472 |
483 |
473 // Fetch all slave information |
484 // Fetch all slave information |
486 |
497 |
487 if (!slave->type) |
498 if (!slave->type) |
488 EC_WARN("Unknown slave device (vendor 0x%08X, code 0x%08X) at" |
499 EC_WARN("Unknown slave device (vendor 0x%08X, code 0x%08X) at" |
489 " position %i.\n", slave->sii_vendor_id, |
500 " position %i.\n", slave->sii_vendor_id, |
490 slave->sii_product_code, i); |
501 slave->sii_product_code, i); |
|
502 |
|
503 // Does the slave support EoE? |
|
504 if (slave->sii_mailbox_protocols & EC_MBOX_EOE) { |
|
505 if (!(eoe = kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) { |
|
506 EC_ERR("Failed to allocate memory for EoE-Object.\n"); |
|
507 return -1; |
|
508 } |
|
509 |
|
510 ec_eoe_init(eoe, slave); |
|
511 list_add_tail(&eoe->list, &master->eoe_slaves); |
|
512 } |
491 } |
513 } |
492 |
514 |
493 return 0; |
515 return 0; |
494 } |
516 } |
495 |
517 |
522 master->stats.corrupted = 0; |
544 master->stats.corrupted = 0; |
523 } |
545 } |
524 if (master->stats.unmatched) { |
546 if (master->stats.unmatched) { |
525 EC_WARN("%i command(s) UNMATCHED!\n", master->stats.unmatched); |
547 EC_WARN("%i command(s) UNMATCHED!\n", master->stats.unmatched); |
526 master->stats.unmatched = 0; |
548 master->stats.unmatched = 0; |
|
549 } |
|
550 if (master->stats.eoe_errors) { |
|
551 EC_WARN("%i EOE ERROR(S)!\n", master->stats.eoe_errors); |
|
552 master->stats.eoe_errors = 0; |
527 } |
553 } |
528 master->stats.t_last = t_now; |
554 master->stats.t_last = t_now; |
529 } |
555 } |
530 } |
556 } |
531 |
557 |
613 } |
639 } |
614 |
640 |
615 if (alias_requested) { |
641 if (alias_requested) { |
616 for (i = alias_slave_index + 1; i < master->slave_count; i++) { |
642 for (i = alias_slave_index + 1; i < master->slave_count; i++) { |
617 slave = master->slaves + i; |
643 slave = master->slaves + i; |
618 if (!slave->type || slave->type->bus_coupler) break; |
644 if (!slave->type || |
|
645 slave->type->special == EC_TYPE_BUS_COUPLER) break; |
619 if (i - alias_slave_index == second) return slave; |
646 if (i - alias_slave_index == second) return slave; |
620 } |
647 } |
621 EC_ERR("Slave address \"%s\" - Bus coupler %i has no %lu. slave" |
648 EC_ERR("Slave address \"%s\" - Bus coupler %i has no %lu. slave" |
622 " following!\n", address, |
649 " following!\n", address, |
623 (master->slaves + alias_slave_index)->ring_position, |
650 (master->slaves + alias_slave_index)->ring_position, |
628 coupler_idx = -1; |
655 coupler_idx = -1; |
629 slave_idx = 0; |
656 slave_idx = 0; |
630 for (i = 0; i < master->slave_count; i++, slave_idx++) { |
657 for (i = 0; i < master->slave_count; i++, slave_idx++) { |
631 slave = master->slaves + i; |
658 slave = master->slaves + i; |
632 if (!slave->type) continue; |
659 if (!slave->type) continue; |
633 if (slave->type->bus_coupler) { |
660 if (slave->type->special == EC_TYPE_BUS_COUPLER) { |
634 coupler_idx++; |
661 coupler_idx++; |
635 slave_idx = 0; |
662 slave_idx = 0; |
636 } |
663 } |
637 if (coupler_idx == first && slave_idx == second) return slave; |
664 if (coupler_idx == first && slave_idx == second) return slave; |
638 } |
665 } |
843 if (slave->base_fmmu_count) { |
870 if (slave->base_fmmu_count) { |
844 if (ec_command_npwr(command, slave->station_address, 0x0600, |
871 if (ec_command_npwr(command, slave->station_address, 0x0600, |
845 EC_FMMU_SIZE * slave->base_fmmu_count)) |
872 EC_FMMU_SIZE * slave->base_fmmu_count)) |
846 return -1; |
873 return -1; |
847 memset(command->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count); |
874 memset(command->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count); |
848 if (unlikely(ec_master_simple_io(master))) { |
875 if (unlikely(ec_master_simple_io(master, command))) { |
849 EC_ERR("Resetting FMMUs failed on slave %i!\n", |
876 EC_ERR("Resetting FMMUs failed on slave %i!\n", |
850 slave->ring_position); |
877 slave->ring_position); |
851 return -1; |
878 return -1; |
852 } |
879 } |
853 } |
880 } |
856 if (slave->base_sync_count) { |
883 if (slave->base_sync_count) { |
857 if (ec_command_npwr(command, slave->station_address, 0x0800, |
884 if (ec_command_npwr(command, slave->station_address, 0x0800, |
858 EC_SYNC_SIZE * slave->base_sync_count)) |
885 EC_SYNC_SIZE * slave->base_sync_count)) |
859 return -1; |
886 return -1; |
860 memset(command->data, 0x00, EC_SYNC_SIZE * slave->base_sync_count); |
887 memset(command->data, 0x00, EC_SYNC_SIZE * slave->base_sync_count); |
861 if (unlikely(ec_master_simple_io(master))) { |
888 if (unlikely(ec_master_simple_io(master, command))) { |
862 EC_ERR("Resetting sync managers failed on slave %i!\n", |
889 EC_ERR("Resetting sync managers failed on slave %i!\n", |
863 slave->ring_position); |
890 slave->ring_position); |
864 return -1; |
891 return -1; |
865 } |
892 } |
866 } |
893 } |
872 sync = type->sync_managers[j]; |
899 sync = type->sync_managers[j]; |
873 if (ec_command_npwr(command, slave->station_address, |
900 if (ec_command_npwr(command, slave->station_address, |
874 0x0800 + j * EC_SYNC_SIZE, EC_SYNC_SIZE)) |
901 0x0800 + j * EC_SYNC_SIZE, EC_SYNC_SIZE)) |
875 return -1; |
902 return -1; |
876 ec_sync_config(sync, command->data); |
903 ec_sync_config(sync, command->data); |
877 if (unlikely(ec_master_simple_io(master))) { |
904 if (unlikely(ec_master_simple_io(master, command))) { |
878 EC_ERR("Setting sync manager %i failed on slave %i!\n", |
905 EC_ERR("Setting sync manager %i failed on slave %i!\n", |
879 j, slave->ring_position); |
906 j, slave->ring_position); |
880 return -1; |
907 return -1; |
881 } |
908 } |
882 } |
909 } |
885 list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) { |
912 list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) { |
886 if (ec_command_npwr(command, slave->station_address, |
913 if (ec_command_npwr(command, slave->station_address, |
887 0x800 + eeprom_sync->index * EC_SYNC_SIZE, |
914 0x800 + eeprom_sync->index * EC_SYNC_SIZE, |
888 EC_SYNC_SIZE)) return -1; |
915 EC_SYNC_SIZE)) return -1; |
889 ec_eeprom_sync_config(eeprom_sync, command->data); |
916 ec_eeprom_sync_config(eeprom_sync, command->data); |
890 if (unlikely(ec_master_simple_io(master))) { |
917 if (unlikely(ec_master_simple_io(master, command))) { |
891 EC_ERR("Setting sync manager %i failed on slave %i!\n", |
918 EC_ERR("Setting sync manager %i failed on slave %i!\n", |
892 eeprom_sync->index, slave->ring_position); |
919 eeprom_sync->index, slave->ring_position); |
893 return -1; |
920 return -1; |
894 } |
921 } |
895 } |
922 } |
901 |
928 |
902 // Stop activation here for slaves without type |
929 // Stop activation here for slaves without type |
903 if (!type) continue; |
930 if (!type) continue; |
904 |
931 |
905 // Slaves that are not registered are only brought into PREOP |
932 // Slaves that are not registered are only brought into PREOP |
906 // state -> nice blinking and mailbox comm. possible |
933 // state -> nice blinking and mailbox communication possible |
907 if (!slave->registered && !slave->type->bus_coupler) { |
934 if (!slave->registered && !slave->type->special) { |
908 EC_WARN("Slave %i was not registered!\n", slave->ring_position); |
935 EC_WARN("Slave %i was not registered!\n", slave->ring_position); |
909 continue; |
936 continue; |
910 } |
937 } |
911 |
938 |
912 // Set FMMUs |
939 // Set FMMUs |
915 fmmu = &slave->fmmus[j]; |
942 fmmu = &slave->fmmus[j]; |
916 if (ec_command_npwr(command, slave->station_address, |
943 if (ec_command_npwr(command, slave->station_address, |
917 0x0600 + j * EC_FMMU_SIZE, EC_FMMU_SIZE)) |
944 0x0600 + j * EC_FMMU_SIZE, EC_FMMU_SIZE)) |
918 return -1; |
945 return -1; |
919 ec_fmmu_config(fmmu, command->data); |
946 ec_fmmu_config(fmmu, command->data); |
920 if (unlikely(ec_master_simple_io(master))) { |
947 if (unlikely(ec_master_simple_io(master, command))) { |
921 EC_ERR("Setting FMMU %i failed on slave %i!\n", |
948 EC_ERR("Setting FMMU %i failed on slave %i!\n", |
922 j, slave->ring_position); |
949 j, slave->ring_position); |
923 return -1; |
950 return -1; |
924 } |
951 } |
925 } |
952 } |
1145 ec_master_output_stats(master); |
1172 ec_master_output_stats(master); |
1146 |
1173 |
1147 // Watchdog-Kommando |
1174 // Watchdog-Kommando |
1148 ec_master_process_watch_command(master); |
1175 ec_master_process_watch_command(master); |
1149 ec_master_queue_command(master, &master->watch_command); |
1176 ec_master_queue_command(master, &master->watch_command); |
|
1177 |
|
1178 // Ethernet-over-EtherCAT |
|
1179 ec_master_run_eoe(master); |
1150 } |
1180 } |
1151 |
1181 |
1152 /*****************************************************************************/ |
1182 /*****************************************************************************/ |
1153 |
1183 |
1154 /** |
1184 /** |
1184 void ecrt_master_print(const ec_master_t *master, /**< EtherCAT-Master */ |
1214 void ecrt_master_print(const ec_master_t *master, /**< EtherCAT-Master */ |
1185 unsigned int verbosity /**< Geschwätzigkeit */ |
1215 unsigned int verbosity /**< Geschwätzigkeit */ |
1186 ) |
1216 ) |
1187 { |
1217 { |
1188 unsigned int i; |
1218 unsigned int i; |
|
1219 ec_eoe_t *eoe; |
1189 |
1220 |
1190 EC_INFO("*** Begin master information ***\n"); |
1221 EC_INFO("*** Begin master information ***\n"); |
1191 for (i = 0; i < master->slave_count; i++) |
1222 if (master->slave_count) { |
1192 ec_slave_print(&master->slaves[i], verbosity); |
1223 EC_INFO("Slave list:\n"); |
|
1224 for (i = 0; i < master->slave_count; i++) |
|
1225 ec_slave_print(&master->slaves[i], verbosity); |
|
1226 } |
|
1227 if (!list_empty(&master->eoe_slaves)) { |
|
1228 EC_INFO("Ethernet-over-EtherCAT (EoE) objects:\n"); |
|
1229 list_for_each_entry(eoe, &master->eoe_slaves, list) { |
|
1230 ec_eoe_print(eoe); |
|
1231 } |
|
1232 } |
1193 EC_INFO("*** End master information ***\n"); |
1233 EC_INFO("*** End master information ***\n"); |
|
1234 } |
|
1235 |
|
1236 /*****************************************************************************/ |
|
1237 |
|
1238 void ec_master_run_eoe(ec_master_t *master /**< EtherCAT-Master */) |
|
1239 { |
|
1240 ec_eoe_t *eoe; |
|
1241 |
|
1242 list_for_each_entry(eoe, &master->eoe_slaves, list) { |
|
1243 ec_eoe_run(eoe); |
|
1244 } |
1194 } |
1245 } |
1195 |
1246 |
1196 /*****************************************************************************/ |
1247 /*****************************************************************************/ |
1197 |
1248 |
1198 EXPORT_SYMBOL(ecrt_master_create_domain); |
1249 EXPORT_SYMBOL(ecrt_master_create_domain); |