diff --git a/TODO b/TODO index f6de929c608d8b3d00ea21239169b109bb48fa04..514dbac853a4236bfb04a5d84cc3af7b7b8b3787 100644 --- a/TODO +++ b/TODO @@ -44,6 +44,7 @@ Version 1.5.0: * Read AL status code on spontaneous state change. * Fix clearing domains etc. when not activated and releasing. * Output -EPROTO if mailbox protocol is not supported. +* Only output watchdog config if not default. Future issues: diff --git a/configure.ac b/configure.ac index 68d2ac70e12fdc2db4610f91b3a353afb419db6a..3d8d93cff01ca42314c1cf60bc675d6b12ac16cf 100644 --- a/configure.ac +++ b/configure.ac @@ -512,6 +512,30 @@ if test "x${hrtimer}" = "x1"; then AC_DEFINE([EC_USE_HRTIMER], [1], [Use hrtimer for scheduling]) fi +#------------------------------------------------------------------------------ +# Read alias address from register +#------------------------------------------------------------------------------ + +AC_ARG_ENABLE([regalias], + AS_HELP_STRING([--enable-regalias], + [Read alias adresses from register (default: no)]), + [ + case "${enableval}" in + yes) regalias=1 + ;; + no) regalias=0 + ;; + *) AC_MSG_ERROR([Invalid value for --enable-regalias]) + ;; + esac + ], + [regalias=0] +) + +if test "x${regalias}" = "x1"; then + AC_DEFINE([EC_REGALIAS], [1], [Read alias adresses from register]) +fi + #------------------------------------------------------------------------------ # Command-line tool #----------------------------------------------------------------------------- diff --git a/examples/rtai/rtai_sample.c b/examples/rtai/rtai_sample.c index eb31b78c9523ed5f89f95dcdf224fa6f1d57ac2b..9748907f1a511905faf2b579acfdd644376e60d2 100644 --- a/examples/rtai/rtai_sample.c +++ b/examples/rtai/rtai_sample.c @@ -76,8 +76,8 @@ static cycles_t t_last_cycle = 0, t_critical; // process data static uint8_t *domain1_pd; // process data memory -#define AnaInSlavePos 0, 1 -#define DigOutSlavePos 0, 3 +#define AnaInSlavePos 0, 3 +#define DigOutSlavePos 0, 2 #define Beckhoff_EL2004 0x00000002, 0x07D43052 #define Beckhoff_EL3162 0x00000002, 0x0C5A3052 @@ -286,8 +286,8 @@ int __init init_mod(void) t_critical = cpu_khz * 1000 / FREQUENCY - cpu_khz * INHIBIT_TIME / 1000; master = ecrt_request_master(0); - if (IS_ERR(master)) { - ret = PTR_ERR(master); + if (!master) { + ret = -EBUSY; printk(KERN_ERR PFX "Requesting master 0 failed!\n"); goto out_return; } diff --git a/master/cdev.c b/master/cdev.c index e2eca4db13fa3ee3042820a040d46c31666fd5af..2440c287837d97d69adffac1be8b98e04ba6c34c 100644 --- a/master/cdev.c +++ b/master/cdev.c @@ -1724,7 +1724,6 @@ int ec_cdev_ioctl_deactivate( return 0; } - /*****************************************************************************/ /** Set max. number of databytes in a cycle diff --git a/master/fsm_slave_scan.c b/master/fsm_slave_scan.c index 7bc3a39386e37b9761e894b7acefafb231a8f094..460a1336e08e61c923d3f464eed0a2b118f9a978 100644 --- a/master/fsm_slave_scan.c +++ b/master/fsm_slave_scan.c @@ -52,7 +52,9 @@ void ec_fsm_slave_scan_state_dc_times(ec_fsm_slave_scan_t *); void ec_fsm_slave_scan_state_datalink(ec_fsm_slave_scan_t *); void ec_fsm_slave_scan_state_sii_size(ec_fsm_slave_scan_t *); void ec_fsm_slave_scan_state_sii_data(ec_fsm_slave_scan_t *); +#ifdef EC_REGALIAS void ec_fsm_slave_scan_state_regalias(ec_fsm_slave_scan_t *); +#endif void ec_fsm_slave_scan_state_preop(ec_fsm_slave_scan_t *); void ec_fsm_slave_scan_state_sync(ec_fsm_slave_scan_t *); void ec_fsm_slave_scan_state_pdos(ec_fsm_slave_scan_t *); @@ -61,7 +63,9 @@ void ec_fsm_slave_scan_state_end(ec_fsm_slave_scan_t *); void ec_fsm_slave_scan_state_error(ec_fsm_slave_scan_t *); void ec_fsm_slave_scan_enter_datalink(ec_fsm_slave_scan_t *); +#ifdef EC_REGALIAS void ec_fsm_slave_scan_enter_regalias(ec_fsm_slave_scan_t *); +#endif void ec_fsm_slave_scan_enter_preop(ec_fsm_slave_scan_t *); void ec_fsm_slave_scan_enter_pdos(ec_fsm_slave_scan_t *); @@ -694,7 +698,15 @@ void ec_fsm_slave_scan_state_sii_data(ec_fsm_slave_scan_t *fsm /**< slave state } } +#ifdef EC_REGALIAS ec_fsm_slave_scan_enter_regalias(fsm); +#else + if (slave->sii.mailbox_protocols & EC_MBOX_COE) { + ec_fsm_slave_scan_enter_preop(fsm); + } else { + fsm->state = ec_fsm_slave_scan_state_end; + } +#endif return; end: @@ -703,13 +715,12 @@ end: fsm->state = ec_fsm_slave_scan_state_error; } - /*****************************************************************************/ -/** - Slave scan entry function: REGALIAS. -*/ +#ifdef EC_REGALIAS +/** Slave scan entry function: REGALIAS. + */ void ec_fsm_slave_scan_enter_regalias( ec_fsm_slave_scan_t *fsm /**< slave state machine */ ) @@ -727,9 +738,8 @@ void ec_fsm_slave_scan_enter_regalias( /*****************************************************************************/ -/** - Slave scan state: REGALIAS. -*/ +/** Slave scan state: REGALIAS. + */ void ec_fsm_slave_scan_state_regalias( ec_fsm_slave_scan_t *fsm /**< slave state machine */ ) @@ -754,6 +764,7 @@ void ec_fsm_slave_scan_state_regalias( EC_SLAVE_DBG(slave, 1, "Read alias %u from register.\n", slave->effective_alias); } + if (slave->sii.mailbox_protocols & EC_MBOX_COE) { ec_fsm_slave_scan_enter_preop(fsm); } else { @@ -761,6 +772,8 @@ void ec_fsm_slave_scan_state_regalias( } } +#endif // defined EC_REGALIAS + /*****************************************************************************/ /** Enter slave scan state PREOP. diff --git a/master/master.c b/master/master.c index 96c2626098944b743a44f401314a593d424dda50..4bc2f8491509f2a28455b574308c4735019abb24 100644 --- a/master/master.c +++ b/master/master.c @@ -439,6 +439,20 @@ void ec_master_clear_domains(ec_master_t *master) /*****************************************************************************/ +/** Clear the configuration applied by the application. + */ +void ec_master_clear_config( + ec_master_t *master /**< EtherCAT master. */ + ) +{ + down(&master->master_sem); + ec_master_clear_domains(master); + ec_master_clear_slave_configs(master); + up(&master->master_sem); +} + +/*****************************************************************************/ + /** Internal sending callback. */ void ec_master_internal_send_cb( @@ -653,15 +667,17 @@ void ec_master_leave_operation_phase( ec_master_t *master /**< EtherCAT master */ ) { - if (master->active) - ecrt_master_deactivate(master); + if (master->active) { + ecrt_master_deactivate(master); // also clears config + } else { + ec_master_clear_config(master); + } EC_MASTER_DBG(master, 1, "OPERATION -> IDLE.\n"); master->phase = EC_IDLE; } - /*****************************************************************************/ /** Injects external datagrams that fit into the datagram queue. @@ -1989,8 +2005,7 @@ void ecrt_master_deactivate(ec_master_t *master) int eoe_was_running; #endif - EC_MASTER_DBG(master, 1, "ecrt_master_deactivate(master = 0x%p)\n", - master); + EC_MASTER_DBG(master, 1, "%s(master = 0x%p)\n", __func__, master); if (!master->active) { EC_MASTER_WARN(master, "%s: Master not active.\n", __func__); @@ -2007,10 +2022,7 @@ void ecrt_master_deactivate(ec_master_t *master) master->receive_cb = ec_master_internal_receive_cb; master->cb_data = master; - down(&master->master_sem); - ec_master_clear_domains(master); - ec_master_clear_slave_configs(master); - up(&master->master_sem); + ec_master_clear_config(master); for (slave = master->slaves; slave < master->slaves + master->slave_count; diff --git a/master/master.h b/master/master.h index c4ea963bc169c34e763d8a049a911dceccf414f0..d0cd7b8a7324cae878afa79af2107f3e8fe884c7 100644 --- a/master/master.h +++ b/master/master.h @@ -170,11 +170,12 @@ struct ec_master { unsigned int injection_seq_rt; /**< Datagram injection sequence number for the realtime side. */ - ec_slave_t *slaves; /**< Array of slaves on the bus. */ unsigned int slave_count; /**< Number of slaves on the bus. */ + /* Configuration applied by the application. */ struct list_head configs; /**< List of slave configurations. */ + struct list_head domains; /**< List of domains. */ u64 app_time; /**< Time of the last ecrt_master_sync() call. */ u64 app_start_time; /**< Application start time. */ @@ -213,7 +214,6 @@ struct ec_master { struct list_head external_datagram_queue; /**< External Datagram queue. */ unsigned int send_interval; /**< Interval between calls to ecrt_master_send */ size_t max_queue_size; /**< Maximum size of datagram queue */ - struct list_head domains; /**< List of domains. */ unsigned int debug_level; /**< Master debug level. */ ec_stats_t stats; /**< Cyclic statistics. */ @@ -242,7 +242,6 @@ struct ec_master { struct list_head reg_requests; /**< Register requests. */ wait_queue_head_t reg_queue; /**< Wait queue for register requests. */ - }; /*****************************************************************************/ diff --git a/master/slave_config.c b/master/slave_config.c index 63eeb2550a7b132cdb528f5fc0538f6695651640..cdd45ceb88458b2ea6089c21b058224d074144aa 100644 --- a/master/slave_config.c +++ b/master/slave_config.c @@ -687,6 +687,12 @@ void ecrt_slave_config_dc(ec_slave_config_t *sc, uint16_t assign_activate, uint32_t sync0_cycle_time, uint32_t sync0_shift_time, uint32_t sync1_cycle_time, uint32_t sync1_shift_time) { + EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, assign_activate = 0x%04X," + " sync0_cycle = %u, sync0_shift = %u," + " sync1_cycle = %u, sync1_shift = %u\n", + __func__, sc, assign_activate, sync0_cycle_time, sync0_shift_time, + sync1_cycle_time, sync1_shift_time); + sc->dc_assign_activate = assign_activate; sc->dc_sync[0].cycle_time = sync0_cycle_time; sc->dc_sync[0].shift_time = sync0_shift_time;