370 |
369 |
371 response_tries_left = 10; |
370 response_tries_left = 10; |
372 do |
371 do |
373 { |
372 { |
374 ec_master_queue_command(master, command); |
373 ec_master_queue_command(master, command); |
375 EtherCAT_rt_master_xio(master); |
374 ecrt_master_sync_io(master); |
376 |
375 |
377 if (command->state == EC_CMD_RECEIVED) { |
376 if (command->state == EC_CMD_RECEIVED) { |
378 break; |
377 break; |
379 } |
378 } |
380 else if (command->state == EC_CMD_TIMEOUT) { |
379 else if (command->state == EC_CMD_TIMEOUT) { |
381 EC_ERR("Simple IO TIMED OUT!\n"); |
380 EC_ERR("Simple-IO TIMEOUT!\n"); |
382 return -1; |
381 return -1; |
383 } |
382 } |
384 else if (command->state == EC_CMD_ERROR) { |
383 else if (command->state == EC_CMD_ERROR) { |
385 EC_ERR("Simple IO command error!\n"); |
384 EC_ERR("Simple-IO command error!\n"); |
386 return -1; |
385 return -1; |
387 } |
386 } |
|
387 |
|
388 // Keine direkte Antwort. Dem Slave Zeit lassen... |
|
389 udelay(10); |
388 } |
390 } |
389 while (unlikely(!command->working_counter && --response_tries_left)); |
391 while (unlikely(!command->working_counter && --response_tries_left)); |
390 |
392 |
391 if (unlikely(!response_tries_left)) { |
393 if (unlikely(!response_tries_left)) { |
392 EC_ERR("No response in simple IO!\n"); |
394 EC_ERR("No response in simple-IO!\n"); |
393 return -1; |
395 return -1; |
394 } |
396 } |
395 |
397 |
396 return 0; |
398 return 0; |
397 } |
399 } |
651 * Echtzeitschnittstelle |
653 * Echtzeitschnittstelle |
652 * |
654 * |
653 *****************************************************************************/ |
655 *****************************************************************************/ |
654 |
656 |
655 /** |
657 /** |
656 Registriert eine neue Domäne. |
658 Erstellt eine neue Domäne. |
657 |
659 |
658 \return Zeiger auf die Domäne bei Erfolg, sonst NULL. |
660 \return Zeiger auf die Domäne bei Erfolg, sonst NULL. |
659 */ |
661 */ |
660 |
662 |
661 ec_domain_t *EtherCAT_rt_master_register_domain(ec_master_t *master, |
663 ec_domain_t *ecrt_master_create_domain(ec_master_t *master /**< Master */) |
662 /**< Domäne */ |
|
663 ec_domain_mode_t mode, |
|
664 /**< Modus */ |
|
665 unsigned int timeout_us |
|
666 /**< Timeout */ |
|
667 ) |
|
668 { |
664 { |
669 ec_domain_t *domain; |
665 ec_domain_t *domain; |
670 |
666 |
671 if (!(domain = (ec_domain_t *) kmalloc(sizeof(ec_domain_t), GFP_KERNEL))) { |
667 if (!(domain = (ec_domain_t *) kmalloc(sizeof(ec_domain_t), GFP_KERNEL))) { |
672 EC_ERR("Error allocating domain memory!\n"); |
668 EC_ERR("Error allocating domain memory!\n"); |
673 return NULL; |
669 return NULL; |
674 } |
670 } |
675 |
671 |
676 ec_domain_init(domain, master, mode, timeout_us); |
672 ec_domain_init(domain, master); |
677 |
|
678 list_add_tail(&domain->list, &master->domains); |
673 list_add_tail(&domain->list, &master->domains); |
679 |
674 |
680 return domain; |
675 return domain; |
681 } |
676 } |
682 |
677 |
690 Zustandsübergänge durch, bis der Slave betriebsbereit ist. |
685 Zustandsübergänge durch, bis der Slave betriebsbereit ist. |
691 |
686 |
692 \return 0 bei Erfolg, sonst < 0 |
687 \return 0 bei Erfolg, sonst < 0 |
693 */ |
688 */ |
694 |
689 |
695 int EtherCAT_rt_master_activate(ec_master_t *master /**< EtherCAT-Master */) |
690 int ecrt_master_activate(ec_master_t *master /**< EtherCAT-Master */) |
696 { |
691 { |
697 unsigned int i, j; |
692 unsigned int i, j; |
698 ec_slave_t *slave; |
693 ec_slave_t *slave; |
699 ec_command_t command; |
694 ec_command_t command; |
700 const ec_sync_t *sync; |
695 const ec_sync_t *sync; |
815 |
810 |
816 /*****************************************************************************/ |
811 /*****************************************************************************/ |
817 |
812 |
818 /** |
813 /** |
819 Setzt alle Slaves zurück in den Init-Zustand. |
814 Setzt alle Slaves zurück in den Init-Zustand. |
820 |
815 */ |
821 \return 0 bei Erfolg, sonst < 0 |
816 |
822 */ |
817 void ecrt_master_deactivate(ec_master_t *master /**< EtherCAT-Master */) |
823 |
|
824 int EtherCAT_rt_master_deactivate(ec_master_t *master /**< EtherCAT-Master */) |
|
825 { |
818 { |
826 ec_slave_t *slave; |
819 ec_slave_t *slave; |
827 unsigned int i; |
820 unsigned int i; |
828 |
821 |
829 for (i = 0; i < master->slave_count; i++) |
822 for (i = 0; i < master->slave_count; i++) |
830 { |
823 { |
831 slave = master->slaves + i; |
824 slave = master->slaves + i; |
832 |
|
833 // CRC-Zählerstände ausgeben |
|
834 ec_slave_check_crc(slave); |
825 ec_slave_check_crc(slave); |
835 |
826 ec_slave_state_change(slave, EC_SLAVE_STATE_INIT); |
836 if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_INIT) != 0)) |
827 } |
837 return -1; |
828 } |
838 } |
829 |
839 |
830 /*****************************************************************************/ |
840 return 0; |
831 |
841 } |
832 /** |
842 |
833 Sendet und empfängt Kommandos synchron. |
843 /*****************************************************************************/ |
834 */ |
844 |
835 |
845 /** |
836 void ecrt_master_sync_io(ec_master_t *master) |
846 Sendet und empfängt Kommandos. |
|
847 |
|
848 \return 0 bei Erfolg, sonst < 0 |
|
849 */ |
|
850 |
|
851 void EtherCAT_rt_master_xio(ec_master_t *master) |
|
852 { |
837 { |
853 ec_command_t *command, *next; |
838 ec_command_t *command, *next; |
854 unsigned int commands_sent; |
839 unsigned int commands_sent; |
855 cycles_t t_start, t_end, t_timeout; |
840 cycles_t t_start, t_end, t_timeout; |
856 |
841 |
910 } |
895 } |
911 |
896 |
912 /*****************************************************************************/ |
897 /*****************************************************************************/ |
913 |
898 |
914 /** |
899 /** |
|
900 Sendet Kommandos asynchron. |
|
901 */ |
|
902 |
|
903 void ecrt_master_async_send(ec_master_t *master) |
|
904 { |
|
905 ec_command_t *command, *next; |
|
906 |
|
907 ec_master_output_stats(master); |
|
908 |
|
909 if (unlikely(!master->device->link_state)) { |
|
910 // Link DOWN, keines der Kommandos kann gesendet werden. |
|
911 list_for_each_entry_safe(command, next, &master->commands, list) { |
|
912 command->state = EC_CMD_ERROR; |
|
913 list_del_init(&command->list); |
|
914 } |
|
915 |
|
916 // Device-Zustand abfragen |
|
917 ec_device_call_isr(master->device); |
|
918 return; |
|
919 } |
|
920 |
|
921 // Rahmen senden |
|
922 ec_master_send_commands(master); |
|
923 } |
|
924 |
|
925 /*****************************************************************************/ |
|
926 |
|
927 /** |
|
928 Empfängt Kommandos asynchron. |
|
929 */ |
|
930 |
|
931 void ecrt_master_async_receive(ec_master_t *master) |
|
932 { |
|
933 ec_command_t *command, *next; |
|
934 |
|
935 ec_master_output_stats(master); |
|
936 |
|
937 ec_device_call_isr(master->device); |
|
938 |
|
939 // Alle empfangenen Kommandos aus der Liste entfernen |
|
940 list_for_each_entry_safe(command, next, &master->commands, list) |
|
941 if (command->state == EC_CMD_RECEIVED) |
|
942 list_del_init(&command->list); |
|
943 |
|
944 // Alle verbleibenden Kommandos entfernen. |
|
945 list_for_each_entry_safe(command, next, &master->commands, list) { |
|
946 switch (command->state) { |
|
947 case EC_CMD_SENT: |
|
948 case EC_CMD_QUEUED: |
|
949 command->state = EC_CMD_TIMEOUT; |
|
950 master->stats.timeouts++; |
|
951 ec_master_output_stats(master); |
|
952 break; |
|
953 default: |
|
954 break; |
|
955 } |
|
956 list_del_init(&command->list); |
|
957 } |
|
958 } |
|
959 |
|
960 /*****************************************************************************/ |
|
961 |
|
962 /** |
915 Setzt die Debug-Ebene des Masters. |
963 Setzt die Debug-Ebene des Masters. |
916 |
964 |
917 Folgende Debug-Level sind definiert: |
965 Folgende Debug-Level sind definiert: |
918 |
966 |
919 - 1: Nur Positionsmarken in bestimmten Funktionen |
967 - 1: Nur Positionsmarken in bestimmten Funktionen |
920 - 2: Komplette Frame-Inhalte |
968 - 2: Komplette Frame-Inhalte |
921 */ |
969 */ |
922 |
970 |
923 void EtherCAT_rt_master_debug(ec_master_t *master, |
971 void ecrt_master_debug(ec_master_t *master, /**< EtherCAT-Master */ |
924 /**< EtherCAT-Master */ |
972 int level /**< Debug-Level */ |
925 int level |
973 ) |
926 /**< Debug-Level */ |
|
927 ) |
|
928 { |
974 { |
929 if (level != master->debug_level) { |
975 if (level != master->debug_level) { |
930 master->debug_level = level; |
976 master->debug_level = level; |
931 EC_INFO("Master debug level set to %i.\n", level); |
977 EC_INFO("Master debug level set to %i.\n", level); |
932 } |
978 } |
950 EC_INFO("*** End master information ***\n"); |
994 EC_INFO("*** End master information ***\n"); |
951 } |
995 } |
952 |
996 |
953 /*****************************************************************************/ |
997 /*****************************************************************************/ |
954 |
998 |
955 EXPORT_SYMBOL(EtherCAT_rt_master_register_domain); |
999 EXPORT_SYMBOL(ecrt_master_create_domain); |
956 EXPORT_SYMBOL(EtherCAT_rt_master_activate); |
1000 EXPORT_SYMBOL(ecrt_master_activate); |
957 EXPORT_SYMBOL(EtherCAT_rt_master_deactivate); |
1001 EXPORT_SYMBOL(ecrt_master_deactivate); |
958 EXPORT_SYMBOL(EtherCAT_rt_master_xio); |
1002 EXPORT_SYMBOL(ecrt_master_sync_io); |
959 EXPORT_SYMBOL(EtherCAT_rt_master_debug); |
1003 EXPORT_SYMBOL(ecrt_master_async_send); |
960 EXPORT_SYMBOL(EtherCAT_rt_master_print); |
1004 EXPORT_SYMBOL(ecrt_master_async_receive); |
|
1005 EXPORT_SYMBOL(ecrt_master_debug); |
|
1006 EXPORT_SYMBOL(ecrt_master_print); |
961 |
1007 |
962 /*****************************************************************************/ |
1008 /*****************************************************************************/ |
963 |
1009 |
964 /* Emacs-Konfiguration |
1010 /* Emacs-Konfiguration |
965 ;;; Local Variables: *** |
1011 ;;; Local Variables: *** |