--- a/TODO Mon May 04 12:10:11 2009 +0000
+++ b/TODO Mon May 04 12:11:00 2009 +0000
@@ -11,9 +11,7 @@
Version 1.5.0:
* Distributed clocks:
- - Use common application time offset when setting start times.
- Check 32/64 bit operations.
- - Set system time offset only when application time available.
- Use vendor correction factors when calculating transmission delays.
* Fix unloading problem of ec_e100 driver.
* Use ec_datagram_zero() where possible.
--- a/master/fsm_slave_config.c Mon May 04 12:10:11 2009 +0000
+++ b/master/fsm_slave_config.c Mon May 04 12:11:00 2009 +0000
@@ -34,6 +34,8 @@
/*****************************************************************************/
+#include <asm/div64.h>
+
#include "globals.h"
#include "master.h"
#include "mailbox.h"
@@ -1063,6 +1065,7 @@
{
ec_datagram_t *datagram = fsm->datagram;
ec_slave_t *slave = fsm->slave;
+ ec_master_t *master = slave->master;
ec_slave_config_t *config = slave->config;
u64 start_time;
@@ -1092,9 +1095,38 @@
}
// set DC start time
- start_time = slave->master->app_time +
- config->dc_sync_shift_times[0] + 100000000ULL; // now + shift + x ns
- if (slave->master->debug_level)
+ start_time = master->app_time + 100000000ULL; // now + X ns
+ // FIXME use slave's local system time here?
+
+ if (config->dc_sync_cycle_times[0]) {
+ // find correct phase
+ if (master->has_start_time) {
+ u32 cycle_time, shift_time, remainder;
+ u64 start, diff;
+
+ cycle_time = config->dc_sync_cycle_times[0];
+ shift_time = config->dc_sync_shift_times[0];
+ diff = start_time - master->app_start_time;
+ remainder = do_div(diff, cycle_time);
+
+ start = start_time + cycle_time - remainder + shift_time;
+
+ if (master->debug_level) {
+ EC_DBG("app_start_time=%llu\n", master->app_start_time);
+ EC_DBG(" start_time=%llu\n", start_time);
+ EC_DBG(" cycle_time=%u\n", cycle_time);
+ EC_DBG(" shift_time=%u\n", shift_time);
+ EC_DBG(" remainder=%u\n", remainder);
+ EC_DBG(" start=%llu\n", start);
+ }
+ start_time = start;
+ } else {
+ EC_WARN("No application time supplied. Cyclic start time will "
+ "not be in phase for slave %u.", slave->ring_position);
+ }
+ }
+
+ if (master->debug_level)
EC_DBG("Slave %u: Setting DC cyclic operation start time to %llu.\n",
slave->ring_position, start_time);
--- a/master/master.c Mon May 04 12:10:11 2009 +0000
+++ b/master/master.c Mon May 04 12:11:00 2009 +0000
@@ -130,6 +130,8 @@
INIT_LIST_HEAD(&master->configs);
master->app_time = 0ULL;
+ master->app_start_time = 0ULL;
+ master->has_start_time = 0;
master->scan_busy = 0;
master->allow_scan = 1;
@@ -626,6 +628,8 @@
#endif
master->app_time = 0ULL;
+ master->app_start_time = 0ULL;
+ master->has_start_time = 0;
if (ec_master_thread_start(master, ec_master_idle_thread,
"EtherCAT-IDLE"))
@@ -1748,6 +1752,11 @@
void ecrt_master_application_time(ec_master_t *master, uint64_t app_time)
{
master->app_time = app_time;
+
+ if (unlikely(!master->has_start_time)) {
+ master->app_start_time = app_time;
+ master->has_start_time = 1;
+ }
}
/*****************************************************************************/
--- a/master/master.h Mon May 04 12:10:11 2009 +0000
+++ b/master/master.h Mon May 04 12:11:00 2009 +0000
@@ -118,6 +118,8 @@
struct list_head configs; /**< List of slave configurations. */
u64 app_time; /**< Time of the last ecrt_master_sync() call. */
+ u64 app_start_time; /**< Application start time. */
+ u8 has_start_time; /**< Start time already taken. */
ec_datagram_t ref_sync_datagram; /**< Datagram used for synchronizing the
reference clock to the master clock. */
ec_datagram_t sync_datagram; /**< Datagram used for DC drift