DC cyclic operation and slave configuration. TBC...
This commit is contained in:
parent
07ab460d36
commit
e3b1d8e573
1
NEWS
1
NEWS
|
|
@ -10,6 +10,7 @@ Changes since 1.4.0:
|
|||
|
||||
* Added a userspace library for accessing the application interface. This
|
||||
library is licensed under LGPLv2.
|
||||
* Added distributed clocks support.
|
||||
* Added VoE mailbox protocol support.
|
||||
* Separated datagram initialization from filling the payload with zeros.
|
||||
Introduced new method ec_datagram_zero() for that.
|
||||
|
|
|
|||
6
TODO
6
TODO
|
|
@ -10,6 +10,10 @@ vim: spelllang=en spell
|
|||
|
||||
Version 1.5.0:
|
||||
|
||||
* Distributed clocks:
|
||||
- Delay calculation.
|
||||
- Synchronize the reference clock to the master clock.
|
||||
* Read alias from register 0x0012 instead of SII.
|
||||
* Output link state in 'ethercat master'.
|
||||
* Finish library implementation.
|
||||
* Re-work EoE code.
|
||||
|
|
@ -22,12 +26,10 @@ Version 1.5.0:
|
|||
* Check force_config flag before error.
|
||||
* Remove allow_scanning flag.
|
||||
* Test File access over EtherCAT (FoE) reading.
|
||||
* Distributed clocks.
|
||||
* Implement ecrt_master_slave() in kernel space.
|
||||
* Check for ioctl() interface version.
|
||||
* Improve application-triggered SDO transfers by moving the statemachine into
|
||||
the SDO handlers.
|
||||
* FoE in application interface?
|
||||
* Apply watchdog patches from J. Mohre.
|
||||
|
||||
Future issues:
|
||||
|
|
|
|||
|
|
@ -41,6 +41,10 @@
|
|||
*
|
||||
* Changes in version 1.5:
|
||||
*
|
||||
* - Added the distributed clocks feature and the respective methods
|
||||
* ecrt_slave_config_dc_assign_activate() and
|
||||
* ecrt_slave_config_dc_sync_cycle_times() to configure a slave for cyclic
|
||||
* operation.
|
||||
* - 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
|
||||
|
|
@ -671,6 +675,25 @@ int ecrt_slave_config_reg_pdo_entry(
|
|||
is desired */
|
||||
);
|
||||
|
||||
/** Sets the AssignActivate word necessary for DC operation.
|
||||
*
|
||||
* The AssignActivate word is vendor-specific and can be taken from the XML
|
||||
* device description file (Device -> Dc -> AssignActivate). Set this to zero,
|
||||
* if the slave shall be not operated without distributed clocks (default).
|
||||
*/
|
||||
void ecrt_slave_config_dc_assign_activate(
|
||||
ec_slave_config_t *sc, /**< Slave configuration. */
|
||||
uint16_t assign_activate /**< AssignActivate word. */
|
||||
);
|
||||
|
||||
/** Sets the cylce times for the SYNC0 and SYNC1 signals.
|
||||
*/
|
||||
void ecrt_slave_config_dc_sync_cycle_times(
|
||||
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]. */
|
||||
);
|
||||
|
||||
/** Add an SDO configuration.
|
||||
*
|
||||
* An SDO configuration is stored in the slave configuration object and is
|
||||
|
|
|
|||
|
|
@ -52,6 +52,9 @@ void ec_fsm_slave_config_state_sdo_conf(ec_fsm_slave_config_t *);
|
|||
void ec_fsm_slave_config_state_pdo_sync(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_state_pdo_conf(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_state_fmmu(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_state_dc_cycle(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_state_dc_start(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_state_dc_assign(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_state_safeop(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_state_op(ec_fsm_slave_config_t *);
|
||||
|
||||
|
|
@ -63,6 +66,8 @@ void ec_fsm_slave_config_enter_sdo_conf(ec_fsm_slave_config_t *);
|
|||
void ec_fsm_slave_config_enter_pdo_conf(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_enter_pdo_sync(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_enter_fmmu(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_enter_dc_cycle(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_enter_dc_assign(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_enter_safeop(ec_fsm_slave_config_t *);
|
||||
|
||||
void ec_fsm_slave_config_state_end(ec_fsm_slave_config_t *);
|
||||
|
|
@ -602,6 +607,7 @@ void ec_fsm_slave_config_enter_sdo_conf(
|
|||
ec_slave_t *slave = fsm->slave;
|
||||
|
||||
// No CoE configuration to be applied?
|
||||
// FIXME check for config
|
||||
if (list_empty(&slave->config->sdo_configs)) { // skip SDO configuration
|
||||
ec_fsm_slave_config_enter_pdo_conf(fsm);
|
||||
return;
|
||||
|
|
@ -805,7 +811,7 @@ void ec_fsm_slave_config_enter_fmmu(
|
|||
}
|
||||
|
||||
if (!slave->base_fmmu_count) { // skip FMMU configuration
|
||||
ec_fsm_slave_config_enter_safeop(fsm);
|
||||
ec_fsm_slave_config_enter_dc_cycle(fsm);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -861,6 +867,161 @@ void ec_fsm_slave_config_state_fmmu(
|
|||
return;
|
||||
}
|
||||
|
||||
ec_fsm_slave_config_enter_dc_cycle(fsm);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Check for DCs to be configured.
|
||||
*/
|
||||
void ec_fsm_slave_config_enter_dc_cycle(
|
||||
ec_fsm_slave_config_t *fsm /**< slave state machine */
|
||||
)
|
||||
{
|
||||
ec_datagram_t *datagram = fsm->datagram;
|
||||
ec_slave_t *slave = fsm->slave;
|
||||
ec_slave_config_t *config = slave->config;
|
||||
|
||||
if (config->dc_assign_activate) {
|
||||
if (!slave->base_dc_supported) {
|
||||
EC_WARN("Attempt to enable synchronized mode for slave %u,"
|
||||
" that seems not to support distributed clocks!\n",
|
||||
slave->ring_position);
|
||||
}
|
||||
|
||||
// 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]);
|
||||
fsm->retries = EC_FSM_RETRIES;
|
||||
fsm->state = ec_fsm_slave_config_state_dc_cycle;
|
||||
} else {
|
||||
ec_fsm_slave_config_enter_dc_assign(fsm);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Slave configuration state: DC CYCLE.
|
||||
*/
|
||||
void ec_fsm_slave_config_state_dc_cycle(
|
||||
ec_fsm_slave_config_t *fsm /**< slave state machine */
|
||||
)
|
||||
{
|
||||
ec_datagram_t *datagram = fsm->datagram;
|
||||
ec_slave_t *slave = fsm->slave;
|
||||
|
||||
if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
|
||||
return;
|
||||
|
||||
if (datagram->state != EC_DATAGRAM_RECEIVED) {
|
||||
fsm->state = ec_fsm_slave_config_state_error;
|
||||
EC_ERR("Failed to receive DC cycle times datagram for slave %u"
|
||||
" (datagram state %u).\n",
|
||||
slave->ring_position, datagram->state);
|
||||
return;
|
||||
}
|
||||
|
||||
if (datagram->working_counter != 1) {
|
||||
slave->error_flag = 1;
|
||||
fsm->state = ec_fsm_slave_config_state_error;
|
||||
EC_ERR("Failed to set DC cycle times of slave %u: ",
|
||||
slave->ring_position);
|
||||
ec_datagram_print_wc_error(datagram);
|
||||
return;
|
||||
}
|
||||
|
||||
// set DC start time
|
||||
ec_datagram_fpwr(datagram, slave->station_address, 0x0990, 8);
|
||||
EC_WRITE_U64(datagram->data, 0x37E11D600ULL); // 15 s, FIXME
|
||||
fsm->retries = EC_FSM_RETRIES;
|
||||
fsm->state = ec_fsm_slave_config_state_dc_start;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Slave configuration state: DC START.
|
||||
*/
|
||||
void ec_fsm_slave_config_state_dc_start(
|
||||
ec_fsm_slave_config_t *fsm /**< slave state machine */
|
||||
)
|
||||
{
|
||||
ec_datagram_t *datagram = fsm->datagram;
|
||||
ec_slave_t *slave = fsm->slave;
|
||||
|
||||
if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
|
||||
return;
|
||||
|
||||
if (datagram->state != EC_DATAGRAM_RECEIVED) {
|
||||
fsm->state = ec_fsm_slave_config_state_error;
|
||||
EC_ERR("Failed to receive DC start time datagram for slave %u"
|
||||
" (datagram state %u).\n",
|
||||
slave->ring_position, datagram->state);
|
||||
return;
|
||||
}
|
||||
|
||||
if (datagram->working_counter != 1) {
|
||||
slave->error_flag = 1;
|
||||
fsm->state = ec_fsm_slave_config_state_error;
|
||||
EC_ERR("Failed to set DC start time of slave %u: ",
|
||||
slave->ring_position);
|
||||
ec_datagram_print_wc_error(datagram);
|
||||
return;
|
||||
}
|
||||
|
||||
ec_fsm_slave_config_enter_dc_assign(fsm);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Set the DC AssignActivate word.
|
||||
*/
|
||||
void ec_fsm_slave_config_enter_dc_assign(
|
||||
ec_fsm_slave_config_t *fsm /**< slave state machine */
|
||||
)
|
||||
{
|
||||
ec_datagram_t *datagram = fsm->datagram;
|
||||
ec_slave_t *slave = fsm->slave;
|
||||
ec_slave_config_t *config = slave->config;
|
||||
|
||||
// assign sync unit to EtherCAT or PDI
|
||||
ec_datagram_fpwr(datagram, slave->station_address, 0x0980, 2);
|
||||
EC_WRITE_U16(datagram->data, config->dc_assign_activate);
|
||||
fsm->retries = EC_FSM_RETRIES;
|
||||
fsm->state = ec_fsm_slave_config_state_dc_assign;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Slave configuration state: DC ASSIGN.
|
||||
*/
|
||||
void ec_fsm_slave_config_state_dc_assign(
|
||||
ec_fsm_slave_config_t *fsm /**< slave state machine */
|
||||
)
|
||||
{
|
||||
ec_datagram_t *datagram = fsm->datagram;
|
||||
ec_slave_t *slave = fsm->slave;
|
||||
|
||||
if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
|
||||
return;
|
||||
|
||||
if (datagram->state != EC_DATAGRAM_RECEIVED) {
|
||||
fsm->state = ec_fsm_slave_config_state_error;
|
||||
EC_ERR("Failed to receive DC activation datagram for slave %u"
|
||||
" (datagram state %u).\n",
|
||||
slave->ring_position, datagram->state);
|
||||
return;
|
||||
}
|
||||
|
||||
if (datagram->working_counter != 1) {
|
||||
slave->error_flag = 1;
|
||||
fsm->state = ec_fsm_slave_config_state_error;
|
||||
EC_ERR("Failed to set DC cyclia operation state of slave %u: ",
|
||||
slave->ring_position);
|
||||
ec_datagram_print_wc_error(datagram);
|
||||
return;
|
||||
}
|
||||
|
||||
ec_fsm_slave_config_enter_safeop(fsm);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,20 +61,26 @@ void ec_slave_config_init(
|
|||
unsigned int i;
|
||||
|
||||
sc->master = master;
|
||||
|
||||
sc->alias = alias;
|
||||
sc->position = position;
|
||||
sc->vendor_id = vendor_id;
|
||||
sc->product_code = product_code;
|
||||
|
||||
sc->slave = NULL;
|
||||
|
||||
for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++)
|
||||
ec_sync_config_init(&sc->sync_configs[i]);
|
||||
|
||||
sc->used_fmmus = 0;
|
||||
|
||||
sc->dc_assign_activate = 0x0000;
|
||||
sc->dc_sync_cycle_times[0] = 0x00000000;
|
||||
sc->dc_sync_cycle_times[1] = 0x00000000;
|
||||
|
||||
INIT_LIST_HEAD(&sc->sdo_configs);
|
||||
INIT_LIST_HEAD(&sc->sdo_requests);
|
||||
INIT_LIST_HEAD(&sc->voe_handlers);
|
||||
|
||||
sc->used_fmmus = 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -399,7 +405,7 @@ ec_voe_handler_t *ec_slave_config_find_voe_handler(
|
|||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Realtime interface
|
||||
* Application interface
|
||||
*****************************************************************************/
|
||||
|
||||
int ecrt_slave_config_sync_manager(ec_slave_config_t *sc, uint8_t sync_index,
|
||||
|
|
@ -665,6 +671,22 @@ int ecrt_slave_config_reg_pdo_entry(
|
|||
return -ENOENT;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void ecrt_slave_config_dc_assign_activate(ec_slave_config_t *sc,
|
||||
uint16_t assign_activate)
|
||||
{
|
||||
sc->dc_assign_activate = assign_activate;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void ecrt_slave_config_dc_sync_cycle_times(ec_slave_config_t *sc,
|
||||
uint32_t sync0_cycle_time, uint32_t sync1_cycle_time)
|
||||
{
|
||||
sc->dc_sync_cycle_times[0] = sync0_cycle_time;
|
||||
sc->dc_sync_cycle_times[1] = sync1_cycle_time;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -880,6 +902,8 @@ EXPORT_SYMBOL(ecrt_slave_config_pdo_mapping_add);
|
|||
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_sdo);
|
||||
EXPORT_SYMBOL(ecrt_slave_config_sdo8);
|
||||
EXPORT_SYMBOL(ecrt_slave_config_sdo16);
|
||||
|
|
|
|||
|
|
@ -66,6 +66,9 @@ 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. */
|
||||
|
||||
struct list_head sdo_configs; /**< List of SDO configurations. */
|
||||
struct list_head sdo_requests; /**< List of SDO requests. */
|
||||
struct list_head voe_handlers; /**< List of VoE handlers. */
|
||||
|
|
|
|||
Loading…
Reference in New Issue