# HG changeset patch # User Florian Pose # Date 1241439060 0 # Node ID 08eaf72409bb473e2adc4253cb70f21526799e4e # Parent f1df39224f49099c0551babfe7f7422608013144 Use application start time as a common reference for cyclic generation start times. diff -r f1df39224f49 -r 08eaf72409bb TODO --- 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. diff -r f1df39224f49 -r 08eaf72409bb master/fsm_slave_config.c --- 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 + #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); diff -r f1df39224f49 -r 08eaf72409bb master/master.c --- 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; + } } /*****************************************************************************/ diff -r f1df39224f49 -r 08eaf72409bb master/master.h --- 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