Determine type of DC implementation (full or delay meas. only); update scan FSM graph.

This commit is contained in:
Florian Pose 2009-04-27 11:38:03 +00:00
parent e3299cfa5e
commit 69da9e5524
9 changed files with 118 additions and 17 deletions

View File

@ -14,7 +14,14 @@ digraph slavescan {
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 @@ digraph slavescan {
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]

View File

@ -262,6 +262,7 @@ int ec_cdev_ioctl_slave(
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;

View File

@ -348,7 +348,7 @@ void ec_fsm_slave_config_enter_dc_clear_assign(
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 @@ void ec_fsm_slave_config_enter_dc_cycle(
}
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);
}

View File

@ -47,6 +47,7 @@ void ec_fsm_slave_scan_state_start(ec_fsm_slave_scan_t *);
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_pdos(ec_fsm_slave_scan_t *);
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 @@ void ec_fsm_slave_scan_state_base(ec_fsm_slave_scan_t *fsm /**< slave state mach
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);

View File

@ -169,6 +169,7 @@ typedef struct {
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;

View File

@ -1363,7 +1363,7 @@ void ec_master_find_dc_ref_clock(
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;
}

View File

@ -100,6 +100,7 @@ void ec_slave_init(
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;

View File

@ -133,6 +133,9 @@ struct ec_slave
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. */

View File

@ -268,18 +268,21 @@ void CommandSlaves::showSlaves(
<< (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 << "???";
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";
}
cout << ")";
} else {
cout << "no";
}