52 void ec_fsm_master_rewrite_addresses(ec_fsm_t *); |
52 void ec_fsm_master_rewrite_addresses(ec_fsm_t *); |
53 void ec_fsm_master_configure_slave(ec_fsm_t *); |
53 void ec_fsm_master_configure_slave(ec_fsm_t *); |
54 void ec_fsm_master_scan_slaves(ec_fsm_t *); |
54 void ec_fsm_master_scan_slaves(ec_fsm_t *); |
55 void ec_fsm_master_write_eeprom(ec_fsm_t *); |
55 void ec_fsm_master_write_eeprom(ec_fsm_t *); |
56 |
56 |
57 void ec_fsm_slave_start_reading(ec_fsm_t *); |
57 void ec_fsm_slavescan_start(ec_fsm_t *); |
58 void ec_fsm_slave_read_state(ec_fsm_t *); |
58 void ec_fsm_slavescan_state(ec_fsm_t *); |
59 void ec_fsm_slave_read_base(ec_fsm_t *); |
59 void ec_fsm_slavescan_base(ec_fsm_t *); |
60 void ec_fsm_slave_read_dl(ec_fsm_t *); |
60 void ec_fsm_slavescan_datalink(ec_fsm_t *); |
61 void ec_fsm_slave_eeprom_size(ec_fsm_t *); |
61 void ec_fsm_slavescan_eeprom_size(ec_fsm_t *); |
62 void ec_fsm_slave_fetch_eeprom(ec_fsm_t *); |
62 void ec_fsm_slavescan_eeprom_data(ec_fsm_t *); |
63 void ec_fsm_slave_fetch_eeprom2(ec_fsm_t *); |
63 void ec_fsm_slavescan_eeprom_data2(ec_fsm_t *); |
64 void ec_fsm_slave_end(ec_fsm_t *); |
64 void ec_fsm_slavescan_end(ec_fsm_t *); |
65 |
65 |
66 void ec_fsm_slave_conf(ec_fsm_t *); |
66 void ec_fsm_slaveconf_start(ec_fsm_t *); |
67 void ec_fsm_slave_sync(ec_fsm_t *); |
67 void ec_fsm_slaveconf_sync(ec_fsm_t *); |
68 void ec_fsm_slave_preop(ec_fsm_t *); |
68 void ec_fsm_slaveconf_preop(ec_fsm_t *); |
69 void ec_fsm_slave_fmmu(ec_fsm_t *); |
69 void ec_fsm_slaveconf_fmmu(ec_fsm_t *); |
70 void ec_fsm_slave_saveop(ec_fsm_t *); |
70 void ec_fsm_slaveconf_saveop(ec_fsm_t *); |
71 void ec_fsm_slave_op(ec_fsm_t *); |
71 void ec_fsm_slaveconf_op(ec_fsm_t *); |
72 void ec_fsm_slave_op2(ec_fsm_t *); |
72 void ec_fsm_slaveconf_op2(ec_fsm_t *); |
|
73 void ec_fsm_slaveconf_end(ec_fsm_t *); |
73 |
74 |
74 void ec_fsm_sii_start_reading(ec_fsm_t *); |
75 void ec_fsm_sii_start_reading(ec_fsm_t *); |
75 void ec_fsm_sii_read_check(ec_fsm_t *); |
76 void ec_fsm_sii_read_check(ec_fsm_t *); |
76 void ec_fsm_sii_read_fetch(ec_fsm_t *); |
77 void ec_fsm_sii_read_fetch(ec_fsm_t *); |
77 void ec_fsm_sii_start_writing(ec_fsm_t *); |
78 void ec_fsm_sii_start_writing(ec_fsm_t *); |
740 EC_INFO("Finished writing EEPROM of slave %i.\n", slave->ring_position); |
741 EC_INFO("Finished writing EEPROM of slave %i.\n", slave->ring_position); |
741 kfree(slave->new_eeprom_data); |
742 kfree(slave->new_eeprom_data); |
742 slave->new_eeprom_data = NULL; |
743 slave->new_eeprom_data = NULL; |
743 |
744 |
744 // restart master state machine. |
745 // restart master state machine. |
745 fsm->master_state = ec_fsm_master_start; // TODO: Scan slaves! |
746 fsm->master_state = ec_fsm_master_start; // TODO: Evaluate new contents! |
746 fsm->master_state(fsm); // execute immediately |
747 fsm->master_state(fsm); // execute immediately |
747 return; |
748 return; |
748 } |
749 } |
749 |
750 |
750 /****************************************************************************** |
751 /****************************************************************************** |
751 * slave state machine |
752 * slave scan sub state machine |
752 *****************************************************************************/ |
753 *****************************************************************************/ |
753 |
754 |
754 /** |
755 /** |
755 Slave state: START_READING. |
756 Slave state: START_READING. |
756 First state of the slave state machine. Writes the station address to the |
757 First state of the slave state machine. Writes the station address to the |
757 slave, according to its ring position. |
758 slave, according to its ring position. |
758 */ |
759 */ |
759 |
760 |
760 void ec_fsm_slave_start_reading(ec_fsm_t *fsm /**< finite state machine */) |
761 void ec_fsm_slavescan_start(ec_fsm_t *fsm /**< finite state machine */) |
761 { |
762 { |
762 ec_datagram_t *datagram = &fsm->datagram; |
763 ec_datagram_t *datagram = &fsm->datagram; |
763 |
764 |
764 // write station address |
765 // write station address |
765 ec_datagram_apwr(datagram, fsm->slave->ring_position, 0x0010, 2); |
766 ec_datagram_apwr(datagram, fsm->slave->ring_position, 0x0010, 2); |
766 EC_WRITE_U16(datagram->data, fsm->slave->station_address); |
767 EC_WRITE_U16(datagram->data, fsm->slave->station_address); |
767 ec_master_queue_datagram(fsm->master, datagram); |
768 ec_master_queue_datagram(fsm->master, datagram); |
768 fsm->slave_state = ec_fsm_slave_read_state; |
769 fsm->slave_state = ec_fsm_slavescan_state; |
769 } |
770 } |
770 |
771 |
771 /*****************************************************************************/ |
772 /*****************************************************************************/ |
772 |
773 |
773 /** |
774 /** |
774 Slave state: READ_STATUS. |
775 Slave state: READ_STATUS. |
775 */ |
776 */ |
776 |
777 |
777 void ec_fsm_slave_read_state(ec_fsm_t *fsm /**< finite state machine */) |
778 void ec_fsm_slavescan_state(ec_fsm_t *fsm /**< finite state machine */) |
778 { |
779 { |
779 ec_datagram_t *datagram = &fsm->datagram; |
780 ec_datagram_t *datagram = &fsm->datagram; |
780 |
781 |
781 if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { |
782 if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { |
782 fsm->slave->error_flag = 1; |
783 fsm->slave->error_flag = 1; |
783 fsm->slave_state = ec_fsm_slave_end; |
784 fsm->slave_state = ec_fsm_slavescan_end; |
784 EC_ERR("Failed to write station address of slave %i.\n", |
785 EC_ERR("Failed to write station address of slave %i.\n", |
785 fsm->slave->ring_position); |
786 fsm->slave->ring_position); |
786 return; |
787 return; |
787 } |
788 } |
788 |
789 |
789 // Read AL state |
790 // Read AL state |
790 ec_datagram_nprd(datagram, fsm->slave->station_address, 0x0130, 2); |
791 ec_datagram_nprd(datagram, fsm->slave->station_address, 0x0130, 2); |
791 ec_master_queue_datagram(fsm->master, datagram); |
792 ec_master_queue_datagram(fsm->master, datagram); |
792 fsm->slave_state = ec_fsm_slave_read_base; |
793 fsm->slave_state = ec_fsm_slavescan_base; |
793 } |
794 } |
794 |
795 |
795 /*****************************************************************************/ |
796 /*****************************************************************************/ |
796 |
797 |
797 /** |
798 /** |
798 Slave state: READ_BASE. |
799 Slave state: READ_BASE. |
799 */ |
800 */ |
800 |
801 |
801 void ec_fsm_slave_read_base(ec_fsm_t *fsm /**< finite state machine */) |
802 void ec_fsm_slavescan_base(ec_fsm_t *fsm /**< finite state machine */) |
802 { |
803 { |
803 ec_datagram_t *datagram = &fsm->datagram; |
804 ec_datagram_t *datagram = &fsm->datagram; |
804 ec_slave_t *slave = fsm->slave; |
805 ec_slave_t *slave = fsm->slave; |
805 |
806 |
806 if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { |
807 if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { |
807 fsm->slave->error_flag = 1; |
808 fsm->slave->error_flag = 1; |
808 fsm->slave_state = ec_fsm_slave_end; |
809 fsm->slave_state = ec_fsm_slavescan_end; |
809 EC_ERR("Failed to read AL state of slave %i.\n", |
810 EC_ERR("Failed to read AL state of slave %i.\n", |
810 fsm->slave->ring_position); |
811 fsm->slave->ring_position); |
811 return; |
812 return; |
812 } |
813 } |
813 |
814 |
819 } |
820 } |
820 |
821 |
821 // read base data |
822 // read base data |
822 ec_datagram_nprd(datagram, fsm->slave->station_address, 0x0000, 6); |
823 ec_datagram_nprd(datagram, fsm->slave->station_address, 0x0000, 6); |
823 ec_master_queue_datagram(fsm->master, datagram); |
824 ec_master_queue_datagram(fsm->master, datagram); |
824 fsm->slave_state = ec_fsm_slave_read_dl; |
825 fsm->slave_state = ec_fsm_slavescan_datalink; |
825 } |
826 } |
826 |
827 |
827 /*****************************************************************************/ |
828 /*****************************************************************************/ |
828 |
829 |
829 /** |
830 /** |
830 Slave state: READ_DL. |
831 Slave state: READ_DL. |
831 */ |
832 */ |
832 |
833 |
833 void ec_fsm_slave_read_dl(ec_fsm_t *fsm /**< finite state machine */) |
834 void ec_fsm_slavescan_datalink(ec_fsm_t *fsm /**< finite state machine */) |
834 { |
835 { |
835 ec_datagram_t *datagram = &fsm->datagram; |
836 ec_datagram_t *datagram = &fsm->datagram; |
836 ec_slave_t *slave = fsm->slave; |
837 ec_slave_t *slave = fsm->slave; |
837 |
838 |
838 if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { |
839 if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { |
839 fsm->slave->error_flag = 1; |
840 fsm->slave->error_flag = 1; |
840 fsm->slave_state = ec_fsm_slave_end; |
841 fsm->slave_state = ec_fsm_slavescan_end; |
841 EC_ERR("Failed to read base data of slave %i.\n", |
842 EC_ERR("Failed to read base data of slave %i.\n", |
842 slave->ring_position); |
843 slave->ring_position); |
843 return; |
844 return; |
844 } |
845 } |
845 |
846 |
853 slave->base_fmmu_count = EC_MAX_FMMUS; |
854 slave->base_fmmu_count = EC_MAX_FMMUS; |
854 |
855 |
855 // read data link status |
856 // read data link status |
856 ec_datagram_nprd(datagram, slave->station_address, 0x0110, 2); |
857 ec_datagram_nprd(datagram, slave->station_address, 0x0110, 2); |
857 ec_master_queue_datagram(slave->master, datagram); |
858 ec_master_queue_datagram(slave->master, datagram); |
858 fsm->slave_state = ec_fsm_slave_eeprom_size; |
859 fsm->slave_state = ec_fsm_slavescan_eeprom_size; |
859 } |
860 } |
860 |
861 |
861 /*****************************************************************************/ |
862 /*****************************************************************************/ |
862 |
863 |
863 /** |
864 /** |
864 Slave state: EEPROM_SIZE. |
865 Slave state: EEPROM_SIZE. |
865 Read the actual size of the EEPROM to allocate the EEPROM image. |
866 Read the actual size of the EEPROM to allocate the EEPROM image. |
866 */ |
867 */ |
867 |
868 |
868 void ec_fsm_slave_eeprom_size(ec_fsm_t *fsm /**< finite state machine */) |
869 void ec_fsm_slavescan_eeprom_size(ec_fsm_t *fsm /**< finite state machine */) |
869 { |
870 { |
870 ec_datagram_t *datagram = &fsm->datagram; |
871 ec_datagram_t *datagram = &fsm->datagram; |
871 ec_slave_t *slave = fsm->slave; |
872 ec_slave_t *slave = fsm->slave; |
872 uint16_t dl_status; |
873 uint16_t dl_status; |
873 unsigned int i; |
874 unsigned int i; |
874 |
875 |
875 if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { |
876 if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { |
876 fsm->slave->error_flag = 1; |
877 fsm->slave->error_flag = 1; |
877 fsm->slave_state = ec_fsm_slave_end; |
878 fsm->slave_state = ec_fsm_slavescan_end; |
878 EC_ERR("Failed to read DL status of slave %i.\n", |
879 EC_ERR("Failed to read DL status of slave %i.\n", |
879 slave->ring_position); |
880 slave->ring_position); |
880 return; |
881 return; |
881 } |
882 } |
882 |
883 |
890 // Start fetching EEPROM size |
891 // Start fetching EEPROM size |
891 |
892 |
892 fsm->sii_offset = 0x0040; // first category header |
893 fsm->sii_offset = 0x0040; // first category header |
893 fsm->sii_mode = 1; |
894 fsm->sii_mode = 1; |
894 fsm->sii_state = ec_fsm_sii_start_reading; |
895 fsm->sii_state = ec_fsm_sii_start_reading; |
895 fsm->slave_state = ec_fsm_slave_fetch_eeprom; |
896 fsm->slave_state = ec_fsm_slavescan_eeprom_data; |
896 fsm->slave_state(fsm); // execute state immediately |
897 fsm->slave_state(fsm); // execute state immediately |
897 } |
898 } |
898 |
899 |
899 /*****************************************************************************/ |
900 /*****************************************************************************/ |
900 |
901 |
901 /** |
902 /** |
902 Slave state: FETCH_EEPROM. |
903 Slave state: FETCH_EEPROM. |
903 */ |
904 */ |
904 |
905 |
905 void ec_fsm_slave_fetch_eeprom(ec_fsm_t *fsm /**< finite state machine */) |
906 void ec_fsm_slavescan_eeprom_data(ec_fsm_t *fsm /**< finite state machine */) |
906 { |
907 { |
907 ec_slave_t *slave = fsm->slave; |
908 ec_slave_t *slave = fsm->slave; |
908 uint16_t cat_type, cat_size; |
909 uint16_t cat_type, cat_size; |
909 |
910 |
910 // execute SII state machine |
911 // execute SII state machine |
911 fsm->sii_state(fsm); |
912 fsm->sii_state(fsm); |
912 |
913 |
913 if (fsm->sii_state == ec_fsm_sii_error) { |
914 if (fsm->sii_state == ec_fsm_sii_error) { |
914 fsm->slave->error_flag = 1; |
915 fsm->slave->error_flag = 1; |
915 fsm->slave_state = ec_fsm_slave_end; |
916 fsm->slave_state = ec_fsm_slavescan_end; |
916 EC_ERR("Failed to read EEPROM size of slave %i.\n", |
917 EC_ERR("Failed to read EEPROM size of slave %i.\n", |
917 slave->ring_position); |
918 slave->ring_position); |
918 return; |
919 return; |
919 } |
920 } |
920 |
921 |
939 } |
940 } |
940 |
941 |
941 if (!(slave->eeprom_data = |
942 if (!(slave->eeprom_data = |
942 (uint8_t *) kmalloc(slave->eeprom_size, GFP_ATOMIC))) { |
943 (uint8_t *) kmalloc(slave->eeprom_size, GFP_ATOMIC))) { |
943 fsm->slave->error_flag = 1; |
944 fsm->slave->error_flag = 1; |
944 fsm->slave_state = ec_fsm_slave_end; |
945 fsm->slave_state = ec_fsm_slavescan_end; |
945 EC_ERR("Failed to allocate EEPROM data on slave %i.\n", |
946 EC_ERR("Failed to allocate EEPROM data on slave %i.\n", |
946 slave->ring_position); |
947 slave->ring_position); |
947 return; |
948 return; |
948 } |
949 } |
949 |
950 |
950 // Start fetching EEPROM contents |
951 // Start fetching EEPROM contents |
951 |
952 |
952 fsm->sii_offset = 0x0000; |
953 fsm->sii_offset = 0x0000; |
953 fsm->sii_mode = 1; |
954 fsm->sii_mode = 1; |
954 fsm->sii_state = ec_fsm_sii_start_reading; |
955 fsm->sii_state = ec_fsm_sii_start_reading; |
955 fsm->slave_state = ec_fsm_slave_fetch_eeprom2; |
956 fsm->slave_state = ec_fsm_slavescan_eeprom_data2; |
956 fsm->slave_state(fsm); // execute state immediately |
957 fsm->slave_state(fsm); // execute state immediately |
957 } |
958 } |
958 |
959 |
959 /*****************************************************************************/ |
960 /*****************************************************************************/ |
960 |
961 |
961 /** |
962 /** |
962 Slave state: FETCH_EEPROM2. |
963 Slave state: FETCH_EEPROM2. |
963 */ |
964 */ |
964 |
965 |
965 void ec_fsm_slave_fetch_eeprom2(ec_fsm_t *fsm /**< finite state machine */) |
966 void ec_fsm_slavescan_eeprom_data2(ec_fsm_t *fsm /**< finite state machine */) |
966 { |
967 { |
967 ec_slave_t *slave = fsm->slave; |
968 ec_slave_t *slave = fsm->slave; |
968 uint16_t *cat_word, cat_type, cat_size; |
969 uint16_t *cat_word, cat_type, cat_size; |
969 |
970 |
970 // execute SII state machine |
971 // execute SII state machine |
971 fsm->sii_state(fsm); |
972 fsm->sii_state(fsm); |
972 |
973 |
973 if (fsm->sii_state == ec_fsm_sii_error) { |
974 if (fsm->sii_state == ec_fsm_sii_error) { |
974 fsm->slave->error_flag = 1; |
975 fsm->slave->error_flag = 1; |
975 fsm->slave_state = ec_fsm_slave_end; |
976 fsm->slave_state = ec_fsm_slavescan_end; |
976 EC_ERR("Failed to fetch EEPROM contents of slave %i.\n", |
977 EC_ERR("Failed to fetch EEPROM contents of slave %i.\n", |
977 slave->ring_position); |
978 slave->ring_position); |
978 return; |
979 return; |
979 } |
980 } |
980 |
981 |
1060 cat_word += cat_size + 2; |
1061 cat_word += cat_size + 2; |
1061 } |
1062 } |
1062 |
1063 |
1063 end: |
1064 end: |
1064 fsm->slave->error_flag = 1; |
1065 fsm->slave->error_flag = 1; |
1065 fsm->slave_state = ec_fsm_slave_end; |
1066 fsm->slave_state = ec_fsm_slavescan_end; |
1066 } |
1067 } |
1067 |
1068 |
1068 /*****************************************************************************/ |
1069 /*****************************************************************************/ |
|
1070 |
|
1071 /** |
|
1072 Slave state: END. |
|
1073 End state of the slave state machine. |
|
1074 */ |
|
1075 |
|
1076 void ec_fsm_slavescan_end(ec_fsm_t *fsm /**< finite state machine */) |
|
1077 { |
|
1078 } |
|
1079 |
|
1080 /****************************************************************************** |
|
1081 * slave configuration sub state machine |
|
1082 *****************************************************************************/ |
1069 |
1083 |
1070 /** |
1084 /** |
1071 Slave state: CONF. |
1085 Slave state: CONF. |
1072 */ |
1086 */ |
1073 |
1087 |
1074 void ec_fsm_slave_conf(ec_fsm_t *fsm /**< finite state machine */) |
1088 void ec_fsm_slaveconf_start(ec_fsm_t *fsm /**< finite state machine */) |
1075 { |
1089 { |
1076 ec_slave_t *slave = fsm->slave; |
1090 ec_slave_t *slave = fsm->slave; |
1077 ec_master_t *master = fsm->master; |
1091 ec_master_t *master = fsm->master; |
1078 ec_datagram_t *datagram = &fsm->datagram; |
1092 ec_datagram_t *datagram = &fsm->datagram; |
1079 |
1093 |
1080 fsm->change_state(fsm); // execute state change state machine |
1094 fsm->change_state(fsm); // execute state change state machine |
1081 |
1095 |
1082 if (fsm->change_state == ec_fsm_change_error) { |
1096 if (fsm->change_state == ec_fsm_change_error) { |
1083 slave->error_flag = 1; |
1097 slave->error_flag = 1; |
1084 fsm->slave_state = ec_fsm_slave_end; |
1098 fsm->slave_state = ec_fsm_slaveconf_end; |
1085 return; |
1099 return; |
1086 } |
1100 } |
1087 |
1101 |
1088 if (fsm->change_state != ec_fsm_change_end) return; |
1102 if (fsm->change_state != ec_fsm_change_end) return; |
1089 |
1103 |
1090 // slave is now in INIT |
1104 // slave is now in INIT |
1091 if (slave->current_state == slave->requested_state) { |
1105 if (slave->current_state == slave->requested_state) { |
1092 fsm->slave_state = ec_fsm_slave_end; // successful |
1106 fsm->slave_state = ec_fsm_slaveconf_end; // successful |
1093 return; |
1107 return; |
1094 } |
1108 } |
1095 |
1109 |
1096 // check for slave registration |
1110 // check for slave registration |
1097 if (!slave->type) { |
1111 if (!slave->type) { |
1100 |
1114 |
1101 // check and reset CRC fault counters |
1115 // check and reset CRC fault counters |
1102 //ec_slave_check_crc(slave); |
1116 //ec_slave_check_crc(slave); |
1103 |
1117 |
1104 if (!slave->base_fmmu_count) { // no fmmus |
1118 if (!slave->base_fmmu_count) { // no fmmus |
1105 fsm->slave_state = ec_fsm_slave_sync; |
1119 fsm->slave_state = ec_fsm_slaveconf_sync; |
1106 fsm->slave_state(fsm); // execute immediately |
1120 fsm->slave_state(fsm); // execute immediately |
1107 return; |
1121 return; |
1108 } |
1122 } |
1109 |
1123 |
1110 // reset FMMUs |
1124 // reset FMMUs |
1111 ec_datagram_npwr(datagram, slave->station_address, 0x0600, |
1125 ec_datagram_npwr(datagram, slave->station_address, 0x0600, |
1112 EC_FMMU_SIZE * slave->base_fmmu_count); |
1126 EC_FMMU_SIZE * slave->base_fmmu_count); |
1113 memset(datagram->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count); |
1127 memset(datagram->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count); |
1114 ec_master_queue_datagram(master, datagram); |
1128 ec_master_queue_datagram(master, datagram); |
1115 fsm->slave_state = ec_fsm_slave_sync; |
1129 fsm->slave_state = ec_fsm_slaveconf_sync; |
1116 } |
1130 } |
1117 |
1131 |
1118 /*****************************************************************************/ |
1132 /*****************************************************************************/ |
1119 |
1133 |
1120 /** |
1134 /** |
1121 Slave state: SYNC. |
1135 Slave state: SYNC. |
1122 Configure sync managers. |
1136 Configure sync managers. |
1123 */ |
1137 */ |
1124 |
1138 |
1125 void ec_fsm_slave_sync(ec_fsm_t *fsm /**< finite state machine */) |
1139 void ec_fsm_slaveconf_sync(ec_fsm_t *fsm /**< finite state machine */) |
1126 { |
1140 { |
1127 ec_datagram_t *datagram = &fsm->datagram; |
1141 ec_datagram_t *datagram = &fsm->datagram; |
1128 ec_slave_t *slave = fsm->slave; |
1142 ec_slave_t *slave = fsm->slave; |
1129 unsigned int j; |
1143 unsigned int j; |
1130 const ec_sync_t *sync; |
1144 const ec_sync_t *sync; |
1131 ec_eeprom_sync_t *eeprom_sync, mbox_sync; |
1145 ec_eeprom_sync_t *eeprom_sync, mbox_sync; |
1132 |
1146 |
1133 if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { |
1147 if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { |
1134 slave->error_flag = 1; |
1148 slave->error_flag = 1; |
1135 fsm->slave_state = ec_fsm_slave_end; |
1149 fsm->slave_state = ec_fsm_slaveconf_end; |
1136 EC_ERR("Failed to reset FMMUs of slave %i.\n", |
1150 EC_ERR("Failed to reset FMMUs of slave %i.\n", |
1137 slave->ring_position); |
1151 slave->ring_position); |
1138 return; |
1152 return; |
1139 } |
1153 } |
1140 |
1154 |
1141 if (!slave->base_sync_count) { // no sync managers |
1155 if (!slave->base_sync_count) { // no sync managers |
1142 fsm->slave_state = ec_fsm_slave_preop; |
1156 fsm->slave_state = ec_fsm_slaveconf_preop; |
1143 fsm->slave_state(fsm); // execute immediately |
1157 fsm->slave_state(fsm); // execute immediately |
1144 return; |
1158 return; |
1145 } |
1159 } |
1146 |
1160 |
1147 // configure sync managers |
1161 // configure sync managers |
1153 // does the slave supply sync manager configurations in its EEPROM? |
1167 // does the slave supply sync manager configurations in its EEPROM? |
1154 if (!list_empty(&slave->eeprom_syncs)) { |
1168 if (!list_empty(&slave->eeprom_syncs)) { |
1155 list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) { |
1169 list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) { |
1156 if (eeprom_sync->index >= slave->base_sync_count) { |
1170 if (eeprom_sync->index >= slave->base_sync_count) { |
1157 fsm->slave->error_flag = 1; |
1171 fsm->slave->error_flag = 1; |
1158 fsm->slave_state = ec_fsm_slave_end; |
1172 fsm->slave_state = ec_fsm_slaveconf_end; |
1159 EC_ERR("Invalid sync manager configuration found!"); |
1173 EC_ERR("Invalid sync manager configuration found!"); |
1160 return; |
1174 return; |
1161 } |
1175 } |
1162 ec_eeprom_sync_config(eeprom_sync, slave, |
1176 ec_eeprom_sync_config(eeprom_sync, slave, |
1163 datagram->data + EC_SYNC_SIZE |
1177 datagram->data + EC_SYNC_SIZE |
1195 EC_INFO("Mailbox configured for unknown slave %i\n", |
1209 EC_INFO("Mailbox configured for unknown slave %i\n", |
1196 slave->ring_position); |
1210 slave->ring_position); |
1197 } |
1211 } |
1198 |
1212 |
1199 ec_master_queue_datagram(fsm->master, datagram); |
1213 ec_master_queue_datagram(fsm->master, datagram); |
1200 fsm->slave_state = ec_fsm_slave_preop; |
1214 fsm->slave_state = ec_fsm_slaveconf_preop; |
1201 } |
1215 } |
1202 |
1216 |
1203 /*****************************************************************************/ |
1217 /*****************************************************************************/ |
1204 |
1218 |
1205 /** |
1219 /** |
1206 Slave state: PREOP. |
1220 Slave state: PREOP. |
1207 Change slave state to PREOP. |
1221 Change slave state to PREOP. |
1208 */ |
1222 */ |
1209 |
1223 |
1210 void ec_fsm_slave_preop(ec_fsm_t *fsm /**< finite state machine */) |
1224 void ec_fsm_slaveconf_preop(ec_fsm_t *fsm /**< finite state machine */) |
1211 { |
1225 { |
1212 ec_datagram_t *datagram = &fsm->datagram; |
1226 ec_datagram_t *datagram = &fsm->datagram; |
1213 ec_slave_t *slave = fsm->slave; |
1227 ec_slave_t *slave = fsm->slave; |
1214 |
1228 |
1215 if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { |
1229 if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { |
1216 slave->error_flag = 1; |
1230 slave->error_flag = 1; |
1217 fsm->slave_state = ec_fsm_slave_end; |
1231 fsm->slave_state = ec_fsm_slaveconf_end; |
1218 EC_ERR("Failed to set sync managers on slave %i.\n", |
1232 EC_ERR("Failed to set sync managers on slave %i.\n", |
1219 slave->ring_position); |
1233 slave->ring_position); |
1220 return; |
1234 return; |
1221 } |
1235 } |
1222 |
1236 |
1223 fsm->change_new = EC_SLAVE_STATE_PREOP; |
1237 fsm->change_new = EC_SLAVE_STATE_PREOP; |
1224 fsm->change_state = ec_fsm_change_start; |
1238 fsm->change_state = ec_fsm_change_start; |
1225 fsm->slave_state = ec_fsm_slave_fmmu; |
1239 fsm->slave_state = ec_fsm_slaveconf_fmmu; |
1226 fsm->change_state(fsm); // execute immediately |
1240 fsm->change_state(fsm); // execute immediately |
1227 } |
1241 } |
1228 |
1242 |
1229 /*****************************************************************************/ |
1243 /*****************************************************************************/ |
1230 |
1244 |
1231 /** |
1245 /** |
1232 Slave state: FMMU. |
1246 Slave state: FMMU. |
1233 Configure FMMUs. |
1247 Configure FMMUs. |
1234 */ |
1248 */ |
1235 |
1249 |
1236 void ec_fsm_slave_fmmu(ec_fsm_t *fsm /**< finite state machine */) |
1250 void ec_fsm_slaveconf_fmmu(ec_fsm_t *fsm /**< finite state machine */) |
1237 { |
1251 { |
1238 ec_slave_t *slave = fsm->slave; |
1252 ec_slave_t *slave = fsm->slave; |
1239 ec_master_t *master = fsm->master; |
1253 ec_master_t *master = fsm->master; |
1240 ec_datagram_t *datagram = &fsm->datagram; |
1254 ec_datagram_t *datagram = &fsm->datagram; |
1241 unsigned int j; |
1255 unsigned int j; |
1242 |
1256 |
1243 fsm->change_state(fsm); // execute state change state machine |
1257 fsm->change_state(fsm); // execute state change state machine |
1244 |
1258 |
1245 if (fsm->change_state == ec_fsm_change_error) { |
1259 if (fsm->change_state == ec_fsm_change_error) { |
1246 slave->error_flag = 1; |
1260 slave->error_flag = 1; |
1247 fsm->slave_state = ec_fsm_slave_end; |
1261 fsm->slave_state = ec_fsm_slaveconf_end; |
1248 return; |
1262 return; |
1249 } |
1263 } |
1250 |
1264 |
1251 if (fsm->change_state != ec_fsm_change_end) return; |
1265 if (fsm->change_state != ec_fsm_change_end) return; |
1252 |
1266 |
1253 // slave is now in PREOP |
1267 // slave is now in PREOP |
1254 if (slave->current_state == slave->requested_state) { |
1268 if (slave->current_state == slave->requested_state) { |
1255 fsm->slave_state = ec_fsm_slave_end; // successful |
1269 fsm->slave_state = ec_fsm_slaveconf_end; // successful |
1256 return; |
1270 return; |
1257 } |
1271 } |
1258 |
1272 |
1259 // stop activation here for slaves without type |
1273 // stop activation here for slaves without type |
1260 if (!slave->type) { |
1274 if (!slave->type) { |
1261 fsm->slave_state = ec_fsm_slave_end; // successful |
1275 fsm->slave_state = ec_fsm_slaveconf_end; // successful |
1262 return; |
1276 return; |
1263 } |
1277 } |
1264 |
1278 |
1265 if (!slave->base_fmmu_count) { |
1279 if (!slave->base_fmmu_count) { |
1266 fsm->slave_state = ec_fsm_slave_saveop; |
1280 fsm->slave_state = ec_fsm_slaveconf_saveop; |
1267 fsm->slave_state(fsm); // execute immediately |
1281 fsm->slave_state(fsm); // execute immediately |
1268 return; |
1282 return; |
1269 } |
1283 } |
1270 |
1284 |
1271 // configure FMMUs |
1285 // configure FMMUs |
1276 ec_fmmu_config(&slave->fmmus[j], slave, |
1290 ec_fmmu_config(&slave->fmmus[j], slave, |
1277 datagram->data + EC_FMMU_SIZE * j); |
1291 datagram->data + EC_FMMU_SIZE * j); |
1278 } |
1292 } |
1279 |
1293 |
1280 ec_master_queue_datagram(master, datagram); |
1294 ec_master_queue_datagram(master, datagram); |
1281 fsm->slave_state = ec_fsm_slave_saveop; |
1295 fsm->slave_state = ec_fsm_slaveconf_saveop; |
1282 } |
1296 } |
1283 |
1297 |
1284 /*****************************************************************************/ |
1298 /*****************************************************************************/ |
1285 |
1299 |
1286 /** |
1300 /** |
1287 Slave state: SAVEOP. |
1301 Slave state: SAVEOP. |
1288 Set slave state to SAVEOP. |
1302 Set slave state to SAVEOP. |
1289 */ |
1303 */ |
1290 |
1304 |
1291 void ec_fsm_slave_saveop(ec_fsm_t *fsm /**< finite state machine */) |
1305 void ec_fsm_slaveconf_saveop(ec_fsm_t *fsm /**< finite state machine */) |
1292 { |
1306 { |
1293 ec_datagram_t *datagram = &fsm->datagram; |
1307 ec_datagram_t *datagram = &fsm->datagram; |
1294 |
1308 |
1295 if (fsm->slave->base_fmmu_count && (datagram->state != EC_CMD_RECEIVED || |
1309 if (fsm->slave->base_fmmu_count && (datagram->state != EC_CMD_RECEIVED || |
1296 datagram->working_counter != 1)) { |
1310 datagram->working_counter != 1)) { |
1297 fsm->slave->error_flag = 1; |
1311 fsm->slave->error_flag = 1; |
1298 fsm->slave_state = ec_fsm_slave_end; |
1312 fsm->slave_state = ec_fsm_slaveconf_end; |
1299 EC_ERR("Failed to set FMMUs on slave %i.\n", |
1313 EC_ERR("Failed to set FMMUs on slave %i.\n", |
1300 fsm->slave->ring_position); |
1314 fsm->slave->ring_position); |
1301 return; |
1315 return; |
1302 } |
1316 } |
1303 |
1317 |
1304 // set state to SAVEOP |
1318 // set state to SAVEOP |
1305 fsm->slave_state = ec_fsm_slave_op; |
1319 fsm->slave_state = ec_fsm_slaveconf_op; |
1306 fsm->change_new = EC_SLAVE_STATE_SAVEOP; |
1320 fsm->change_new = EC_SLAVE_STATE_SAVEOP; |
1307 fsm->change_state = ec_fsm_change_start; |
1321 fsm->change_state = ec_fsm_change_start; |
1308 fsm->change_state(fsm); // execute immediately |
1322 fsm->change_state(fsm); // execute immediately |
1309 } |
1323 } |
1310 |
1324 |
1313 /** |
1327 /** |
1314 Slave state: OP. |
1328 Slave state: OP. |
1315 Set slave state to OP. |
1329 Set slave state to OP. |
1316 */ |
1330 */ |
1317 |
1331 |
1318 void ec_fsm_slave_op(ec_fsm_t *fsm /**< finite state machine */) |
1332 void ec_fsm_slaveconf_op(ec_fsm_t *fsm /**< finite state machine */) |
1319 { |
1333 { |
1320 fsm->change_state(fsm); // execute state change state machine |
1334 fsm->change_state(fsm); // execute state change state machine |
1321 |
1335 |
1322 if (fsm->change_state == ec_fsm_change_error) { |
1336 if (fsm->change_state == ec_fsm_change_error) { |
1323 fsm->slave->error_flag = 1; |
1337 fsm->slave->error_flag = 1; |
1324 fsm->slave_state = ec_fsm_slave_end; |
1338 fsm->slave_state = ec_fsm_slaveconf_end; |
1325 return; |
1339 return; |
1326 } |
1340 } |
1327 |
1341 |
1328 if (fsm->change_state != ec_fsm_change_end) return; |
1342 if (fsm->change_state != ec_fsm_change_end) return; |
1329 |
1343 |
1330 // slave is now in SAVEOP |
1344 // slave is now in SAVEOP |
1331 if (fsm->slave->current_state == fsm->slave->requested_state) { |
1345 if (fsm->slave->current_state == fsm->slave->requested_state) { |
1332 fsm->slave_state = ec_fsm_slave_end; // successful |
1346 fsm->slave_state = ec_fsm_slaveconf_end; // successful |
1333 return; |
1347 return; |
1334 } |
1348 } |
1335 |
1349 |
1336 // set state to OP |
1350 // set state to OP |
1337 fsm->slave_state = ec_fsm_slave_op2; |
1351 fsm->slave_state = ec_fsm_slaveconf_op2; |
1338 fsm->change_new = EC_SLAVE_STATE_OP; |
1352 fsm->change_new = EC_SLAVE_STATE_OP; |
1339 fsm->change_state = ec_fsm_change_start; |
1353 fsm->change_state = ec_fsm_change_start; |
1340 fsm->change_state(fsm); // execute immediately |
1354 fsm->change_state(fsm); // execute immediately |
1341 } |
1355 } |
1342 |
1356 |
1345 /** |
1359 /** |
1346 Slave state: OP2 |
1360 Slave state: OP2 |
1347 Executes the change state machine, until the OP state is set. |
1361 Executes the change state machine, until the OP state is set. |
1348 */ |
1362 */ |
1349 |
1363 |
1350 void ec_fsm_slave_op2(ec_fsm_t *fsm /**< finite state machine */) |
1364 void ec_fsm_slaveconf_op2(ec_fsm_t *fsm /**< finite state machine */) |
1351 { |
1365 { |
1352 fsm->change_state(fsm); // execute state change state machine |
1366 fsm->change_state(fsm); // execute state change state machine |
1353 |
1367 |
1354 if (fsm->change_state == ec_fsm_change_error) { |
1368 if (fsm->change_state == ec_fsm_change_error) { |
1355 fsm->slave->error_flag = 1; |
1369 fsm->slave->error_flag = 1; |
1356 fsm->slave_state = ec_fsm_slave_end; |
1370 fsm->slave_state = ec_fsm_slaveconf_end; |
1357 return; |
1371 return; |
1358 } |
1372 } |
1359 |
1373 |
1360 if (fsm->change_state != ec_fsm_change_end) return; |
1374 if (fsm->change_state != ec_fsm_change_end) return; |
1361 |
1375 |
1362 // slave is now in OP |
1376 // slave is now in OP |
1363 fsm->slave_state = ec_fsm_slave_end; // successful |
1377 fsm->slave_state = ec_fsm_slaveconf_end; // successful |
1364 } |
1378 } |
1365 |
1379 |
1366 /*****************************************************************************/ |
1380 /*****************************************************************************/ |
1367 |
1381 |
1368 /** |
1382 /** |
1369 Slave state: END. |
1383 Slave state: END. |
1370 End state of the slave state machine. |
1384 End state of the slave state machine. |
1371 */ |
1385 */ |
1372 |
1386 |
1373 void ec_fsm_slave_end(ec_fsm_t *fsm /**< finite state machine */) |
1387 void ec_fsm_slaveconf_end(ec_fsm_t *fsm /**< finite state machine */) |
1374 { |
1388 { |
1375 } |
1389 } |
1376 |
1390 |
1377 /****************************************************************************** |
1391 /****************************************************************************** |
1378 * SII state machine |
1392 * SII sub state machine |
1379 *****************************************************************************/ |
1393 *****************************************************************************/ |
1380 |
1394 |
1381 /** |
1395 /** |
1382 SII state: START_READING. |
1396 SII state: START_READING. |
1383 Starts reading the slave information interface. |
1397 Starts reading the slave information interface. |