# HG changeset patch # User Florian Pose # Date 1240832283 0 # Node ID 8fc38c37d86e427815b5371db360efc71f04878b # Parent 8b10ba4d330225632e2b75257cb6d4ce676953b7 Determine type of DC implementation (full or delay meas. only); update scan FSM graph. diff -r 8b10ba4d3302 -r 8fc38c37d86e documentation/graphs/fsm_slave_scan.dot --- a/documentation/graphs/fsm_slave_scan.dot Fri Apr 24 13:43:51 2009 +0000 +++ b/documentation/graphs/fsm_slave_scan.dot Mon Apr 27 11:38:03 2009 +0000 @@ -14,7 +14,14 @@ state -> base [weight=10] base [fontname="Helvetica"] - base -> datalink [weight=10] + base -> dc_cap [weight=10] + base -> enter_datalink [fontname="Helvetica", label="DC not\nsupported"] + + dc_cap [fontname="Helvetica"] + dc_cap -> enter_datalink [weight=10] + + enter_datalink [shape=point, label=""] + enter_datalink -> datalink [weight=10] datalink [fontname="Helvetica"] datalink -> sii_size [weight=10] @@ -23,10 +30,21 @@ sii_size -> sii_data [weight=10] sii_data [fontname="Helvetica"] - sii_data -> preop [weight=10] + sii_data -> end [fontname="Helvetica", label="No category\ndata"] + sii_data -> enter_preop [weight=10] + + enter_preop [shape=point, label=""] + enter_preop -> preop [fontname="Helvetica", label="Not in\nPREOP"] + enter_preop -> sync [weight=10] preop [fontname="Helvetica"] - preop -> pdos [weight=10] + preop -> enter_pdos [weight=10] + + sync [fontname="Helvetica"] + sync -> enter_pdos [weight=10] + + enter_pdos [shape=point, label=""] + enter_pdos -> pdos [weight=10] pdos [fontname="Helvetica"] pdos -> end [weight=10] diff -r 8b10ba4d3302 -r 8fc38c37d86e master/cdev.c --- a/master/cdev.c Fri Apr 24 13:43:51 2009 +0000 +++ b/master/cdev.c Mon Apr 27 11:38:03 2009 +0000 @@ -262,6 +262,7 @@ data.fmmu_bit = slave->base_fmmu_bit_operation; data.dc_supported = slave->base_dc_supported; data.dc_range = slave->base_dc_range; + data.has_dc_system_time = slave->has_dc_system_time; data.al_state = slave->current_state; data.error_flag = slave->error_flag; diff -r 8b10ba4d3302 -r 8fc38c37d86e master/fsm_slave_config.c --- a/master/fsm_slave_config.c Fri Apr 24 13:43:51 2009 +0000 +++ b/master/fsm_slave_config.c Mon Apr 27 11:38:03 2009 +0000 @@ -348,7 +348,7 @@ ec_slave_t *slave = fsm->slave; ec_datagram_t *datagram = fsm->datagram; - if (!slave->base_dc_supported) { + if (!slave->base_dc_supported || !slave->has_dc_system_time) { ec_fsm_slave_config_enter_mbox_sync(fsm); return; } @@ -1035,7 +1035,7 @@ } if (config->dc_assign_activate) { - if (!slave->base_dc_supported) { + if (!slave->base_dc_supported || !slave->has_dc_system_time) { EC_WARN("Slave %u seems not to support distributed clocks!\n", slave->ring_position); } diff -r 8b10ba4d3302 -r 8fc38c37d86e master/fsm_slave_scan.c --- a/master/fsm_slave_scan.c Fri Apr 24 13:43:51 2009 +0000 +++ b/master/fsm_slave_scan.c Mon Apr 27 11:38:03 2009 +0000 @@ -47,6 +47,7 @@ void ec_fsm_slave_scan_state_address(ec_fsm_slave_scan_t *); void ec_fsm_slave_scan_state_state(ec_fsm_slave_scan_t *); void ec_fsm_slave_scan_state_base(ec_fsm_slave_scan_t *); +void ec_fsm_slave_scan_state_dc_cap(ec_fsm_slave_scan_t *); void ec_fsm_slave_scan_state_datalink(ec_fsm_slave_scan_t *); void ec_fsm_slave_scan_state_sii_size(ec_fsm_slave_scan_t *); void ec_fsm_slave_scan_state_sii_data(ec_fsm_slave_scan_t *); @@ -57,6 +58,7 @@ void ec_fsm_slave_scan_state_end(ec_fsm_slave_scan_t *); void ec_fsm_slave_scan_state_error(ec_fsm_slave_scan_t *); +void ec_fsm_slave_scan_enter_datalink(ec_fsm_slave_scan_t *); void ec_fsm_slave_scan_enter_preop(ec_fsm_slave_scan_t *); void ec_fsm_slave_scan_enter_pdos(ec_fsm_slave_scan_t *); @@ -316,6 +318,78 @@ slave->base_dc_supported = (octet >> 2) & 0x01; slave->base_dc_range = ((octet >> 3) & 0x01) ? EC_DC_64 : EC_DC_32; + if (slave->base_dc_supported) { + // read DC capabilities + ec_datagram_fprd(datagram, slave->station_address, 0x0910, + slave->base_dc_range == EC_DC_64 ? 8 : 4); + ec_datagram_zero(datagram); + fsm->retries = EC_FSM_RETRIES; + fsm->state = ec_fsm_slave_scan_state_dc_cap; + } else { + ec_fsm_slave_scan_enter_datalink(fsm); + } +} + +/*****************************************************************************/ + +/** + Slave scan state: DC CAPABILITIES. +*/ + +void ec_fsm_slave_scan_state_dc_cap( + ec_fsm_slave_scan_t *fsm /**< slave state machine */ + ) +{ + ec_datagram_t *datagram = fsm->datagram; + ec_slave_t *slave = fsm->slave; + + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; + + if (datagram->state != EC_DATAGRAM_RECEIVED) { + fsm->state = ec_fsm_slave_scan_state_error; + EC_ERR("Failed to receive system time datagram for slave %u" + " (datagram state %u).\n", + slave->ring_position, datagram->state); + return; + } + + if (datagram->working_counter == 1) { + slave->has_dc_system_time = 1; + if (slave->master->debug_level) { + EC_DBG("Slave %u has the System Time register.\n", + slave->ring_position); + } + } else if (datagram->working_counter == 0) { + if (slave->master->debug_level) { + EC_DBG("Slave %u has no System Time register; delay " + "measurement only.\n", slave->ring_position); + } + } else { + fsm->slave->error_flag = 1; + fsm->state = ec_fsm_slave_scan_state_error; + EC_ERR("Failed to determine, if system time register is " + "supported by slave %u: ", slave->ring_position); + ec_datagram_print_wc_error(datagram); + return; + } + + ec_fsm_slave_scan_enter_datalink(fsm); +} + +/*****************************************************************************/ + +/** + Slave scan entry function: DATALINK. +*/ + +void ec_fsm_slave_scan_enter_datalink( + ec_fsm_slave_scan_t *fsm /**< slave state machine */ + ) +{ + ec_datagram_t *datagram = fsm->datagram; + ec_slave_t *slave = fsm->slave; + // read data link status ec_datagram_fprd(datagram, slave->station_address, 0x0110, 2); ec_datagram_zero(datagram); diff -r 8b10ba4d3302 -r 8fc38c37d86e master/ioctl.h --- a/master/ioctl.h Fri Apr 24 13:43:51 2009 +0000 +++ b/master/ioctl.h Mon Apr 27 11:38:03 2009 +0000 @@ -169,6 +169,7 @@ uint8_t fmmu_bit; uint8_t dc_supported; ec_slave_dc_range_t dc_range; + uint8_t has_dc_system_time; uint8_t al_state; uint8_t error_flag; uint8_t sync_count; diff -r 8b10ba4d3302 -r 8fc38c37d86e master/master.c --- a/master/master.c Fri Apr 24 13:43:51 2009 +0000 +++ b/master/master.c Mon Apr 27 11:38:03 2009 +0000 @@ -1363,7 +1363,7 @@ for (slave = master->slaves; slave < master->slaves + master->slave_count; slave++) { - if (slave->base_dc_supported) { + if (slave->base_dc_supported && slave->has_dc_system_time) { ref_clock_addr = slave->station_address; break; } diff -r 8b10ba4d3302 -r 8fc38c37d86e master/slave.c --- a/master/slave.c Fri Apr 24 13:43:51 2009 +0000 +++ b/master/slave.c Mon Apr 27 11:38:03 2009 +0000 @@ -100,6 +100,7 @@ slave->base_fmmu_bit_operation = 0; slave->base_dc_supported = 0; slave->base_dc_range = EC_DC_32; + slave->has_dc_system_time = 0; slave->sii_words = NULL; slave->sii_nwords = 0; diff -r 8b10ba4d3302 -r 8fc38c37d86e master/slave.h --- a/master/slave.h Fri Apr 24 13:43:51 2009 +0000 +++ b/master/slave.h Mon Apr 27 11:38:03 2009 +0000 @@ -133,6 +133,9 @@ uint8_t base_fmmu_bit_operation; /**< FMMU bit operation is supported. */ uint8_t base_dc_supported; /**< Distributed clocks are supported. */ ec_slave_dc_range_t base_dc_range; /**< DC range. */ + uint8_t has_dc_system_time; /**< The slave supports the DC system time + register. Otherwise it can only be used for + delay measurement. */ // data link status ec_slave_port_t ports[EC_MAX_PORTS]; /**< Port link status. */ diff -r 8b10ba4d3302 -r 8fc38c37d86e tool/CommandSlaves.cpp --- a/tool/CommandSlaves.cpp Fri Apr 24 13:43:51 2009 +0000 +++ b/tool/CommandSlaves.cpp Mon Apr 27 11:38:03 2009 +0000 @@ -268,18 +268,21 @@ << (si->fmmu_bit ? "yes" : "no") << endl << " Distributed clocks: "; if (si->dc_supported) { - cout << "yes ("; - switch (si->dc_range) { - case EC_DC_32: - cout << "32 bit"; - break; - case EC_DC_64: - cout << "64 bit"; - break; - default: - cout << "???"; - } - cout << ")"; + if (si->has_dc_system_time) { + cout << "yes, "; + switch (si->dc_range) { + case EC_DC_32: + cout << "32 bit"; + break; + case EC_DC_64: + cout << "64 bit"; + break; + default: + cout << "???"; + } + } else { + cout << "yes, delay measurement only"; + } } else { cout << "no"; }