mirror of
https://gitlab.com/etherlab.org/ethercat.git
synced 2026-02-06 11:51:45 +08:00
Changed terms "Pdo mapping" -> "Pdo assignment" and "Pdo configuration"
-> "Pdo mapping"; created ecrt_slave_config_pdo_assign_clear() and ecrt_slave_config_pdo_mapping_clear().
This commit is contained in:
@@ -5,12 +5,12 @@
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
GRAPHS := \
|
||||
fsm_slave_conf \
|
||||
fsm_slave_scan \
|
||||
fsm_pdo_mapping \
|
||||
fsm_pdo_config \
|
||||
fsm_coe_map \
|
||||
fsm_master \
|
||||
fsm_coe_map
|
||||
fsm_pdo_assign \
|
||||
fsm_pdo_mapping \
|
||||
fsm_slave_conf \
|
||||
fsm_slave_scan
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
19
documentation/graphs/fsm_pdo_assign.dot
Normal file
19
documentation/graphs/fsm_pdo_assign.dot
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
digraph pdomapping {
|
||||
size="7,9"
|
||||
center=1
|
||||
ratio=fill
|
||||
|
||||
next_sync [shape=point,label=""]
|
||||
|
||||
start -> next_sync [label="First SM"]
|
||||
next_sync -> end [label="No more SMs"]
|
||||
next_sync -> zero_count [label="Next SM"]
|
||||
zero_count -> next_sync [label="No Pdos"]
|
||||
zero_count -> add_pdo [label="Map first Pdo", weight=5]
|
||||
add_pdo -> add_pdo [label="Map next Pdo"]
|
||||
add_pdo -> pdo_count [label="No more Pdos", weight=5]
|
||||
pdo_count -> next_sync
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
digraph pdoconfig {
|
||||
size="7,9"
|
||||
center=1
|
||||
ratio=fill
|
||||
|
||||
next_pdo [shape=point,label=""]
|
||||
|
||||
start -> next_pdo [label="First Pdo"]
|
||||
next_pdo -> end [label="No more Pdos"]
|
||||
next_pdo -> zero_count [label="Next Pdo"]
|
||||
zero_count -> next_pdo [label="No Entries"]
|
||||
zero_count -> add_entry [label="Add first entry", weight=5]
|
||||
add_entry -> add_entry [label="Add next entry"]
|
||||
add_entry -> entry_count [label="No more Entries", weight=5]
|
||||
entry_count -> next_pdo
|
||||
}
|
||||
@@ -1,19 +1,19 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
digraph pdomapping {
|
||||
digraph pdoconfig {
|
||||
size="7,9"
|
||||
center=1
|
||||
ratio=fill
|
||||
|
||||
next_sync [shape=point,label=""]
|
||||
next_pdo [shape=point,label=""]
|
||||
|
||||
start -> next_sync [label="First SM"]
|
||||
next_sync -> end [label="No more SMs"]
|
||||
next_sync -> zero_count [label="Next SM"]
|
||||
zero_count -> next_sync [label="No Pdos"]
|
||||
zero_count -> add_pdo [label="Map first Pdo", weight=5]
|
||||
add_pdo -> add_pdo [label="Map next Pdo"]
|
||||
add_pdo -> pdo_count [label="No more Pdos", weight=5]
|
||||
pdo_count -> next_sync
|
||||
start -> next_pdo [label="First Pdo"]
|
||||
next_pdo -> end [label="No more Pdos"]
|
||||
next_pdo -> zero_count [label="Next Pdo"]
|
||||
zero_count -> next_pdo [label="No Entries"]
|
||||
zero_count -> add_entry [label="Add first entry", weight=5]
|
||||
add_entry -> add_entry [label="Add next entry"]
|
||||
add_entry -> entry_count [label="No more Entries", weight=5]
|
||||
entry_count -> next_pdo
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ digraph slaveconf {
|
||||
enter_mbox_sync [shape=point,label=""]
|
||||
enter_fmmu [shape=point,label=""]
|
||||
enter_sdo_conf [shape=point,label=""]
|
||||
enter_mapping [shape=point,label=""]
|
||||
enter_pdo_assign [shape=point,label=""]
|
||||
enter_pdo_sync [shape=point,label=""]
|
||||
enter_safeop [shape=point,label=""]
|
||||
|
||||
@@ -32,18 +32,18 @@ digraph slaveconf {
|
||||
preop -> end [label="PREOP req."]
|
||||
preop -> enter_sdo_conf [weight=10]
|
||||
enter_sdo_conf -> enter_safeop [label="No configuration"]
|
||||
enter_sdo_conf -> enter_mapping [label="No Sdo configs"]
|
||||
enter_sdo_conf -> enter_pdo_assign [label="No Sdo configs"]
|
||||
enter_sdo_conf -> sdo_conf [label="Sdo configs", weight=10]
|
||||
sdo_conf -> sdo_conf
|
||||
sdo_conf -> error
|
||||
sdo_conf -> enter_mapping [weight=10]
|
||||
enter_mapping -> mapping [weight=10]
|
||||
mapping -> mapping
|
||||
mapping -> error
|
||||
mapping -> pdo_conf [weight=10]
|
||||
pdo_conf -> pdo_conf
|
||||
pdo_conf -> error
|
||||
pdo_conf -> enter_pdo_sync [weight=10]
|
||||
sdo_conf -> enter_pdo_assign [weight=10]
|
||||
enter_pdo_assign -> pdo_assign [weight=10]
|
||||
pdo_assign -> pdo_assign
|
||||
pdo_assign -> error
|
||||
pdo_assign -> pdo_mapping [weight=10]
|
||||
pdo_mapping -> pdo_mapping
|
||||
pdo_mapping -> error
|
||||
pdo_mapping -> enter_pdo_sync [weight=10]
|
||||
enter_pdo_sync -> pdo_sync [label="Pdo SMs", weight=10]
|
||||
enter_pdo_sync -> enter_fmmu
|
||||
pdo_sync -> pdo_sync
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
#define FREQUENCY 100
|
||||
|
||||
// Optional features
|
||||
#define CONFIGURE_MAPPING
|
||||
#define CONFIGURE_PDOS
|
||||
#define EXTERNAL_MEMORY
|
||||
#define SDO_ACCESS
|
||||
|
||||
@@ -82,7 +82,7 @@ const static ec_pdo_entry_reg_t domain1_regs[] = {
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifdef CONFIGURE_MAPPING
|
||||
#ifdef CONFIGURE_PDOS
|
||||
static ec_pdo_entry_info_t el3162_channel1[] = {
|
||||
{0x3101, 1, 8}, // status
|
||||
{0x3101, 2, 16} // value
|
||||
@@ -93,10 +93,10 @@ static ec_pdo_entry_info_t el3162_channel2[] = {
|
||||
{0x3102, 2, 16} // value
|
||||
};
|
||||
|
||||
static ec_pdo_info_t el3162_mapping[] = {
|
||||
static ec_pdo_info_t el3162_pdos[] = {
|
||||
{EC_DIR_INPUT, 0x1A00, 2, el3162_channel1},
|
||||
{EC_DIR_INPUT, 0x1A01, 2, el3162_channel2},
|
||||
{EC_MAP_END}
|
||||
{EC_END}
|
||||
};
|
||||
|
||||
static ec_pdo_entry_info_t el2004_channels[] = {
|
||||
@@ -106,7 +106,7 @@ static ec_pdo_entry_info_t el2004_channels[] = {
|
||||
{0x3001, 4, 1} // Value 4
|
||||
};
|
||||
|
||||
static ec_pdo_info_t el2004_mapping[] = {
|
||||
static ec_pdo_info_t el2004_pdos[] = {
|
||||
{EC_DIR_OUTPUT, 0x1600, 1, &el2004_channels[0]},
|
||||
{EC_DIR_OUTPUT, 0x1601, 1, &el2004_channels[1]},
|
||||
{EC_DIR_OUTPUT, 0x1602, 1, &el2004_channels[2]},
|
||||
@@ -251,7 +251,7 @@ void release_lock(void *data)
|
||||
|
||||
int __init init_mini_module(void)
|
||||
{
|
||||
#ifdef CONFIGURE_MAPPING
|
||||
#ifdef CONFIGURE_PDOS
|
||||
ec_slave_config_t *sc;
|
||||
#endif
|
||||
#ifdef EXTERNAL_MEMORY
|
||||
@@ -273,15 +273,15 @@ int __init init_mini_module(void)
|
||||
goto out_release_master;
|
||||
}
|
||||
|
||||
#ifdef CONFIGURE_MAPPING
|
||||
printk(KERN_INFO PFX "Configuring Pdo mapping...\n");
|
||||
#ifdef CONFIGURE_PDOS
|
||||
printk(KERN_INFO PFX "Configuring Pdos...\n");
|
||||
if (!(sc = ecrt_master_slave_config(master, 0, 1, Beckhoff_EL3162))) {
|
||||
printk(KERN_ERR PFX "Failed to get slave configuration.\n");
|
||||
goto out_release_master;
|
||||
}
|
||||
|
||||
if (ecrt_slave_config_mapping(sc, EC_MAP_END, el3162_mapping)) {
|
||||
printk(KERN_ERR PFX "Failed to configure Pdo mapping.\n");
|
||||
if (ecrt_slave_config_pdos(sc, EC_END, el3162_pdos)) {
|
||||
printk(KERN_ERR PFX "Failed to configure Pdos.\n");
|
||||
goto out_release_master;
|
||||
}
|
||||
|
||||
@@ -290,8 +290,8 @@ int __init init_mini_module(void)
|
||||
goto out_release_master;
|
||||
}
|
||||
|
||||
if (ecrt_slave_config_mapping(sc, 4, el2004_mapping)) {
|
||||
printk(KERN_ERR PFX "Failed to configure Pdo mapping.\n");
|
||||
if (ecrt_slave_config_pdos(sc, 4, el2004_pdos)) {
|
||||
printk(KERN_ERR PFX "Failed to configure Pdos.\n");
|
||||
goto out_release_master;
|
||||
}
|
||||
#endif
|
||||
|
||||
172
include/ecrt.h
172
include/ecrt.h
@@ -37,10 +37,10 @@
|
||||
*
|
||||
* \defgroup RealtimeInterface EtherCAT Realtime Interface
|
||||
*
|
||||
* EtherCAT interface for realtime modules. This interface is designed for
|
||||
* realtime modules that want to use EtherCAT. There are functions to request
|
||||
* a master, to map process data, to communicate with slaves via CoE and to
|
||||
* configure and activate the bus.
|
||||
* EtherCAT interface for realtime applications. This interface is designed
|
||||
* for realtime modules that want to use EtherCAT. There are functions to
|
||||
* request a master, to map process data, to communicate with slaves via CoE
|
||||
* and to configure and activate the bus.
|
||||
*
|
||||
* Changes in Version 1.4:
|
||||
*
|
||||
@@ -64,11 +64,12 @@
|
||||
* is directly usable. If the domain's process data is allocated internally,
|
||||
* the start address can be retrieved with ecrt_domain_data().
|
||||
* - Replaced ecrt_slave_pdo_mapping/add/clear() with
|
||||
* ecrt_slave_config_pdo() to add a Pdo to the mapping and
|
||||
* ecrt_slave_config_pdo_entry() to add a Pdo entry to a Pdo configuration.
|
||||
* ecrt_slave_config_mapping() is a convenience function for
|
||||
* both, that uses the new data types ec_pdo_info_t and ec_pdo_entry_info_t.
|
||||
* Mapped Pdo entries can now immediately be registered.
|
||||
* ecrt_slave_config_pdo_assign_add() to add a Pdo to a sync manager's Pdo
|
||||
* assignment and ecrt_slave_config_pdo_mapping_add() to add a Pdo entry to a
|
||||
* Pdo's mapping. ecrt_slave_config_pdos() is a convenience function
|
||||
* for both, that uses the new data types ec_pdo_info_t and
|
||||
* ec_pdo_entry_info_t. Pdo entries, that are mapped with these functions
|
||||
* can now immediately be registered, even if the bus is offline.
|
||||
* - Renamed ec_bus_status_t, ec_master_status_t to ec_bus_state_t and
|
||||
* ec_master_state_t, respectively. Renamed ecrt_master_get_status() to
|
||||
* ecrt_master_state(), for consistency reasons.
|
||||
@@ -122,11 +123,11 @@
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** End of mapping.
|
||||
/** End of the Pdo list.
|
||||
*
|
||||
* This is used in ecrt_slave_config_mapping().
|
||||
* This is used in ecrt_slave_config_pdos().
|
||||
*/
|
||||
#define EC_MAP_END ~0U
|
||||
#define EC_END ~0U
|
||||
|
||||
/******************************************************************************
|
||||
* Data types
|
||||
@@ -149,6 +150,9 @@ typedef struct ec_sdo_request ec_sdo_request_t; /**< \see ec_sdo_request. */
|
||||
/** Bus state.
|
||||
*
|
||||
* This is used in ec_master_state_t.
|
||||
*
|
||||
* \deprecated
|
||||
* \todo remove
|
||||
*/
|
||||
typedef enum {
|
||||
EC_BUS_FAILURE = -1, /**< At least one configured slave is offline. */
|
||||
@@ -214,9 +218,10 @@ typedef enum {
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Pdo entry mapping.
|
||||
/** Pdo entry information.
|
||||
*
|
||||
* \see ecrt_slave_config_mapping().
|
||||
* This can be used to map multiple Pdo entries into a given Pdo using
|
||||
* ecrt_slave_config_pdos().
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t index; /**< Index of the Pdo entry to add to the Pdo
|
||||
@@ -230,17 +235,17 @@ typedef struct {
|
||||
|
||||
/** Pdo information.
|
||||
*
|
||||
* \see ecrt_slave_config_mapping().
|
||||
* This can be use to assign multiple Pdos to a sync manager using
|
||||
* ecrt_slave_config_pdos().
|
||||
*/
|
||||
typedef struct {
|
||||
ec_direction_t dir; /**< Pdo direction (input/output). */
|
||||
uint16_t index; /**< Index of the Pdo to map. */
|
||||
unsigned int n_entries; /**< Number of Pdo entries for the Pdo
|
||||
configuration. Zero means, that the default Pdo
|
||||
configuration shall be used. */
|
||||
ec_pdo_entry_info_t *entries; /**< Pdo configuration array. This
|
||||
array must contain at least \a
|
||||
n_entries values. */
|
||||
unsigned int n_entries; /**< Number of Pdo entries in \a entries to map.
|
||||
Zero means, that the default mapping shall be
|
||||
used. */
|
||||
ec_pdo_entry_info_t *entries; /**< Array of Pdo entries to map. This must
|
||||
contain at least \a n_entries values. */
|
||||
} ec_pdo_info_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -358,27 +363,38 @@ ec_slave_config_t *ecrt_master_slave_config(
|
||||
uint32_t product_code /**< Expected product code. */
|
||||
);
|
||||
|
||||
/** Applies the bus configuration and switches to realtime mode.
|
||||
/** Finishes the configuration phase and prepares for realtime mode.
|
||||
*
|
||||
* Does the complete configuration and activation for all slaves. Sets sync
|
||||
* managers and FMMUs, and does the appropriate transitions, until the slave
|
||||
* is operational.
|
||||
* This function has to be called after all Pdo entries are registered. It
|
||||
* tells the master that the configuration phase is finished and the realtime
|
||||
* operation will begin. The function allocates internal memory for the
|
||||
* domains and calculates the logical FMMU addresses for domain members. It
|
||||
* tells the master state machine that the bus configuration is now to be
|
||||
* applied.
|
||||
*
|
||||
* \attention After this function has been called, the realtime application is
|
||||
* in charge of cyclically calling ecrt_master_send() and
|
||||
* ecrt_master_receive() to ensure bus communication. Before calling this
|
||||
* function, the master thread is responsible for that, so these functions may
|
||||
* not be called!
|
||||
*
|
||||
* \return 0 in case of success, else < 0
|
||||
*/
|
||||
int ecrt_master_activate(
|
||||
ec_master_t *master /**< EtherCAT master. */
|
||||
);
|
||||
int ecrt_master_activate( ec_master_t *master /**< EtherCAT master. */);
|
||||
|
||||
/** Sends all datagrams in the queue.
|
||||
*
|
||||
* \todo doc
|
||||
* This has to be called cyclically by the realtime application after
|
||||
* ecrt_master_activate() has returned.
|
||||
*/
|
||||
void ecrt_master_send(
|
||||
ec_master_t *master /**< EtherCAT master. */
|
||||
);
|
||||
|
||||
/** Fetches received frames from the hardware and processes the datagrams.
|
||||
*
|
||||
* This has to be called cyclically by the realtime application after
|
||||
* ecrt_master_activate() has returned.
|
||||
*/
|
||||
void ecrt_master_receive(
|
||||
ec_master_t *master /**< EtherCAT master. */
|
||||
@@ -397,48 +413,64 @@ void ecrt_master_state(
|
||||
* Slave configuration methods
|
||||
*****************************************************************************/
|
||||
|
||||
/** Add a Pdo to the slave's Pdo mapping for the given direction.
|
||||
/** Add a Pdo to a sync manager's Pdo assignment.
|
||||
*
|
||||
* The first call of this function for a given \a dir will clear the default
|
||||
* mapping.
|
||||
*
|
||||
* \see ecrt_slave_config_mapping()
|
||||
* \see ecrt_slave_config_pdos()
|
||||
* \return zero on success, else non-zero
|
||||
*/
|
||||
int ecrt_slave_config_pdo(
|
||||
int ecrt_slave_config_pdo_assign_add(
|
||||
ec_slave_config_t *sc, /**< Slave configuration. */
|
||||
ec_direction_t dir, /**< Pdo direction (input/output). */
|
||||
uint16_t index /**< Index of the Pdo to map. */
|
||||
ec_direction_t dir, /**< Sync manager direction (input/output). */
|
||||
uint16_t index /**< Index of the Pdo to assign. */
|
||||
);
|
||||
|
||||
/** Add a Pdo entry to the given Pdo's configuration.
|
||||
/** Clear a sync manager's Pdo assignment.
|
||||
*
|
||||
* The first call of this function for a given \a pdo_index will clear the
|
||||
* default Pdo configuration.
|
||||
* This can be called before assigning Pdos via
|
||||
* ecrt_slave_config_pdo_assign_add(), to clear the default assignment.
|
||||
*/
|
||||
void ecrt_slave_config_pdo_assign_clear(
|
||||
ec_slave_config_t *sc, /**< Slave configuration. */
|
||||
ec_direction_t dir /**< Sync manager direction (input/output). */
|
||||
);
|
||||
|
||||
/** Add a Pdo entry to the given Pdo's mapping.
|
||||
*
|
||||
* \see ecrt_slave_config_mapping()
|
||||
* \see ecrt_slave_config_pdos()
|
||||
* \return zero on success, else non-zero
|
||||
*/
|
||||
int ecrt_slave_config_pdo_entry(
|
||||
int ecrt_slave_config_pdo_mapping_add(
|
||||
ec_slave_config_t *sc, /**< Slave configuration. */
|
||||
uint16_t pdo_index, /**< Index of the Pdo to configure. */
|
||||
uint16_t pdo_index, /**< Index of the Pdo. */
|
||||
uint16_t entry_index, /**< Index of the Pdo entry to add to the Pdo's
|
||||
configuration. */
|
||||
mapping. */
|
||||
uint8_t entry_subindex, /**< Subindex of the Pdo entry to add to the
|
||||
Pdo's configuration. */
|
||||
Pdo's mapping. */
|
||||
uint8_t entry_bit_length /**< Size of the Pdo entry in bit. */
|
||||
);
|
||||
|
||||
/** Specify the Pdo mapping and (optionally) the Pdo configuration.
|
||||
/** Clear the mapping of a given Pdo.
|
||||
*
|
||||
* This function is a convenience function for the ecrt_slave_config_pdo()
|
||||
* and ecrt_slave_config_pdo_entry() functions, that are better suitable
|
||||
* for automatic code generation.
|
||||
* This can be called before mapping Pdo entries via
|
||||
* ecrt_slave_config_pdo_mapping_add(), to clear the default mapping.
|
||||
*/
|
||||
void ecrt_slave_config_pdo_mapping_clear(
|
||||
ec_slave_config_t *sc, /**< Slave configuration. */
|
||||
uint16_t pdo_index /**< Index of the Pdo. */
|
||||
);
|
||||
|
||||
/** Specify the Pdo assignment and (optionally) the Pdo mappings.
|
||||
*
|
||||
* The following example shows, how to specify a complete Pdo mapping
|
||||
* including the Pdo configuration. With this information, the master is able
|
||||
* to reserve the complete process data, even if the slave is not present
|
||||
* at configuration time:
|
||||
* This function is a convenience wrapper for the functions
|
||||
* ecrt_slave_config_pdo_assign_clear(), ecrt_slave_config_pdo_assign_add(),
|
||||
* ecrt_slave_config_pdo_mapping_clear() and
|
||||
* ecrt_slave_config_pdo_mapping_add(), that are better suitable for automatic
|
||||
* code generation.
|
||||
*
|
||||
* The following example shows, how to specify a complete Pdo assignment
|
||||
* including the Pdo mappings. With this information, the master is able to
|
||||
* reserve the complete process data, even if the slave is not present at
|
||||
* configuration time:
|
||||
*
|
||||
* \code
|
||||
* const ec_pdo_entry_info_t el3162_channel1[] = {
|
||||
@@ -451,52 +483,52 @@ int ecrt_slave_config_pdo_entry(
|
||||
* {0x3102, 2, 16} // value
|
||||
* };
|
||||
*
|
||||
* const ec_pdo_info_t el3162_mapping[] = {
|
||||
* const ec_pdo_info_t el3162_pdos[] = {
|
||||
* {EC_DIR_INPUT, 0x1A00, 2, el3162_channel1},
|
||||
* {EC_DIR_INPUT, 0x1A01, 2, el3162_channel2},
|
||||
* };
|
||||
*
|
||||
* if (ecrt_slave_config_mapping(sc, 2, el3162_mapping))
|
||||
* if (ecrt_slave_config_pdos(sc, 2, el3162_pdos))
|
||||
* return -1; // error
|
||||
* \endcode
|
||||
*
|
||||
* The next example shows, how to configure only the Pdo mapping. The entries
|
||||
* for each mapped Pdo are taken from the default Pdo configuration. Please
|
||||
* note, that Pdo entry registration will fail, if the Pdo configuration is
|
||||
* left empty and the slave is offline.
|
||||
*
|
||||
* The next example shows, how to configure only the Pdo assignment. The
|
||||
* entries for each assigned Pdo are taken from the Pdo's default mapping.
|
||||
* Please note, that Pdo entry registration will fail, if the Pdo
|
||||
* configuration is left empty and the slave is offline.
|
||||
*
|
||||
* \code
|
||||
* const ec_pdo_info_t pdo_mapping[] = {
|
||||
* const ec_pdo_info_t pdos[] = {
|
||||
* {EC_DIR_INPUT, 0x1600}, // Channel 1
|
||||
* {EC_DIR_INPUT, 0x1601} // Channel 2
|
||||
* };
|
||||
*
|
||||
* if (ecrt_slave_config_mapping(slave_config_ana_in, 2, pdo_mapping))
|
||||
* if (ecrt_slave_config_pdos(slave_config_ana_in, 2, pdos))
|
||||
* return -1; // error
|
||||
* \endcode
|
||||
*
|
||||
* Processing of \a pdo_infos will stop, if
|
||||
* - the number of processed items reaches \a n_infos, or
|
||||
* - the \a dir member of an ec_pdo_info_t item is EC_MAP_END. In this case,
|
||||
* - the \a dir member of an ec_pdo_info_t item is EC_END. In this case,
|
||||
* \a n_infos should set to a number greater than the number of list items;
|
||||
* using EC_MAP_END is recommended.
|
||||
* using EC_END is recommended.
|
||||
*
|
||||
* \return zero on success, else non-zero
|
||||
*/
|
||||
int ecrt_slave_config_mapping(
|
||||
int ecrt_slave_config_pdos(
|
||||
ec_slave_config_t *sc, /**< Slave configuration. */
|
||||
unsigned int n_infos, /**< Number of Pdo infos in \a pdo_infos. */
|
||||
const ec_pdo_info_t pdo_infos[] /**< List with Pdo mapping. */
|
||||
const ec_pdo_info_t pdo_infos[] /**< List with Pdos. */
|
||||
);
|
||||
|
||||
/** Registers a Pdo entry for process data exchange in a domain.
|
||||
*
|
||||
* Searches the current mapping and Pdo configurations for the given Pdo
|
||||
* Searches the current Pdo assignment and Pdo mappings for the given Pdo
|
||||
* entry. An error is raised, if the given entry is not mapped. Otherwise, the
|
||||
* corresponding sync manager and FMMU configurations are provided for slave
|
||||
* configuration and the respective sync manager's Pdos are appended to the
|
||||
* given domain, if not already done. The offset of the requested Pdo entry's
|
||||
* data inside the domain's process data is returned.
|
||||
* configuration and the respective sync manager's assigned Pdos are appended
|
||||
* to the given domain, if not already done. The offset of the requested Pdo
|
||||
* entry's data inside the domain's process data is returned.
|
||||
*
|
||||
* \retval >=0 Success: Offset of the Pdo entry's process data.
|
||||
* \retval -1 Error: Pdo entry not found.
|
||||
|
||||
@@ -42,7 +42,7 @@ ec_master-objs := \
|
||||
fsm_coe.o \
|
||||
fsm_coe_map.o \
|
||||
fsm_master.o \
|
||||
fsm_pdo_config.o \
|
||||
fsm_pdo_assign.o \
|
||||
fsm_pdo_mapping.o \
|
||||
fsm_sii.o \
|
||||
fsm_slave_config.o \
|
||||
@@ -51,7 +51,7 @@ ec_master-objs := \
|
||||
master.o \
|
||||
module.o \
|
||||
pdo.o \
|
||||
pdo_mapping.o \
|
||||
pdo_list.o \
|
||||
sdo.o \
|
||||
sdo_entry.o \
|
||||
sdo_request.o \
|
||||
|
||||
@@ -44,7 +44,7 @@ EXTRA_DIST = \
|
||||
fsm_coe.c fsm_coe.h \
|
||||
fsm_coe_map.c fsm_coe_map.h \
|
||||
fsm_master.c fsm_master.h \
|
||||
fsm_pdo_config.c fsm_pdo_config.h \
|
||||
fsm_pdo_assign.c fsm_pdo_assign.h \
|
||||
fsm_pdo_mapping.c fsm_pdo_mapping.h \
|
||||
fsm_sii.c fsm_sii.h \
|
||||
fsm_slave_config.c fsm_slave_config.h \
|
||||
@@ -54,7 +54,7 @@ EXTRA_DIST = \
|
||||
master.c master.h \
|
||||
module.c \
|
||||
pdo.c pdo.h \
|
||||
pdo_mapping.c pdo_mapping.h \
|
||||
pdo_list.c pdo_list.h \
|
||||
sdo.c sdo.h \
|
||||
sdo_entry.c sdo_entry.h \
|
||||
sdo_request.c sdo_request.h \
|
||||
|
||||
@@ -62,7 +62,7 @@ void ec_fmmu_config_init(
|
||||
fmmu->dir = dir;
|
||||
|
||||
fmmu->logical_start_address = domain->data_size;
|
||||
fmmu->data_size = ec_pdo_mapping_total_size(&sc->mapping[dir]);
|
||||
fmmu->data_size = ec_pdo_list_total_size(&sc->pdos[dir]);
|
||||
|
||||
ec_domain_add_fmmu_config(domain, fmmu);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
/**
|
||||
\file
|
||||
EtherCAT CoE mapping state machines.
|
||||
EtherCAT Pdo information state machines.
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -73,7 +73,7 @@ void ec_fsm_coe_map_init(
|
||||
fsm->fsm_coe = fsm_coe;
|
||||
fsm->state = NULL;
|
||||
ec_sdo_request_init(&fsm->request);
|
||||
ec_pdo_mapping_init(&fsm->mapping);
|
||||
ec_pdo_list_init(&fsm->pdos);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -85,7 +85,7 @@ void ec_fsm_coe_map_init(
|
||||
void ec_fsm_coe_map_clear(ec_fsm_coe_map_t *fsm /**< finite state machine */)
|
||||
{
|
||||
ec_sdo_request_clear(&fsm->request);
|
||||
ec_pdo_mapping_clear(&fsm->mapping);
|
||||
ec_pdo_list_clear(&fsm->pdos);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -135,14 +135,14 @@ int ec_fsm_coe_map_success(ec_fsm_coe_map_t *fsm /**< Finite state machine */)
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Start reading mapping.
|
||||
* Start reading Pdo assignment.
|
||||
*/
|
||||
|
||||
void ec_fsm_coe_map_state_start(
|
||||
ec_fsm_coe_map_t *fsm /**< finite state machine */
|
||||
)
|
||||
{
|
||||
// read mapping for first direction
|
||||
// read Pdo assignment for first direction
|
||||
fsm->dir = (ec_direction_t) -1; // next is EC_DIR_OUTPUT
|
||||
ec_fsm_coe_map_action_next_dir(fsm);
|
||||
}
|
||||
@@ -150,7 +150,7 @@ void ec_fsm_coe_map_state_start(
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Read mapping of next direction manager.
|
||||
* Read Pdo assignment of next direction manager.
|
||||
*/
|
||||
|
||||
void ec_fsm_coe_map_action_next_dir(
|
||||
@@ -176,10 +176,10 @@ void ec_fsm_coe_map_action_next_dir(
|
||||
fsm->sync_sdo_index = 0x1C10 + fsm->sync->index;
|
||||
|
||||
if (slave->master->debug_level)
|
||||
EC_DBG("Reading Pdo mapping of sync manager %u of slave %u.\n",
|
||||
EC_DBG("Reading Pdo assignment of sync manager %u of slave %u.\n",
|
||||
fsm->sync->index, slave->ring_position);
|
||||
|
||||
ec_pdo_mapping_clear_pdos(&fsm->mapping);
|
||||
ec_pdo_list_clear_pdos(&fsm->pdos);
|
||||
|
||||
ec_sdo_request_address(&fsm->request, fsm->sync_sdo_index, 0);
|
||||
ecrt_sdo_request_read(&fsm->request);
|
||||
@@ -190,7 +190,7 @@ void ec_fsm_coe_map_action_next_dir(
|
||||
}
|
||||
|
||||
if (slave->master->debug_level)
|
||||
EC_DBG("Reading of Pdo mapping finished for slave %u.\n",
|
||||
EC_DBG("Reading of Pdo assignment finished for slave %u.\n",
|
||||
slave->ring_position);
|
||||
|
||||
fsm->state = ec_fsm_coe_map_state_end;
|
||||
@@ -199,7 +199,7 @@ void ec_fsm_coe_map_action_next_dir(
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Count mapped Pdos.
|
||||
* Count assigned Pdos.
|
||||
*/
|
||||
|
||||
void ec_fsm_coe_map_state_pdo_count(
|
||||
@@ -218,7 +218,7 @@ void ec_fsm_coe_map_state_pdo_count(
|
||||
fsm->sync_subindices = EC_READ_U8(fsm->request.data);
|
||||
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG(" %u Pdos mapped.\n", fsm->sync_subindices);
|
||||
EC_DBG(" %u Pdos assigned.\n", fsm->sync_subindices);
|
||||
|
||||
// read first Pdo
|
||||
fsm->sync_subindex = 1;
|
||||
@@ -245,15 +245,15 @@ void ec_fsm_coe_map_action_next_pdo(
|
||||
return;
|
||||
}
|
||||
|
||||
// finished reading Pdo mapping/configuration
|
||||
// finished reading Pdo assignment/mapping
|
||||
|
||||
if (ec_pdo_mapping_copy(&fsm->sync->mapping, &fsm->mapping)) {
|
||||
if (ec_pdo_list_copy(&fsm->sync->pdos, &fsm->pdos)) {
|
||||
fsm->state = ec_fsm_coe_map_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
fsm->sync->mapping_source = EC_SYNC_MAPPING_COE;
|
||||
ec_pdo_mapping_clear_pdos(&fsm->mapping);
|
||||
fsm->sync->assign_source = EC_ASSIGN_COE;
|
||||
ec_pdo_list_clear_pdos(&fsm->pdos);
|
||||
|
||||
// next direction
|
||||
ec_fsm_coe_map_action_next_dir(fsm);
|
||||
@@ -272,7 +272,7 @@ void ec_fsm_coe_map_state_pdo(
|
||||
if (ec_fsm_coe_exec(fsm->fsm_coe)) return;
|
||||
|
||||
if (!ec_fsm_coe_success(fsm->fsm_coe)) {
|
||||
EC_ERR("Failed to read mapped Pdo index from slave %u.\n",
|
||||
EC_ERR("Failed to read assigned Pdo index from slave %u.\n",
|
||||
fsm->slave->ring_position);
|
||||
fsm->state = ec_fsm_coe_map_state_error;
|
||||
return;
|
||||
@@ -292,7 +292,7 @@ void ec_fsm_coe_map_state_pdo(
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG(" Pdo 0x%04X.\n", fsm->pdo->index);
|
||||
|
||||
list_add_tail(&fsm->pdo->list, &fsm->mapping.pdos);
|
||||
list_add_tail(&fsm->pdo->list, &fsm->pdos.list);
|
||||
|
||||
ec_sdo_request_address(&fsm->request, fsm->pdo->index, 0);
|
||||
ecrt_sdo_request_read(&fsm->request);
|
||||
@@ -304,7 +304,7 @@ void ec_fsm_coe_map_state_pdo(
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Read number of Pdo entries.
|
||||
* Read number of mapped Pdo entries.
|
||||
*/
|
||||
|
||||
void ec_fsm_coe_map_state_pdo_entry_count(
|
||||
@@ -367,7 +367,7 @@ void ec_fsm_coe_map_state_pdo_entry(
|
||||
if (ec_fsm_coe_exec(fsm->fsm_coe)) return;
|
||||
|
||||
if (!ec_fsm_coe_success(fsm->fsm_coe)) {
|
||||
EC_ERR("Failed to read index of mapped Pdo entry from slave %u.\n",
|
||||
EC_ERR("Failed to read mapped Pdo entry from slave %u.\n",
|
||||
fsm->slave->ring_position);
|
||||
fsm->state = ec_fsm_coe_map_state_error;
|
||||
return;
|
||||
|
||||
@@ -67,11 +67,11 @@ struct ec_fsm_coe_map
|
||||
uint8_t sync_subindices; /**< number of mapped Pdos */
|
||||
uint16_t sync_subindex; /**< current subindex in mapping Sdo */
|
||||
|
||||
ec_pdo_mapping_t mapping; /**< Mapping to apply. */
|
||||
ec_pdo_t *pdo; /**< current Pdo */
|
||||
ec_sdo_t *pdo_sdo; /**< current Pdo Sdo */
|
||||
uint8_t pdo_subindices; /**< number of Pdo entries */
|
||||
uint16_t pdo_subindex; /**< current subindex in Pdo Sdo */
|
||||
ec_pdo_list_t pdos; /**< List of read in Pdos. */
|
||||
ec_pdo_t *pdo; /**< Current Pdo. */
|
||||
ec_sdo_t *pdo_sdo; /**< Current Pdo Sdo. */
|
||||
uint8_t pdo_subindices; /**< Number of Pdo entries. */
|
||||
uint16_t pdo_subindex; /**< Current subindex in Pdo Sdo. */
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
380
master/fsm_pdo_assign.c
Normal file
380
master/fsm_pdo_assign.c
Normal file
@@ -0,0 +1,380 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2006 Florian Pose, Ingenieurgemeinschaft IgH
|
||||
*
|
||||
* This file is part of the IgH EtherCAT Master.
|
||||
*
|
||||
* The IgH EtherCAT Master is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* The IgH EtherCAT Master is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with the IgH EtherCAT Master; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* The right to use EtherCAT Technology is granted and comes free of
|
||||
* charge under condition of compatibility of product made by
|
||||
* Licensee. People intending to distribute/sell products based on the
|
||||
* code, have to sign an agreement to guarantee that products using
|
||||
* software based on IgH EtherCAT master stay compatible with the actual
|
||||
* EtherCAT specification (which are released themselves as an open
|
||||
* standard) as the (only) precondition to have the right to use EtherCAT
|
||||
* Technology, IP and trade marks.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/** \file
|
||||
* EtherCAT Pdo assignment state machine.
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#include "globals.h"
|
||||
#include "master.h"
|
||||
#include "mailbox.h"
|
||||
#include "slave_config.h"
|
||||
|
||||
#include "fsm_pdo_assign.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void ec_fsm_pdo_assign_state_start(ec_fsm_pdo_assign_t *);
|
||||
void ec_fsm_pdo_assign_state_zero_count(ec_fsm_pdo_assign_t *);
|
||||
void ec_fsm_pdo_assign_state_add_pdo(ec_fsm_pdo_assign_t *);
|
||||
void ec_fsm_pdo_assign_state_pdo_count(ec_fsm_pdo_assign_t *);
|
||||
void ec_fsm_pdo_assign_state_end(ec_fsm_pdo_assign_t *);
|
||||
void ec_fsm_pdo_assign_state_error(ec_fsm_pdo_assign_t *);
|
||||
|
||||
void ec_fsm_pdo_assign_next_dir(ec_fsm_pdo_assign_t *);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Constructor.
|
||||
*/
|
||||
void ec_fsm_pdo_assign_init(
|
||||
ec_fsm_pdo_assign_t *fsm, /**< Pdo assignment state machine. */
|
||||
ec_fsm_coe_t *fsm_coe /**< CoE state machine to use */
|
||||
)
|
||||
{
|
||||
fsm->fsm_coe = fsm_coe;
|
||||
ec_sdo_request_init(&fsm->request);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Destructor.
|
||||
*/
|
||||
void ec_fsm_pdo_assign_clear(
|
||||
ec_fsm_pdo_assign_t *fsm /**< Pdo assignment state machine. */
|
||||
)
|
||||
{
|
||||
ec_sdo_request_clear(&fsm->request);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Start Pdo assignment state machine.
|
||||
*/
|
||||
void ec_fsm_pdo_assign_start(
|
||||
ec_fsm_pdo_assign_t *fsm, /**< Pdo assignment state machine. */
|
||||
ec_slave_t *slave /**< slave to configure */
|
||||
)
|
||||
{
|
||||
fsm->slave = slave;
|
||||
fsm->state = ec_fsm_pdo_assign_state_start;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Get running state.
|
||||
*
|
||||
* \return false, if state machine has terminated
|
||||
*/
|
||||
int ec_fsm_pdo_assign_running(
|
||||
const ec_fsm_pdo_assign_t *fsm /**< Pdo assignment state machine. */
|
||||
)
|
||||
{
|
||||
return fsm->state != ec_fsm_pdo_assign_state_end
|
||||
&& fsm->state != ec_fsm_pdo_assign_state_error;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Executes the current state of the state machine.
|
||||
*
|
||||
* If the state machine's datagram is not sent or received yet, the execution
|
||||
* of the state machine is delayed to the next cycle.
|
||||
*
|
||||
* \return false, if state machine has terminated
|
||||
*/
|
||||
int ec_fsm_pdo_assign_exec(
|
||||
ec_fsm_pdo_assign_t *fsm /**< Pdo assignment state machine. */
|
||||
)
|
||||
{
|
||||
fsm->state(fsm);
|
||||
return ec_fsm_pdo_assign_running(fsm);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Get execution result.
|
||||
*
|
||||
* \return true, if the state machine terminated gracefully
|
||||
*/
|
||||
int ec_fsm_pdo_assign_success(
|
||||
const ec_fsm_pdo_assign_t *fsm /**< Pdo assignment state machine. */
|
||||
)
|
||||
{
|
||||
return fsm->state == ec_fsm_pdo_assign_state_end;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* State functions.
|
||||
*****************************************************************************/
|
||||
|
||||
/** Start Pdo assignment.
|
||||
*/
|
||||
void ec_fsm_pdo_assign_state_start(
|
||||
ec_fsm_pdo_assign_t *fsm /**< Pdo assignment state machine. */
|
||||
)
|
||||
{
|
||||
if (!fsm->slave->config) {
|
||||
fsm->state = ec_fsm_pdo_assign_state_end;
|
||||
return;
|
||||
}
|
||||
|
||||
fsm->dir = (ec_direction_t) -1; // next is EC_DIR_OUTPUT
|
||||
ec_fsm_pdo_assign_next_dir(fsm);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Process Pdo assignment of next direction.
|
||||
*/
|
||||
void ec_fsm_pdo_assign_next_dir(
|
||||
ec_fsm_pdo_assign_t *fsm /**< Pdo assignment state machine. */
|
||||
)
|
||||
{
|
||||
fsm->dir++;
|
||||
|
||||
for (; fsm->dir <= EC_DIR_INPUT; fsm->dir++) {
|
||||
fsm->pdos = &fsm->slave->config->pdos[fsm->dir];
|
||||
|
||||
if (!(fsm->sync = ec_slave_get_pdo_sync(fsm->slave, fsm->dir))) {
|
||||
if (!list_empty(&fsm->pdos->list)) {
|
||||
EC_ERR("No sync manager for direction %u!\n", fsm->dir);
|
||||
fsm->state = ec_fsm_pdo_assign_state_end;
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if assignment has to be altered
|
||||
if (ec_pdo_list_equal(&fsm->sync->pdos, fsm->pdos))
|
||||
continue;
|
||||
|
||||
// Pdo assignment has to be changed. Does the slave support this?
|
||||
if (!(fsm->slave->sii.mailbox_protocols & EC_MBOX_COE)
|
||||
|| (fsm->slave->sii.has_general
|
||||
&& !fsm->slave->sii.coe_details.enable_pdo_assign)) {
|
||||
EC_ERR("Slave %u does not support assigning Pdos!\n",
|
||||
fsm->slave->ring_position);
|
||||
fsm->state = ec_fsm_pdo_assign_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fsm->slave->master->debug_level) {
|
||||
EC_DBG("Changing Pdo assignment for SM%u of slave %u.\n",
|
||||
fsm->sync->index, fsm->slave->ring_position);
|
||||
}
|
||||
|
||||
if (ec_sdo_request_alloc(&fsm->request, 2)) {
|
||||
fsm->state = ec_fsm_pdo_assign_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
// set mapped Pdo count to zero
|
||||
EC_WRITE_U8(fsm->request.data, 0); // zero Pdos mapped
|
||||
fsm->request.data_size = 1;
|
||||
ec_sdo_request_address(&fsm->request, 0x1C10 + fsm->sync->index, 0);
|
||||
ecrt_sdo_request_write(&fsm->request);
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("Setting Pdo count to zero for SM%u.\n", fsm->sync->index);
|
||||
|
||||
fsm->state = ec_fsm_pdo_assign_state_zero_count;
|
||||
ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request);
|
||||
ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
|
||||
return;
|
||||
}
|
||||
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("Pdo assignment finished for slave %u.\n",
|
||||
fsm->slave->ring_position);
|
||||
fsm->state = ec_fsm_pdo_assign_state_end;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Assign next Pdo.
|
||||
*/
|
||||
ec_pdo_t *ec_fsm_pdo_assign_next_pdo(
|
||||
const ec_fsm_pdo_assign_t *fsm, /**< Pdo assignment state machine. */
|
||||
const struct list_head *list /**< current Pdo list item */
|
||||
)
|
||||
{
|
||||
list = list->next;
|
||||
if (list == &fsm->pdos->list)
|
||||
return NULL; // no next Pdo
|
||||
return list_entry(list, ec_pdo_t, list);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Assign a Pdo.
|
||||
*/
|
||||
void ec_fsm_pdo_assign_add_pdo(
|
||||
ec_fsm_pdo_assign_t *fsm /**< Pdo assignment state machine. */
|
||||
)
|
||||
{
|
||||
EC_WRITE_U16(fsm->request.data, fsm->pdo->index);
|
||||
fsm->request.data_size = 2;
|
||||
ec_sdo_request_address(&fsm->request,
|
||||
0x1C10 + fsm->sync->index, fsm->pdo_count);
|
||||
ecrt_sdo_request_write(&fsm->request);
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("Assigning Pdo 0x%04X at position %u.\n",
|
||||
fsm->pdo->index, fsm->pdo_count);
|
||||
|
||||
fsm->state = ec_fsm_pdo_assign_state_add_pdo;
|
||||
ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request);
|
||||
ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Set the number of assigned Pdos to zero.
|
||||
*/
|
||||
void ec_fsm_pdo_assign_state_zero_count(
|
||||
ec_fsm_pdo_assign_t *fsm /**< Pdo assignment state machine. */
|
||||
)
|
||||
{
|
||||
if (ec_fsm_coe_exec(fsm->fsm_coe)) return;
|
||||
|
||||
if (!ec_fsm_coe_success(fsm->fsm_coe)) {
|
||||
EC_ERR("Failed to clear Pdo assignment of slave %u.\n",
|
||||
fsm->slave->ring_position);
|
||||
fsm->state = ec_fsm_pdo_assign_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
// assign all Pdos belonging to the current sync manager
|
||||
|
||||
// find first Pdo
|
||||
if (!(fsm->pdo = ec_fsm_pdo_assign_next_pdo(fsm, &fsm->pdos->list))) {
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("No Pdos to assign for SM%u of slave %u.\n",
|
||||
fsm->sync->index, fsm->slave->ring_position);
|
||||
ec_fsm_pdo_assign_next_dir(fsm);
|
||||
return;
|
||||
}
|
||||
|
||||
// assign first Pdo
|
||||
fsm->pdo_count = 1;
|
||||
ec_fsm_pdo_assign_add_pdo(fsm);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Add a Pdo to the sync managers Pdo assignment.
|
||||
*/
|
||||
void ec_fsm_pdo_assign_state_add_pdo(
|
||||
ec_fsm_pdo_assign_t *fsm /**< Pdo assignment state machine. */
|
||||
)
|
||||
{
|
||||
if (ec_fsm_coe_exec(fsm->fsm_coe)) return;
|
||||
|
||||
if (!ec_fsm_coe_success(fsm->fsm_coe)) {
|
||||
EC_ERR("Failed to map Pdo 0x%04X for SM%u of slave %u.\n",
|
||||
fsm->pdo->index, fsm->sync->index, fsm->slave->ring_position);
|
||||
fsm->state = ec_fsm_pdo_assign_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
// find next Pdo
|
||||
if (!(fsm->pdo = ec_fsm_pdo_assign_next_pdo(fsm, &fsm->pdo->list))) {
|
||||
// no more Pdos to map. write Pdo count
|
||||
EC_WRITE_U8(fsm->request.data, fsm->pdo_count);
|
||||
fsm->request.data_size = 1;
|
||||
ec_sdo_request_address(&fsm->request, 0x1C10 + fsm->sync->index, 0);
|
||||
ecrt_sdo_request_write(&fsm->request);
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("Setting number of assigned Pdos to %u.\n",
|
||||
fsm->pdo_count);
|
||||
|
||||
fsm->state = ec_fsm_pdo_assign_state_pdo_count;
|
||||
ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request);
|
||||
ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
|
||||
return;
|
||||
}
|
||||
|
||||
// add next Pdo to assignment
|
||||
fsm->pdo_count++;
|
||||
ec_fsm_pdo_assign_add_pdo(fsm);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Set the number of assigned Pdos.
|
||||
*/
|
||||
void ec_fsm_pdo_assign_state_pdo_count(
|
||||
ec_fsm_pdo_assign_t *fsm /**< Pdo assignment state machine. */
|
||||
)
|
||||
{
|
||||
if (ec_fsm_coe_exec(fsm->fsm_coe)) return;
|
||||
|
||||
if (!ec_fsm_coe_success(fsm->fsm_coe)) {
|
||||
EC_ERR("Failed to set number of assigned Pdos for slave %u.\n",
|
||||
fsm->slave->ring_position);
|
||||
fsm->state = ec_fsm_pdo_assign_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("Successfully set Pdo assignment for SM%u of slave %u.\n",
|
||||
fsm->sync->index, fsm->slave->ring_position);
|
||||
|
||||
// assignment for this direction finished
|
||||
ec_fsm_pdo_assign_next_dir(fsm);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Common state functions
|
||||
*****************************************************************************/
|
||||
|
||||
/** State: ERROR.
|
||||
*/
|
||||
void ec_fsm_pdo_assign_state_error(
|
||||
ec_fsm_pdo_assign_t *fsm /**< Pdo assignment state machine. */
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** State: END.
|
||||
*/
|
||||
void ec_fsm_pdo_assign_state_end(
|
||||
ec_fsm_pdo_assign_t *fsm /**< Pdo assignment state machine. */
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -31,50 +31,54 @@
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/** \file
|
||||
* EtherCAT Pdo configuration state machine structures.
|
||||
*/
|
||||
/**
|
||||
\file
|
||||
EtherCAT Pdo assignment state machine structures.
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef __EC_FSM_PDO_CONFIG__
|
||||
#define __EC_FSM_PDO_CONFIG__
|
||||
#ifndef _EC_FSM_PDO_ASSIGN_H_
|
||||
#define _EC_FSM_PDO_ASSIGN_H_
|
||||
|
||||
#include "../include/ecrt.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "../include/ecrt.h"
|
||||
#include "datagram.h"
|
||||
#include "fsm_coe.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* \see ec_fsm_pdo_config
|
||||
* \see ec_fsm_pdo_assign
|
||||
*/
|
||||
typedef struct ec_fsm_pdo_config ec_fsm_pdo_config_t;
|
||||
typedef struct ec_fsm_pdo_assign ec_fsm_pdo_assign_t;
|
||||
|
||||
/** Pdo configuration state machine.
|
||||
/** Pdo assignment state machine.
|
||||
*/
|
||||
struct ec_fsm_pdo_config
|
||||
struct ec_fsm_pdo_assign
|
||||
{
|
||||
void (*state)(ec_fsm_pdo_config_t *); /**< state function */
|
||||
ec_fsm_coe_t *fsm_coe; /**< CoE state machine to use */
|
||||
void (*state)(ec_fsm_pdo_assign_t *); /**< State function. */
|
||||
ec_fsm_coe_t *fsm_coe; /**< CoE state machine to use. */
|
||||
ec_slave_t *slave; /**< Slave the FSM runs on. */
|
||||
|
||||
const ec_pdo_t *pdo; /**< Current Pdo to configure. */
|
||||
const ec_pdo_entry_t *entry; /**< Current entry. */
|
||||
ec_direction_t dir; /**< Current direction. */
|
||||
const ec_sync_t *sync; /**< Current sync manager. */
|
||||
const ec_pdo_list_t *pdos; /**< Target Pdo assignment. */
|
||||
const ec_pdo_t *pdo; /**< Current Pdo. */
|
||||
|
||||
ec_sdo_request_t request; /**< Sdo request. */
|
||||
unsigned int entry_count; /**< Number of configured entries. */
|
||||
unsigned int pdo_count; /**< Number of assigned Pdos. */
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void ec_fsm_pdo_config_init(ec_fsm_pdo_config_t *, ec_fsm_coe_t *);
|
||||
void ec_fsm_pdo_config_clear(ec_fsm_pdo_config_t *);
|
||||
void ec_fsm_pdo_assign_init(ec_fsm_pdo_assign_t *, ec_fsm_coe_t *);
|
||||
void ec_fsm_pdo_assign_clear(ec_fsm_pdo_assign_t *);
|
||||
|
||||
void ec_fsm_pdo_config_start(ec_fsm_pdo_config_t *, ec_slave_t *);
|
||||
int ec_fsm_pdo_config_exec(ec_fsm_pdo_config_t *);
|
||||
int ec_fsm_pdo_config_success(const ec_fsm_pdo_config_t *);
|
||||
void ec_fsm_pdo_assign_start(ec_fsm_pdo_assign_t *, ec_slave_t *);
|
||||
int ec_fsm_pdo_assign_exec(ec_fsm_pdo_assign_t *);
|
||||
int ec_fsm_pdo_assign_success(const ec_fsm_pdo_assign_t *);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@@ -1,385 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2006 Florian Pose, Ingenieurgemeinschaft IgH
|
||||
*
|
||||
* This file is part of the IgH EtherCAT Master.
|
||||
*
|
||||
* The IgH EtherCAT Master is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* The IgH EtherCAT Master is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with the IgH EtherCAT Master; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* The right to use EtherCAT Technology is granted and comes free of
|
||||
* charge under condition of compatibility of product made by
|
||||
* Licensee. People intending to distribute/sell products based on the
|
||||
* code, have to sign an agreement to guarantee that products using
|
||||
* software based on IgH EtherCAT master stay compatible with the actual
|
||||
* EtherCAT specification (which are released themselves as an open
|
||||
* standard) as the (only) precondition to have the right to use EtherCAT
|
||||
* Technology, IP and trade marks.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/** \file
|
||||
* EtherCAT Pdo configuration state machine.
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#include "globals.h"
|
||||
#include "master.h"
|
||||
#include "mailbox.h"
|
||||
#include "slave_config.h"
|
||||
|
||||
#include "fsm_pdo_config.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void ec_fsm_pdo_config_state_start(ec_fsm_pdo_config_t *);
|
||||
void ec_fsm_pdo_config_state_zero_count(ec_fsm_pdo_config_t *);
|
||||
void ec_fsm_pdo_config_state_add_entry(ec_fsm_pdo_config_t *);
|
||||
void ec_fsm_pdo_config_state_entry_count(ec_fsm_pdo_config_t *);
|
||||
void ec_fsm_pdo_config_state_end(ec_fsm_pdo_config_t *);
|
||||
void ec_fsm_pdo_config_state_error(ec_fsm_pdo_config_t *);
|
||||
|
||||
void ec_fsm_pdo_config_next_pdo(ec_fsm_pdo_config_t *);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Constructor.
|
||||
*/
|
||||
void ec_fsm_pdo_config_init(
|
||||
ec_fsm_pdo_config_t *fsm, /**< pdo_config state machine */
|
||||
ec_fsm_coe_t *fsm_coe /**< CoE state machine to use */
|
||||
)
|
||||
{
|
||||
fsm->fsm_coe = fsm_coe;
|
||||
ec_sdo_request_init(&fsm->request);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Destructor.
|
||||
*/
|
||||
void ec_fsm_pdo_config_clear(
|
||||
ec_fsm_pdo_config_t *fsm /**< pdo_config state machine */
|
||||
)
|
||||
{
|
||||
ec_sdo_request_clear(&fsm->request);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Start Pdo configuration state machine.
|
||||
*/
|
||||
void ec_fsm_pdo_config_start(
|
||||
ec_fsm_pdo_config_t *fsm, /**< Pdo configuration state machine */
|
||||
ec_slave_t *slave /**< slave to configure */
|
||||
)
|
||||
{
|
||||
fsm->slave = slave;
|
||||
fsm->state = ec_fsm_pdo_config_state_start;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Get running state.
|
||||
*
|
||||
* \return false, if state machine has terminated
|
||||
*/
|
||||
int ec_fsm_pdo_config_running(
|
||||
const ec_fsm_pdo_config_t *fsm /**< Pdo configuration state machine */
|
||||
)
|
||||
{
|
||||
return fsm->state != ec_fsm_pdo_config_state_end
|
||||
&& fsm->state != ec_fsm_pdo_config_state_error;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Executes the current state.
|
||||
*
|
||||
* \return false, if state machine has terminated
|
||||
*/
|
||||
int ec_fsm_pdo_config_exec(
|
||||
ec_fsm_pdo_config_t *fsm /**< Pdo configuration state machine */
|
||||
)
|
||||
{
|
||||
fsm->state(fsm);
|
||||
return ec_fsm_pdo_config_running(fsm);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Get execution result.
|
||||
*
|
||||
* \return true, if the state machine terminated gracefully
|
||||
*/
|
||||
int ec_fsm_pdo_config_success(
|
||||
const ec_fsm_pdo_config_t *fsm /**< Pdo configuration state machine */
|
||||
)
|
||||
{
|
||||
return fsm->state == ec_fsm_pdo_config_state_end;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* State functions.
|
||||
*****************************************************************************/
|
||||
|
||||
/** Start Pdo configuration.
|
||||
*/
|
||||
void ec_fsm_pdo_config_state_start(
|
||||
ec_fsm_pdo_config_t *fsm /**< Pdo configuration state machine */
|
||||
)
|
||||
{
|
||||
if (!fsm->slave->config) {
|
||||
fsm->state = ec_fsm_pdo_config_state_end;
|
||||
return;
|
||||
}
|
||||
|
||||
fsm->pdo = NULL;
|
||||
ec_fsm_pdo_config_next_pdo(fsm);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Process configuration of next Pdo.
|
||||
*/
|
||||
void ec_fsm_pdo_config_next_pdo(
|
||||
ec_fsm_pdo_config_t *fsm /**< Pdo configuration state machine */
|
||||
)
|
||||
{
|
||||
ec_direction_t dir;
|
||||
const ec_pdo_mapping_t *map;
|
||||
const ec_pdo_t *pdo, *mapped_pdo;
|
||||
|
||||
for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++) {
|
||||
map = &fsm->slave->config->mapping[dir];
|
||||
|
||||
list_for_each_entry(pdo, &map->pdos, list) {
|
||||
if (fsm->pdo) { // there was a Pdo configured in the last run
|
||||
if (pdo == fsm->pdo) // this is the last Pdo
|
||||
fsm->pdo = NULL; // take the next one
|
||||
} else {
|
||||
if ((mapped_pdo = ec_slave_find_pdo(fsm->slave, pdo->index)))
|
||||
if (ec_pdo_equal_entries(pdo, mapped_pdo))
|
||||
continue; // Pdo configured correctly
|
||||
|
||||
fsm->pdo = pdo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!fsm->pdo) {
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("Pdo configuration finished for slave %u.\n",
|
||||
fsm->slave->ring_position);
|
||||
fsm->state = ec_fsm_pdo_config_state_end;
|
||||
return;
|
||||
}
|
||||
|
||||
// Pdo configuration has to be changed. Does the slave support this?
|
||||
if (!(fsm->slave->sii.mailbox_protocols & EC_MBOX_COE)
|
||||
|| (fsm->slave->sii.has_general
|
||||
&& !fsm->slave->sii.coe_details.enable_pdo_configuration)) {
|
||||
EC_ERR("Slave %u does not support changing the Pdo configuration!\n",
|
||||
fsm->slave->ring_position);
|
||||
fsm->state = ec_fsm_pdo_config_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fsm->slave->master->debug_level) {
|
||||
EC_DBG("Changing configuration of Pdo 0x%04X of slave %u.\n",
|
||||
fsm->pdo->index, fsm->slave->ring_position);
|
||||
}
|
||||
|
||||
if (ec_sdo_request_alloc(&fsm->request, 4)) {
|
||||
fsm->state = ec_fsm_pdo_config_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
// set mapped Pdo count to zero
|
||||
EC_WRITE_U8(fsm->request.data, 0);
|
||||
fsm->request.data_size = 1;
|
||||
ec_sdo_request_address(&fsm->request, fsm->pdo->index, 0);
|
||||
ecrt_sdo_request_write(&fsm->request);
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("Setting entry count to zero for Pdo 0x%04X.\n",
|
||||
fsm->pdo->index);
|
||||
|
||||
fsm->state = ec_fsm_pdo_config_state_zero_count;
|
||||
ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request);
|
||||
ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Process next Pdo entry.
|
||||
*/
|
||||
ec_pdo_entry_t *ec_fsm_pdo_config_next_entry(
|
||||
const ec_fsm_pdo_config_t *fsm, /**< Pdo configuration state machine */
|
||||
const struct list_head *list /**< current entry list item */
|
||||
)
|
||||
{
|
||||
list = list->next;
|
||||
if (list == &fsm->pdo->entries)
|
||||
return NULL; // no next entry
|
||||
return list_entry(list, ec_pdo_entry_t, list);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Starts to add a Pdo entry.
|
||||
*/
|
||||
void ec_fsm_pdo_config_add_entry(
|
||||
ec_fsm_pdo_config_t *fsm /**< Pdo configuration state machine. */
|
||||
)
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
value = fsm->entry->index << 16
|
||||
| fsm->entry->subindex << 8 | fsm->entry->bit_length;
|
||||
EC_WRITE_U32(fsm->request.data, value);
|
||||
fsm->request.data_size = 4;
|
||||
ec_sdo_request_address(&fsm->request, fsm->pdo->index, fsm->entry_count);
|
||||
ecrt_sdo_request_write(&fsm->request);
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("Configuring Pdo entry %08X at position %u.\n",
|
||||
value, fsm->entry_count);
|
||||
|
||||
fsm->state = ec_fsm_pdo_config_state_add_entry;
|
||||
ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request);
|
||||
ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Set the number of configured entries to zero.
|
||||
*/
|
||||
void ec_fsm_pdo_config_state_zero_count(
|
||||
ec_fsm_pdo_config_t *fsm /**< Pdo configuration state machine */
|
||||
)
|
||||
{
|
||||
if (ec_fsm_coe_exec(fsm->fsm_coe)) return;
|
||||
|
||||
if (!ec_fsm_coe_success(fsm->fsm_coe)) {
|
||||
EC_ERR("Failed to clear Pdo configuration for slave %u.\n",
|
||||
fsm->slave->ring_position);
|
||||
fsm->state = ec_fsm_pdo_config_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
// find first entry
|
||||
if (!(fsm->entry =
|
||||
ec_fsm_pdo_config_next_entry(fsm, &fsm->pdo->entries))) {
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("No entries to configure for Pdo 0x%04X of slave %u.\n",
|
||||
fsm->pdo->index, fsm->slave->ring_position);
|
||||
ec_fsm_pdo_config_next_pdo(fsm);
|
||||
return;
|
||||
}
|
||||
|
||||
// add first entry
|
||||
fsm->entry_count = 1;
|
||||
ec_fsm_pdo_config_add_entry(fsm);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Add a Pdo entry.
|
||||
*/
|
||||
void ec_fsm_pdo_config_state_add_entry(
|
||||
ec_fsm_pdo_config_t *fsm /**< Pdo configuration state machine */
|
||||
)
|
||||
{
|
||||
if (ec_fsm_coe_exec(fsm->fsm_coe)) return;
|
||||
|
||||
if (!ec_fsm_coe_success(fsm->fsm_coe)) {
|
||||
EC_ERR("Failed to add entry 0x%04X:%u for slave %u.\n",
|
||||
fsm->entry->index, fsm->entry->subindex,
|
||||
fsm->slave->ring_position);
|
||||
fsm->state = ec_fsm_pdo_config_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
// find next entry
|
||||
if (!(fsm->entry = ec_fsm_pdo_config_next_entry(fsm, &fsm->entry->list))) {
|
||||
// No more entries to add. Write entry count.
|
||||
EC_WRITE_U8(fsm->request.data, fsm->entry_count);
|
||||
fsm->request.data_size = 1;
|
||||
ec_sdo_request_address(&fsm->request, fsm->pdo->index, 0);
|
||||
ecrt_sdo_request_write(&fsm->request);
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("Setting number of Pdo entries to %u.\n",
|
||||
fsm->entry_count);
|
||||
|
||||
fsm->state = ec_fsm_pdo_config_state_entry_count;
|
||||
ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request);
|
||||
ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
|
||||
return;
|
||||
}
|
||||
|
||||
// add next entry
|
||||
fsm->entry_count++;
|
||||
ec_fsm_pdo_config_add_entry(fsm);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Set the number of entries.
|
||||
*/
|
||||
void ec_fsm_pdo_config_state_entry_count(
|
||||
ec_fsm_pdo_config_t *fsm /**< Pdo configuration state machine */
|
||||
)
|
||||
{
|
||||
if (ec_fsm_coe_exec(fsm->fsm_coe)) return;
|
||||
|
||||
if (!ec_fsm_coe_success(fsm->fsm_coe)) {
|
||||
EC_ERR("Failed to set number of entries for slave %u.\n",
|
||||
fsm->slave->ring_position);
|
||||
fsm->state = ec_fsm_pdo_config_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("Successfully configured Pdo 0x%04X on slave %u.\n",
|
||||
fsm->pdo->index, fsm->slave->ring_position);
|
||||
|
||||
ec_fsm_pdo_config_next_pdo(fsm);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Common state functions
|
||||
*****************************************************************************/
|
||||
|
||||
/** State: ERROR.
|
||||
*/
|
||||
void ec_fsm_pdo_config_state_error(
|
||||
ec_fsm_pdo_config_t *fsm /**< Pdo configuration state machine */
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** State: END.
|
||||
*/
|
||||
void ec_fsm_pdo_config_state_end(
|
||||
ec_fsm_pdo_config_t *fsm /**< Pdo configuration state machine */
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -48,20 +48,20 @@
|
||||
|
||||
void ec_fsm_pdo_mapping_state_start(ec_fsm_pdo_mapping_t *);
|
||||
void ec_fsm_pdo_mapping_state_zero_count(ec_fsm_pdo_mapping_t *);
|
||||
void ec_fsm_pdo_mapping_state_add_pdo(ec_fsm_pdo_mapping_t *);
|
||||
void ec_fsm_pdo_mapping_state_pdo_count(ec_fsm_pdo_mapping_t *);
|
||||
void ec_fsm_pdo_mapping_state_add_entry(ec_fsm_pdo_mapping_t *);
|
||||
void ec_fsm_pdo_mapping_state_entry_count(ec_fsm_pdo_mapping_t *);
|
||||
void ec_fsm_pdo_mapping_state_end(ec_fsm_pdo_mapping_t *);
|
||||
void ec_fsm_pdo_mapping_state_error(ec_fsm_pdo_mapping_t *);
|
||||
|
||||
void ec_fsm_pdo_mapping_next_dir(ec_fsm_pdo_mapping_t *);
|
||||
void ec_fsm_pdo_mapping_next_pdo(ec_fsm_pdo_mapping_t *);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Constructor.
|
||||
*/
|
||||
void ec_fsm_pdo_mapping_init(
|
||||
ec_fsm_pdo_mapping_t *fsm, /**< mapping state machine */
|
||||
ec_fsm_coe_t *fsm_coe /**< CoE state machine to use */
|
||||
ec_fsm_pdo_mapping_t *fsm, /**< Pdo mapping state machine. */
|
||||
ec_fsm_coe_t *fsm_coe /**< CoE state machine to use. */
|
||||
)
|
||||
{
|
||||
fsm->fsm_coe = fsm_coe;
|
||||
@@ -73,7 +73,7 @@ void ec_fsm_pdo_mapping_init(
|
||||
/** Destructor.
|
||||
*/
|
||||
void ec_fsm_pdo_mapping_clear(
|
||||
ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */
|
||||
ec_fsm_pdo_mapping_t *fsm /**< Pdo mapping state machine. */
|
||||
)
|
||||
{
|
||||
ec_sdo_request_clear(&fsm->request);
|
||||
@@ -81,10 +81,10 @@ void ec_fsm_pdo_mapping_clear(
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Start Pdo mapping configuration state machine.
|
||||
/** Start Pdo mapping state machine.
|
||||
*/
|
||||
void ec_fsm_pdo_mapping_start(
|
||||
ec_fsm_pdo_mapping_t *fsm, /**< mapping state machine */
|
||||
ec_fsm_pdo_mapping_t *fsm, /**< Pdo mapping state machine. */
|
||||
ec_slave_t *slave /**< slave to configure */
|
||||
)
|
||||
{
|
||||
@@ -99,7 +99,7 @@ void ec_fsm_pdo_mapping_start(
|
||||
* \return false, if state machine has terminated
|
||||
*/
|
||||
int ec_fsm_pdo_mapping_running(
|
||||
const ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */
|
||||
const ec_fsm_pdo_mapping_t *fsm /**< Pdo mapping state machine. */
|
||||
)
|
||||
{
|
||||
return fsm->state != ec_fsm_pdo_mapping_state_end
|
||||
@@ -108,15 +108,12 @@ int ec_fsm_pdo_mapping_running(
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Executes the current state of the state machine.
|
||||
*
|
||||
* If the state machine's datagram is not sent or received yet, the execution
|
||||
* of the state machine is delayed to the next cycle.
|
||||
/** Executes the current state.
|
||||
*
|
||||
* \return false, if state machine has terminated
|
||||
*/
|
||||
int ec_fsm_pdo_mapping_exec(
|
||||
ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */
|
||||
ec_fsm_pdo_mapping_t *fsm /**< Pdo mapping state machine. */
|
||||
)
|
||||
{
|
||||
fsm->state(fsm);
|
||||
@@ -130,7 +127,7 @@ int ec_fsm_pdo_mapping_exec(
|
||||
* \return true, if the state machine terminated gracefully
|
||||
*/
|
||||
int ec_fsm_pdo_mapping_success(
|
||||
const ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */
|
||||
const ec_fsm_pdo_mapping_t *fsm /**< Pdo mapping state machine. */
|
||||
)
|
||||
{
|
||||
return fsm->state == ec_fsm_pdo_mapping_state_end;
|
||||
@@ -140,10 +137,10 @@ int ec_fsm_pdo_mapping_success(
|
||||
* State functions.
|
||||
*****************************************************************************/
|
||||
|
||||
/** Start mapping configuration.
|
||||
/** Start Pdo mapping.
|
||||
*/
|
||||
void ec_fsm_pdo_mapping_state_start(
|
||||
ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */
|
||||
ec_fsm_pdo_mapping_t *fsm /**< Pdo mapping state machine. */
|
||||
)
|
||||
{
|
||||
if (!fsm->slave->config) {
|
||||
@@ -151,119 +148,128 @@ void ec_fsm_pdo_mapping_state_start(
|
||||
return;
|
||||
}
|
||||
|
||||
fsm->dir = (ec_direction_t) -1; // next is EC_DIR_OUTPUT
|
||||
ec_fsm_pdo_mapping_next_dir(fsm);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Process mapping of next direction.
|
||||
*/
|
||||
void ec_fsm_pdo_mapping_next_dir(
|
||||
ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */
|
||||
)
|
||||
{
|
||||
fsm->dir++;
|
||||
|
||||
for (; fsm->dir <= EC_DIR_INPUT; fsm->dir++) {
|
||||
fsm->mapping = &fsm->slave->config->mapping[fsm->dir];
|
||||
|
||||
if (!(fsm->sync = ec_slave_get_pdo_sync(fsm->slave, fsm->dir))) {
|
||||
if (!list_empty(&fsm->mapping->pdos)) {
|
||||
EC_ERR("No sync manager for direction %u!\n", fsm->dir);
|
||||
fsm->state = ec_fsm_pdo_mapping_state_end;
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if mapping has to be altered
|
||||
if (ec_pdo_mapping_equal(&fsm->sync->mapping, fsm->mapping))
|
||||
continue;
|
||||
|
||||
// Pdo mapping has to be changed. Does the slave support this?
|
||||
if (!fsm->slave->sii.mailbox_protocols & EC_MBOX_COE
|
||||
|| (fsm->slave->sii.has_general
|
||||
&& !fsm->slave->sii.coe_details.enable_pdo_assign)) {
|
||||
EC_ERR("Slave %u does not support changing the Pdo mapping!\n",
|
||||
fsm->slave->ring_position);
|
||||
fsm->state = ec_fsm_pdo_mapping_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fsm->slave->master->debug_level) {
|
||||
EC_DBG("Changing Pdo mapping for SM%u of slave %u.\n",
|
||||
fsm->sync->index, fsm->slave->ring_position);
|
||||
}
|
||||
|
||||
if (ec_sdo_request_alloc(&fsm->request, 2)) {
|
||||
fsm->state = ec_fsm_pdo_mapping_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
// set mapped Pdo count to zero
|
||||
EC_WRITE_U8(fsm->request.data, 0); // zero Pdos mapped
|
||||
fsm->request.data_size = 1;
|
||||
ec_sdo_request_address(&fsm->request, 0x1C10 + fsm->sync->index, 0);
|
||||
ecrt_sdo_request_write(&fsm->request);
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("Setting Pdo count to zero for SM%u.\n", fsm->sync->index);
|
||||
|
||||
fsm->state = ec_fsm_pdo_mapping_state_zero_count;
|
||||
ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request);
|
||||
ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
|
||||
return;
|
||||
}
|
||||
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("Pdo mapping finished for slave %u.\n",
|
||||
fsm->slave->ring_position);
|
||||
fsm->state = ec_fsm_pdo_mapping_state_end;
|
||||
fsm->pdo = NULL;
|
||||
ec_fsm_pdo_mapping_next_pdo(fsm);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Process mapping of next Pdo.
|
||||
*/
|
||||
ec_pdo_t *ec_fsm_pdo_mapping_next_pdo(
|
||||
const ec_fsm_pdo_mapping_t *fsm, /**< mapping state machine */
|
||||
const struct list_head *list /**< current Pdo list item */
|
||||
void ec_fsm_pdo_mapping_next_pdo(
|
||||
ec_fsm_pdo_mapping_t *fsm /**< Pdo mapping state machine. */
|
||||
)
|
||||
{
|
||||
list = list->next;
|
||||
if (list == &fsm->mapping->pdos)
|
||||
return NULL; // no next Pdo
|
||||
return list_entry(list, ec_pdo_t, list);
|
||||
}
|
||||
ec_direction_t dir;
|
||||
const ec_pdo_list_t *pdos;
|
||||
const ec_pdo_t *pdo, *assigned_pdo;
|
||||
|
||||
for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++) {
|
||||
pdos = &fsm->slave->config->pdos[dir];
|
||||
|
||||
/*****************************************************************************/
|
||||
list_for_each_entry(pdo, &pdos->list, list) {
|
||||
if (fsm->pdo) { // there was a Pdo mapping changed in the last run
|
||||
if (pdo == fsm->pdo) // this is the last Pdo
|
||||
fsm->pdo = NULL; // take the next one
|
||||
} else {
|
||||
if ((assigned_pdo = ec_slave_find_pdo(fsm->slave, pdo->index)))
|
||||
if (ec_pdo_equal_entries(pdo, assigned_pdo))
|
||||
continue; // Pdo entries mapped correctly
|
||||
|
||||
/** Add a Pdo to the mapping.
|
||||
*/
|
||||
void ec_fsm_pdo_mapping_add_pdo(
|
||||
ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */
|
||||
)
|
||||
{
|
||||
EC_WRITE_U16(fsm->request.data, fsm->pdo->index);
|
||||
fsm->request.data_size = 2;
|
||||
ec_sdo_request_address(&fsm->request,
|
||||
0x1C10 + fsm->sync->index, fsm->pdo_count);
|
||||
fsm->pdo = pdo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!fsm->pdo) {
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("Pdo mapping finished for slave %u.\n",
|
||||
fsm->slave->ring_position);
|
||||
fsm->state = ec_fsm_pdo_mapping_state_end;
|
||||
return;
|
||||
}
|
||||
|
||||
// Pdo mapping has to be changed. Does the slave support this?
|
||||
if (!(fsm->slave->sii.mailbox_protocols & EC_MBOX_COE)
|
||||
|| (fsm->slave->sii.has_general
|
||||
&& !fsm->slave->sii.coe_details.enable_pdo_configuration)) {
|
||||
EC_ERR("Slave %u does not support changing the Pdo mapping!\n",
|
||||
fsm->slave->ring_position);
|
||||
fsm->state = ec_fsm_pdo_mapping_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fsm->slave->master->debug_level) {
|
||||
EC_DBG("Changing mapping of Pdo 0x%04X of slave %u.\n",
|
||||
fsm->pdo->index, fsm->slave->ring_position);
|
||||
}
|
||||
|
||||
if (ec_sdo_request_alloc(&fsm->request, 4)) {
|
||||
fsm->state = ec_fsm_pdo_mapping_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
// set mapped Pdo count to zero
|
||||
EC_WRITE_U8(fsm->request.data, 0);
|
||||
fsm->request.data_size = 1;
|
||||
ec_sdo_request_address(&fsm->request, fsm->pdo->index, 0);
|
||||
ecrt_sdo_request_write(&fsm->request);
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("Mapping Pdo 0x%04X at position %u.\n",
|
||||
fsm->pdo->index, fsm->pdo_count);
|
||||
|
||||
fsm->state = ec_fsm_pdo_mapping_state_add_pdo;
|
||||
EC_DBG("Setting entry count to zero for Pdo 0x%04X.\n",
|
||||
fsm->pdo->index);
|
||||
|
||||
fsm->state = ec_fsm_pdo_mapping_state_zero_count;
|
||||
ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request);
|
||||
ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Set the number of mapped Pdos to zero.
|
||||
/** Process next Pdo entry.
|
||||
*/
|
||||
ec_pdo_entry_t *ec_fsm_pdo_mapping_next_entry(
|
||||
const ec_fsm_pdo_mapping_t *fsm, /**< Pdo mapping state machine. */
|
||||
const struct list_head *list /**< current entry list item */
|
||||
)
|
||||
{
|
||||
list = list->next;
|
||||
if (list == &fsm->pdo->entries)
|
||||
return NULL; // no next entry
|
||||
return list_entry(list, ec_pdo_entry_t, list);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Starts to add a Pdo entry.
|
||||
*/
|
||||
void ec_fsm_pdo_mapping_add_entry(
|
||||
ec_fsm_pdo_mapping_t *fsm /**< Pdo mapping state machine. */
|
||||
)
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
value = fsm->entry->index << 16
|
||||
| fsm->entry->subindex << 8 | fsm->entry->bit_length;
|
||||
EC_WRITE_U32(fsm->request.data, value);
|
||||
fsm->request.data_size = 4;
|
||||
ec_sdo_request_address(&fsm->request, fsm->pdo->index, fsm->entry_count);
|
||||
ecrt_sdo_request_write(&fsm->request);
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("Configuring Pdo entry %08X at position %u.\n",
|
||||
value, fsm->entry_count);
|
||||
|
||||
fsm->state = ec_fsm_pdo_mapping_state_add_entry;
|
||||
ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request);
|
||||
ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Set the number of mapped entries to zero.
|
||||
*/
|
||||
void ec_fsm_pdo_mapping_state_zero_count(
|
||||
ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */
|
||||
ec_fsm_pdo_mapping_t *fsm /**< Pdo mapping state machine. */
|
||||
)
|
||||
{
|
||||
if (ec_fsm_coe_exec(fsm->fsm_coe)) return;
|
||||
@@ -275,84 +281,83 @@ void ec_fsm_pdo_mapping_state_zero_count(
|
||||
return;
|
||||
}
|
||||
|
||||
// map all Pdos belonging to the current sync manager
|
||||
|
||||
// find first Pdo
|
||||
if (!(fsm->pdo = ec_fsm_pdo_mapping_next_pdo(fsm, &fsm->mapping->pdos))) {
|
||||
// find first entry
|
||||
if (!(fsm->entry =
|
||||
ec_fsm_pdo_mapping_next_entry(fsm, &fsm->pdo->entries))) {
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("No Pdos to map for SM%u of slave %u.\n",
|
||||
fsm->sync->index, fsm->slave->ring_position);
|
||||
ec_fsm_pdo_mapping_next_dir(fsm);
|
||||
EC_DBG("No entries to map for Pdo 0x%04X of slave %u.\n",
|
||||
fsm->pdo->index, fsm->slave->ring_position);
|
||||
ec_fsm_pdo_mapping_next_pdo(fsm);
|
||||
return;
|
||||
}
|
||||
|
||||
// add first Pdo to mapping
|
||||
fsm->pdo_count = 1;
|
||||
ec_fsm_pdo_mapping_add_pdo(fsm);
|
||||
// add first entry
|
||||
fsm->entry_count = 1;
|
||||
ec_fsm_pdo_mapping_add_entry(fsm);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Add a Pdo to the sync managers mapping.
|
||||
/** Add a Pdo entry.
|
||||
*/
|
||||
void ec_fsm_pdo_mapping_state_add_pdo(
|
||||
ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */
|
||||
void ec_fsm_pdo_mapping_state_add_entry(
|
||||
ec_fsm_pdo_mapping_t *fsm /**< Pdo mapping state machine. */
|
||||
)
|
||||
{
|
||||
if (ec_fsm_coe_exec(fsm->fsm_coe)) return;
|
||||
|
||||
if (!ec_fsm_coe_success(fsm->fsm_coe)) {
|
||||
EC_ERR("Failed to map Pdo 0x%04X for SM%u of slave %u.\n",
|
||||
fsm->pdo->index, fsm->sync->index, fsm->slave->ring_position);
|
||||
EC_ERR("Failed to add entry 0x%04X:%u for slave %u.\n",
|
||||
fsm->entry->index, fsm->entry->subindex,
|
||||
fsm->slave->ring_position);
|
||||
fsm->state = ec_fsm_pdo_mapping_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
// find next Pdo
|
||||
if (!(fsm->pdo = ec_fsm_pdo_mapping_next_pdo(fsm, &fsm->pdo->list))) {
|
||||
// no more Pdos to map. write Pdo count
|
||||
EC_WRITE_U8(fsm->request.data, fsm->pdo_count);
|
||||
// find next entry
|
||||
if (!(fsm->entry = ec_fsm_pdo_mapping_next_entry(fsm, &fsm->entry->list))) {
|
||||
// No more entries to add. Write entry count.
|
||||
EC_WRITE_U8(fsm->request.data, fsm->entry_count);
|
||||
fsm->request.data_size = 1;
|
||||
ec_sdo_request_address(&fsm->request, 0x1C10 + fsm->sync->index, 0);
|
||||
ec_sdo_request_address(&fsm->request, fsm->pdo->index, 0);
|
||||
ecrt_sdo_request_write(&fsm->request);
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("Setting number of mapped Pdos to %u.\n",
|
||||
fsm->pdo_count);
|
||||
EC_DBG("Setting number of Pdo entries to %u.\n",
|
||||
fsm->entry_count);
|
||||
|
||||
fsm->state = ec_fsm_pdo_mapping_state_pdo_count;
|
||||
fsm->state = ec_fsm_pdo_mapping_state_entry_count;
|
||||
ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request);
|
||||
ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
|
||||
return;
|
||||
}
|
||||
|
||||
// add next Pdo to mapping
|
||||
fsm->pdo_count++;
|
||||
ec_fsm_pdo_mapping_add_pdo(fsm);
|
||||
// add next entry
|
||||
fsm->entry_count++;
|
||||
ec_fsm_pdo_mapping_add_entry(fsm);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Set the number of mapped Pdos.
|
||||
/** Set the number of entries.
|
||||
*/
|
||||
void ec_fsm_pdo_mapping_state_pdo_count(
|
||||
ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */
|
||||
void ec_fsm_pdo_mapping_state_entry_count(
|
||||
ec_fsm_pdo_mapping_t *fsm /**< Pdo mapping state machine. */
|
||||
)
|
||||
{
|
||||
if (ec_fsm_coe_exec(fsm->fsm_coe)) return;
|
||||
|
||||
if (!ec_fsm_coe_success(fsm->fsm_coe)) {
|
||||
EC_ERR("Failed to set number of mapped Pdos for slave %u.\n",
|
||||
EC_ERR("Failed to set number of entries for slave %u.\n",
|
||||
fsm->slave->ring_position);
|
||||
fsm->state = ec_fsm_pdo_mapping_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("Successfully set Pdo mapping for SM%u of slave %u.\n",
|
||||
fsm->sync->index, fsm->slave->ring_position);
|
||||
EC_DBG("Successfully configured mapping for Pdo 0x%04X on slave %u.\n",
|
||||
fsm->pdo->index, fsm->slave->ring_position);
|
||||
|
||||
// mapping configuration for this direction finished
|
||||
ec_fsm_pdo_mapping_next_dir(fsm);
|
||||
ec_fsm_pdo_mapping_next_pdo(fsm);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@@ -362,7 +367,7 @@ void ec_fsm_pdo_mapping_state_pdo_count(
|
||||
/** State: ERROR.
|
||||
*/
|
||||
void ec_fsm_pdo_mapping_state_error(
|
||||
ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */
|
||||
ec_fsm_pdo_mapping_t *fsm /**< Pdo mapping state machine. */
|
||||
)
|
||||
{
|
||||
}
|
||||
@@ -372,7 +377,7 @@ void ec_fsm_pdo_mapping_state_error(
|
||||
/** State: END.
|
||||
*/
|
||||
void ec_fsm_pdo_mapping_state_end(
|
||||
ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */
|
||||
ec_fsm_pdo_mapping_t *fsm /**< Pdo mapping state machine. */
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -31,19 +31,17 @@
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
\file
|
||||
EtherCAT Pdo mapping state machine structures.
|
||||
*/
|
||||
/** \file
|
||||
* EtherCAT Pdo configuration state machine structures.
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef __EC_FSM_PDO_MAPPING__
|
||||
#define __EC_FSM_PDO_MAPPING__
|
||||
|
||||
#include "../include/ecrt.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "../include/ecrt.h"
|
||||
#include "datagram.h"
|
||||
#include "fsm_coe.h"
|
||||
|
||||
@@ -54,21 +52,19 @@
|
||||
*/
|
||||
typedef struct ec_fsm_pdo_mapping ec_fsm_pdo_mapping_t;
|
||||
|
||||
/** Pdo mapping state machine.
|
||||
/** Pdo configuration state machine.
|
||||
*/
|
||||
struct ec_fsm_pdo_mapping
|
||||
{
|
||||
void (*state)(ec_fsm_pdo_mapping_t *); /**< State function. */
|
||||
ec_fsm_coe_t *fsm_coe; /**< CoE state machine to use. */
|
||||
void (*state)(ec_fsm_pdo_mapping_t *); /**< state function */
|
||||
ec_fsm_coe_t *fsm_coe; /**< CoE state machine to use */
|
||||
ec_slave_t *slave; /**< Slave the FSM runs on. */
|
||||
|
||||
ec_direction_t dir; /**< Current direction. */
|
||||
const ec_sync_t *sync; /**< Current sync manager. */
|
||||
const ec_pdo_mapping_t *mapping; /**< Target Pdo mapping. */
|
||||
const ec_pdo_t *pdo; /**< Current Pdo. */
|
||||
const ec_pdo_t *pdo; /**< Current Pdo to configure. */
|
||||
const ec_pdo_entry_t *entry; /**< Current entry. */
|
||||
|
||||
ec_sdo_request_t request; /**< Sdo request. */
|
||||
unsigned int pdo_count; /**< Number of mapped Pdos. */
|
||||
unsigned int entry_count; /**< Number of configured entries. */
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@@ -52,8 +52,8 @@ void ec_fsm_slave_config_state_clear_fmmus(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_state_mbox_sync(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_state_preop(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_state_sdo_conf(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_state_mapping(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_state_pdo_conf(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_state_pdo_assign(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_state_pdo_mapping(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_state_pdo_sync(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_state_fmmu(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_state_safeop(ec_fsm_slave_config_t *);
|
||||
@@ -62,7 +62,7 @@ void ec_fsm_slave_config_state_op(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_enter_mbox_sync(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_enter_preop(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_enter_sdo_conf(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_enter_mapping(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_enter_pdo_assign(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_safeop(ec_fsm_slave_config_t *);
|
||||
@@ -83,8 +83,8 @@ void ec_fsm_slave_config_init(ec_fsm_slave_config_t *fsm, /**< slave state machi
|
||||
// init sub state machines
|
||||
ec_fsm_change_init(&fsm->fsm_change, fsm->datagram);
|
||||
ec_fsm_coe_init(&fsm->fsm_coe, fsm->datagram);
|
||||
ec_fsm_pdo_mapping_init(&fsm->fsm_pdo_map, &fsm->fsm_coe);
|
||||
ec_fsm_pdo_config_init(&fsm->fsm_pdo_conf, &fsm->fsm_coe);
|
||||
ec_fsm_pdo_assign_init(&fsm->fsm_pdo_assign, &fsm->fsm_coe);
|
||||
ec_fsm_pdo_mapping_init(&fsm->fsm_pdo_mapping, &fsm->fsm_coe);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -96,8 +96,8 @@ void ec_fsm_slave_config_clear(ec_fsm_slave_config_t *fsm /**< slave state machi
|
||||
// clear sub state machines
|
||||
ec_fsm_change_clear(&fsm->fsm_change);
|
||||
ec_fsm_coe_clear(&fsm->fsm_coe);
|
||||
ec_fsm_pdo_mapping_clear(&fsm->fsm_pdo_map);
|
||||
ec_fsm_pdo_config_clear(&fsm->fsm_pdo_conf);
|
||||
ec_fsm_pdo_assign_clear(&fsm->fsm_pdo_assign);
|
||||
ec_fsm_pdo_mapping_clear(&fsm->fsm_pdo_mapping);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -442,7 +442,7 @@ void ec_fsm_slave_config_enter_sdo_conf(ec_fsm_slave_config_t *fsm /**< slave st
|
||||
|
||||
// No CoE configuration to be applied?
|
||||
if (list_empty(&slave->config->sdo_configs)) { // skip Sdo configuration
|
||||
ec_fsm_slave_config_enter_mapping(fsm);
|
||||
ec_fsm_slave_config_enter_pdo_assign(fsm);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -486,65 +486,65 @@ void ec_fsm_slave_config_state_sdo_conf(
|
||||
}
|
||||
|
||||
// All Sdos are now configured.
|
||||
ec_fsm_slave_config_enter_mapping(fsm);
|
||||
ec_fsm_slave_config_enter_pdo_assign(fsm);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Check for Pdo mappings to be applied.
|
||||
* Check for alternate Pdo assignments to be applied.
|
||||
*/
|
||||
|
||||
void ec_fsm_slave_config_enter_mapping(
|
||||
void ec_fsm_slave_config_enter_pdo_assign(
|
||||
ec_fsm_slave_config_t *fsm /**< slave state machine */
|
||||
)
|
||||
{
|
||||
// start configuring Pdo mapping
|
||||
fsm->state = ec_fsm_slave_config_state_mapping;
|
||||
ec_fsm_pdo_mapping_start(&fsm->fsm_pdo_map, fsm->slave);
|
||||
ec_fsm_pdo_mapping_exec(&fsm->fsm_pdo_map); // execute immediately
|
||||
// start applying alternate Pdo assignments
|
||||
fsm->state = ec_fsm_slave_config_state_pdo_assign;
|
||||
ec_fsm_pdo_assign_start(&fsm->fsm_pdo_assign, fsm->slave);
|
||||
ec_fsm_pdo_assign_exec(&fsm->fsm_pdo_assign); // execute immediately
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Slave configuration state: MAPPING.
|
||||
Slave configuration state: PDO_ASSIGN.
|
||||
*/
|
||||
|
||||
void ec_fsm_slave_config_state_mapping(
|
||||
void ec_fsm_slave_config_state_pdo_assign(
|
||||
ec_fsm_slave_config_t *fsm /**< slave state machine */
|
||||
)
|
||||
{
|
||||
if (ec_fsm_pdo_mapping_exec(&fsm->fsm_pdo_map)) return;
|
||||
if (ec_fsm_pdo_assign_exec(&fsm->fsm_pdo_assign)) return;
|
||||
|
||||
if (!ec_fsm_pdo_mapping_success(&fsm->fsm_pdo_map)) {
|
||||
EC_ERR("Pdo mapping configuration failed for slave %u.\n",
|
||||
if (!ec_fsm_pdo_assign_success(&fsm->fsm_pdo_assign)) {
|
||||
EC_ERR("Pdo assignment failed for slave %u.\n",
|
||||
fsm->slave->ring_position);
|
||||
fsm->slave->error_flag = 1;
|
||||
fsm->state = ec_fsm_slave_config_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
// Start Pdo configuration
|
||||
fsm->state = ec_fsm_slave_config_state_pdo_conf;
|
||||
ec_fsm_pdo_config_start(&fsm->fsm_pdo_conf, fsm->slave);
|
||||
ec_fsm_pdo_config_exec(&fsm->fsm_pdo_conf); // execute immediately
|
||||
// Start configuring Pdo mapping
|
||||
fsm->state = ec_fsm_slave_config_state_pdo_mapping;
|
||||
ec_fsm_pdo_mapping_start(&fsm->fsm_pdo_mapping, fsm->slave);
|
||||
ec_fsm_pdo_mapping_exec(&fsm->fsm_pdo_mapping); // execute immediately
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Slave configuration state: PDO_CONF.
|
||||
Slave configuration state: PDO_MAPPING.
|
||||
*/
|
||||
|
||||
void ec_fsm_slave_config_state_pdo_conf(
|
||||
void ec_fsm_slave_config_state_pdo_mapping(
|
||||
ec_fsm_slave_config_t *fsm /**< slave state machine */
|
||||
)
|
||||
{
|
||||
if (ec_fsm_pdo_config_exec(&fsm->fsm_pdo_conf)) return;
|
||||
if (ec_fsm_pdo_mapping_exec(&fsm->fsm_pdo_mapping)) return;
|
||||
|
||||
if (!ec_fsm_pdo_config_success(&fsm->fsm_pdo_conf)) {
|
||||
EC_ERR("Pdo configuration failed for slave %u.\n",
|
||||
if (!ec_fsm_pdo_mapping_success(&fsm->fsm_pdo_mapping)) {
|
||||
EC_ERR("Configuration of Pdo mapping failed for slave %u.\n",
|
||||
fsm->slave->ring_position);
|
||||
fsm->slave->error_flag = 1;
|
||||
fsm->state = ec_fsm_slave_config_state_error;
|
||||
@@ -592,7 +592,7 @@ void ec_fsm_slave_config_enter_pdo_sync(
|
||||
for (i = 0; i < num_syncs; i++) {
|
||||
sync = &slave->sii.syncs[i + offset];
|
||||
dir = ec_sync_direction(sync);
|
||||
size = ec_pdo_mapping_total_size(&slave->config->mapping[dir]);
|
||||
size = ec_pdo_list_total_size(&slave->config->pdos[dir]);
|
||||
ec_sync_config(sync, size, datagram->data + EC_SYNC_PAGE_SIZE * i);
|
||||
}
|
||||
|
||||
|
||||
@@ -48,8 +48,8 @@
|
||||
#include "datagram.h"
|
||||
#include "fsm_change.h"
|
||||
#include "fsm_coe.h"
|
||||
#include "fsm_pdo_assign.h"
|
||||
#include "fsm_pdo_mapping.h"
|
||||
#include "fsm_pdo_config.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@@ -68,8 +68,8 @@ struct ec_fsm_slave_config
|
||||
ec_sdo_request_t *request; /**< Sdo request for Sdo configuration. */
|
||||
ec_fsm_change_t fsm_change; /**< State change state machine. */
|
||||
ec_fsm_coe_t fsm_coe; /**< CoE state machine. */
|
||||
ec_fsm_pdo_mapping_t fsm_pdo_map; /**< Pdo mapping state machine. */
|
||||
ec_fsm_pdo_config_t fsm_pdo_conf; /**< Pdo configuration state machine. */
|
||||
ec_fsm_pdo_assign_t fsm_pdo_assign; /**< Pdo assignment state machine. */
|
||||
ec_fsm_pdo_mapping_t fsm_pdo_mapping; /**< Pdo mapping state machine. */
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@@ -50,8 +50,6 @@
|
||||
#include "fsm_change.h"
|
||||
#include "fsm_coe.h"
|
||||
#include "fsm_coe_map.h"
|
||||
#include "fsm_pdo_mapping.h"
|
||||
#include "fsm_pdo_config.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -1510,7 +1510,7 @@ ec_slave_config_t *ecrt_master_slave_config(ec_master_t *master,
|
||||
|
||||
// try to find the addressed slave
|
||||
ec_slave_config_attach(sc);
|
||||
ec_slave_config_load_default_mapping(sc);
|
||||
ec_slave_config_load_default_assignment(sc);
|
||||
|
||||
list_add_tail(&sc->list, &master->configs);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
/**
|
||||
\file
|
||||
EtherCAT Pdo mapping methods.
|
||||
EtherCAT Pdo list methods.
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -45,38 +45,37 @@
|
||||
#include "slave_config.h"
|
||||
#include "master.h"
|
||||
|
||||
#include "pdo_mapping.h"
|
||||
#include "pdo_list.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Pdo mapping constructor.
|
||||
/** Pdo list constructor.
|
||||
*/
|
||||
void ec_pdo_mapping_init(
|
||||
ec_pdo_mapping_t *pm /**< Pdo mapping. */
|
||||
void ec_pdo_list_init(
|
||||
ec_pdo_list_t *pl /**< Pdo list. */
|
||||
)
|
||||
{
|
||||
INIT_LIST_HEAD(&pm->pdos);
|
||||
pm->default_mapping = 1;
|
||||
INIT_LIST_HEAD(&pl->list);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Pdo mapping destructor.
|
||||
/** Pdo list destructor.
|
||||
*/
|
||||
void ec_pdo_mapping_clear(ec_pdo_mapping_t *pm /**< Pdo mapping. */)
|
||||
void ec_pdo_list_clear(ec_pdo_list_t *pl /**< Pdo list. */)
|
||||
{
|
||||
ec_pdo_mapping_clear_pdos(pm);
|
||||
ec_pdo_list_clear_pdos(pl);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Clears the list of mapped Pdos.
|
||||
*/
|
||||
void ec_pdo_mapping_clear_pdos(ec_pdo_mapping_t *pm /**< Pdo mapping. */)
|
||||
void ec_pdo_list_clear_pdos(ec_pdo_list_t *pl /**< Pdo list. */)
|
||||
{
|
||||
ec_pdo_t *pdo, *next;
|
||||
|
||||
list_for_each_entry_safe(pdo, next, &pm->pdos, list) {
|
||||
list_for_each_entry_safe(pdo, next, &pl->list, list) {
|
||||
list_del_init(&pdo->list);
|
||||
ec_pdo_clear(pdo);
|
||||
kfree(pdo);
|
||||
@@ -89,8 +88,8 @@ void ec_pdo_mapping_clear_pdos(ec_pdo_mapping_t *pm /**< Pdo mapping. */)
|
||||
*
|
||||
* \retval Data size in byte.
|
||||
*/
|
||||
uint16_t ec_pdo_mapping_total_size(
|
||||
const ec_pdo_mapping_t *pm /**< Pdo mapping. */
|
||||
uint16_t ec_pdo_list_total_size(
|
||||
const ec_pdo_list_t *pl /**< Pdo list. */
|
||||
)
|
||||
{
|
||||
unsigned int bit_size;
|
||||
@@ -99,7 +98,7 @@ uint16_t ec_pdo_mapping_total_size(
|
||||
uint16_t byte_size;
|
||||
|
||||
bit_size = 0;
|
||||
list_for_each_entry(pdo, &pm->pdos, list) {
|
||||
list_for_each_entry(pdo, &pl->list, list) {
|
||||
list_for_each_entry(pdo_entry, &pdo->entries, list) {
|
||||
bit_size += pdo_entry->bit_length;
|
||||
}
|
||||
@@ -115,13 +114,13 @@ uint16_t ec_pdo_mapping_total_size(
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Add a new Pdo to the mapping.
|
||||
/** Add a new Pdo to the list.
|
||||
*
|
||||
* \retval >0 Pointer to new Pdo.
|
||||
* \retval NULL No memory.
|
||||
*/
|
||||
ec_pdo_t *ec_pdo_mapping_add_pdo(
|
||||
ec_pdo_mapping_t *pm, /**< Pdo mapping. */
|
||||
ec_pdo_t *ec_pdo_list_add_pdo(
|
||||
ec_pdo_list_t *pl, /**< Pdo list. */
|
||||
ec_direction_t dir, /**< Direction. */
|
||||
uint16_t index /**< Pdo index. */
|
||||
)
|
||||
@@ -136,25 +135,25 @@ ec_pdo_t *ec_pdo_mapping_add_pdo(
|
||||
ec_pdo_init(pdo);
|
||||
pdo->dir = dir;
|
||||
pdo->index = index;
|
||||
list_add_tail(&pdo->list, &pm->pdos);
|
||||
list_add_tail(&pdo->list, &pl->list);
|
||||
return pdo;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Add the copy of an existing Pdo to the mapping.
|
||||
/** Add the copy of an existing Pdo to the list.
|
||||
*
|
||||
* \return 0 on success, else < 0
|
||||
*/
|
||||
int ec_pdo_mapping_add_pdo_copy(
|
||||
ec_pdo_mapping_t *pm, /**< Pdo mapping. */
|
||||
int ec_pdo_list_add_pdo_copy(
|
||||
ec_pdo_list_t *pl, /**< Pdo list. */
|
||||
const ec_pdo_t *pdo /**< Pdo to add. */
|
||||
)
|
||||
{
|
||||
ec_pdo_t *mapped_pdo;
|
||||
|
||||
// Pdo already mapped?
|
||||
list_for_each_entry(mapped_pdo, &pm->pdos, list) {
|
||||
list_for_each_entry(mapped_pdo, &pl->list, list) {
|
||||
if (mapped_pdo->index != pdo->index) continue;
|
||||
EC_ERR("Pdo 0x%04X is already mapped!\n", pdo->index);
|
||||
return -1;
|
||||
@@ -170,28 +169,28 @@ int ec_pdo_mapping_add_pdo_copy(
|
||||
return -1;
|
||||
}
|
||||
|
||||
list_add_tail(&mapped_pdo->list, &pm->pdos);
|
||||
list_add_tail(&mapped_pdo->list, &pl->list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Makes a deep copy of another Pdo mapping.
|
||||
/** Makes a deep copy of another Pdo list.
|
||||
*
|
||||
* \return 0 on success, else < 0
|
||||
*/
|
||||
int ec_pdo_mapping_copy(
|
||||
ec_pdo_mapping_t *pm, /**< Pdo mapping. */
|
||||
const ec_pdo_mapping_t *other /**< Pdo mapping to copy from. */
|
||||
int ec_pdo_list_copy(
|
||||
ec_pdo_list_t *pl, /**< Pdo list. */
|
||||
const ec_pdo_list_t *other /**< Pdo list to copy from. */
|
||||
)
|
||||
{
|
||||
ec_pdo_t *other_pdo;
|
||||
|
||||
ec_pdo_mapping_clear_pdos(pm);
|
||||
ec_pdo_list_clear_pdos(pl);
|
||||
|
||||
// Pdo already mapped?
|
||||
list_for_each_entry(other_pdo, &other->pdos, list) {
|
||||
if (ec_pdo_mapping_add_pdo_copy(pm, other_pdo))
|
||||
list_for_each_entry(other_pdo, &other->list, list) {
|
||||
if (ec_pdo_list_add_pdo_copy(pl, other_pdo))
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -200,24 +199,24 @@ int ec_pdo_mapping_copy(
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Compares two Pdo mappings.
|
||||
/** Compares two Pdo lists.
|
||||
*
|
||||
* Only the mapping is compared, not the Pdo entries (i. e. the Pdo
|
||||
* Only the list is compared, not the Pdo entries (i. e. the Pdo
|
||||
* configuration).
|
||||
*
|
||||
* \retval 1 The given Pdo mappings are equal.
|
||||
* \retval 0 The given Pdo mappings differ.
|
||||
* \retval 1 The given Pdo lists are equal.
|
||||
* \retval 0 The given Pdo lists differ.
|
||||
*/
|
||||
int ec_pdo_mapping_equal(
|
||||
const ec_pdo_mapping_t *pm1, /**< First mapping. */
|
||||
const ec_pdo_mapping_t *pm2 /**< Second mapping. */
|
||||
int ec_pdo_list_equal(
|
||||
const ec_pdo_list_t *pl1, /**< First list. */
|
||||
const ec_pdo_list_t *pl2 /**< Second list. */
|
||||
)
|
||||
{
|
||||
const struct list_head *h1, *h2, *l1, *l2;
|
||||
const ec_pdo_t *p1, *p2;
|
||||
|
||||
h1 = l1 = &pm1->pdos;
|
||||
h2 = l2 = &pm2->pdos;
|
||||
h1 = l1 = &pl1->list;
|
||||
h2 = l2 = &pl2->list;
|
||||
|
||||
while (1) {
|
||||
l1 = l1->next;
|
||||
@@ -242,14 +241,14 @@ int ec_pdo_mapping_equal(
|
||||
|
||||
/** Finds a Pdo with the given index.
|
||||
*/
|
||||
ec_pdo_t *ec_pdo_mapping_find_pdo(
|
||||
const ec_pdo_mapping_t *pm, /**< Pdo mapping. */
|
||||
ec_pdo_t *ec_pdo_list_find_pdo(
|
||||
const ec_pdo_list_t *pl, /**< Pdo list. */
|
||||
uint16_t index /**< Pdo index. */
|
||||
)
|
||||
{
|
||||
ec_pdo_t *pdo;
|
||||
|
||||
list_for_each_entry(pdo, &pm->pdos, list) {
|
||||
list_for_each_entry(pdo, &pl->list, list) {
|
||||
if (pdo->index != index)
|
||||
continue;
|
||||
return pdo;
|
||||
@@ -262,14 +261,14 @@ ec_pdo_t *ec_pdo_mapping_find_pdo(
|
||||
|
||||
/** Finds a Pdo with the given index and returns a const pointer.
|
||||
*/
|
||||
const ec_pdo_t *ec_pdo_mapping_find_pdo_const(
|
||||
const ec_pdo_mapping_t *pm, /**< Pdo mapping. */
|
||||
const ec_pdo_t *ec_pdo_list_find_pdo_const(
|
||||
const ec_pdo_list_t *pl, /**< Pdo list. */
|
||||
uint16_t index /**< Pdo index. */
|
||||
)
|
||||
{
|
||||
const ec_pdo_t *pdo;
|
||||
|
||||
list_for_each_entry(pdo, &pm->pdos, list) {
|
||||
list_for_each_entry(pdo, &pl->list, list) {
|
||||
if (pdo->index != index)
|
||||
continue;
|
||||
return pdo;
|
||||
@@ -33,13 +33,13 @@
|
||||
|
||||
/**
|
||||
\file
|
||||
EtherCAT Pdo mapping structure.
|
||||
EtherCAT Pdo list structure.
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef _EC_PDO_MAPPING_H_
|
||||
#define _EC_PDO_MAPPING_H_
|
||||
#ifndef _EC_PDO_LIST_H_
|
||||
#define _EC_PDO_LIST_H_
|
||||
|
||||
#include <linux/list.h>
|
||||
|
||||
@@ -50,31 +50,30 @@
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** EtherCAT Pdo mapping.
|
||||
/** EtherCAT Pdo list.
|
||||
*/
|
||||
typedef struct {
|
||||
struct list_head pdos; /**< List of Pdos. */
|
||||
unsigned int default_mapping; /**< This is the default mapping. */
|
||||
} ec_pdo_mapping_t;
|
||||
struct list_head list; /**< List of Pdos. */
|
||||
} ec_pdo_list_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void ec_pdo_mapping_init(ec_pdo_mapping_t *);
|
||||
void ec_pdo_mapping_clear(ec_pdo_mapping_t *);
|
||||
void ec_pdo_list_init(ec_pdo_list_t *);
|
||||
void ec_pdo_list_clear(ec_pdo_list_t *);
|
||||
|
||||
void ec_pdo_mapping_clear_pdos(ec_pdo_mapping_t *);
|
||||
void ec_pdo_list_clear_pdos(ec_pdo_list_t *);
|
||||
|
||||
ec_pdo_t *ec_pdo_mapping_add_pdo(ec_pdo_mapping_t *, ec_direction_t,
|
||||
ec_pdo_t *ec_pdo_list_add_pdo(ec_pdo_list_t *, ec_direction_t,
|
||||
uint16_t);
|
||||
int ec_pdo_mapping_add_pdo_copy(ec_pdo_mapping_t *, const ec_pdo_t *);
|
||||
int ec_pdo_list_add_pdo_copy(ec_pdo_list_t *, const ec_pdo_t *);
|
||||
|
||||
int ec_pdo_mapping_copy(ec_pdo_mapping_t *, const ec_pdo_mapping_t *);
|
||||
int ec_pdo_list_copy(ec_pdo_list_t *, const ec_pdo_list_t *);
|
||||
|
||||
uint16_t ec_pdo_mapping_total_size(const ec_pdo_mapping_t *);
|
||||
int ec_pdo_mapping_equal(const ec_pdo_mapping_t *, const ec_pdo_mapping_t *);
|
||||
uint16_t ec_pdo_list_total_size(const ec_pdo_list_t *);
|
||||
int ec_pdo_list_equal(const ec_pdo_list_t *, const ec_pdo_list_t *);
|
||||
|
||||
ec_pdo_t *ec_pdo_mapping_find_pdo(const ec_pdo_mapping_t *, uint16_t);
|
||||
const ec_pdo_t *ec_pdo_mapping_find_pdo_const(const ec_pdo_mapping_t *,
|
||||
ec_pdo_t *ec_pdo_list_find_pdo(const ec_pdo_list_t *, uint16_t);
|
||||
const ec_pdo_t *ec_pdo_list_find_pdo_const(const ec_pdo_list_t *,
|
||||
uint16_t);
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -615,10 +615,10 @@ int ec_slave_fetch_sii_pdos(
|
||||
}
|
||||
sync = &slave->sii.syncs[pdo->sync_index];
|
||||
|
||||
if (ec_pdo_mapping_add_pdo_copy(&sync->mapping, pdo))
|
||||
if (ec_pdo_list_add_pdo_copy(&sync->pdos, pdo))
|
||||
return -1;
|
||||
|
||||
sync->mapping_source = EC_SYNC_MAPPING_SII;
|
||||
sync->assign_source = EC_ASSIGN_SII;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -798,7 +798,7 @@ ssize_t ec_slave_info(const ec_slave_t *slave, /**< EtherCAT slave */
|
||||
}
|
||||
|
||||
if (slave->sii.sync_count) {
|
||||
buf += sprintf(buf, "Sync managers / Pdo mapping:\n");
|
||||
buf += sprintf(buf, "Sync managers / assigned Pdos:\n");
|
||||
|
||||
for (i = 0; i < slave->sii.sync_count; i++) {
|
||||
sync = &slave->sii.syncs[i];
|
||||
@@ -808,16 +808,28 @@ ssize_t ec_slave_info(const ec_slave_t *slave, /**< EtherCAT slave */
|
||||
sync->length, sync->control_register,
|
||||
sync->enable ? "enable" : "disable");
|
||||
|
||||
if (list_empty(&sync->mapping.pdos)) {
|
||||
buf += sprintf(buf, " No Pdos mapped.\n");
|
||||
} else if (sync->mapping_source != EC_SYNC_MAPPING_NONE) {
|
||||
buf += sprintf(buf,
|
||||
" Pdo mapping information from %s.\n",
|
||||
sync->mapping_source == EC_SYNC_MAPPING_SII
|
||||
? "SII" : "CoE");
|
||||
if (list_empty(&sync->pdos.list)) {
|
||||
buf += sprintf(buf, " No Pdos assigned.\n");
|
||||
} else if (sync->assign_source != EC_ASSIGN_NONE) {
|
||||
buf += sprintf(buf, " Pdo assignment from ");
|
||||
switch (sync->assign_source) {
|
||||
case EC_ASSIGN_SII:
|
||||
buf += sprintf(buf, "SII");
|
||||
break;
|
||||
case EC_ASSIGN_COE:
|
||||
buf += sprintf(buf, "CoE");
|
||||
break;
|
||||
case EC_ASSIGN_CUSTOM:
|
||||
buf += sprintf(buf, "application");
|
||||
break;
|
||||
default:
|
||||
buf += sprintf(buf, "?");
|
||||
break;
|
||||
}
|
||||
buf += sprintf(buf, ".\n");
|
||||
}
|
||||
|
||||
list_for_each_entry(pdo, &sync->mapping.pdos, list) {
|
||||
list_for_each_entry(pdo, &sync->pdos.list, list) {
|
||||
buf += sprintf(buf, " %s 0x%04X \"%s\"\n",
|
||||
pdo->dir == EC_DIR_OUTPUT ? "RxPdo" : "TxPdo",
|
||||
pdo->index, pdo->name ? pdo->name : "???");
|
||||
@@ -843,10 +855,10 @@ ssize_t ec_slave_info(const ec_slave_t *slave, /**< EtherCAT slave */
|
||||
pdo->dir == EC_DIR_OUTPUT ? "RxPdo" : "TxPdo",
|
||||
pdo->index, pdo->name ? pdo->name : "???");
|
||||
if (pdo->sync_index >= 0)
|
||||
buf += sprintf(buf, ", default mapping: SM%u.\n",
|
||||
buf += sprintf(buf, ", default assignment: SM%u.\n",
|
||||
pdo->sync_index);
|
||||
else
|
||||
buf += sprintf(buf, ", no default mapping.\n");
|
||||
buf += sprintf(buf, ", no default assignment.\n");
|
||||
|
||||
list_for_each_entry(pdo_entry, &pdo->entries, list) {
|
||||
buf += sprintf(buf, " 0x%04X:%X \"%s\", %u bit\n",
|
||||
@@ -1302,7 +1314,7 @@ const ec_pdo_t *ec_slave_find_pdo(
|
||||
for (i = 0; i < slave->sii.sync_count; i++) {
|
||||
sync = &slave->sii.syncs[i];
|
||||
|
||||
if (!(pdo = ec_pdo_mapping_find_pdo_const(&sync->mapping, index)))
|
||||
if (!(pdo = ec_pdo_list_find_pdo_const(&sync->pdos, index)))
|
||||
continue;
|
||||
|
||||
return pdo;
|
||||
|
||||
@@ -102,7 +102,7 @@ int ec_slave_config_init(ec_slave_config_t *sc, /**< Slave configuration. */
|
||||
sc->slave = NULL;
|
||||
|
||||
for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++)
|
||||
ec_pdo_mapping_init(&sc->mapping[dir]);
|
||||
ec_pdo_list_init(&sc->pdos[dir]);
|
||||
|
||||
INIT_LIST_HEAD(&sc->sdo_configs);
|
||||
INIT_LIST_HEAD(&sc->sdo_requests);
|
||||
@@ -166,7 +166,7 @@ void ec_slave_config_clear(struct kobject *kobj /**< kobject of the config. */)
|
||||
|
||||
// Free Pdo mappings
|
||||
for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++)
|
||||
ec_pdo_mapping_clear(&sc->mapping[dir]);
|
||||
ec_pdo_list_clear(&sc->pdos[dir]);
|
||||
|
||||
// free all Sdo configurations
|
||||
list_for_each_entry_safe(req, next_req, &sc->sdo_configs, list) {
|
||||
@@ -236,7 +236,7 @@ ssize_t ec_slave_config_info(
|
||||
{
|
||||
char *buf = buffer;
|
||||
ec_direction_t dir;
|
||||
const ec_pdo_mapping_t *map;
|
||||
const ec_pdo_list_t *pdos;
|
||||
const ec_pdo_t *pdo;
|
||||
const ec_pdo_entry_t *entry;
|
||||
char str[20];
|
||||
@@ -246,13 +246,13 @@ ssize_t ec_slave_config_info(
|
||||
buf += sprintf(buf, "Position: %u\n", sc->position);
|
||||
|
||||
for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++) {
|
||||
map = &sc->mapping[dir];
|
||||
pdos = &sc->pdos[dir];
|
||||
|
||||
if (!list_empty(&map->pdos)) {
|
||||
buf += sprintf(buf, "%s mapping:\n",
|
||||
if (!list_empty(&pdos->list)) {
|
||||
buf += sprintf(buf, "%s Pdo assignment / mapping:\n",
|
||||
dir == EC_DIR_OUTPUT ? "Output" : "Input");
|
||||
|
||||
list_for_each_entry(pdo, &map->pdos, list) {
|
||||
list_for_each_entry(pdo, &pdos->list, list) {
|
||||
buf += sprintf(buf, " %s 0x%04X \"%s\"\n",
|
||||
pdo->dir == EC_DIR_OUTPUT ? "RxPdo" : "TxPdo",
|
||||
pdo->index, pdo->name ? pdo->name : "???");
|
||||
@@ -429,31 +429,29 @@ void ec_slave_config_detach(
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Loads the default mapping from the slave object.
|
||||
/** Loads the default Pdo assignment from the slave object.
|
||||
*/
|
||||
void ec_slave_config_load_default_mapping(ec_slave_config_t *sc)
|
||||
void ec_slave_config_load_default_assignment(ec_slave_config_t *sc)
|
||||
{
|
||||
ec_direction_t dir;
|
||||
ec_pdo_mapping_t *map;
|
||||
ec_pdo_list_t *pdos;
|
||||
ec_sync_t *sync;
|
||||
|
||||
if (!sc->slave)
|
||||
return;
|
||||
|
||||
for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++) {
|
||||
map = &sc->mapping[dir];
|
||||
if (!(sync = ec_slave_get_pdo_sync(sc->slave, dir)))
|
||||
continue;
|
||||
ec_pdo_mapping_copy(map, &sync->mapping);
|
||||
map->default_mapping = 1;
|
||||
pdos = &sc->pdos[dir];
|
||||
if ((sync = ec_slave_get_pdo_sync(sc->slave, dir)))
|
||||
ec_pdo_list_copy(pdos, &sync->pdos);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Loads the default configuration for a Pdo from the slave object.
|
||||
/** Loads the default mapping for a Pdo from the slave object.
|
||||
*/
|
||||
void ec_slave_config_load_default_pdo_config(
|
||||
void ec_slave_config_load_default_mapping(
|
||||
const ec_slave_config_t *sc,
|
||||
ec_pdo_t *pdo
|
||||
)
|
||||
@@ -479,7 +477,7 @@ void ec_slave_config_load_default_pdo_config(
|
||||
return;
|
||||
}
|
||||
|
||||
list_for_each_entry(default_pdo, &sync->mapping.pdos, list) {
|
||||
list_for_each_entry(default_pdo, &sync->pdos.list, list) {
|
||||
if (default_pdo->index != pdo->index)
|
||||
continue;
|
||||
|
||||
@@ -508,113 +506,128 @@ void ec_slave_config_load_default_pdo_config(
|
||||
* Realtime interface
|
||||
*****************************************************************************/
|
||||
|
||||
int ecrt_slave_config_pdo(ec_slave_config_t *sc, ec_direction_t dir,
|
||||
uint16_t index)
|
||||
int ecrt_slave_config_pdo_assign_add(ec_slave_config_t *sc,
|
||||
ec_direction_t dir, uint16_t index)
|
||||
{
|
||||
ec_pdo_mapping_t *pm = &sc->mapping[dir];
|
||||
ec_pdo_list_t *pl = &sc->pdos[dir];
|
||||
ec_pdo_t *pdo;
|
||||
|
||||
if (pm->default_mapping) {
|
||||
if (sc->master->debug_level)
|
||||
EC_DBG("Clearing default mapping for dir %u, config %u:%u.\n",
|
||||
dir, sc->alias, sc->position);
|
||||
pm->default_mapping = 0;
|
||||
ec_pdo_mapping_clear_pdos(pm);
|
||||
}
|
||||
|
||||
if (sc->master->debug_level)
|
||||
EC_DBG("Adding Pdo 0x%04X to mapping for dir %u, config %u:%u.\n",
|
||||
EC_DBG("Adding Pdo 0x%04X to assignment for dir %u, config %u:%u.\n",
|
||||
index, dir, sc->alias, sc->position);
|
||||
|
||||
if (!(pdo = ec_pdo_mapping_add_pdo(pm, dir, index)))
|
||||
if (!(pdo = ec_pdo_list_add_pdo(pl, dir, index)))
|
||||
return -1;
|
||||
|
||||
ec_slave_config_load_default_pdo_config(sc, pdo);
|
||||
ec_slave_config_load_default_mapping(sc, pdo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int ecrt_slave_config_pdo_entry(ec_slave_config_t *sc, uint16_t pdo_index,
|
||||
uint16_t entry_index, uint8_t entry_subindex,
|
||||
void ecrt_slave_config_pdo_assign_clear(ec_slave_config_t *sc,
|
||||
ec_direction_t dir)
|
||||
{
|
||||
if (sc->master->debug_level)
|
||||
EC_DBG("Clearing Pdo assignment for dir %u, config %u:%u.\n",
|
||||
dir, sc->alias, sc->position);
|
||||
|
||||
ec_pdo_list_clear_pdos(&sc->pdos[dir]);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int ecrt_slave_config_pdo_mapping_add(ec_slave_config_t *sc,
|
||||
uint16_t pdo_index, uint16_t entry_index, uint8_t entry_subindex,
|
||||
uint8_t entry_bit_length)
|
||||
{
|
||||
ec_direction_t dir;
|
||||
ec_pdo_t *pdo;
|
||||
|
||||
if (sc->master->debug_level)
|
||||
EC_DBG("Adding Pdo entry 0x%04X:%u (%u bit) to configuration of Pdo"
|
||||
EC_DBG("Adding Pdo entry 0x%04X:%u (%u bit) to mapping of Pdo"
|
||||
" 0x%04X, config %u:%u.\n", entry_index, entry_subindex,
|
||||
entry_bit_length, pdo_index, sc->alias, sc->position);
|
||||
|
||||
for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++)
|
||||
if ((pdo = ec_pdo_mapping_find_pdo(&sc->mapping[dir], pdo_index)))
|
||||
if ((pdo = ec_pdo_list_find_pdo(&sc->pdos[dir], pdo_index)))
|
||||
break;
|
||||
|
||||
if (!pdo) {
|
||||
EC_ERR("Pdo 0x%04X was not found in the mapping of config %u:%u.\n",
|
||||
EC_ERR("Pdo 0x%04X is not assigned in config %u:%u.\n",
|
||||
pdo_index, sc->alias, sc->position);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pdo->default_config) {
|
||||
if (sc->master->debug_level)
|
||||
EC_DBG("Clearing default configuration of Pdo 0x%04X,"
|
||||
" config %u:%u.\n", pdo->index, sc->alias, sc->position);
|
||||
pdo->default_config = 0;
|
||||
ec_pdo_clear_entries(pdo);
|
||||
}
|
||||
|
||||
return ec_pdo_add_entry(pdo, entry_index, entry_subindex,
|
||||
entry_bit_length) ? 0 : -1;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int ecrt_slave_config_mapping(ec_slave_config_t *sc, unsigned int n_infos,
|
||||
void ecrt_slave_config_pdo_mapping_clear(ec_slave_config_t *sc,
|
||||
uint16_t pdo_index)
|
||||
{
|
||||
ec_direction_t dir;
|
||||
ec_pdo_t *pdo;
|
||||
|
||||
if (sc->master->debug_level)
|
||||
EC_DBG("Clearing mapping of Pdo 0x%04X, config %u:%u.\n",
|
||||
pdo_index, sc->alias, sc->position);
|
||||
|
||||
for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++)
|
||||
if ((pdo = ec_pdo_list_find_pdo(&sc->pdos[dir], pdo_index)))
|
||||
break;
|
||||
|
||||
if (!pdo) {
|
||||
EC_WARN("Pdo 0x%04X is not assigned in config %u:%u.\n",
|
||||
pdo_index, sc->alias, sc->position);
|
||||
return;
|
||||
}
|
||||
|
||||
ec_pdo_clear_entries(pdo);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int ecrt_slave_config_pdos(ec_slave_config_t *sc, unsigned int n_infos,
|
||||
const ec_pdo_info_t pdo_infos[])
|
||||
{
|
||||
unsigned int i, j;
|
||||
const ec_pdo_info_t *pi;
|
||||
ec_pdo_mapping_t *pm;
|
||||
ec_pdo_t *pdo;
|
||||
ec_pdo_list_t *pl;
|
||||
unsigned int cleared[] = {0, 0};
|
||||
const ec_pdo_entry_info_t *ei;
|
||||
|
||||
for (i = 0; i < n_infos; i++) {
|
||||
pi = &pdo_infos[i];
|
||||
|
||||
if (pi->dir == EC_MAP_END)
|
||||
if (pi->dir == EC_END)
|
||||
break;
|
||||
|
||||
pm = &sc->mapping[pi->dir];
|
||||
pl = &sc->pdos[pi->dir];
|
||||
|
||||
if (pm->default_mapping) {
|
||||
if (sc->master->debug_level)
|
||||
EC_DBG("Clearing default mapping for dir %u, config %u:%u.\n",
|
||||
pi->dir, sc->alias, sc->position);
|
||||
pm->default_mapping = 0;
|
||||
ec_pdo_mapping_clear_pdos(pm);
|
||||
if (!cleared[pi->dir]) {
|
||||
ecrt_slave_config_pdo_assign_clear(sc, pi->dir);
|
||||
cleared[pi->dir] = 1;
|
||||
}
|
||||
|
||||
if (sc->master->debug_level)
|
||||
EC_DBG("Adding Pdo 0x%04X to mapping for dir %u, config %u:%u.\n",
|
||||
pi->index, pi->dir, sc->alias, sc->position);
|
||||
|
||||
if (!(pdo = ec_pdo_mapping_add_pdo(pm, pi->dir, pi->index)))
|
||||
if (ecrt_slave_config_pdo_assign_add(sc, pi->dir, pi->index))
|
||||
return -1;
|
||||
|
||||
if (pi->n_entries && pi->entries) { // configuration provided
|
||||
if (pi->n_entries && pi->entries) { // mapping provided
|
||||
if (sc->master->debug_level)
|
||||
EC_DBG(" Pdo configuration information provided.\n");
|
||||
EC_DBG(" Pdo mapping information provided.\n");
|
||||
|
||||
ecrt_slave_config_pdo_mapping_clear(sc, pi->index);
|
||||
|
||||
for (j = 0; j < pi->n_entries; j++) {
|
||||
ei = &pi->entries[j];
|
||||
if (!ec_pdo_add_entry(pdo, ei->index, ei->subindex,
|
||||
ei->bit_length))
|
||||
|
||||
if (ecrt_slave_config_pdo_mapping_add(sc, pi->index,
|
||||
ei->index, ei->subindex, ei->bit_length))
|
||||
return -1;
|
||||
}
|
||||
} else { // use default Pdo configuration
|
||||
ec_slave_config_load_default_pdo_config(sc, pdo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -631,16 +644,16 @@ int ecrt_slave_config_reg_pdo_entry(
|
||||
)
|
||||
{
|
||||
ec_direction_t dir;
|
||||
ec_pdo_mapping_t *map;
|
||||
ec_pdo_list_t *pdos;
|
||||
unsigned int bit_offset, byte_offset;
|
||||
ec_pdo_t *pdo;
|
||||
ec_pdo_entry_t *entry;
|
||||
int ret;
|
||||
|
||||
for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++) {
|
||||
map = &sc->mapping[dir];
|
||||
pdos = &sc->pdos[dir];
|
||||
bit_offset = 0;
|
||||
list_for_each_entry(pdo, &map->pdos, list) {
|
||||
list_for_each_entry(pdo, &pdos->list, list) {
|
||||
list_for_each_entry(entry, &pdo->entries, list) {
|
||||
if (entry->index != index || entry->subindex != subindex) {
|
||||
bit_offset += entry->bit_length;
|
||||
@@ -726,9 +739,11 @@ ec_sdo_request_t *ecrt_slave_config_create_sdo_request(ec_slave_config_t *sc,
|
||||
|
||||
/** \cond */
|
||||
|
||||
EXPORT_SYMBOL(ecrt_slave_config_pdo);
|
||||
EXPORT_SYMBOL(ecrt_slave_config_pdo_entry);
|
||||
EXPORT_SYMBOL(ecrt_slave_config_mapping);
|
||||
EXPORT_SYMBOL(ecrt_slave_config_pdo_assign_add);
|
||||
EXPORT_SYMBOL(ecrt_slave_config_pdo_assign_clear);
|
||||
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_sdo8);
|
||||
EXPORT_SYMBOL(ecrt_slave_config_sdo16);
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
#include "globals.h"
|
||||
#include "slave.h"
|
||||
#include "fmmu_config.h"
|
||||
#include "pdo_mapping.h"
|
||||
#include "pdo_list.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@@ -69,7 +69,7 @@ struct ec_slave_config {
|
||||
ec_slave_t *slave; /**< Slave pointer. This is \a NULL, if the slave is
|
||||
offline. */
|
||||
|
||||
ec_pdo_mapping_t mapping[2]; /**< Output and input Pdo mapping. */
|
||||
ec_pdo_list_t pdos[2]; /**< Output and input Pdo assignment / mapping. */
|
||||
|
||||
struct list_head sdo_configs; /**< List of Sdo configurations. */
|
||||
struct list_head sdo_requests; /**< List of Sdo requests. */
|
||||
@@ -87,8 +87,8 @@ void ec_slave_config_destroy(ec_slave_config_t *);
|
||||
int ec_slave_config_attach(ec_slave_config_t *);
|
||||
void ec_slave_config_detach(ec_slave_config_t *);
|
||||
|
||||
void ec_slave_config_load_default_mapping(ec_slave_config_t *);
|
||||
void ec_slave_config_load_default_pdo_config(const ec_slave_config_t *,
|
||||
void ec_slave_config_load_default_assignment(ec_slave_config_t *);
|
||||
void ec_slave_config_load_default_mapping(const ec_slave_config_t *,
|
||||
ec_pdo_t *);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@@ -56,8 +56,8 @@ void ec_sync_init(
|
||||
sync->slave = slave;
|
||||
sync->index = index;
|
||||
|
||||
ec_pdo_mapping_init(&sync->mapping);
|
||||
sync->mapping_source = EC_SYNC_MAPPING_NONE;
|
||||
ec_pdo_list_init(&sync->pdos);
|
||||
sync->assign_source = EC_ASSIGN_NONE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -76,10 +76,10 @@ void ec_sync_init_copy(
|
||||
sync->control_register = other->control_register;
|
||||
sync->enable = other->enable;
|
||||
|
||||
ec_pdo_mapping_init(&sync->mapping);
|
||||
ec_pdo_mapping_copy(&sync->mapping, &other->mapping);
|
||||
ec_pdo_list_init(&sync->pdos);
|
||||
ec_pdo_list_copy(&sync->pdos, &other->pdos);
|
||||
|
||||
sync->mapping_source = other->mapping_source;
|
||||
sync->assign_source = other->assign_source;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -90,7 +90,7 @@ void ec_sync_clear(
|
||||
ec_sync_t *sync /**< EtherCAT sync manager. */
|
||||
)
|
||||
{
|
||||
ec_pdo_mapping_clear(&sync->mapping);
|
||||
ec_pdo_list_clear(&sync->pdos);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -129,7 +129,7 @@ int ec_sync_add_pdo(
|
||||
const ec_pdo_t *pdo /**< Pdo to map. */
|
||||
)
|
||||
{
|
||||
return ec_pdo_mapping_add_pdo_copy(&sync->mapping, pdo);
|
||||
return ec_pdo_list_add_pdo_copy(&sync->pdos, pdo);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@@ -45,18 +45,18 @@
|
||||
#include "../include/ecrt.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "pdo_mapping.h"
|
||||
#include "pdo_list.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** EtherCAT sync manager Pdo mapping information source.
|
||||
/** EtherCAT Pdo assignment source.
|
||||
*/
|
||||
typedef enum {
|
||||
EC_SYNC_MAPPING_NONE, /**< No Pdo mapping information. */
|
||||
EC_SYNC_MAPPING_SII, /**< Pdo mapping information from SII. */
|
||||
EC_SYNC_MAPPING_COE, /**< Pdo mapping information from CoE dictionary. */
|
||||
EC_SYNC_MAPPING_CUSTOM, /**< Pdo mapping configured externally. */
|
||||
} ec_sync_mapping_source_t;
|
||||
EC_ASSIGN_NONE, /**< No Pdos assigned. */
|
||||
EC_ASSIGN_SII, /**< Pdo assignment read from SII. */
|
||||
EC_ASSIGN_COE, /**< Pdo assignment read via CoE. */
|
||||
EC_ASSIGN_CUSTOM, /**< Pdos assignment set by application. */
|
||||
} ec_assign_source_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@@ -69,8 +69,8 @@ typedef struct {
|
||||
uint16_t length; /**< Data length in bytes. */
|
||||
uint8_t control_register; /**< Control register value. */
|
||||
uint8_t enable; /**< Enable bit. */
|
||||
ec_pdo_mapping_t mapping; /**< Current Pdo mapping. */
|
||||
ec_sync_mapping_source_t mapping_source; /**< Pdo mapping source. */
|
||||
ec_pdo_list_t pdos; /**< Current Pdo assignment. */
|
||||
ec_assign_source_t assign_source; /**< Pdo assignment source. */
|
||||
} ec_sync_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
Reference in New Issue
Block a user