diff --git a/TODO b/TODO index 41ee54ac4c9014486a84f715714a1d437cbd02e4..42ba47072c01e756d13e3c8c7c2ec5f76d74d874 100644 --- a/TODO +++ b/TODO @@ -12,8 +12,8 @@ Version 1.5.0: * Distributed clocks: - Delay calculation. - - User same application time offset when setting start times. - - Replace timeval by uint64 EtherCAT time. + - Use common application time offset when setting start times. + - Check 32/64 bit operations. * Fix arguments of reg_read. * Sign/Abs type for reg_ commands? * Number layout for reg_read. diff --git a/examples/dc_rtai/dc_rtai_sample.c b/examples/dc_rtai/dc_rtai_sample.c index c587302a12a7f11c14dc0ba1b0a3d2e4cfeed2b9..503cbdeb5bf3e0fedb34d69a40b22ff594b534d8 100644 --- a/examples/dc_rtai/dc_rtai_sample.c +++ b/examples/dc_rtai/dc_rtai_sample.c @@ -220,13 +220,16 @@ void run(long data) tv.tv_usec -= 1000000; tv.tv_sec++; } - //printk(KERN_INFO PFX "tv=%u.%06u\n", (u32) tv.tv_sec, (u32) tv.tv_usec); if (sync_ref_counter) { sync_ref_counter--; } else { sync_ref_counter = 9; - ecrt_master_sync_reference_clock(master, &tv); +#if 0 + printk(KERN_INFO PFX "ref: %u %u %llu\n", + (u32) tv.tv_sec, (u32) tv.tv_usec, EC_TIMEVAL2NANO(&tv)); +#endif + ecrt_master_sync_reference_clock(master, EC_TIMEVAL2NANO(&tv)); } ecrt_master_sync_slave_clocks(master); ecrt_domain_queue(domain1); diff --git a/examples/dc_user/main.c b/examples/dc_user/main.c index 1bffa4e31c15f0ad40cf37d767bdbbf04ccfc1ba..444a0abf741147be78d8a10b8540a6f50260278d 100644 --- a/examples/dc_user/main.c +++ b/examples/dc_user/main.c @@ -169,7 +169,7 @@ void cyclic_task() sync_ref_counter--; } else { sync_ref_counter = 9; - ecrt_master_sync_reference_clock(master, &app_time); + ecrt_master_sync_reference_clock(master, EC_TIMEVAL2NANO(&app_time)); } ecrt_master_sync_slave_clocks(master); diff --git a/include/ecrt.h b/include/ecrt.h index ac53f9e7030a7e78ab5e2533c4bbfcdb07e2dc28..ed8317a9802539a30038125a136902562f8ba7fb 100644 --- a/include/ecrt.h +++ b/include/ecrt.h @@ -46,7 +46,8 @@ * ecrt_slave_config_dc_sync_cycle_times() and * ecrt_slave_config_dc_sync_shift_times() to configure a slave for cyclic * operation, and ecrt_master_sync_reference_clock() and - * ecrt_master_sync_slave_clocks() for drift compensation. + * ecrt_master_sync_slave_clocks() for drift compensation. The + * EC_TIMEVAL2NANO() macro can be used for epoch time conversion. * - Changed the meaning of the negative return values of * ecrt_slave_config_reg_pdo_entry() and ecrt_slave_config_sdo*(). * - Imlemented the Vendor-specific over EtherCAT mailbox protocol. See @@ -114,6 +115,17 @@ */ #define EC_MAX_STRING_LENGTH 64 +/** Timeval to nanoseconds conversion. + * + * This macro converts a unix epoch time to EtherCAT DC time. + * + * \see ecrt_master_sync_reference_clock() + * + * \param TV Pointer to struct timeval. + */ +#define EC_TIMEVAL2NANO(TV) \ + (((TV)->tv_sec - 946684800ULL) * 1000000000ULL + (TV)->tv_usec * 1000ULL) + /****************************************************************************** * Data types *****************************************************************************/ @@ -510,11 +522,13 @@ void ecrt_master_state( /** Queues the DC reference clock drift compensation datagram for sending. * - * The reference clock will by synchronized to the \a app_time. + * The reference clock will by synchronized to the \a app_time. The time is + * defined as nanoseconds from 2000-01-01 00:00. Converting an epoch time can + * be done with the EC_TIMEVAL2NANO() macro. */ void ecrt_master_sync_reference_clock( ec_master_t *master, /**< EtherCAT master. */ - const struct timeval *app_time /**< Application time. */ + uint64_t app_time /**< Application time. */ ); /** Queues the DC clock drift compensation datagram for sending. diff --git a/lib/master.c b/lib/master.c index 298cd60fc8fd9af9aee7746a19d9c863ede5f2ee..f266f75253d7ead40d7b5a48ee8e492023558442 100644 --- a/lib/master.c +++ b/lib/master.c @@ -190,13 +190,11 @@ void ecrt_master_state(const ec_master_t *master, ec_master_state_t *state) /*****************************************************************************/ -void ecrt_master_sync_reference_clock(ec_master_t *master, - const struct timeval *app_time) +void ecrt_master_sync_reference_clock(ec_master_t *master, uint64_t app_time) { ec_ioctl_dc_t data; - data.app_time.tv_sec = app_time->tv_sec; - data.app_time.tv_usec = app_time->tv_usec; + data.app_time = app_time; if (ioctl(master->fd, EC_IOCTL_SYNC_REF, &data) == -1) { fprintf(stderr, "Failed to sync reference clock: %s\n", diff --git a/master/cdev.c b/master/cdev.c index 8fbd265cb845053463091898dac8736ac8330697..395ccdb245503728bd1dd26e7cedfa19f798adfe 100644 --- a/master/cdev.c +++ b/master/cdev.c @@ -1647,7 +1647,7 @@ int ec_cdev_ioctl_sync_ref( return -EFAULT; spin_lock_bh(&master->internal_lock); - ecrt_master_sync_reference_clock(master, &data.app_time); + ecrt_master_sync_reference_clock(master, data.app_time); spin_unlock_bh(&master->internal_lock); return 0; } diff --git a/master/globals.h b/master/globals.h index 2daf06c65f69923a70b6b91f6cc1dfce56b423ac..3444f15020e6effded750d59e7541352f87ea41c 100644 --- a/master/globals.h +++ b/master/globals.h @@ -251,13 +251,6 @@ enum { .name = EC_STR(NAME), .owner = THIS_MODULE, .mode = S_IRUGO | S_IWUSR \ } -/** Timeval to nanoseconds conversion. - * - * \param TV Pointer to struct timeval. - */ -#define EC_TIMEVAL2NANO(TV) \ - (((TV)->tv_sec - 946684800ULL) * 1000000000ULL + (TV)->tv_usec * 1000ULL) - /*****************************************************************************/ extern char *ec_master_version_str; diff --git a/master/ioctl.h b/master/ioctl.h index fb3d31718aed91e69745f2a17f0826d47c644e00..431fe246898cb0d032baba307501533be8154d8d 100644 --- a/master/ioctl.h +++ b/master/ioctl.h @@ -389,7 +389,7 @@ typedef struct { typedef struct { // inputs - struct timeval app_time; + uint64_t app_time; } ec_ioctl_dc_t; /*****************************************************************************/ diff --git a/master/master.c b/master/master.c index e0a8384fc260a655640124f761a8757e2c737c88..231b7a80eb66b41407779de8926bedf17c521596 100644 --- a/master/master.c +++ b/master/master.c @@ -1651,9 +1651,9 @@ void ecrt_master_state(const ec_master_t *master, ec_master_state_t *state) /*****************************************************************************/ void ecrt_master_sync_reference_clock(ec_master_t *master, - const struct timeval *app_time) + uint64_t app_time) { - master->app_time = EC_TIMEVAL2NANO(app_time); + master->app_time = app_time; EC_WRITE_U32(master->ref_sync_datagram.data, master->app_time); ec_master_queue_datagram(master, &master->ref_sync_datagram); }