diff --git a/master/master.c b/master/master.c index 3699ba2d..8b74215f 100644 --- a/master/master.c +++ b/master/master.c @@ -949,6 +949,69 @@ void ec_master_calc_addressing(ec_master_t *master /**< EtherCAT master */) } } +/*****************************************************************************/ + +/** + Measures the time, a frame is on the bus. +*/ + +void ec_master_measure_bus_time(ec_master_t *master) +{ + ec_datagram_t datagram; + cycles_t t_start, t_end, t_timeout; + uint32_t times[100], sum, min, max, i; + + ec_datagram_init(&datagram); + + if (ec_datagram_brd(&datagram, 0x130, 2)) { + EC_ERR("Failed to allocate datagram for bus time measuring.\n"); + ec_datagram_clear(&datagram); + return; + } + + t_timeout = (cycles_t) EC_IO_TIMEOUT * (cpu_khz / 1000); + + sum = 0; + min = 0xFFFFFFFF; + max = 0; + + for (i = 0; i < 100; i++) { + ec_master_queue_datagram(master, &datagram); + ecrt_master_send(master); + t_start = get_cycles(); + + while (1) { // active waiting + ec_device_call_isr(master->device); + t_end = get_cycles(); // take current time + + if (datagram.state == EC_DATAGRAM_RECEIVED) { + break; + } + else if (datagram.state == EC_DATAGRAM_ERROR) { + EC_WARN("Failed to measure bus time.\n"); + goto error; + } + else if (t_end - t_start >= t_timeout) { + EC_WARN("Timeout while measuring bus time.\n"); + goto error; + } + } + + times[i] = (unsigned int) (t_end - t_start) * 1000 / cpu_khz; + sum += times[i]; + if (times[i] > max) max = times[i]; + if (times[i] < min) min = times[i]; + } + + EC_INFO("Bus time is (min/avg/max) %u/%u.%u/%u us.\n", + min, sum / 100, sum % 100, max); + + error: + // Dequeue and free datagram + list_del(&datagram.queue); + ec_datagram_clear(&datagram); +} + /****************************************************************************** * Realtime interface *****************************************************************************/ diff --git a/master/master.h b/master/master.h index 3a7f3e69..15c39ac9 100644 --- a/master/master.h +++ b/master/master.h @@ -150,6 +150,7 @@ int ec_master_bus_scan(ec_master_t *); // misc. void ec_master_output_stats(ec_master_t *); void ec_master_clear_slaves(ec_master_t *); +void ec_master_measure_bus_time(ec_master_t *); // other methods void ec_sync_config(const ec_sii_sync_t *, const ec_slave_t *, uint8_t *); diff --git a/master/module.c b/master/module.c index 65f89ec9..1f7f791f 100644 --- a/master/module.c +++ b/master/module.c @@ -369,6 +369,7 @@ int ecdev_start(unsigned int master_index /**< master index */) return -1; } + ec_master_measure_bus_time(master); ec_master_idle_start(master); return 0; } @@ -429,6 +430,7 @@ ec_master_t *ecrt_request_master(unsigned int master_index goto out_release; } + ec_master_measure_bus_time(master); ec_master_idle_stop(master); ec_master_reset(master); master->mode = EC_MASTER_MODE_OPERATION;