diff --git a/master/cdev.c b/master/cdev.c index 496f76274db04848285a6db6656c2c22d1130ab3..f1a5a80dc8b904e78aad34ad6f1a7f7a58723ee6 100644 --- a/master/cdev.c +++ b/master/cdev.c @@ -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; diff --git a/master/fsm_master.c b/master/fsm_master.c index 166d68bc45d871f50d678d6486983468cd803662..b33c75b8aaead026fb2c82def1bf3e1df2570243 100644 --- a/master/fsm_master.c +++ b/master/fsm_master.c @@ -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); diff --git a/master/ioctl.h b/master/ioctl.h index 06740f8dda8d0b5c27da0935e2e0841a17de415a..fe7cc3dd569166aea1a2ec9feb8b1df74aa69ba0 100644 --- a/master/ioctl.h +++ b/master/ioctl.h @@ -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; diff --git a/master/master.c b/master/master.c index 3b312d4d0442129a3370520da001419345742291..7deec24e56955a978c2e568ca9b00b58f705232e 100644 --- a/master/master.c +++ b/master/master.c @@ -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 *****************************************************************************/ diff --git a/master/master.h b/master/master.h index b7659f0819ac60a0215238f284a51166f2e9f497..34e08120ce41d03b249f4d1bf767e6592fac5ef3 100644 --- a/master/master.h +++ b/master/master.h @@ -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 *); /*****************************************************************************/ diff --git a/master/slave.c b/master/slave.c index ef406dc8ea3d7c6d240ff6c3cf0cd618f7ffa3e3..f2a928bedf60b57de1867d466e27b0dc7776905c 100644 --- a/master/slave.c +++ b/master/slave.c @@ -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; diff --git a/master/slave.h b/master/slave.h index a470c940a702e9a3088ec2a844a21d36aae37e71..75611650b3a3dc02eee34a9211f310155b70c3ba 100644 --- a/master/slave.h +++ b/master/slave.h @@ -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. */ diff --git a/tool/CommandSlaves.cpp b/tool/CommandSlaves.cpp index c010e5731d0ae464aacd775a214de00c87536ce4..2642da32de7d8eb86cd79eb8e05491c2fa8cf302 100644 --- a/tool/CommandSlaves.cpp +++ b/tool/CommandSlaves.cpp @@ -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 {