55 void ec_fsm_master_address(ec_fsm_t *); |
55 void ec_fsm_master_address(ec_fsm_t *); |
56 void ec_fsm_master_conf(ec_fsm_t *); |
56 void ec_fsm_master_conf(ec_fsm_t *); |
57 void ec_fsm_master_eeprom(ec_fsm_t *); |
57 void ec_fsm_master_eeprom(ec_fsm_t *); |
58 |
58 |
59 void ec_fsm_slave_start_reading(ec_fsm_t *); |
59 void ec_fsm_slave_start_reading(ec_fsm_t *); |
60 void ec_fsm_slave_read_status(ec_fsm_t *); |
60 void ec_fsm_slave_read_state(ec_fsm_t *); |
61 void ec_fsm_slave_read_base(ec_fsm_t *); |
61 void ec_fsm_slave_read_base(ec_fsm_t *); |
62 void ec_fsm_slave_read_dl(ec_fsm_t *); |
62 void ec_fsm_slave_read_dl(ec_fsm_t *); |
63 void ec_fsm_slave_eeprom_size(ec_fsm_t *); |
63 void ec_fsm_slave_eeprom_size(ec_fsm_t *); |
64 void ec_fsm_slave_fetch_eeprom(ec_fsm_t *); |
64 void ec_fsm_slave_fetch_eeprom(ec_fsm_t *); |
65 void ec_fsm_slave_fetch_eeprom2(ec_fsm_t *); |
65 void ec_fsm_slave_fetch_eeprom2(ec_fsm_t *); |
97 Constructor. |
97 Constructor. |
98 */ |
98 */ |
99 |
99 |
100 int ec_fsm_init(ec_fsm_t *fsm, /**< finite state machine */ |
100 int ec_fsm_init(ec_fsm_t *fsm, /**< finite state machine */ |
101 ec_master_t *master /**< EtherCAT master */ |
101 ec_master_t *master /**< EtherCAT master */ |
102 ) |
102 ) |
103 { |
103 { |
104 fsm->master = master; |
104 fsm->master = master; |
105 fsm->master_state = ec_fsm_master_start; |
105 fsm->master_state = ec_fsm_master_start; |
106 fsm->master_slaves_responding = 0; |
106 fsm->master_slaves_responding = 0; |
107 fsm->master_slave_states = EC_SLAVE_STATE_UNKNOWN; |
107 fsm->master_slave_states = EC_SLAVE_STATE_UNKNOWN; |
108 fsm->master_validation = 0; |
108 fsm->master_validation = 0; |
109 |
109 |
110 ec_command_init(&fsm->command); |
110 ec_command_init(&fsm->command); |
111 if (ec_command_prealloc(&fsm->command, EC_MAX_DATA_SIZE)) { |
111 if (ec_command_prealloc(&fsm->command, EC_MAX_DATA_SIZE)) { |
112 EC_ERR("FSM failed to allocate FSM command.\n"); |
112 EC_ERR("Failed to allocate FSM command.\n"); |
113 return -1; |
113 return -1; |
114 } |
114 } |
115 |
115 |
116 return 0; |
116 return 0; |
117 } |
117 } |
288 { |
288 { |
289 ec_master_t *master = fsm->master; |
289 ec_master_t *master = fsm->master; |
290 ec_slave_t *slave = fsm->slave; |
290 ec_slave_t *slave = fsm->slave; |
291 |
291 |
292 // have all states been read? |
292 // have all states been read? |
293 if (slave->list.next == &master->slaves) { |
293 if (slave->list.next != &master->slaves) { |
294 |
294 // process next slave |
295 // check, if a bus validation has to be done |
295 fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list); |
296 if (fsm->master_validation) { |
296 ec_command_nprd(&fsm->command, fsm->slave->station_address, 0x0130, 2); |
297 fsm->master_validation = 0; |
297 ec_master_queue_command(master, &fsm->command); |
298 list_for_each_entry(slave, &master->slaves, list) { |
298 fsm->master_state = ec_fsm_master_states; |
299 if (slave->online) continue; |
299 return; |
300 |
300 } |
301 // At least one slave is offline. validate! |
301 |
302 EC_INFO("Validating bus.\n"); |
302 // all slave stated read; check, if a bus validation has to be done |
303 fsm->slave = list_entry(master->slaves.next, ec_slave_t, list); |
303 if (fsm->master_validation) { |
304 fsm->master_state = ec_fsm_master_validate_vendor; |
304 fsm->master_validation = 0; |
305 fsm->sii_offset = 0x0008; // vendor ID |
305 list_for_each_entry(slave, &master->slaves, list) { |
306 fsm->sii_mode = 0; |
306 if (slave->online) continue; |
307 fsm->sii_state = ec_fsm_sii_start_reading; |
307 |
308 fsm->sii_state(fsm); // execute immediately |
308 // At least one slave is offline. validate! |
309 return; |
309 EC_INFO("Validating bus.\n"); |
310 } |
310 fsm->slave = list_entry(master->slaves.next, ec_slave_t, list); |
|
311 fsm->master_state = ec_fsm_master_validate_vendor; |
|
312 fsm->sii_offset = 0x0008; // vendor ID |
|
313 fsm->sii_mode = 0; |
|
314 fsm->sii_state = ec_fsm_sii_start_reading; |
|
315 fsm->sii_state(fsm); // execute immediately |
|
316 return; |
311 } |
317 } |
312 |
318 } |
313 fsm->master_state = ec_fsm_master_proc_states; |
319 |
314 fsm->master_state(fsm); // execute immediately |
320 fsm->master_state = ec_fsm_master_proc_states; |
315 return; |
321 fsm->master_state(fsm); // execute immediately |
316 } |
|
317 |
|
318 // process next slave |
|
319 fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list); |
|
320 ec_command_nprd(&fsm->command, fsm->slave->station_address, 0x0130, 2); |
|
321 ec_master_queue_command(master, &fsm->command); |
|
322 fsm->master_state = ec_fsm_master_states; |
|
323 } |
322 } |
324 |
323 |
325 /*****************************************************************************/ |
324 /*****************************************************************************/ |
326 |
325 |
327 /** |
326 /** |
409 |
408 |
410 if (master->mode == EC_MASTER_MODE_FREERUN) { |
409 if (master->mode == EC_MASTER_MODE_FREERUN) { |
411 // nothing to configure. check for pending EEPROM write operations. |
410 // nothing to configure. check for pending EEPROM write operations. |
412 list_for_each_entry(slave, &master->slaves, list) { |
411 list_for_each_entry(slave, &master->slaves, list) { |
413 if (!slave->new_eeprom_data) continue; |
412 if (!slave->new_eeprom_data) continue; |
|
413 |
|
414 if (!slave->online || slave->error_flag) { |
|
415 kfree(slave->new_eeprom_data); |
|
416 slave->new_eeprom_data = NULL; |
|
417 EC_ERR("Discarding EEPROM data, slave %i not ready.\n", |
|
418 slave->ring_position); |
|
419 continue; |
|
420 } |
414 |
421 |
415 // found pending EEPROM write operation. execute it! |
422 // found pending EEPROM write operation. execute it! |
416 EC_INFO("Writing EEPROM of slave %i...\n", slave->ring_position); |
423 EC_INFO("Writing EEPROM of slave %i...\n", slave->ring_position); |
417 fsm->sii_offset = 0x0000; |
424 fsm->sii_offset = 0x0000; |
418 memcpy(fsm->sii_value, slave->new_eeprom_data, 2); |
425 memcpy(fsm->sii_value, slave->new_eeprom_data, 2); |
442 ec_slave_t *slave = fsm->slave; |
449 ec_slave_t *slave = fsm->slave; |
443 |
450 |
444 fsm->sii_state(fsm); // execute SII state machine |
451 fsm->sii_state(fsm); // execute SII state machine |
445 |
452 |
446 if (fsm->sii_state == ec_fsm_sii_error) { |
453 if (fsm->sii_state == ec_fsm_sii_error) { |
447 fsm->slave->error_flag = 1; |
454 fsm->slave->error_flag = 1; |
448 EC_ERR("Failed to validate vendor ID of slave %i.\n", |
455 EC_ERR("Failed to validate vendor ID of slave %i.\n", |
449 slave->ring_position); |
456 slave->ring_position); |
450 fsm->master_state = ec_fsm_master_start; |
457 fsm->master_state = ec_fsm_master_start; |
451 fsm->master_state(fsm); // execute immediately |
458 fsm->master_state(fsm); // execute immediately |
452 return; |
459 return; |
481 ec_slave_t *slave = fsm->slave; |
488 ec_slave_t *slave = fsm->slave; |
482 |
489 |
483 fsm->sii_state(fsm); // execute SII state machine |
490 fsm->sii_state(fsm); // execute SII state machine |
484 |
491 |
485 if (fsm->sii_state == ec_fsm_sii_error) { |
492 if (fsm->sii_state == ec_fsm_sii_error) { |
486 fsm->slave->error_flag = 1; |
493 fsm->slave->error_flag = 1; |
487 EC_ERR("Failed to validate product code of slave %i.\n", |
494 EC_ERR("Failed to validate product code of slave %i.\n", |
488 slave->ring_position); |
495 slave->ring_position); |
489 fsm->master_state = ec_fsm_master_start; |
496 fsm->master_state = ec_fsm_master_start; |
490 fsm->master_state(fsm); // execute immediately |
497 fsm->master_state(fsm); // execute immediately |
491 return; |
498 return; |
638 } |
645 } |
639 } |
646 } |
640 |
647 |
641 // determine initial state. |
648 // determine initial state. |
642 if ((slave->type && |
649 if ((slave->type && |
643 (slave->type->special == EC_TYPE_BUS_COUPLER || |
650 (slave->type->special == EC_TYPE_BUS_COUPLER || |
644 slave->type->special == EC_TYPE_INFRA))) { |
651 slave->type->special == EC_TYPE_INFRA))) { |
645 slave->requested_state = EC_SLAVE_STATE_OP; |
652 slave->requested_state = EC_SLAVE_STATE_OP; |
646 } |
653 } |
647 else { |
654 else { |
648 if (master->mode == EC_MASTER_MODE_RUNNING) |
655 if (master->mode == EC_MASTER_MODE_RUNNING) |
649 slave->requested_state = EC_SLAVE_STATE_PREOP; |
656 slave->requested_state = EC_SLAVE_STATE_PREOP; |
700 ec_slave_t *slave = fsm->slave; |
707 ec_slave_t *slave = fsm->slave; |
701 |
708 |
702 fsm->sii_state(fsm); // execute SII state machine |
709 fsm->sii_state(fsm); // execute SII state machine |
703 |
710 |
704 if (fsm->sii_state == ec_fsm_sii_error) { |
711 if (fsm->sii_state == ec_fsm_sii_error) { |
705 fsm->slave->error_flag = 1; |
712 fsm->slave->error_flag = 1; |
706 EC_ERR("Failed to write EEPROM contents to slave %i.\n", |
713 EC_ERR("Failed to write EEPROM contents to slave %i.\n", |
707 slave->ring_position); |
714 slave->ring_position); |
708 kfree(slave->new_eeprom_data); |
715 kfree(slave->new_eeprom_data); |
709 slave->new_eeprom_data = NULL; |
716 slave->new_eeprom_data = NULL; |
710 fsm->master_state = ec_fsm_master_start; |
717 fsm->master_state = ec_fsm_master_start; |
749 |
756 |
750 // write station address |
757 // write station address |
751 ec_command_apwr(command, fsm->slave->ring_position, 0x0010, 2); |
758 ec_command_apwr(command, fsm->slave->ring_position, 0x0010, 2); |
752 EC_WRITE_U16(command->data, fsm->slave->station_address); |
759 EC_WRITE_U16(command->data, fsm->slave->station_address); |
753 ec_master_queue_command(fsm->master, command); |
760 ec_master_queue_command(fsm->master, command); |
754 fsm->slave_state = ec_fsm_slave_read_status; |
761 fsm->slave_state = ec_fsm_slave_read_state; |
755 } |
762 } |
756 |
763 |
757 /*****************************************************************************/ |
764 /*****************************************************************************/ |
758 |
765 |
759 /** |
766 /** |
760 Slave state: READ_STATUS. |
767 Slave state: READ_STATUS. |
761 */ |
768 */ |
762 |
769 |
763 void ec_fsm_slave_read_status(ec_fsm_t *fsm /**< finite state machine */) |
770 void ec_fsm_slave_read_state(ec_fsm_t *fsm /**< finite state machine */) |
764 { |
771 { |
765 ec_command_t *command = &fsm->command; |
772 ec_command_t *command = &fsm->command; |
766 |
773 |
767 if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { |
774 if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { |
768 EC_ERR("FSM failed to write station address of slave %i.\n", |
775 fsm->slave->error_flag = 1; |
|
776 fsm->slave_state = ec_fsm_slave_end; |
|
777 EC_ERR("Failed to write station address of slave %i.\n", |
769 fsm->slave->ring_position); |
778 fsm->slave->ring_position); |
770 fsm->slave_state = ec_fsm_slave_end; |
779 return; |
771 return; |
780 } |
772 } |
781 |
773 |
782 // Read AL state |
774 // read AL status |
|
775 ec_command_nprd(command, fsm->slave->station_address, 0x0130, 2); |
783 ec_command_nprd(command, fsm->slave->station_address, 0x0130, 2); |
776 ec_master_queue_command(fsm->master, command); |
784 ec_master_queue_command(fsm->master, command); |
777 fsm->slave_state = ec_fsm_slave_read_base; |
785 fsm->slave_state = ec_fsm_slave_read_base; |
778 } |
786 } |
779 |
787 |
788 ec_command_t *command = &fsm->command; |
796 ec_command_t *command = &fsm->command; |
789 ec_slave_t *slave = fsm->slave; |
797 ec_slave_t *slave = fsm->slave; |
790 |
798 |
791 if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { |
799 if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { |
792 fsm->slave->error_flag = 1; |
800 fsm->slave->error_flag = 1; |
793 EC_ERR("FSM failed to read AL status of slave %i.\n", |
801 fsm->slave_state = ec_fsm_slave_end; |
|
802 EC_ERR("Failed to read AL state of slave %i.\n", |
794 fsm->slave->ring_position); |
803 fsm->slave->ring_position); |
795 fsm->slave_state = ec_fsm_slave_end; |
|
796 return; |
804 return; |
797 } |
805 } |
798 |
806 |
799 slave->current_state = EC_READ_U8(command->data); |
807 slave->current_state = EC_READ_U8(command->data); |
800 if (slave->current_state & EC_ACK) { |
808 if (slave->current_state & EC_ACK) { |
801 EC_WARN("Slave %i has status error bit set (0x%02X)!\n", |
809 EC_WARN("Slave %i has state error bit set (0x%02X)!\n", |
802 slave->ring_position, slave->current_state); |
810 slave->ring_position, slave->current_state); |
803 slave->current_state &= 0x0F; |
811 slave->current_state &= 0x0F; |
804 } |
812 } |
805 |
813 |
806 // read base data |
814 // read base data |
820 ec_command_t *command = &fsm->command; |
828 ec_command_t *command = &fsm->command; |
821 ec_slave_t *slave = fsm->slave; |
829 ec_slave_t *slave = fsm->slave; |
822 |
830 |
823 if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { |
831 if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { |
824 fsm->slave->error_flag = 1; |
832 fsm->slave->error_flag = 1; |
825 EC_ERR("FSM failed to read base data of slave %i.\n", |
833 fsm->slave_state = ec_fsm_slave_end; |
|
834 EC_ERR("Failed to read base data of slave %i.\n", |
826 slave->ring_position); |
835 slave->ring_position); |
827 fsm->slave_state = ec_fsm_slave_end; |
|
828 return; |
836 return; |
829 } |
837 } |
830 |
838 |
831 slave->base_type = EC_READ_U8 (command->data); |
839 slave->base_type = EC_READ_U8 (command->data); |
832 slave->base_revision = EC_READ_U8 (command->data + 1); |
840 slave->base_revision = EC_READ_U8 (command->data + 1); |
857 uint16_t dl_status; |
865 uint16_t dl_status; |
858 unsigned int i; |
866 unsigned int i; |
859 |
867 |
860 if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { |
868 if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { |
861 fsm->slave->error_flag = 1; |
869 fsm->slave->error_flag = 1; |
862 EC_ERR("FSM failed to read DL status of slave %i.\n", |
870 fsm->slave_state = ec_fsm_slave_end; |
|
871 EC_ERR("Failed to read DL status of slave %i.\n", |
863 slave->ring_position); |
872 slave->ring_position); |
864 fsm->slave_state = ec_fsm_slave_end; |
|
865 return; |
873 return; |
866 } |
874 } |
867 |
875 |
868 dl_status = EC_READ_U16(command->data); |
876 dl_status = EC_READ_U16(command->data); |
869 for (i = 0; i < 4; i++) { |
877 for (i = 0; i < 4; i++) { |
894 |
902 |
895 // execute SII state machine |
903 // execute SII state machine |
896 fsm->sii_state(fsm); |
904 fsm->sii_state(fsm); |
897 |
905 |
898 if (fsm->sii_state == ec_fsm_sii_error) { |
906 if (fsm->sii_state == ec_fsm_sii_error) { |
899 fsm->slave->error_flag = 1; |
907 fsm->slave->error_flag = 1; |
900 fsm->slave_state = ec_fsm_slave_end; |
908 fsm->slave_state = ec_fsm_slave_end; |
901 EC_ERR("Failed to read EEPROM size of slave %i.\n", |
909 EC_ERR("Failed to read EEPROM size of slave %i.\n", |
902 slave->ring_position); |
910 slave->ring_position); |
903 return; |
911 return; |
904 } |
912 } |
924 } |
932 } |
925 |
933 |
926 if (!(slave->eeprom_data = |
934 if (!(slave->eeprom_data = |
927 (uint8_t *) kmalloc(slave->eeprom_size, GFP_ATOMIC))) { |
935 (uint8_t *) kmalloc(slave->eeprom_size, GFP_ATOMIC))) { |
928 fsm->slave->error_flag = 1; |
936 fsm->slave->error_flag = 1; |
|
937 fsm->slave_state = ec_fsm_slave_end; |
929 EC_ERR("Failed to allocate EEPROM data on slave %i.\n", |
938 EC_ERR("Failed to allocate EEPROM data on slave %i.\n", |
930 slave->ring_position); |
939 slave->ring_position); |
931 fsm->slave_state = ec_fsm_slave_end; |
|
932 return; |
940 return; |
933 } |
941 } |
934 |
942 |
935 // Start fetching EEPROM contents |
943 // Start fetching EEPROM contents |
936 |
944 |
954 |
962 |
955 // execute SII state machine |
963 // execute SII state machine |
956 fsm->sii_state(fsm); |
964 fsm->sii_state(fsm); |
957 |
965 |
958 if (fsm->sii_state == ec_fsm_sii_error) { |
966 if (fsm->sii_state == ec_fsm_sii_error) { |
959 fsm->slave->error_flag = 1; |
967 fsm->slave->error_flag = 1; |
960 fsm->slave_state = ec_fsm_slave_end; |
968 fsm->slave_state = ec_fsm_slave_end; |
961 EC_ERR("Failed to fetch EEPROM contents of slave %i.\n", |
969 EC_ERR("Failed to fetch EEPROM contents of slave %i.\n", |
962 slave->ring_position); |
970 slave->ring_position); |
963 return; |
971 return; |
964 } |
972 } |
1063 ec_command_t *command = &fsm->command; |
1071 ec_command_t *command = &fsm->command; |
1064 |
1072 |
1065 fsm->change_state(fsm); // execute state change state machine |
1073 fsm->change_state(fsm); // execute state change state machine |
1066 |
1074 |
1067 if (fsm->change_state == ec_fsm_change_error) { |
1075 if (fsm->change_state == ec_fsm_change_error) { |
1068 slave->error_flag = 1; |
1076 slave->error_flag = 1; |
1069 fsm->slave_state = ec_fsm_slave_end; |
1077 fsm->slave_state = ec_fsm_slave_end; |
1070 return; |
1078 return; |
1071 } |
1079 } |
1072 |
1080 |
1073 if (fsm->change_state != ec_fsm_change_end) return; |
1081 if (fsm->change_state != ec_fsm_change_end) return; |
1074 |
1082 |
1075 // slave is now in INIT |
1083 // slave is now in INIT |
1076 if (slave->current_state == slave->requested_state) { |
1084 if (slave->current_state == slave->requested_state) { |
1077 fsm->slave_state = ec_fsm_slave_end; |
1085 fsm->slave_state = ec_fsm_slave_end; // successful |
1078 return; |
1086 return; |
1079 } |
1087 } |
1080 |
1088 |
1081 // check for slave registration |
1089 // check for slave registration |
1082 if (!slave->type) { |
1090 if (!slave->type) { |
1114 unsigned int j; |
1122 unsigned int j; |
1115 const ec_sync_t *sync; |
1123 const ec_sync_t *sync; |
1116 ec_eeprom_sync_t *eeprom_sync, mbox_sync; |
1124 ec_eeprom_sync_t *eeprom_sync, mbox_sync; |
1117 |
1125 |
1118 if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { |
1126 if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { |
|
1127 slave->error_flag = 1; |
|
1128 fsm->slave_state = ec_fsm_slave_end; |
1119 EC_ERR("Failed to reset FMMUs of slave %i.\n", |
1129 EC_ERR("Failed to reset FMMUs of slave %i.\n", |
1120 slave->ring_position); |
1130 slave->ring_position); |
1121 slave->error_flag = 1; |
|
1122 fsm->slave_state = ec_fsm_slave_end; |
|
1123 return; |
1131 return; |
1124 } |
1132 } |
1125 |
1133 |
1126 if (!slave->base_sync_count) { // no sync managers |
1134 if (!slave->base_sync_count) { // no sync managers |
1127 fsm->slave_state = ec_fsm_slave_preop; |
1135 fsm->slave_state = ec_fsm_slave_preop; |
1147 { |
1155 { |
1148 // does it supply sync manager configurations in its EEPROM? |
1156 // does it supply sync manager configurations in its EEPROM? |
1149 if (!list_empty(&slave->eeprom_syncs)) { |
1157 if (!list_empty(&slave->eeprom_syncs)) { |
1150 list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) { |
1158 list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) { |
1151 if (eeprom_sync->index >= slave->base_sync_count) { |
1159 if (eeprom_sync->index >= slave->base_sync_count) { |
1152 EC_ERR("Invalid sync manager configuration found!"); |
|
1153 fsm->slave->error_flag = 1; |
1160 fsm->slave->error_flag = 1; |
1154 fsm->slave_state = ec_fsm_slave_end; |
1161 fsm->slave_state = ec_fsm_slave_end; |
|
1162 EC_ERR("Invalid sync manager configuration found!"); |
1155 return; |
1163 return; |
1156 } |
1164 } |
1157 ec_eeprom_sync_config(eeprom_sync, |
1165 ec_eeprom_sync_config(eeprom_sync, |
1158 command->data + EC_SYNC_SIZE |
1166 command->data + EC_SYNC_SIZE |
1159 * eeprom_sync->index); |
1167 * eeprom_sync->index); |
1197 { |
1205 { |
1198 ec_command_t *command = &fsm->command; |
1206 ec_command_t *command = &fsm->command; |
1199 ec_slave_t *slave = fsm->slave; |
1207 ec_slave_t *slave = fsm->slave; |
1200 |
1208 |
1201 if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { |
1209 if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { |
|
1210 slave->error_flag = 1; |
|
1211 fsm->slave_state = ec_fsm_slave_end; |
1202 EC_ERR("Failed to set sync managers on slave %i.\n", |
1212 EC_ERR("Failed to set sync managers on slave %i.\n", |
1203 slave->ring_position); |
1213 slave->ring_position); |
1204 slave->error_flag = 1; |
|
1205 fsm->slave_state = ec_fsm_slave_end; |
|
1206 return; |
1214 return; |
1207 } |
1215 } |
1208 |
1216 |
1209 fsm->change_new = EC_SLAVE_STATE_PREOP; |
1217 fsm->change_new = EC_SLAVE_STATE_PREOP; |
1210 fsm->change_state = ec_fsm_change_start; |
1218 fsm->change_state = ec_fsm_change_start; |
1227 unsigned int j; |
1235 unsigned int j; |
1228 |
1236 |
1229 fsm->change_state(fsm); // execute state change state machine |
1237 fsm->change_state(fsm); // execute state change state machine |
1230 |
1238 |
1231 if (fsm->change_state == ec_fsm_change_error) { |
1239 if (fsm->change_state == ec_fsm_change_error) { |
1232 slave->error_flag = 1; |
1240 slave->error_flag = 1; |
1233 fsm->slave_state = ec_fsm_slave_end; |
1241 fsm->slave_state = ec_fsm_slave_end; |
1234 return; |
1242 return; |
1235 } |
1243 } |
1236 |
1244 |
1237 if (fsm->change_state != ec_fsm_change_end) return; |
1245 if (fsm->change_state != ec_fsm_change_end) return; |
1238 |
1246 |
1239 // slave is now in PREOP |
1247 // slave is now in PREOP |
1240 if (slave->current_state == slave->requested_state) { |
1248 if (slave->current_state == slave->requested_state) { |
1241 fsm->slave_state = ec_fsm_slave_end; |
1249 fsm->slave_state = ec_fsm_slave_end; // successful |
1242 return; |
1250 return; |
1243 } |
1251 } |
1244 |
1252 |
1245 // stop activation here for slaves without type |
1253 // stop activation here for slaves without type |
1246 if (!slave->type) { |
1254 if (!slave->type) { |
1247 fsm->slave_state = ec_fsm_slave_end; |
1255 fsm->slave_state = ec_fsm_slave_end; // successful |
1248 return; |
1256 return; |
1249 } |
1257 } |
1250 |
1258 |
1251 if (!slave->base_fmmu_count) { |
1259 if (!slave->base_fmmu_count) { |
1252 fsm->slave_state = ec_fsm_slave_saveop; |
1260 fsm->slave_state = ec_fsm_slave_saveop; |
1278 { |
1286 { |
1279 ec_command_t *command = &fsm->command; |
1287 ec_command_t *command = &fsm->command; |
1280 |
1288 |
1281 if (fsm->slave->base_fmmu_count && (command->state != EC_CMD_RECEIVED || |
1289 if (fsm->slave->base_fmmu_count && (command->state != EC_CMD_RECEIVED || |
1282 command->working_counter != 1)) { |
1290 command->working_counter != 1)) { |
1283 EC_ERR("FSM failed to set FMMUs on slave %i.\n", |
|
1284 fsm->slave->ring_position); |
|
1285 fsm->slave->error_flag = 1; |
1291 fsm->slave->error_flag = 1; |
1286 fsm->slave_state = ec_fsm_slave_end; |
1292 fsm->slave_state = ec_fsm_slave_end; |
|
1293 EC_ERR("Failed to set FMMUs on slave %i.\n", |
|
1294 fsm->slave->ring_position); |
1287 return; |
1295 return; |
1288 } |
1296 } |
1289 |
1297 |
1290 // set state to SAVEOP |
1298 // set state to SAVEOP |
1291 fsm->slave_state = ec_fsm_slave_op; |
1299 fsm->slave_state = ec_fsm_slave_op; |
1304 void ec_fsm_slave_op(ec_fsm_t *fsm /**< finite state machine */) |
1312 void ec_fsm_slave_op(ec_fsm_t *fsm /**< finite state machine */) |
1305 { |
1313 { |
1306 fsm->change_state(fsm); // execute state change state machine |
1314 fsm->change_state(fsm); // execute state change state machine |
1307 |
1315 |
1308 if (fsm->change_state == ec_fsm_change_error) { |
1316 if (fsm->change_state == ec_fsm_change_error) { |
1309 fsm->slave->error_flag = 1; |
1317 fsm->slave->error_flag = 1; |
1310 fsm->slave_state = ec_fsm_slave_end; |
1318 fsm->slave_state = ec_fsm_slave_end; |
1311 return; |
1319 return; |
1312 } |
1320 } |
1313 |
1321 |
1314 if (fsm->change_state != ec_fsm_change_end) return; |
1322 if (fsm->change_state != ec_fsm_change_end) return; |
1315 |
1323 |
1316 // slave is now in SAVEOP |
1324 // slave is now in SAVEOP |
1317 if (fsm->slave->current_state == fsm->slave->requested_state) { |
1325 if (fsm->slave->current_state == fsm->slave->requested_state) { |
1318 fsm->slave_state = ec_fsm_slave_end; |
1326 fsm->slave_state = ec_fsm_slave_end; // successful |
1319 return; |
1327 return; |
1320 } |
1328 } |
1321 |
1329 |
1322 // set state to OP |
1330 // set state to OP |
1323 fsm->slave_state = ec_fsm_slave_op2; |
1331 fsm->slave_state = ec_fsm_slave_op2; |
1336 void ec_fsm_slave_op2(ec_fsm_t *fsm /**< finite state machine */) |
1344 void ec_fsm_slave_op2(ec_fsm_t *fsm /**< finite state machine */) |
1337 { |
1345 { |
1338 fsm->change_state(fsm); // execute state change state machine |
1346 fsm->change_state(fsm); // execute state change state machine |
1339 |
1347 |
1340 if (fsm->change_state == ec_fsm_change_error) { |
1348 if (fsm->change_state == ec_fsm_change_error) { |
1341 fsm->slave->error_flag = 1; |
1349 fsm->slave->error_flag = 1; |
1342 fsm->slave_state = ec_fsm_slave_end; |
1350 fsm->slave_state = ec_fsm_slave_end; |
1343 return; |
1351 return; |
1344 } |
1352 } |
1345 |
1353 |
1346 if (fsm->change_state != ec_fsm_change_end) return; |
1354 if (fsm->change_state != ec_fsm_change_end) return; |
1347 |
1355 |
1348 // slave is now in OP |
1356 // slave is now in OP |
1349 fsm->slave_state = ec_fsm_slave_end; |
1357 fsm->slave_state = ec_fsm_slave_end; // successful |
1350 } |
1358 } |
1351 |
1359 |
1352 /*****************************************************************************/ |
1360 /*****************************************************************************/ |
1353 |
1361 |
1354 /** |
1362 /** |
1607 { |
1615 { |
1608 ec_command_t *command = &fsm->command; |
1616 ec_command_t *command = &fsm->command; |
1609 ec_slave_t *slave = fsm->slave; |
1617 ec_slave_t *slave = fsm->slave; |
1610 |
1618 |
1611 if (command->state != EC_CMD_RECEIVED) { |
1619 if (command->state != EC_CMD_RECEIVED) { |
|
1620 fsm->change_state = ec_fsm_change_error; |
1612 EC_ERR("Failed to send state command to slave %i!\n", |
1621 EC_ERR("Failed to send state command to slave %i!\n", |
1613 fsm->slave->ring_position); |
1622 fsm->slave->ring_position); |
|
1623 return; |
|
1624 } |
|
1625 |
|
1626 if (command->working_counter != 1) { |
1614 fsm->change_state = ec_fsm_change_error; |
1627 fsm->change_state = ec_fsm_change_error; |
1615 return; |
|
1616 } |
|
1617 |
|
1618 if (command->working_counter != 1) { |
|
1619 EC_ERR("Failed to set state 0x%02X on slave %i: Slave did not" |
1628 EC_ERR("Failed to set state 0x%02X on slave %i: Slave did not" |
1620 " respond.\n", fsm->change_new, fsm->slave->ring_position); |
1629 " respond.\n", fsm->change_new, fsm->slave->ring_position); |
1621 fsm->change_state = ec_fsm_change_error; |
|
1622 return; |
1630 return; |
1623 } |
1631 } |
1624 |
1632 |
1625 fsm->change_start = get_cycles(); |
1633 fsm->change_start = get_cycles(); |
1626 |
1634 |
1640 { |
1648 { |
1641 ec_command_t *command = &fsm->command; |
1649 ec_command_t *command = &fsm->command; |
1642 ec_slave_t *slave = fsm->slave; |
1650 ec_slave_t *slave = fsm->slave; |
1643 |
1651 |
1644 if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { |
1652 if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { |
|
1653 fsm->change_state = ec_fsm_change_error; |
1645 EC_ERR("Failed to check state 0x%02X on slave %i.\n", |
1654 EC_ERR("Failed to check state 0x%02X on slave %i.\n", |
1646 fsm->change_new, slave->ring_position); |
1655 fsm->change_new, slave->ring_position); |
1647 fsm->change_state = ec_fsm_change_error; |
|
1648 return; |
1656 return; |
1649 } |
1657 } |
1650 |
1658 |
1651 slave->current_state = EC_READ_U8(command->data); |
1659 slave->current_state = EC_READ_U8(command->data); |
1652 |
1660 |
1720 ec_slave_t *slave = fsm->slave; |
1728 ec_slave_t *slave = fsm->slave; |
1721 uint32_t code; |
1729 uint32_t code; |
1722 const ec_code_msg_t *al_msg; |
1730 const ec_code_msg_t *al_msg; |
1723 |
1731 |
1724 if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { |
1732 if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { |
|
1733 fsm->change_state = ec_fsm_change_error; |
1725 EC_ERR("Reception of AL status code command failed.\n"); |
1734 EC_ERR("Reception of AL status code command failed.\n"); |
1726 fsm->change_state = ec_fsm_change_error; |
|
1727 return; |
1735 return; |
1728 } |
1736 } |
1729 |
1737 |
1730 if ((code = EC_READ_U16(command->data))) { |
1738 if ((code = EC_READ_U16(command->data))) { |
1731 for (al_msg = al_status_messages; al_msg->code; al_msg++) { |
1739 for (al_msg = al_status_messages; al_msg->code; al_msg++) { |
1755 { |
1763 { |
1756 ec_command_t *command = &fsm->command; |
1764 ec_command_t *command = &fsm->command; |
1757 ec_slave_t *slave = fsm->slave; |
1765 ec_slave_t *slave = fsm->slave; |
1758 |
1766 |
1759 if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { |
1767 if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { |
|
1768 fsm->change_state = ec_fsm_change_error; |
1760 EC_ERR("Reception of state ack command failed.\n"); |
1769 EC_ERR("Reception of state ack command failed.\n"); |
1761 fsm->change_state = ec_fsm_change_error; |
|
1762 return; |
1770 return; |
1763 } |
1771 } |
1764 |
1772 |
1765 // read new AL status |
1773 // read new AL status |
1766 ec_command_nprd(command, slave->station_address, 0x0130, 2); |
1774 ec_command_nprd(command, slave->station_address, 0x0130, 2); |
1779 { |
1787 { |
1780 ec_command_t *command = &fsm->command; |
1788 ec_command_t *command = &fsm->command; |
1781 ec_slave_t *slave = fsm->slave; |
1789 ec_slave_t *slave = fsm->slave; |
1782 |
1790 |
1783 if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { |
1791 if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { |
|
1792 fsm->change_state = ec_fsm_change_error; |
1784 EC_ERR("Reception of state ack check command failed.\n"); |
1793 EC_ERR("Reception of state ack check command failed.\n"); |
|
1794 return; |
|
1795 } |
|
1796 |
|
1797 slave->current_state = EC_READ_U8(command->data); |
|
1798 |
|
1799 if (slave->current_state == fsm->change_new) { |
1785 fsm->change_state = ec_fsm_change_error; |
1800 fsm->change_state = ec_fsm_change_error; |
1786 return; |
|
1787 } |
|
1788 |
|
1789 slave->current_state = EC_READ_U8(command->data); |
|
1790 |
|
1791 if (slave->current_state == fsm->change_new) { |
|
1792 EC_INFO("Acknowleged state 0x%02X on slave %i.\n", |
1801 EC_INFO("Acknowleged state 0x%02X on slave %i.\n", |
1793 slave->current_state, slave->ring_position); |
1802 slave->current_state, slave->ring_position); |
1794 fsm->change_state = ec_fsm_change_error; |
1803 return; |
1795 return; |
1804 } |
1796 } |
1805 |
1797 |
1806 fsm->change_state = ec_fsm_change_error; |
1798 EC_WARN("Failed to acknowledge state 0x%02X on slave %i" |
1807 EC_WARN("Failed to acknowledge state 0x%02X on slave %i" |
1799 " - Timeout!\n", fsm->change_new, slave->ring_position); |
1808 " - Timeout!\n", fsm->change_new, slave->ring_position); |
1800 fsm->change_state = ec_fsm_change_error; |
|
1801 } |
1809 } |
1802 |
1810 |
1803 /*****************************************************************************/ |
1811 /*****************************************************************************/ |
1804 |
1812 |
1805 /** |
1813 /** |