Determine type of DC implementation (full or delay meas. only); update scan FSM graph.
--- 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]
--- 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;
--- 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);
}
--- 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);
--- 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;
--- 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;
}
--- 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;
--- 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. */
--- 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";
}