50 void ec_fsm_slave_config_state_boot_preop(ec_fsm_slave_config_t *); |
50 void ec_fsm_slave_config_state_boot_preop(ec_fsm_slave_config_t *); |
51 void ec_fsm_slave_config_state_sdo_conf(ec_fsm_slave_config_t *); |
51 void ec_fsm_slave_config_state_sdo_conf(ec_fsm_slave_config_t *); |
52 void ec_fsm_slave_config_state_pdo_sync(ec_fsm_slave_config_t *); |
52 void ec_fsm_slave_config_state_pdo_sync(ec_fsm_slave_config_t *); |
53 void ec_fsm_slave_config_state_pdo_conf(ec_fsm_slave_config_t *); |
53 void ec_fsm_slave_config_state_pdo_conf(ec_fsm_slave_config_t *); |
54 void ec_fsm_slave_config_state_fmmu(ec_fsm_slave_config_t *); |
54 void ec_fsm_slave_config_state_fmmu(ec_fsm_slave_config_t *); |
|
55 void ec_fsm_slave_config_state_dc_read(ec_fsm_slave_config_t *); |
|
56 void ec_fsm_slave_config_state_dc_offset(ec_fsm_slave_config_t *); |
55 void ec_fsm_slave_config_state_dc_cycle(ec_fsm_slave_config_t *); |
57 void ec_fsm_slave_config_state_dc_cycle(ec_fsm_slave_config_t *); |
56 void ec_fsm_slave_config_state_dc_start(ec_fsm_slave_config_t *); |
58 void ec_fsm_slave_config_state_dc_start(ec_fsm_slave_config_t *); |
57 void ec_fsm_slave_config_state_dc_assign(ec_fsm_slave_config_t *); |
59 void ec_fsm_slave_config_state_dc_assign(ec_fsm_slave_config_t *); |
58 void ec_fsm_slave_config_state_safeop(ec_fsm_slave_config_t *); |
60 void ec_fsm_slave_config_state_safeop(ec_fsm_slave_config_t *); |
59 void ec_fsm_slave_config_state_op(ec_fsm_slave_config_t *); |
61 void ec_fsm_slave_config_state_op(ec_fsm_slave_config_t *); |
865 slave->ring_position); |
866 slave->ring_position); |
866 ec_datagram_print_wc_error(datagram); |
867 ec_datagram_print_wc_error(datagram); |
867 return; |
868 return; |
868 } |
869 } |
869 |
870 |
870 ec_fsm_slave_config_enter_dc_cycle(fsm); |
871 ec_fsm_slave_config_enter_dc_read(fsm); |
871 } |
872 } |
872 |
873 |
873 /*****************************************************************************/ |
874 /*****************************************************************************/ |
874 |
875 |
875 /** Check for DCs to be configured. |
876 /** Check for DCs to be configured. |
876 */ |
877 */ |
877 void ec_fsm_slave_config_enter_dc_cycle( |
878 void ec_fsm_slave_config_enter_dc_read( |
878 ec_fsm_slave_config_t *fsm /**< slave state machine */ |
879 ec_fsm_slave_config_t *fsm /**< slave state machine */ |
879 ) |
880 ) |
880 { |
881 { |
881 ec_datagram_t *datagram = fsm->datagram; |
882 ec_slave_t *slave = fsm->slave; |
882 ec_slave_t *slave = fsm->slave; |
883 |
883 ec_slave_config_t *config = slave->config; |
884 if (slave->base_dc_supported) { |
|
885 // read DC system time and system time offset |
|
886 ec_datagram_fprd(fsm->datagram, slave->station_address, 0x0910, 24); |
|
887 fsm->retries = EC_FSM_RETRIES; |
|
888 fsm->state = ec_fsm_slave_config_state_dc_read; |
|
889 } else { |
|
890 ec_fsm_slave_config_enter_safeop(fsm); |
|
891 } |
|
892 } |
|
893 |
|
894 /*****************************************************************************/ |
|
895 |
|
896 /** Slave configuration state: DC READ. |
|
897 */ |
|
898 void ec_fsm_slave_config_state_dc_read( |
|
899 ec_fsm_slave_config_t *fsm /**< slave state machine */ |
|
900 ) |
|
901 { |
|
902 ec_datagram_t *datagram = fsm->datagram; |
|
903 ec_slave_t *slave = fsm->slave; |
|
904 u64 system_time, old_offset, new_offset; |
|
905 |
|
906 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
|
907 return; |
|
908 |
|
909 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
|
910 fsm->state = ec_fsm_slave_config_state_error; |
|
911 EC_ERR("Failed to receive DC times datagram for slave %u" |
|
912 " (datagram state %u).\n", |
|
913 slave->ring_position, datagram->state); |
|
914 return; |
|
915 } |
|
916 |
|
917 if (datagram->working_counter != 1) { |
|
918 slave->error_flag = 1; |
|
919 fsm->state = ec_fsm_slave_config_state_error; |
|
920 EC_ERR("Failed to get DC times of slave %u: ", |
|
921 slave->ring_position); |
|
922 ec_datagram_print_wc_error(datagram); |
|
923 return; |
|
924 } |
|
925 |
|
926 system_time = EC_READ_U64(datagram->data); |
|
927 old_offset = EC_READ_U64(datagram->data + 16); |
|
928 new_offset = slave->master->app_time - system_time + old_offset; |
|
929 |
|
930 if (slave->master->debug_level) |
|
931 EC_DBG("Slave %u: DC system_time=%llu old_offset=%llu, " |
|
932 "app_time=%llu, new_offset=%llu\n", |
|
933 slave->ring_position, system_time, old_offset, |
|
934 slave->master->app_time, new_offset); |
|
935 |
|
936 // set DC system time offset |
|
937 ec_datagram_fpwr(datagram, slave->station_address, 0x0920, 8); |
|
938 EC_WRITE_U64(datagram->data, new_offset); |
|
939 fsm->retries = EC_FSM_RETRIES; |
|
940 fsm->state = ec_fsm_slave_config_state_dc_offset; |
|
941 } |
|
942 |
|
943 /*****************************************************************************/ |
|
944 |
|
945 /** Slave configuration state: DC OFFSET. |
|
946 */ |
|
947 void ec_fsm_slave_config_state_dc_offset( |
|
948 ec_fsm_slave_config_t *fsm /**< slave state machine */ |
|
949 ) |
|
950 { |
|
951 ec_datagram_t *datagram = fsm->datagram; |
|
952 ec_slave_t *slave = fsm->slave; |
|
953 ec_slave_config_t *config = slave->config; // FIXME |
|
954 |
|
955 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
|
956 return; |
|
957 |
|
958 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
|
959 fsm->state = ec_fsm_slave_config_state_error; |
|
960 EC_ERR("Failed to receive DC system time offset datagram for slave %u" |
|
961 " (datagram state %u).\n", |
|
962 slave->ring_position, datagram->state); |
|
963 return; |
|
964 } |
|
965 |
|
966 if (datagram->working_counter != 1) { |
|
967 slave->error_flag = 1; |
|
968 fsm->state = ec_fsm_slave_config_state_error; |
|
969 EC_ERR("Failed to set DC system time offset of slave %u: ", |
|
970 slave->ring_position); |
|
971 ec_datagram_print_wc_error(datagram); |
|
972 return; |
|
973 } |
884 |
974 |
885 if (config->dc_assign_activate) { |
975 if (config->dc_assign_activate) { |
886 if (!slave->base_dc_supported) { |
|
887 EC_WARN("Attempt to enable synchronized mode for slave %u," |
|
888 " that seems not to support distributed clocks!\n", |
|
889 slave->ring_position); |
|
890 } |
|
891 |
|
892 // set DC cycle times |
976 // set DC cycle times |
893 ec_datagram_fpwr(datagram, slave->station_address, 0x09A0, 8); |
977 ec_datagram_fpwr(datagram, slave->station_address, 0x09A0, 8); |
894 EC_WRITE_U32(datagram->data, config->dc_sync_cycle_times[0]); |
978 EC_WRITE_U32(datagram->data, config->dc_sync_cycle_times[0]); |
895 EC_WRITE_U32(datagram->data + 4, config->dc_sync_cycle_times[1]); |
979 EC_WRITE_U32(datagram->data + 4, config->dc_sync_cycle_times[1]); |
896 fsm->retries = EC_FSM_RETRIES; |
980 fsm->retries = EC_FSM_RETRIES; |
897 fsm->state = ec_fsm_slave_config_state_dc_cycle; |
981 fsm->state = ec_fsm_slave_config_state_dc_cycle; |
898 } else { |
982 } else { |
899 ec_fsm_slave_config_enter_dc_assign(fsm); |
983 ec_fsm_slave_config_enter_safeop(fsm); |
900 } |
984 } |
901 } |
985 } |
902 |
986 |
903 /*****************************************************************************/ |
987 /*****************************************************************************/ |
904 |
988 |
966 EC_ERR("Failed to set DC start time of slave %u: ", |
1057 EC_ERR("Failed to set DC start time of slave %u: ", |
967 slave->ring_position); |
1058 slave->ring_position); |
968 ec_datagram_print_wc_error(datagram); |
1059 ec_datagram_print_wc_error(datagram); |
969 return; |
1060 return; |
970 } |
1061 } |
971 |
|
972 ec_fsm_slave_config_enter_dc_assign(fsm); |
|
973 } |
|
974 |
|
975 /*****************************************************************************/ |
|
976 |
|
977 /** Set the DC AssignActivate word. |
|
978 */ |
|
979 void ec_fsm_slave_config_enter_dc_assign( |
|
980 ec_fsm_slave_config_t *fsm /**< slave state machine */ |
|
981 ) |
|
982 { |
|
983 ec_datagram_t *datagram = fsm->datagram; |
|
984 ec_slave_t *slave = fsm->slave; |
|
985 ec_slave_config_t *config = slave->config; |
|
986 |
1062 |
987 // assign sync unit to EtherCAT or PDI |
1063 // assign sync unit to EtherCAT or PDI |
988 ec_datagram_fpwr(datagram, slave->station_address, 0x0980, 2); |
1064 ec_datagram_fpwr(datagram, slave->station_address, 0x0980, 2); |
989 EC_WRITE_U16(datagram->data, config->dc_assign_activate); |
1065 EC_WRITE_U16(datagram->data, config->dc_assign_activate); |
990 fsm->retries = EC_FSM_RETRIES; |
1066 fsm->retries = EC_FSM_RETRIES; |