From c39919e6cce93fa9f48c62b7614cf4e956d95ae9 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Mon, 4 May 2009 12:46:30 +0000 Subject: [PATCH] Replaced ecrt_slave_config_dc_cycle_times() and ecrt_slave_config_dc_shift_times() by ecrt_slave_config_dc_sync_signals(). --- examples/dc_rtai/dc_rtai_sample.c | 3 +- examples/dc_user/main.c | 3 +- include/ecrt.h | 30 ++++++++----------- lib/slave_config.c | 29 +++++------------- master/cdev.c | 50 +++++-------------------------- master/fsm_slave_config.c | 22 +++++++------- master/globals.h | 10 +++++++ master/ioctl.h | 46 ++++++++++++++-------------- master/slave_config.c | 31 ++++++++----------- master/slave_config.h | 5 ++-- 10 files changed, 87 insertions(+), 142 deletions(-) diff --git a/examples/dc_rtai/dc_rtai_sample.c b/examples/dc_rtai/dc_rtai_sample.c index 336fb2da..ddca94fa 100644 --- a/examples/dc_rtai/dc_rtai_sample.c +++ b/examples/dc_rtai/dc_rtai_sample.c @@ -329,8 +329,7 @@ int __init init_mod(void) #if 1 // configure SYNC signals for this slave ecrt_slave_config_dc_assign_activate(sc, 0x0700); - ecrt_slave_config_dc_sync_cycle_times(sc, 1000000, 0); - ecrt_slave_config_dc_sync_shift_times(sc, 440000, 0); + ecrt_slave_config_dc_sync_signals(sc, 1000000, 440000, 0, 0); #endif printk(KERN_INFO PFX "Activating master...\n"); diff --git a/examples/dc_user/main.c b/examples/dc_user/main.c index 71f645ed..385b7f61 100644 --- a/examples/dc_user/main.c +++ b/examples/dc_user/main.c @@ -240,8 +240,7 @@ int main(int argc, char **argv) #if 1 // configure SYNC signals for this slave ecrt_slave_config_dc_assign_activate(sc, 0x0700); - ecrt_slave_config_dc_sync_cycle_times(sc, 10000000, 0); - ecrt_slave_config_dc_sync_shift_times(sc, 4400000, 0); + ecrt_slave_config_dc_sync_signals(sc, 10000000, 4400000, 0, 0); #endif printf("Activating master...\n"); diff --git a/include/ecrt.h b/include/ecrt.h index 4a9b3510..6528627d 100644 --- a/include/ecrt.h +++ b/include/ecrt.h @@ -42,12 +42,12 @@ * Changes in version 1.5: * * - Added the distributed clocks feature and the respective methods - * ecrt_slave_config_dc_assign_activate(), - * 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. The - * EC_TIMEVAL2NANO() macro can be used for epoch time conversion. + * ecrt_slave_config_dc_assign_activate() and + * ecrt_slave_config_dc_sync_signals() to configure a slave for cyclic + * operation, and ecrt_master_application_time(), + * ecrt_master_sync_reference_clock() and ecrt_master_sync_slave_clocks() + * for offset and 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 @@ -733,20 +733,14 @@ void ecrt_slave_config_dc_assign_activate( uint16_t assign_activate /**< AssignActivate word. */ ); -/** Sets the cycle times for the SYNC0 and SYNC1 signals. +/** Sets the cycle and shift times for the sync signals. */ -void ecrt_slave_config_dc_sync_cycle_times( +void ecrt_slave_config_dc_sync_signals( ec_slave_config_t *sc, /**< Slave configuration. */ - uint32_t sync0_cycle_time, /**< SYNC0 cycle time [ns]. */ - uint32_t sync1_cycle_time /**< SYNC1 cycle time [ns]. */ - ); - -/** Sets the shift times for the SYNC0 and SYNC1 signals. - */ -void ecrt_slave_config_dc_sync_shift_times( - ec_slave_config_t *sc, /**< Slave configuration. */ - uint32_t sync0_shift_time, /**< SYNC0 shift time [ns]. */ - uint32_t sync1_shift_time /**< SYNC1 shift time [ns]. */ + uint32_t sync0_cycle, /**< SYNC0 cycle time [ns]. */ + uint32_t sync0_shift, /**< SYNC0 shift time [ns]. */ + uint32_t sync1_cycle, /**< SYNC1 cycle time [ns]. */ + uint32_t sync1_shift /**< SYNC1 shift time [ns]. */ ); /** Add an SDO configuration. diff --git a/lib/slave_config.c b/lib/slave_config.c index 03f102d2..1715d9ec 100644 --- a/lib/slave_config.c +++ b/lib/slave_config.c @@ -259,32 +259,19 @@ void ecrt_slave_config_dc_assign_activate(ec_slave_config_t *sc, /*****************************************************************************/ -void ecrt_slave_config_dc_sync_cycle_times(ec_slave_config_t *sc, - uint32_t sync0_cycle_time, uint32_t sync1_cycle_time) +void ecrt_slave_config_dc_sync_signals(ec_slave_config_t *sc, + uint32_t sync0_cycle_time, uint32_t sync0_shift_time, + uint32_t sync1_cycle_time, uint32_t sync1_shift_time) { ec_ioctl_sc_dc_t data; data.config_index = sc->index; - data.cycle[0] = sync0_cycle_time; - data.cycle[1] = sync1_cycle_time; + data.sync[0].cycle_time = sync0_cycle_time; + data.sync[0].shift_time = sync0_shift_time; + data.sync[1].cycle_time = sync1_cycle_time; + data.sync[1].shift_time = sync1_shift_time; - if (ioctl(sc->master->fd, EC_IOCTL_SC_DC_CYCLE, &data) == -1) { - fprintf(stderr, "Failed to set assign_activate word.\n"); - } -} - -/*****************************************************************************/ - -void ecrt_slave_config_dc_sync_shift_times(ec_slave_config_t *sc, - uint32_t sync0_shift_time, uint32_t sync1_shift_time) -{ - ec_ioctl_sc_dc_t data; - - data.config_index = sc->index; - data.shift[0] = sync0_shift_time; - data.shift[1] = sync1_shift_time; - - if (ioctl(sc->master->fd, EC_IOCTL_SC_DC_SHIFT, &data) == -1) { + if (ioctl(sc->master->fd, EC_IOCTL_SC_DC_SYNC, &data) == -1) { fprintf(stderr, "Failed to set assign_activate word.\n"); } } diff --git a/master/cdev.c b/master/cdev.c index db1200f6..32138ce7 100644 --- a/master/cdev.c +++ b/master/cdev.c @@ -1940,7 +1940,7 @@ int ec_cdev_ioctl_sc_dc_assign( /** Sets the DC cycle times. */ -int ec_cdev_ioctl_sc_dc_cycle( +int ec_cdev_ioctl_sc_dc_sync_signals( ec_master_t *master, /**< EtherCAT master. */ unsigned long arg, /**< ioctl() argument. */ ec_cdev_priv_t *priv /**< Private data structure of file handle. */ @@ -1963,41 +1963,11 @@ int ec_cdev_ioctl_sc_dc_cycle( return -ENOENT; } - ecrt_slave_config_dc_sync_cycle_times(sc, data.cycle[0], data.cycle[1]); - - up(&master->master_sem); - - return 0; -} - -/*****************************************************************************/ - -/** Sets the DC shift times. - */ -int ec_cdev_ioctl_sc_dc_shift( - ec_master_t *master, /**< EtherCAT master. */ - unsigned long arg, /**< ioctl() argument. */ - ec_cdev_priv_t *priv /**< Private data structure of file handle. */ - ) -{ - ec_ioctl_sc_dc_t data; - ec_slave_config_t *sc; - - if (unlikely(!priv->requested)) - return -EPERM; - - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) - return -EFAULT; - - if (down_interruptible(&master->master_sem)) - return -EINTR; - - if (!(sc = ec_master_get_config(master, data.config_index))) { - up(&master->master_sem); - return -ENOENT; - } - - ecrt_slave_config_dc_sync_shift_times(sc, data.shift[0], data.shift[1]); + ecrt_slave_config_dc_sync_signals(sc, + data.sync[0].cycle_time, + data.sync[0].shift_time, + data.sync[1].cycle_time, + data.sync[1].shift_time); up(&master->master_sem); @@ -3229,14 +3199,10 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (!(filp->f_mode & FMODE_WRITE)) return -EPERM; return ec_cdev_ioctl_sc_dc_assign(master, arg, priv); - case EC_IOCTL_SC_DC_CYCLE: + case EC_IOCTL_SC_DC_SYNC: if (!(filp->f_mode & FMODE_WRITE)) return -EPERM; - return ec_cdev_ioctl_sc_dc_cycle(master, arg, priv); - case EC_IOCTL_SC_DC_SHIFT: - if (!(filp->f_mode & FMODE_WRITE)) - return -EPERM; - return ec_cdev_ioctl_sc_dc_shift(master, arg, priv); + return ec_cdev_ioctl_sc_dc_sync_signals(master, arg, priv); case EC_IOCTL_SC_SDO: if (!(filp->f_mode & FMODE_WRITE)) return -EPERM; diff --git a/master/fsm_slave_config.c b/master/fsm_slave_config.c index 5eb8938c..9a20f1b3 100644 --- a/master/fsm_slave_config.c +++ b/master/fsm_slave_config.c @@ -1045,8 +1045,8 @@ void ec_fsm_slave_config_enter_dc_cycle( // set DC cycle times ec_datagram_fpwr(datagram, slave->station_address, 0x09A0, 8); - EC_WRITE_U32(datagram->data, config->dc_sync_cycle_times[0]); - EC_WRITE_U32(datagram->data + 4, config->dc_sync_cycle_times[1]); + EC_WRITE_U32(datagram->data, config->dc_sync[0].cycle_time); + EC_WRITE_U32(datagram->data + 4, config->dc_sync[1].cycle_time); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_slave_config_state_dc_cycle; } else { @@ -1067,6 +1067,7 @@ void ec_fsm_slave_config_state_dc_cycle( ec_slave_t *slave = fsm->slave; ec_master_t *master = slave->master; ec_slave_config_t *config = slave->config; + ec_sync_signal_t *sync0 = &config->dc_sync[0]; u64 start_time; if (!config) { // config removed in the meantime @@ -1098,24 +1099,23 @@ void ec_fsm_slave_config_state_dc_cycle( start_time = master->app_time + 100000000ULL; // now + X ns // FIXME use slave's local system time here? - if (config->dc_sync_cycle_times[0]) { + if (sync0->cycle_time) { // find correct phase if (master->has_start_time) { - u32 cycle_time, shift_time, remainder; - u64 start, diff; + u64 diff, start; + u32 remainder; - 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); + remainder = do_div(diff, sync0->cycle_time); - start = start_time + cycle_time - remainder + shift_time; + start = start_time + + sync0->cycle_time - remainder + sync0->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(" cycle_time=%u\n", sync0->cycle_time); + EC_DBG(" shift_time=%u\n", sync0->shift_time); EC_DBG(" remainder=%u\n", remainder); EC_DBG(" start=%llu\n", start); } diff --git a/master/globals.h b/master/globals.h index 85c97cd7..fb83c22c 100644 --- a/master/globals.h +++ b/master/globals.h @@ -102,6 +102,9 @@ /** Size of an FMMU configuration page. */ #define EC_FMMU_PAGE_SIZE 16 +/** Number of DC sync signals. */ +#define EC_SYNC_SIGNAL_COUNT 2 + /** Slave state mask. * * Apply this mask to a slave state byte to get the slave state without @@ -182,6 +185,13 @@ typedef enum { port 0 receive time. */ } ec_slave_dc_range_t; +/** EtherCAT slave sync signal configuration. + */ +typedef struct { + uint32_t cycle_time; /**< Cycle time [ns]. */ + uint32_t shift_time; /**< Shift time [ns]. */ +} ec_sync_signal_t; + /** Access states for SDO entries. * * The access rights are managed per AL state. diff --git a/master/ioctl.h b/master/ioctl.h index ce681418..b9b9da54 100644 --- a/master/ioctl.h +++ b/master/ioctl.h @@ -96,28 +96,27 @@ #define EC_IOCTL_SC_CLEAR_ENTRIES EC_IOW(0x26, ec_ioctl_config_pdo_t) #define EC_IOCTL_SC_REG_PDO_ENTRY EC_IOWR(0x27, ec_ioctl_reg_pdo_entry_t) #define EC_IOCTL_SC_DC_ASSIGN EC_IOW(0x28, ec_ioctl_sc_dc_t) -#define EC_IOCTL_SC_DC_CYCLE EC_IOW(0x29, ec_ioctl_sc_dc_t) -#define EC_IOCTL_SC_DC_SHIFT EC_IOW(0x2a, ec_ioctl_sc_dc_t) -#define EC_IOCTL_SC_SDO EC_IOW(0x2b, ec_ioctl_sc_sdo_t) -#define EC_IOCTL_SC_SDO_REQUEST EC_IOWR(0x2c, ec_ioctl_sdo_request_t) -#define EC_IOCTL_SC_VOE EC_IOWR(0x2d, ec_ioctl_voe_t) -#define EC_IOCTL_SC_STATE EC_IOWR(0x2e, ec_ioctl_sc_state_t) -#define EC_IOCTL_DOMAIN_OFFSET EC_IO(0x2f) -#define EC_IOCTL_DOMAIN_PROCESS EC_IO(0x30) -#define EC_IOCTL_DOMAIN_QUEUE EC_IO(0x31) -#define EC_IOCTL_DOMAIN_STATE EC_IOWR(0x32, ec_ioctl_domain_state_t) -#define EC_IOCTL_SDO_REQUEST_TIMEOUT EC_IOWR(0x33, ec_ioctl_sdo_request_t) -#define EC_IOCTL_SDO_REQUEST_STATE EC_IOWR(0x34, ec_ioctl_sdo_request_t) -#define EC_IOCTL_SDO_REQUEST_READ EC_IOWR(0x35, ec_ioctl_sdo_request_t) -#define EC_IOCTL_SDO_REQUEST_WRITE EC_IOWR(0x36, ec_ioctl_sdo_request_t) -#define EC_IOCTL_SDO_REQUEST_DATA EC_IOWR(0x37, ec_ioctl_sdo_request_t) -#define EC_IOCTL_VOE_SEND_HEADER EC_IOW(0x38, ec_ioctl_voe_t) -#define EC_IOCTL_VOE_REC_HEADER EC_IOWR(0x39, ec_ioctl_voe_t) -#define EC_IOCTL_VOE_READ EC_IOW(0x3a, ec_ioctl_voe_t) -#define EC_IOCTL_VOE_READ_NOSYNC EC_IOW(0x3b, ec_ioctl_voe_t) -#define EC_IOCTL_VOE_WRITE EC_IOWR(0x3c, ec_ioctl_voe_t) -#define EC_IOCTL_VOE_EXEC EC_IOWR(0x3d, ec_ioctl_voe_t) -#define EC_IOCTL_VOE_DATA EC_IOWR(0x3e, ec_ioctl_voe_t) +#define EC_IOCTL_SC_DC_SYNC EC_IOW(0x29, ec_ioctl_sc_dc_t) +#define EC_IOCTL_SC_SDO EC_IOW(0x2a, ec_ioctl_sc_sdo_t) +#define EC_IOCTL_SC_SDO_REQUEST EC_IOWR(0x2b, ec_ioctl_sdo_request_t) +#define EC_IOCTL_SC_VOE EC_IOWR(0x2c, ec_ioctl_voe_t) +#define EC_IOCTL_SC_STATE EC_IOWR(0x2d, ec_ioctl_sc_state_t) +#define EC_IOCTL_DOMAIN_OFFSET EC_IO(0x2e) +#define EC_IOCTL_DOMAIN_PROCESS EC_IO(0x2f) +#define EC_IOCTL_DOMAIN_QUEUE EC_IO(0x30) +#define EC_IOCTL_DOMAIN_STATE EC_IOWR(0x31, ec_ioctl_domain_state_t) +#define EC_IOCTL_SDO_REQUEST_TIMEOUT EC_IOWR(0x32, ec_ioctl_sdo_request_t) +#define EC_IOCTL_SDO_REQUEST_STATE EC_IOWR(0x33, ec_ioctl_sdo_request_t) +#define EC_IOCTL_SDO_REQUEST_READ EC_IOWR(0x34, ec_ioctl_sdo_request_t) +#define EC_IOCTL_SDO_REQUEST_WRITE EC_IOWR(0x35, ec_ioctl_sdo_request_t) +#define EC_IOCTL_SDO_REQUEST_DATA EC_IOWR(0x36, ec_ioctl_sdo_request_t) +#define EC_IOCTL_VOE_SEND_HEADER EC_IOW(0x37, ec_ioctl_voe_t) +#define EC_IOCTL_VOE_REC_HEADER EC_IOWR(0x38, ec_ioctl_voe_t) +#define EC_IOCTL_VOE_READ EC_IOW(0x39, ec_ioctl_voe_t) +#define EC_IOCTL_VOE_READ_NOSYNC EC_IOW(0x3a, ec_ioctl_voe_t) +#define EC_IOCTL_VOE_WRITE EC_IOWR(0x3b, ec_ioctl_voe_t) +#define EC_IOCTL_VOE_EXEC EC_IOWR(0x3c, ec_ioctl_voe_t) +#define EC_IOCTL_VOE_DATA EC_IOWR(0x3d, ec_ioctl_voe_t) /*****************************************************************************/ @@ -475,8 +474,7 @@ typedef struct { // inputs uint32_t config_index; uint16_t assign_activate; - uint32_t cycle[2]; - uint32_t shift[2]; + ec_sync_signal_t sync[EC_SYNC_SIGNAL_COUNT]; } ec_ioctl_sc_dc_t; /*****************************************************************************/ diff --git a/master/slave_config.c b/master/slave_config.c index 1132cf62..c8bdb42c 100644 --- a/master/slave_config.c +++ b/master/slave_config.c @@ -75,10 +75,10 @@ void ec_slave_config_init( sc->used_fmmus = 0; sc->dc_assign_activate = 0x0000; - sc->dc_sync_cycle_times[0] = 0x00000000; - sc->dc_sync_cycle_times[1] = 0x00000000; - sc->dc_sync_shift_times[0] = 0x00000000; - sc->dc_sync_shift_times[1] = 0x00000000; + sc->dc_sync[0].cycle_time = 0x00000000; + sc->dc_sync[1].cycle_time = 0x00000000; + sc->dc_sync[0].shift_time = 0x00000000; + sc->dc_sync[1].shift_time = 0x00000000; INIT_LIST_HEAD(&sc->sdo_configs); INIT_LIST_HEAD(&sc->sdo_requests); @@ -683,20 +683,14 @@ void ecrt_slave_config_dc_assign_activate(ec_slave_config_t *sc, /*****************************************************************************/ -void ecrt_slave_config_dc_sync_cycle_times(ec_slave_config_t *sc, - uint32_t sync0_cycle_time, uint32_t sync1_cycle_time) +void ecrt_slave_config_dc_sync_signals(ec_slave_config_t *sc, + uint32_t sync0_cycle_time, uint32_t sync0_shift_time, + uint32_t sync1_cycle_time, uint32_t sync1_shift_time) { - sc->dc_sync_cycle_times[0] = sync0_cycle_time; - sc->dc_sync_cycle_times[1] = sync1_cycle_time; -} - -/*****************************************************************************/ - -void ecrt_slave_config_dc_sync_shift_times(ec_slave_config_t *sc, - uint32_t sync0_shift_time, uint32_t sync1_shift_time) -{ - sc->dc_sync_shift_times[0] = sync0_shift_time; - sc->dc_sync_shift_times[1] = sync1_shift_time; + sc->dc_sync[0].cycle_time = sync0_cycle_time; + sc->dc_sync[0].shift_time = sync0_shift_time; + sc->dc_sync[1].cycle_time = sync1_cycle_time; + sc->dc_sync[1].shift_time = sync1_shift_time; } /*****************************************************************************/ @@ -914,8 +908,7 @@ EXPORT_SYMBOL(ecrt_slave_config_pdo_mapping_clear); EXPORT_SYMBOL(ecrt_slave_config_pdos); EXPORT_SYMBOL(ecrt_slave_config_reg_pdo_entry); EXPORT_SYMBOL(ecrt_slave_config_dc_assign_activate); -EXPORT_SYMBOL(ecrt_slave_config_dc_sync_cycle_times); -EXPORT_SYMBOL(ecrt_slave_config_dc_sync_shift_times); +EXPORT_SYMBOL(ecrt_slave_config_dc_sync_signals); EXPORT_SYMBOL(ecrt_slave_config_sdo); EXPORT_SYMBOL(ecrt_slave_config_sdo8); EXPORT_SYMBOL(ecrt_slave_config_sdo16); diff --git a/master/slave_config.h b/master/slave_config.h index 7617dc06..35430a8d 100644 --- a/master/slave_config.h +++ b/master/slave_config.h @@ -66,9 +66,8 @@ struct ec_slave_config { ec_fmmu_config_t fmmu_configs[EC_MAX_FMMUS]; /**< FMMU configurations. */ uint8_t used_fmmus; /**< Number of FMMUs used. */ - uint16_t dc_assign_activate; /**< Vendor-specific AssignActivate word. */ - uint32_t dc_sync_cycle_times[2]; /**< SYNC[0,1] cycle times. */ - uint32_t dc_sync_shift_times[2]; /**< SYNC[0,1] shift times. */ + uint16_t dc_assign_activate; /**< Vendor-specific AssignActivate word. */ + ec_sync_signal_t dc_sync[EC_SYNC_SIGNAL_COUNT]; /**< DC sync signals. */ struct list_head sdo_configs; /**< List of SDO configurations. */ struct list_head sdo_requests; /**< List of SDO requests. */