Bus topology calculation.

This commit is contained in:
Florian Pose 2009-04-29 09:43:04 +00:00
parent d427828ecc
commit f4b6807cc9
8 changed files with 75 additions and 4 deletions

View File

@ -262,6 +262,11 @@ int ec_cdev_ioctl_slave(
data.ports[i].dl_loop = slave->ports[i].dl_loop;
data.ports[i].dl_signal = slave->ports[i].dl_signal;
data.dc_receive_times[i] = slave->dc_receive_times[i];
if (slave->next_slave[i]) {
data.next_slave[i] = slave->next_slave[i]->ring_position;
} else {
data.next_slave[i] = 0xffff;
}
}
data.fmmu_bit = slave->base_fmmu_bit_operation;
data.dc_supported = slave->base_dc_supported;

View File

@ -867,6 +867,9 @@ void ec_fsm_master_state_scan_slave(
// find DC reference clock
ec_master_find_dc_ref_clock(master);
// calculate bus topology
ec_master_calc_topology(master);
// Attach slave configurations
ec_master_attach_slave_configs(master);

View File

@ -167,6 +167,7 @@ typedef struct {
int16_t current_on_ebus;
ec_slave_port_desc_t port_descs[EC_MAX_PORTS];
ec_slave_port_t ports[EC_MAX_PORTS];
uint16_t next_slave[EC_MAX_PORTS];
uint8_t fmmu_bit;
uint8_t dc_supported;
ec_slave_dc_range_t dc_range;

View File

@ -1373,6 +1373,57 @@ void ec_master_find_dc_ref_clock(
ec_datagram_frmw(&master->sync_datagram, ref_clock_addr, 0x0910, 4);
}
/*****************************************************************************/
/** Calculates the bus topology; recursion function.
*/
int ec_master_calc_topology_rec(
ec_master_t *master, /**< EtherCAT master. */
ec_slave_t *port0_slave, /**< Slave at port 0. */
unsigned int *slave_position /**< Slave position. */
)
{
ec_slave_t *slave = master->slaves + *slave_position;
unsigned int i;
int ret;
slave->next_slave[0] = port0_slave;
for (i = 1; i < EC_MAX_PORTS; i++) {
if (!slave->ports[i].dl_loop) {
*slave_position = *slave_position + 1;
if (*slave_position < master->slave_count) {
slave->next_slave[i] = master->slaves + *slave_position;
ret = ec_master_calc_topology_rec(master,
slave, slave_position);
if (ret)
return ret;
} else {
return -1;
}
}
}
return 0;
}
/*****************************************************************************/
/** Calculates the bus topology.
*/
void ec_master_calc_topology(
ec_master_t *master /**< EtherCAT master. */
)
{
unsigned int slave_position = 0;
if (master->slave_count == 0)
return;
if (ec_master_calc_topology_rec(master, NULL, &slave_position))
EC_ERR("Failed to calculate bus topology.\n");
}
/******************************************************************************
* Application interface
*****************************************************************************/

View File

@ -234,6 +234,7 @@ ec_slave_config_t *ecrt_master_slave_config_err(ec_master_t *, uint16_t,
uint16_t, uint32_t, uint32_t);
void ec_master_find_dc_ref_clock(ec_master_t *);
void ec_master_calc_topology(ec_master_t *);
/*****************************************************************************/

View File

@ -97,6 +97,8 @@ void ec_slave_init(
slave->sii.physical_layer[i] = 0xFF;
slave->dc_receive_times[i] = 0U;
slave->next_slave[i] = NULL;
}
slave->base_fmmu_bit_operation = 0;

View File

@ -131,6 +131,7 @@ struct ec_slave
// data link status
ec_slave_port_t ports[EC_MAX_PORTS]; /**< Port link status. */
ec_slave_t *next_slave[EC_MAX_PORTS]; /**< Connected slaves. */
// SII
uint16_t *sii_words; /**< Complete SII image. */

View File

@ -266,7 +266,7 @@ void CommandSlaves::showSlaves(
cout << "no" << endl;
}
cout << "Port Type Link Loop Signal";
cout << "Port Type Link Loop Signal NextSlave";
if (si->dc_supported)
cout << " RxTime Diff";
cout << endl;
@ -294,11 +294,18 @@ void CommandSlaves::showSlaves(
<< (si->ports[i].dl_link ? "up" : "down")
<< " " << setw(6)
<< (si->ports[i].dl_loop ? "closed" : "open")
<< " " << setw(3)
<< (si->ports[i].dl_signal ? "yes" : "no");
<< " " << setw(6)
<< (si->ports[i].dl_signal ? "yes" : "no")
<< " " << setw(9) << right;
if (si->next_slave[i] != 0xffff) {
cout << dec << si->next_slave[i];
} else {
cout << "-";
}
if (si->dc_supported) {
cout << " " << setw(10) << right;
cout << " " << setw(10) << right;
if (si->ports[i].dl_signal) {
cout << dec << si->dc_receive_times[i];
} else {