47 /** Maximum clock difference (in ns) before going to SAFEOP. |
47 /** Maximum clock difference (in ns) before going to SAFEOP. |
48 * |
48 * |
49 * Wait for DC time difference to drop under this absolute value before |
49 * Wait for DC time difference to drop under this absolute value before |
50 * requesting SAFEOP. |
50 * requesting SAFEOP. |
51 */ |
51 */ |
52 #define EC_DC_MAX_SYNC_DIFF_NS 5000 |
52 #define EC_DC_MAX_SYNC_DIFF_NS 10000 |
53 |
53 |
54 /** Maximum time (in ms) to wait for clock discipline. |
54 /** Maximum time (in ms) to wait for clock discipline. |
55 */ |
55 */ |
56 #define EC_DC_SYNC_WAIT_MS 5000 |
56 #define EC_DC_SYNC_WAIT_MS 5000 |
57 |
57 |
65 void ec_fsm_slave_config_state_init(ec_fsm_slave_config_t *); |
65 void ec_fsm_slave_config_state_init(ec_fsm_slave_config_t *); |
66 void ec_fsm_slave_config_state_clear_fmmus(ec_fsm_slave_config_t *); |
66 void ec_fsm_slave_config_state_clear_fmmus(ec_fsm_slave_config_t *); |
67 void ec_fsm_slave_config_state_clear_sync(ec_fsm_slave_config_t *); |
67 void ec_fsm_slave_config_state_clear_sync(ec_fsm_slave_config_t *); |
68 void ec_fsm_slave_config_state_dc_clear_assign(ec_fsm_slave_config_t *); |
68 void ec_fsm_slave_config_state_dc_clear_assign(ec_fsm_slave_config_t *); |
69 void ec_fsm_slave_config_state_mbox_sync(ec_fsm_slave_config_t *); |
69 void ec_fsm_slave_config_state_mbox_sync(ec_fsm_slave_config_t *); |
|
70 #ifdef EC_SII_ASSIGN |
|
71 void ec_fsm_slave_config_state_assign_pdi(ec_fsm_slave_config_t *); |
|
72 #endif |
70 void ec_fsm_slave_config_state_boot_preop(ec_fsm_slave_config_t *); |
73 void ec_fsm_slave_config_state_boot_preop(ec_fsm_slave_config_t *); |
|
74 #ifdef EC_SII_ASSIGN |
|
75 void ec_fsm_slave_config_state_assign_ethercat(ec_fsm_slave_config_t *); |
|
76 #endif |
71 void ec_fsm_slave_config_state_sdo_conf(ec_fsm_slave_config_t *); |
77 void ec_fsm_slave_config_state_sdo_conf(ec_fsm_slave_config_t *); |
72 void ec_fsm_slave_config_state_soe_conf_preop(ec_fsm_slave_config_t *); |
78 void ec_fsm_slave_config_state_soe_conf_preop(ec_fsm_slave_config_t *); |
73 void ec_fsm_slave_config_state_watchdog_divider(ec_fsm_slave_config_t *); |
79 void ec_fsm_slave_config_state_watchdog_divider(ec_fsm_slave_config_t *); |
74 void ec_fsm_slave_config_state_watchdog(ec_fsm_slave_config_t *); |
80 void ec_fsm_slave_config_state_watchdog(ec_fsm_slave_config_t *); |
75 void ec_fsm_slave_config_state_pdo_sync(ec_fsm_slave_config_t *); |
81 void ec_fsm_slave_config_state_pdo_sync(ec_fsm_slave_config_t *); |
85 |
91 |
86 void ec_fsm_slave_config_enter_init(ec_fsm_slave_config_t *); |
92 void ec_fsm_slave_config_enter_init(ec_fsm_slave_config_t *); |
87 void ec_fsm_slave_config_enter_clear_sync(ec_fsm_slave_config_t *); |
93 void ec_fsm_slave_config_enter_clear_sync(ec_fsm_slave_config_t *); |
88 void ec_fsm_slave_config_enter_dc_clear_assign(ec_fsm_slave_config_t *); |
94 void ec_fsm_slave_config_enter_dc_clear_assign(ec_fsm_slave_config_t *); |
89 void ec_fsm_slave_config_enter_mbox_sync(ec_fsm_slave_config_t *); |
95 void ec_fsm_slave_config_enter_mbox_sync(ec_fsm_slave_config_t *); |
|
96 #ifdef EC_SII_ASSIGN |
|
97 void ec_fsm_slave_config_enter_assign_pdi(ec_fsm_slave_config_t *); |
|
98 #endif |
90 void ec_fsm_slave_config_enter_boot_preop(ec_fsm_slave_config_t *); |
99 void ec_fsm_slave_config_enter_boot_preop(ec_fsm_slave_config_t *); |
91 void ec_fsm_slave_config_enter_sdo_conf(ec_fsm_slave_config_t *); |
100 void ec_fsm_slave_config_enter_sdo_conf(ec_fsm_slave_config_t *); |
92 void ec_fsm_slave_config_enter_soe_conf_preop(ec_fsm_slave_config_t *); |
101 void ec_fsm_slave_config_enter_soe_conf_preop(ec_fsm_slave_config_t *); |
93 void ec_fsm_slave_config_enter_pdo_conf(ec_fsm_slave_config_t *); |
102 void ec_fsm_slave_config_enter_pdo_conf(ec_fsm_slave_config_t *); |
94 void ec_fsm_slave_config_enter_watchdog_divider(ec_fsm_slave_config_t *); |
103 void ec_fsm_slave_config_enter_watchdog_divider(ec_fsm_slave_config_t *); |
112 void ec_fsm_slave_config_init( |
121 void ec_fsm_slave_config_init( |
113 ec_fsm_slave_config_t *fsm, /**< slave state machine */ |
122 ec_fsm_slave_config_t *fsm, /**< slave state machine */ |
114 ec_datagram_t *datagram, /**< datagram structure to use */ |
123 ec_datagram_t *datagram, /**< datagram structure to use */ |
115 ec_fsm_change_t *fsm_change, /**< State change state machine to use. */ |
124 ec_fsm_change_t *fsm_change, /**< State change state machine to use. */ |
116 ec_fsm_coe_t *fsm_coe, /**< CoE state machine to use. */ |
125 ec_fsm_coe_t *fsm_coe, /**< CoE state machine to use. */ |
|
126 ec_fsm_soe_t *fsm_soe, /**< SoE state machine to use. */ |
117 ec_fsm_pdo_t *fsm_pdo /**< PDO configuration state machine to use. */ |
127 ec_fsm_pdo_t *fsm_pdo /**< PDO configuration state machine to use. */ |
118 ) |
128 ) |
119 { |
129 { |
120 ec_sdo_request_init(&fsm->request_copy); |
130 ec_sdo_request_init(&fsm->request_copy); |
121 ec_soe_request_init(&fsm->soe_request_copy); |
131 ec_soe_request_init(&fsm->soe_request_copy); |
122 |
132 |
123 fsm->datagram = datagram; |
133 fsm->datagram = datagram; |
124 fsm->fsm_change = fsm_change; |
134 fsm->fsm_change = fsm_change; |
125 fsm->fsm_coe = fsm_coe; |
135 fsm->fsm_coe = fsm_coe; |
|
136 fsm->fsm_soe = fsm_soe; |
126 fsm->fsm_pdo = fsm_pdo; |
137 fsm->fsm_pdo = fsm_pdo; |
127 } |
138 } |
128 |
139 |
129 /*****************************************************************************/ |
140 /*****************************************************************************/ |
130 |
141 |
175 */ |
186 */ |
176 int ec_fsm_slave_config_exec( |
187 int ec_fsm_slave_config_exec( |
177 ec_fsm_slave_config_t *fsm /**< slave state machine */ |
188 ec_fsm_slave_config_t *fsm /**< slave state machine */ |
178 ) |
189 ) |
179 { |
190 { |
180 if (fsm->datagram->state == EC_DATAGRAM_QUEUED |
191 if (fsm->datagram->state == EC_DATAGRAM_SENT |
181 || fsm->datagram->state == EC_DATAGRAM_SENT) { |
192 || fsm->datagram->state == EC_DATAGRAM_QUEUED) { |
182 // datagram was not sent or received yet. |
193 // datagram was not sent or received yet. |
183 return ec_fsm_slave_config_running(fsm); |
194 return ec_fsm_slave_config_running(fsm); |
184 } |
195 } |
185 |
196 |
186 fsm->state(fsm); |
197 fsm->state(fsm); |
428 |
439 |
429 if (!slave->sii.mailbox_protocols) { |
440 if (!slave->sii.mailbox_protocols) { |
430 // no mailbox protocols supported |
441 // no mailbox protocols supported |
431 EC_SLAVE_DBG(slave, 1, "Slave does not support" |
442 EC_SLAVE_DBG(slave, 1, "Slave does not support" |
432 " mailbox communication.\n"); |
443 " mailbox communication.\n"); |
|
444 #ifdef EC_SII_ASSIGN |
|
445 ec_fsm_slave_config_enter_assign_pdi(fsm); |
|
446 #else |
433 ec_fsm_slave_config_enter_boot_preop(fsm); |
447 ec_fsm_slave_config_enter_boot_preop(fsm); |
|
448 #endif |
434 return; |
449 return; |
435 } |
450 } |
436 |
451 |
437 EC_SLAVE_DBG(slave, 1, "Configuring mailbox sync managers...\n"); |
452 EC_SLAVE_DBG(slave, 1, "Configuring mailbox sync managers...\n"); |
438 |
453 |
591 EC_SLAVE_ERR(slave, "Failed to set sync managers: "); |
606 EC_SLAVE_ERR(slave, "Failed to set sync managers: "); |
592 ec_datagram_print_wc_error(datagram); |
607 ec_datagram_print_wc_error(datagram); |
593 return; |
608 return; |
594 } |
609 } |
595 |
610 |
|
611 #ifdef EC_SII_ASSIGN |
|
612 ec_fsm_slave_config_enter_assign_pdi(fsm); |
|
613 #else |
596 ec_fsm_slave_config_enter_boot_preop(fsm); |
614 ec_fsm_slave_config_enter_boot_preop(fsm); |
597 } |
615 #endif |
|
616 } |
|
617 |
|
618 /*****************************************************************************/ |
|
619 |
|
620 #ifdef EC_SII_ASSIGN |
|
621 |
|
622 /** Assign SII to PDI. |
|
623 */ |
|
624 void ec_fsm_slave_config_enter_assign_pdi( |
|
625 ec_fsm_slave_config_t *fsm /**< slave state machine */ |
|
626 ) |
|
627 { |
|
628 ec_datagram_t *datagram = fsm->datagram; |
|
629 ec_slave_t *slave = fsm->slave; |
|
630 |
|
631 if (fsm->slave->requested_state != EC_SLAVE_STATE_BOOT) { |
|
632 EC_SLAVE_DBG(slave, 1, "Assigning SII access to PDI.\n"); |
|
633 |
|
634 ec_datagram_fpwr(datagram, slave->station_address, 0x0500, 0x01); |
|
635 EC_WRITE_U8(datagram->data, 0x01); // PDI |
|
636 fsm->retries = EC_FSM_RETRIES; |
|
637 fsm->state = ec_fsm_slave_config_state_assign_pdi; |
|
638 } |
|
639 else { |
|
640 ec_fsm_slave_config_enter_boot_preop(fsm); |
|
641 } |
|
642 } |
|
643 |
|
644 /*****************************************************************************/ |
|
645 |
|
646 /** Slave configuration state: ASSIGN_PDI. |
|
647 */ |
|
648 void ec_fsm_slave_config_state_assign_pdi( |
|
649 ec_fsm_slave_config_t *fsm /**< slave state machine */ |
|
650 ) |
|
651 { |
|
652 ec_datagram_t *datagram = fsm->datagram; |
|
653 ec_slave_t *slave = fsm->slave; |
|
654 |
|
655 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { |
|
656 return; |
|
657 } |
|
658 |
|
659 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
|
660 EC_SLAVE_WARN(slave, "Failed receive SII assignment datagram: "); |
|
661 ec_datagram_print_state(datagram); |
|
662 goto cont_preop; |
|
663 } |
|
664 |
|
665 if (datagram->working_counter != 1) { |
|
666 EC_SLAVE_WARN(slave, "Failed to assign SII to PDI: "); |
|
667 ec_datagram_print_wc_error(datagram); |
|
668 } |
|
669 |
|
670 cont_preop: |
|
671 ec_fsm_slave_config_enter_boot_preop(fsm); |
|
672 } |
|
673 |
|
674 #endif |
598 |
675 |
599 /*****************************************************************************/ |
676 /*****************************************************************************/ |
600 |
677 |
601 /** Request PREOP state. |
678 /** Request PREOP state. |
602 */ |
679 */ |
605 ) |
682 ) |
606 { |
683 { |
607 fsm->state = ec_fsm_slave_config_state_boot_preop; |
684 fsm->state = ec_fsm_slave_config_state_boot_preop; |
608 |
685 |
609 if (fsm->slave->requested_state != EC_SLAVE_STATE_BOOT) { |
686 if (fsm->slave->requested_state != EC_SLAVE_STATE_BOOT) { |
610 ec_fsm_change_start(fsm->fsm_change, fsm->slave, EC_SLAVE_STATE_PREOP); |
687 ec_fsm_change_start(fsm->fsm_change, |
|
688 fsm->slave, EC_SLAVE_STATE_PREOP); |
611 } else { // BOOT |
689 } else { // BOOT |
612 ec_fsm_change_start(fsm->fsm_change, fsm->slave, EC_SLAVE_STATE_BOOT); |
690 ec_fsm_change_start(fsm->fsm_change, |
|
691 fsm->slave, EC_SLAVE_STATE_BOOT); |
613 } |
692 } |
614 |
693 |
615 ec_fsm_change_exec(fsm->fsm_change); // execute immediately |
694 ec_fsm_change_exec(fsm->fsm_change); // execute immediately |
616 } |
695 } |
617 |
696 |
623 ec_fsm_slave_config_t *fsm /**< slave state machine */ |
702 ec_fsm_slave_config_t *fsm /**< slave state machine */ |
624 ) |
703 ) |
625 { |
704 { |
626 ec_slave_t *slave = fsm->slave; |
705 ec_slave_t *slave = fsm->slave; |
627 |
706 |
628 if (ec_fsm_change_exec(fsm->fsm_change)) return; |
707 if (ec_fsm_change_exec(fsm->fsm_change)) { |
|
708 return; |
|
709 } |
629 |
710 |
630 if (!ec_fsm_change_success(fsm->fsm_change)) { |
711 if (!ec_fsm_change_success(fsm->fsm_change)) { |
631 if (!fsm->fsm_change->spontaneous_change) |
712 if (!fsm->fsm_change->spontaneous_change) |
632 slave->error_flag = 1; |
713 slave->error_flag = 1; |
633 fsm->state = ec_fsm_slave_config_state_error; |
714 fsm->state = ec_fsm_slave_config_state_error; |
638 slave->jiffies_preop = fsm->datagram->jiffies_received; |
719 slave->jiffies_preop = fsm->datagram->jiffies_received; |
639 |
720 |
640 EC_SLAVE_DBG(slave, 1, "Now in %s.\n", |
721 EC_SLAVE_DBG(slave, 1, "Now in %s.\n", |
641 slave->requested_state != EC_SLAVE_STATE_BOOT ? "PREOP" : "BOOT"); |
722 slave->requested_state != EC_SLAVE_STATE_BOOT ? "PREOP" : "BOOT"); |
642 |
723 |
|
724 #ifdef EC_SII_ASSIGN |
|
725 EC_SLAVE_DBG(slave, 1, "Assigning SII access back to EtherCAT.\n"); |
|
726 |
|
727 ec_datagram_fpwr(fsm->datagram, slave->station_address, 0x0500, 0x01); |
|
728 EC_WRITE_U8(fsm->datagram->data, 0x00); // EtherCAT |
|
729 fsm->retries = EC_FSM_RETRIES; |
|
730 fsm->state = ec_fsm_slave_config_state_assign_ethercat; |
|
731 #else |
643 if (slave->current_state == slave->requested_state) { |
732 if (slave->current_state == slave->requested_state) { |
644 fsm->state = ec_fsm_slave_config_state_end; // successful |
733 fsm->state = ec_fsm_slave_config_state_end; // successful |
645 EC_SLAVE_DBG(slave, 1, "Finished configuration.\n"); |
734 EC_SLAVE_DBG(slave, 1, "Finished configuration.\n"); |
646 return; |
735 return; |
647 } |
736 } |
648 |
737 |
649 ec_fsm_slave_config_enter_sdo_conf(fsm); |
738 ec_fsm_slave_config_enter_sdo_conf(fsm); |
650 } |
739 #endif |
|
740 } |
|
741 |
|
742 /*****************************************************************************/ |
|
743 |
|
744 #ifdef EC_SII_ASSIGN |
|
745 |
|
746 /** Slave configuration state: ASSIGN_ETHERCAT. |
|
747 */ |
|
748 void ec_fsm_slave_config_state_assign_ethercat( |
|
749 ec_fsm_slave_config_t *fsm /**< slave state machine */ |
|
750 ) |
|
751 { |
|
752 ec_datagram_t *datagram = fsm->datagram; |
|
753 ec_slave_t *slave = fsm->slave; |
|
754 |
|
755 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { |
|
756 return; |
|
757 } |
|
758 |
|
759 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
|
760 EC_SLAVE_WARN(slave, "Failed receive SII assignment datagram: "); |
|
761 ec_datagram_print_state(datagram); |
|
762 goto cont_sdo_conf; |
|
763 } |
|
764 |
|
765 if (datagram->working_counter != 1) { |
|
766 EC_SLAVE_WARN(slave, "Failed to assign SII back to EtherCAT: "); |
|
767 ec_datagram_print_wc_error(datagram); |
|
768 } |
|
769 |
|
770 cont_sdo_conf: |
|
771 if (slave->current_state == slave->requested_state) { |
|
772 fsm->state = ec_fsm_slave_config_state_end; // successful |
|
773 EC_SLAVE_DBG(slave, 1, "Finished configuration.\n"); |
|
774 return; |
|
775 } |
|
776 |
|
777 ec_fsm_slave_config_enter_sdo_conf(fsm); |
|
778 } |
|
779 |
|
780 #endif |
651 |
781 |
652 /*****************************************************************************/ |
782 /*****************************************************************************/ |
653 |
783 |
654 /** Check for SDO configurations to be applied. |
784 /** Check for SDO configurations to be applied. |
655 */ |
785 */ |
675 fsm->request = list_entry(fsm->slave->config->sdo_configs.next, |
805 fsm->request = list_entry(fsm->slave->config->sdo_configs.next, |
676 ec_sdo_request_t, list); |
806 ec_sdo_request_t, list); |
677 ec_sdo_request_copy(&fsm->request_copy, fsm->request); |
807 ec_sdo_request_copy(&fsm->request_copy, fsm->request); |
678 ecrt_sdo_request_write(&fsm->request_copy); |
808 ecrt_sdo_request_write(&fsm->request_copy); |
679 ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request_copy); |
809 ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request_copy); |
680 ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately |
810 ec_fsm_coe_exec(fsm->fsm_coe, fsm->datagram); // execute immediately |
681 } |
811 } |
682 |
812 |
683 /*****************************************************************************/ |
813 /*****************************************************************************/ |
684 |
814 |
685 /** Slave configuration state: SDO_CONF. |
815 /** Slave configuration state: SDO_CONF. |
686 */ |
816 */ |
687 void ec_fsm_slave_config_state_sdo_conf( |
817 void ec_fsm_slave_config_state_sdo_conf( |
688 ec_fsm_slave_config_t *fsm /**< slave state machine */ |
818 ec_fsm_slave_config_t *fsm /**< slave state machine */ |
689 ) |
819 ) |
690 { |
820 { |
691 if (ec_fsm_coe_exec(fsm->fsm_coe)) return; |
821 if (ec_fsm_coe_exec(fsm->fsm_coe, fsm->datagram)) { |
|
822 return; |
|
823 } |
692 |
824 |
693 if (!ec_fsm_coe_success(fsm->fsm_coe)) { |
825 if (!ec_fsm_coe_success(fsm->fsm_coe)) { |
694 EC_SLAVE_ERR(fsm->slave, "SDO configuration failed.\n"); |
826 EC_SLAVE_ERR(fsm->slave, "SDO configuration failed.\n"); |
695 fsm->slave->error_flag = 1; |
827 fsm->slave->error_flag = 1; |
696 fsm->state = ec_fsm_slave_config_state_error; |
828 fsm->state = ec_fsm_slave_config_state_error; |
707 fsm->request = list_entry(fsm->request->list.next, |
839 fsm->request = list_entry(fsm->request->list.next, |
708 ec_sdo_request_t, list); |
840 ec_sdo_request_t, list); |
709 ec_sdo_request_copy(&fsm->request_copy, fsm->request); |
841 ec_sdo_request_copy(&fsm->request_copy, fsm->request); |
710 ecrt_sdo_request_write(&fsm->request_copy); |
842 ecrt_sdo_request_write(&fsm->request_copy); |
711 ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request_copy); |
843 ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request_copy); |
712 ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately |
844 ec_fsm_coe_exec(fsm->fsm_coe, fsm->datagram); // execute immediately |
713 return; |
845 return; |
714 } |
846 } |
715 |
847 |
716 // All SDOs are now configured. |
848 // All SDOs are now configured. |
717 ec_fsm_slave_config_enter_soe_conf_preop(fsm); |
849 ec_fsm_slave_config_enter_soe_conf_preop(fsm); |
724 void ec_fsm_slave_config_enter_soe_conf_preop( |
856 void ec_fsm_slave_config_enter_soe_conf_preop( |
725 ec_fsm_slave_config_t *fsm /**< slave state machine */ |
857 ec_fsm_slave_config_t *fsm /**< slave state machine */ |
726 ) |
858 ) |
727 { |
859 { |
728 ec_slave_t *slave = fsm->slave; |
860 ec_slave_t *slave = fsm->slave; |
729 ec_fsm_soe_t *fsm_soe = &slave->fsm.fsm_soe; |
|
730 ec_soe_request_t *req; |
861 ec_soe_request_t *req; |
731 |
862 |
732 if (!slave->config) { |
863 if (!slave->config) { |
733 ec_fsm_slave_config_enter_pdo_sync(fsm); |
864 ec_fsm_slave_config_enter_pdo_sync(fsm); |
734 return; |
865 return; |
739 // start SoE configuration |
870 // start SoE configuration |
740 fsm->state = ec_fsm_slave_config_state_soe_conf_preop; |
871 fsm->state = ec_fsm_slave_config_state_soe_conf_preop; |
741 fsm->soe_request = req; |
872 fsm->soe_request = req; |
742 ec_soe_request_copy(&fsm->soe_request_copy, fsm->soe_request); |
873 ec_soe_request_copy(&fsm->soe_request_copy, fsm->soe_request); |
743 ec_soe_request_write(&fsm->soe_request_copy); |
874 ec_soe_request_write(&fsm->soe_request_copy); |
744 ec_fsm_soe_transfer(fsm_soe, fsm->slave, &fsm->soe_request_copy); |
875 ec_fsm_soe_transfer(fsm->fsm_soe, fsm->slave, |
745 ec_fsm_soe_exec(fsm_soe); // execute immediately |
876 &fsm->soe_request_copy); |
746 ec_slave_mbox_queue_datagrams(slave, fsm_soe->mbox); |
877 ec_fsm_soe_exec(fsm->fsm_soe, fsm->datagram); |
747 return; |
878 return; |
748 } |
879 } |
749 } |
880 } |
750 |
881 |
751 // No SoE configuration to be applied in PREOP |
882 // No SoE configuration to be applied in PREOP |
759 void ec_fsm_slave_config_state_soe_conf_preop( |
890 void ec_fsm_slave_config_state_soe_conf_preop( |
760 ec_fsm_slave_config_t *fsm /**< slave state machine */ |
891 ec_fsm_slave_config_t *fsm /**< slave state machine */ |
761 ) |
892 ) |
762 { |
893 { |
763 ec_slave_t *slave = fsm->slave; |
894 ec_slave_t *slave = fsm->slave; |
764 ec_fsm_soe_t *fsm_soe = &slave->fsm.fsm_soe; |
895 |
765 |
896 if (ec_fsm_soe_exec(fsm->fsm_soe, fsm->datagram)) { |
766 if (ec_fsm_soe_exec(fsm_soe)) { |
897 return; |
767 ec_slave_mbox_queue_datagrams(slave, fsm_soe->mbox); |
898 } |
768 return; |
899 |
769 } |
900 if (!ec_fsm_soe_success(fsm->fsm_soe)) { |
770 |
|
771 if (!ec_fsm_soe_success(fsm_soe)) { |
|
772 EC_SLAVE_ERR(slave, "SoE configuration failed.\n"); |
901 EC_SLAVE_ERR(slave, "SoE configuration failed.\n"); |
773 fsm->slave->error_flag = 1; |
902 fsm->slave->error_flag = 1; |
774 fsm->state = ec_fsm_slave_config_state_error; |
903 fsm->state = ec_fsm_slave_config_state_error; |
775 return; |
904 return; |
776 } |
905 } |
785 fsm->soe_request = list_entry(fsm->soe_request->list.next, |
914 fsm->soe_request = list_entry(fsm->soe_request->list.next, |
786 ec_soe_request_t, list); |
915 ec_soe_request_t, list); |
787 if (fsm->soe_request->al_state == EC_AL_STATE_PREOP) { |
916 if (fsm->soe_request->al_state == EC_AL_STATE_PREOP) { |
788 ec_soe_request_copy(&fsm->soe_request_copy, fsm->soe_request); |
917 ec_soe_request_copy(&fsm->soe_request_copy, fsm->soe_request); |
789 ec_soe_request_write(&fsm->soe_request_copy); |
918 ec_soe_request_write(&fsm->soe_request_copy); |
790 ec_fsm_soe_transfer(fsm_soe, fsm->slave, &fsm->soe_request_copy); |
919 ec_fsm_soe_transfer(fsm->fsm_soe, fsm->slave, |
791 ec_fsm_soe_exec(fsm_soe); // execute immediately |
920 &fsm->soe_request_copy); |
792 ec_slave_mbox_queue_datagrams(slave, fsm_soe->mbox); |
921 ec_fsm_soe_exec(fsm->fsm_soe, fsm->datagram); |
793 return; |
922 return; |
794 } |
923 } |
795 } |
924 } |
796 |
925 |
797 // All PREOP IDNs are now configured. |
926 // All PREOP IDNs are now configured. |
820 ec_fsm_slave_config_t *fsm /**< slave state machine */ |
949 ec_fsm_slave_config_t *fsm /**< slave state machine */ |
821 ) |
950 ) |
822 { |
951 { |
823 // TODO check for config here |
952 // TODO check for config here |
824 |
953 |
825 if (ec_fsm_pdo_exec(fsm->fsm_pdo)) |
954 if (ec_fsm_pdo_exec(fsm->fsm_pdo, fsm->datagram)) { |
826 return; |
955 return; |
|
956 } |
827 |
957 |
828 if (!fsm->slave->config) { // config removed in the meantime |
958 if (!fsm->slave->config) { // config removed in the meantime |
829 ec_fsm_slave_config_reconfigure(fsm); |
959 ec_fsm_slave_config_reconfigure(fsm); |
830 return; |
960 return; |
831 } |
961 } |
1261 } |
1391 } |
1262 |
1392 |
1263 abs_sync_diff = EC_READ_U32(datagram->data) & 0x7fffffff; |
1393 abs_sync_diff = EC_READ_U32(datagram->data) & 0x7fffffff; |
1264 diff_ms = (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; |
1394 diff_ms = (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; |
1265 |
1395 |
1266 if (abs_sync_diff > EC_DC_MAX_SYNC_DIFF_NS) { |
1396 if (abs_sync_diff > EC_DC_MAX_SYNC_DIFF_NS) { |
1267 |
1397 |
1268 if (diff_ms >= EC_DC_SYNC_WAIT_MS) { |
1398 if (diff_ms >= EC_DC_SYNC_WAIT_MS) { |
1269 EC_SLAVE_WARN(slave, "Slave did not sync after %lu ms.\n", |
1399 EC_SLAVE_WARN(slave, "Slave did not sync after %lu ms.\n", |
1270 diff_ms); |
1400 diff_ms); |
1271 } else { |
1401 } else { |
1298 start = start_time + |
1428 start = start_time + |
1299 sync0->cycle_time - remainder + sync0->shift_time; |
1429 sync0->cycle_time - remainder + sync0->shift_time; |
1300 |
1430 |
1301 EC_SLAVE_DBG(slave, 1, "app_start_time=%llu\n", |
1431 EC_SLAVE_DBG(slave, 1, "app_start_time=%llu\n", |
1302 master->app_start_time); |
1432 master->app_start_time); |
|
1433 EC_SLAVE_DBG(slave, 1, " app_time=%llu\n", master->app_time); |
1303 EC_SLAVE_DBG(slave, 1, " start_time=%llu\n", start_time); |
1434 EC_SLAVE_DBG(slave, 1, " start_time=%llu\n", start_time); |
1304 EC_SLAVE_DBG(slave, 1, " cycle_time=%u\n", sync0->cycle_time); |
1435 EC_SLAVE_DBG(slave, 1, " cycle_time=%u\n", sync0->cycle_time); |
1305 EC_SLAVE_DBG(slave, 1, " shift_time=%u\n", sync0->shift_time); |
1436 EC_SLAVE_DBG(slave, 1, " shift_time=%i\n", sync0->shift_time); |
1306 EC_SLAVE_DBG(slave, 1, " remainder=%u\n", remainder); |
1437 EC_SLAVE_DBG(slave, 1, " remainder=%u\n", remainder); |
1307 EC_SLAVE_DBG(slave, 1, " start=%llu\n", start); |
1438 EC_SLAVE_DBG(slave, 1, " start=%llu\n", start); |
1308 start_time = start; |
1439 start_time = start; |
1309 } else { |
1440 } else { |
1310 EC_SLAVE_WARN(slave, "No application time supplied." |
1441 EC_SLAVE_WARN(slave, "No application time supplied." |
1450 void ec_fsm_slave_config_enter_soe_conf_safeop( |
1581 void ec_fsm_slave_config_enter_soe_conf_safeop( |
1451 ec_fsm_slave_config_t *fsm /**< slave state machine */ |
1582 ec_fsm_slave_config_t *fsm /**< slave state machine */ |
1452 ) |
1583 ) |
1453 { |
1584 { |
1454 ec_slave_t *slave = fsm->slave; |
1585 ec_slave_t *slave = fsm->slave; |
1455 ec_fsm_soe_t *fsm_soe = &slave->fsm.fsm_soe; |
|
1456 ec_soe_request_t *req; |
1586 ec_soe_request_t *req; |
1457 |
1587 |
1458 if (!slave->config) { |
1588 if (!slave->config) { |
1459 ec_fsm_slave_config_enter_op(fsm); |
1589 ec_fsm_slave_config_enter_op(fsm); |
1460 return; |
1590 return; |
1465 // start SoE configuration |
1595 // start SoE configuration |
1466 fsm->state = ec_fsm_slave_config_state_soe_conf_safeop; |
1596 fsm->state = ec_fsm_slave_config_state_soe_conf_safeop; |
1467 fsm->soe_request = req; |
1597 fsm->soe_request = req; |
1468 ec_soe_request_copy(&fsm->soe_request_copy, fsm->soe_request); |
1598 ec_soe_request_copy(&fsm->soe_request_copy, fsm->soe_request); |
1469 ec_soe_request_write(&fsm->soe_request_copy); |
1599 ec_soe_request_write(&fsm->soe_request_copy); |
1470 ec_fsm_soe_transfer(fsm_soe, fsm->slave, &fsm->soe_request_copy); |
1600 ec_fsm_soe_transfer(fsm->fsm_soe, fsm->slave, |
1471 ec_fsm_soe_exec(fsm_soe); // execute immediately |
1601 &fsm->soe_request_copy); |
1472 ec_slave_mbox_queue_datagrams(slave, fsm_soe->mbox); |
1602 ec_fsm_soe_exec(fsm->fsm_soe, fsm->datagram); |
1473 return; |
1603 return; |
1474 } |
1604 } |
1475 } |
1605 } |
1476 |
1606 |
1477 // No SoE configuration to be applied in SAFEOP |
1607 // No SoE configuration to be applied in SAFEOP |
1485 void ec_fsm_slave_config_state_soe_conf_safeop( |
1615 void ec_fsm_slave_config_state_soe_conf_safeop( |
1486 ec_fsm_slave_config_t *fsm /**< slave state machine */ |
1616 ec_fsm_slave_config_t *fsm /**< slave state machine */ |
1487 ) |
1617 ) |
1488 { |
1618 { |
1489 ec_slave_t *slave = fsm->slave; |
1619 ec_slave_t *slave = fsm->slave; |
1490 ec_fsm_soe_t *fsm_soe = &slave->fsm.fsm_soe; |
1620 |
1491 |
1621 if (ec_fsm_soe_exec(fsm->fsm_soe, fsm->datagram)) { |
1492 if (ec_fsm_soe_exec(fsm_soe)) { |
1622 return; |
1493 ec_slave_mbox_queue_datagrams(slave, fsm_soe->mbox); |
1623 } |
1494 return; |
1624 |
1495 } |
1625 if (!ec_fsm_soe_success(fsm->fsm_soe)) { |
1496 |
|
1497 if (!ec_fsm_soe_success(fsm_soe)) { |
|
1498 EC_SLAVE_ERR(slave, "SoE configuration failed.\n"); |
1626 EC_SLAVE_ERR(slave, "SoE configuration failed.\n"); |
1499 fsm->slave->error_flag = 1; |
1627 fsm->slave->error_flag = 1; |
1500 fsm->state = ec_fsm_slave_config_state_error; |
1628 fsm->state = ec_fsm_slave_config_state_error; |
1501 return; |
1629 return; |
1502 } |
1630 } |
1511 fsm->soe_request = list_entry(fsm->soe_request->list.next, |
1639 fsm->soe_request = list_entry(fsm->soe_request->list.next, |
1512 ec_soe_request_t, list); |
1640 ec_soe_request_t, list); |
1513 if (fsm->soe_request->al_state == EC_AL_STATE_SAFEOP) { |
1641 if (fsm->soe_request->al_state == EC_AL_STATE_SAFEOP) { |
1514 ec_soe_request_copy(&fsm->soe_request_copy, fsm->soe_request); |
1642 ec_soe_request_copy(&fsm->soe_request_copy, fsm->soe_request); |
1515 ec_soe_request_write(&fsm->soe_request_copy); |
1643 ec_soe_request_write(&fsm->soe_request_copy); |
1516 ec_fsm_soe_transfer(fsm_soe, fsm->slave, &fsm->soe_request_copy); |
1644 ec_fsm_soe_transfer(fsm->fsm_soe, fsm->slave, |
1517 ec_fsm_soe_exec(fsm_soe); // execute immediately |
1645 &fsm->soe_request_copy); |
1518 ec_slave_mbox_queue_datagrams(slave, fsm_soe->mbox); |
1646 ec_fsm_soe_exec(fsm->fsm_soe, fsm->datagram); |
1519 return; |
1647 return; |
1520 } |
1648 } |
1521 } |
1649 } |
1522 |
1650 |
1523 // All SAFEOP IDNs are now configured. |
1651 // All SAFEOP IDNs are now configured. |