Added ecrt_slave_config_pdo() and ecrt_slave_config_pdo_entry().
This commit is contained in:
parent
338dbf2a27
commit
ea501996b2
11
NEWS
11
NEWS
|
|
@ -17,7 +17,7 @@ Changes in version 1.4.0:
|
|||
- Added ec_slave_config_state_t for the new method
|
||||
ecrt_slave_config_state().
|
||||
- Process data memory for a domain can now be allocated externally. This
|
||||
offers the possibility to use a shared-memory-region. Therefore,
|
||||
offers the possibility to use a shared-memory region. Therefore,
|
||||
added the domain methods ecrt_domain_size() and
|
||||
ecrt_domain_external_memory().
|
||||
- Replaced the process data pointers in the Pdo entry registration
|
||||
|
|
@ -27,10 +27,11 @@ Changes in version 1.4.0:
|
|||
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_mapping() that is now able to specify Pdo mapping and
|
||||
Pdo configuration. Pdo entries mapped in this way can now immediately be
|
||||
registered. The Pdo mapping and the configuration are described with the
|
||||
new data types ec_pdo_info_t and ec_pdo_entry_info_t.
|
||||
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.
|
||||
- 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.
|
||||
|
|
|
|||
100
include/ecrt.h
100
include/ecrt.h
|
|
@ -54,7 +54,7 @@
|
|||
* - Added ec_slave_config_state_t for the new method
|
||||
* ecrt_slave_config_state().
|
||||
* - Process data memory for a domain can now be allocated externally. This
|
||||
* offers the possibility to use a shared-memory-region. Therefore,
|
||||
* offers the possibility to use a shared-memory region. Therefore,
|
||||
* added the domain methods ecrt_domain_size() and
|
||||
* ecrt_domain_external_memory().
|
||||
* - Replaced the process data pointers in the Pdo entry registration
|
||||
|
|
@ -64,10 +64,11 @@
|
|||
* 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_mapping() that is now able to specify Pdo mapping and
|
||||
* Pdo configuration. Pdo entries mapped in this way can now immediately be
|
||||
* registered. The Pdo mapping and the configuration are described with the
|
||||
* new data types ec_pdo_info_t and ec_pdo_entry_info_t.
|
||||
* 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.
|
||||
* - 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.
|
||||
|
|
@ -370,7 +371,43 @@ void ecrt_master_state(
|
|||
* Slave configuration methods
|
||||
*****************************************************************************/
|
||||
|
||||
/** Add a Pdo to the slave's Pdo mapping for the given direction.
|
||||
*
|
||||
* The first call of this function for a given \a dir will clear the default
|
||||
* mapping.
|
||||
*
|
||||
* \see ecrt_slave_config_mapping()
|
||||
* \return zero on success, else non-zero
|
||||
*/
|
||||
int ecrt_slave_config_pdo(
|
||||
ec_slave_config_t *sc, /**< Slave configuration. */
|
||||
ec_direction_t dir, /**< Pdo direction (input/output). */
|
||||
uint16_t index /**< Index of the Pdo to map. */
|
||||
);
|
||||
|
||||
/** Add a Pdo entry to the given Pdo's configuration.
|
||||
*
|
||||
* The first call of this function for a given \a pdo_index will clear the
|
||||
* default Pdo configuration.
|
||||
*
|
||||
* \see ecrt_slave_config_mapping()
|
||||
* \return zero on success, else non-zero
|
||||
*/
|
||||
int ecrt_slave_config_pdo_entry(
|
||||
ec_slave_config_t *sc, /**< Slave configuration. */
|
||||
uint16_t pdo_index, /**< Index of the Pdo to configure. */
|
||||
uint16_t entry_index, /**< Index of the Pdo entry to add to the Pdo's
|
||||
configuration. */
|
||||
uint8_t entry_subindex, /**< Subindex of the Pdo entry to add to the
|
||||
Pdo's configuration. */
|
||||
uint8_t entry_bit_length /**< Size of the Pdo entry in bit. */
|
||||
);
|
||||
|
||||
/** Specify the Pdo mapping and (optionally) the Pdo configuration.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* The following example shows, how to specify a complete Pdo mapping
|
||||
* including the Pdo configuration. With this information, the master is able
|
||||
|
|
@ -378,26 +415,29 @@ void ecrt_master_state(
|
|||
* at configuration time:
|
||||
*
|
||||
* \code
|
||||
* const ec_pdo_info_t complete_mapping[] = {
|
||||
* {EC_DIR_INPUT, 0x1600, 2, { // channel 1
|
||||
* {0x7000, 0, 16}, // value
|
||||
* {0x7000, 1, 8}, // status
|
||||
* }},
|
||||
* {EC_DIR_INPUT, 0x1601, 2, { // channel 2
|
||||
* {0x7001, 0, 16}, // value
|
||||
* {0x7001, 1, 8}, // status
|
||||
* }}
|
||||
* const ec_pdo_entry_info_t el3162_channel1[] = {
|
||||
* {0x3101, 1, 8}, // status
|
||||
* {0x3101, 2, 16} // value
|
||||
* };
|
||||
*
|
||||
* if (ecrt_slave_config_mapping(slave_config_ana_in, 2, complete_mapping)) {
|
||||
* // error
|
||||
* }
|
||||
* const ec_pdo_entry_info_t el3162_channel2[] = {
|
||||
* {0x3102, 1, 8}, // status
|
||||
* {0x3102, 2, 16} // value
|
||||
* };
|
||||
*
|
||||
* const ec_pdo_info_t el3162_mapping[] = {
|
||||
* {EC_DIR_INPUT, 0x1A00, 2, el3162_channel1},
|
||||
* {EC_DIR_INPUT, 0x1A01, 2, el3162_channel2},
|
||||
* };
|
||||
*
|
||||
* if (ecrt_slave_config_mapping(sc, 2, el3162_mapping))
|
||||
* 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 no Pdo configuration is
|
||||
* specified and the slave is offline.
|
||||
* 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[] = {
|
||||
|
|
@ -405,9 +445,8 @@ void ecrt_master_state(
|
|||
* {EC_DIR_INPUT, 0x1601} // Channel 2
|
||||
* };
|
||||
*
|
||||
* if (ecrt_slave_config_mapping(slave_config_ana_in, 2, pdo_mapping)) {
|
||||
* // error
|
||||
* }
|
||||
* if (ecrt_slave_config_mapping(slave_config_ana_in, 2, pdo_mapping))
|
||||
* return -1; // error
|
||||
* \endcode
|
||||
*
|
||||
* \return zero on success, else non-zero
|
||||
|
|
@ -418,15 +457,18 @@ int ecrt_slave_config_mapping(
|
|||
const ec_pdo_info_t pdos[] /**< List with Pdo mapping. */
|
||||
);
|
||||
|
||||
/** Registers a Pdo entry of the given slave configuration at a domain.
|
||||
/** Registers a Pdo entry for process data exchange in a domain.
|
||||
*
|
||||
* Searches the mapping and the Pdo configurations for the given Pdo entry. If
|
||||
* found, the curresponding sync manager/FMMU is added to the domain and the
|
||||
* offset of the Pdo entry's data in the domain process data is returned.
|
||||
* Searches the current mapping and Pdo configurations 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.
|
||||
*
|
||||
* \retval >=0 Offset of the Pdo entry's process data.
|
||||
* \retval -1 Pdo entry not found.
|
||||
* \retval -2 Failed to register Pdo entry.
|
||||
* \retval >=0 Success: Offset of the Pdo entry's process data.
|
||||
* \retval -1 Error: Pdo entry not found.
|
||||
* \retval -2 Error: Failed to register Pdo entry.
|
||||
*/
|
||||
int ecrt_slave_config_reg_pdo_entry(
|
||||
ec_slave_config_t *sc, /**< Slave configuration. */
|
||||
|
|
|
|||
36
master/pdo.c
36
master/pdo.c
|
|
@ -44,10 +44,6 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
void ec_pdo_clear_entries(ec_pdo_t *);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Pdo constructor.
|
||||
*/
|
||||
void ec_pdo_init(
|
||||
|
|
@ -57,6 +53,7 @@ void ec_pdo_init(
|
|||
pdo->sync_index = -1; // not assigned
|
||||
pdo->name = NULL;
|
||||
INIT_LIST_HEAD(&pdo->entries);
|
||||
pdo->default_config = 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -70,6 +67,7 @@ int ec_pdo_init_copy(ec_pdo_t *pdo, const ec_pdo_t *other_pdo)
|
|||
pdo->sync_index = other_pdo->sync_index;
|
||||
pdo->name = NULL;
|
||||
INIT_LIST_HEAD(&pdo->entries);
|
||||
pdo->default_config = other_pdo->default_config;
|
||||
|
||||
if (ec_pdo_set_name(pdo, other_pdo->name))
|
||||
goto out_return;
|
||||
|
|
@ -89,7 +87,7 @@ out_return:
|
|||
|
||||
/** Pdo destructor.
|
||||
*/
|
||||
void ec_pdo_clear(ec_pdo_t *pdo /**< EtherCAT Pdo */)
|
||||
void ec_pdo_clear(ec_pdo_t *pdo /**< EtherCAT Pdo. */)
|
||||
{
|
||||
if (pdo->name)
|
||||
kfree(pdo->name);
|
||||
|
|
@ -101,7 +99,7 @@ void ec_pdo_clear(ec_pdo_t *pdo /**< EtherCAT Pdo */)
|
|||
|
||||
/** Clear Pdo entry list.
|
||||
*/
|
||||
void ec_pdo_clear_entries(ec_pdo_t *pdo /**< EtherCAT Pdo */)
|
||||
void ec_pdo_clear_entries(ec_pdo_t *pdo /**< EtherCAT Pdo. */)
|
||||
{
|
||||
ec_pdo_entry_t *entry, *next;
|
||||
|
||||
|
|
@ -142,6 +140,32 @@ int ec_pdo_set_name(
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Add a new Pdo entry to the configuration.
|
||||
*/
|
||||
ec_pdo_entry_t *ec_pdo_add_entry(
|
||||
ec_pdo_t *pdo,
|
||||
uint16_t index,
|
||||
uint8_t subindex,
|
||||
uint8_t bit_length
|
||||
)
|
||||
{
|
||||
ec_pdo_entry_t *entry;
|
||||
|
||||
if (!(entry = kmalloc(sizeof(ec_pdo_entry_t), GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate memory for Pdo entry.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ec_pdo_entry_init(entry);
|
||||
entry->index = index;
|
||||
entry->subindex = subindex;
|
||||
entry->bit_length = bit_length;
|
||||
list_add_tail(&entry->list, &pdo->entries);
|
||||
return entry;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Copy Pdo entries from another Pdo.
|
||||
*/
|
||||
int ec_pdo_copy_entries(ec_pdo_t *pdo, const ec_pdo_t *other)
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@ typedef struct {
|
|||
int8_t sync_index; /**< Assigned sync manager. */
|
||||
char *name; /**< Pdo name. */
|
||||
struct list_head entries; /**< List of Pdo entries. */
|
||||
unsigned int default_config; /**< The entries contain the default Pdo
|
||||
configuration. */
|
||||
} ec_pdo_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -77,7 +79,9 @@ typedef struct {
|
|||
void ec_pdo_init(ec_pdo_t *);
|
||||
int ec_pdo_init_copy(ec_pdo_t *, const ec_pdo_t *);
|
||||
void ec_pdo_clear(ec_pdo_t *);
|
||||
void ec_pdo_clear_entries(ec_pdo_t *);
|
||||
int ec_pdo_set_name(ec_pdo_t *, const char *);
|
||||
ec_pdo_entry_t *ec_pdo_add_entry(ec_pdo_t *, uint16_t, uint8_t, uint8_t);
|
||||
int ec_pdo_copy_entries(ec_pdo_t *, const ec_pdo_t *);
|
||||
int ec_pdo_equal_entries(const ec_pdo_t *, const ec_pdo_t *);
|
||||
|
||||
|
|
|
|||
|
|
@ -115,7 +115,34 @@ uint16_t ec_pdo_mapping_total_size(
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Adds a Pdo to the mapping.
|
||||
/** Add a new Pdo to the mapping.
|
||||
*
|
||||
* \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. */
|
||||
uint16_t index, /**< Pdo index. */
|
||||
ec_direction_t dir /**< Direction. */
|
||||
)
|
||||
{
|
||||
ec_pdo_t *pdo;
|
||||
|
||||
if (!(pdo = (ec_pdo_t *) kmalloc(sizeof(ec_pdo_t), GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate memory for Pdo.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ec_pdo_init(pdo);
|
||||
pdo->dir = dir;
|
||||
pdo->index = index;
|
||||
list_add_tail(&pdo->list, &pm->pdos);
|
||||
return pdo;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Add the copy of an existing Pdo to the mapping.
|
||||
*
|
||||
* \return 0 on success, else < 0
|
||||
*/
|
||||
|
|
@ -134,7 +161,7 @@ int ec_pdo_mapping_add_pdo_copy(
|
|||
}
|
||||
|
||||
if (!(mapped_pdo = kmalloc(sizeof(ec_pdo_t), GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate memory for Pdo mapping.\n");
|
||||
EC_ERR("Failed to allocate Pdo memory.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -149,111 +176,6 @@ int ec_pdo_mapping_add_pdo_copy(
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Add a Pdo to the mapping.
|
||||
*
|
||||
* The first call of this method will clear the default mapping.
|
||||
*
|
||||
* \retval 0 Success.
|
||||
* \retval -1 Error.
|
||||
*/
|
||||
int ec_pdo_mapping_add_pdo_info(
|
||||
ec_pdo_mapping_t *pm, /**< Pdo mapping. */
|
||||
const ec_pdo_info_t *pdo_info, /**< Pdo information. */
|
||||
const ec_slave_config_t *config /**< Slave configuration, to load
|
||||
default entries. */
|
||||
)
|
||||
{
|
||||
unsigned int i;
|
||||
ec_pdo_t *pdo;
|
||||
ec_pdo_entry_t *entry;
|
||||
const ec_pdo_entry_info_t *entry_info;
|
||||
|
||||
if (pm->default_mapping) {
|
||||
pm->default_mapping = 0;
|
||||
ec_pdo_mapping_clear_pdos(pm);
|
||||
}
|
||||
|
||||
if (!(pdo = (ec_pdo_t *) kmalloc(sizeof(ec_pdo_t), GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate memory for Pdo.\n");
|
||||
goto out_return;
|
||||
}
|
||||
|
||||
ec_pdo_init(pdo);
|
||||
pdo->dir = pdo_info->dir;
|
||||
pdo->index = pdo_info->index;
|
||||
|
||||
if (config->master->debug_level)
|
||||
EC_INFO("Adding Pdo 0x%04X to mapping.\n", pdo->index);
|
||||
|
||||
if (pdo_info->n_entries && pdo_info->entries) { // configuration provided
|
||||
if (config->master->debug_level)
|
||||
EC_INFO(" Pdo configuration provided.\n");
|
||||
|
||||
for (i = 0; i < pdo_info->n_entries; i++) {
|
||||
entry_info = &pdo_info->entries[i];
|
||||
|
||||
if (!(entry = kmalloc(sizeof(ec_pdo_entry_t), GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate memory for Pdo entry.\n");
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
ec_pdo_entry_init(entry);
|
||||
entry->index = entry_info->index;
|
||||
entry->subindex = entry_info->subindex;
|
||||
entry->bit_length = entry_info->bit_length;
|
||||
list_add_tail(&entry->list, &pdo->entries);
|
||||
}
|
||||
} else { // use default Pdo configuration
|
||||
if (config->master->debug_level)
|
||||
EC_INFO(" Using default Pdo configuration.\n");
|
||||
|
||||
if (config->slave) {
|
||||
ec_sync_t *sync;
|
||||
ec_pdo_t *default_pdo;
|
||||
|
||||
if ((sync = ec_slave_get_pdo_sync(config->slave, pdo->dir))) {
|
||||
list_for_each_entry(default_pdo, &sync->mapping.pdos, list) {
|
||||
if (default_pdo->index != pdo->index)
|
||||
continue;
|
||||
if (config->master->debug_level)
|
||||
EC_INFO(" Found Pdo name \"%s\".\n",
|
||||
default_pdo->name);
|
||||
// try to take Pdo name from mapped one
|
||||
if (ec_pdo_set_name(pdo, default_pdo->name))
|
||||
goto out_free;
|
||||
// copy entries (= default Pdo configuration)
|
||||
if (ec_pdo_copy_entries(pdo, default_pdo))
|
||||
goto out_free;
|
||||
if (config->master->debug_level) {
|
||||
const ec_pdo_entry_t *entry;
|
||||
list_for_each_entry(entry, &pdo->entries, list) {
|
||||
EC_INFO(" Entry 0x%04X:%u.\n",
|
||||
entry->index, entry->subindex);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
EC_WARN("Slave %u does not provide a default Pdo"
|
||||
" configuration!\n", config->slave->ring_position);
|
||||
}
|
||||
} else {
|
||||
EC_WARN("Failed to load default Pdo configuration for %u:%u:"
|
||||
" Slave not found.\n", config->alias, config->position);
|
||||
}
|
||||
}
|
||||
|
||||
list_add_tail(&pdo->list, &pm->pdos);
|
||||
return 0;
|
||||
|
||||
out_free:
|
||||
ec_pdo_clear(pdo);
|
||||
kfree(pdo);
|
||||
out_return:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Makes a deep copy of another Pdo mapping.
|
||||
*
|
||||
* \return 0 on success, else < 0
|
||||
|
|
@ -318,6 +240,26 @@ 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. */
|
||||
uint16_t index /**< Pdo index. */
|
||||
)
|
||||
{
|
||||
ec_pdo_t *pdo;
|
||||
|
||||
list_for_each_entry(pdo, &pm->pdos, list) {
|
||||
if (pdo->index != index)
|
||||
continue;
|
||||
return pdo;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Finds a Pdo with the given index and returns a const pointer.
|
||||
*/
|
||||
const ec_pdo_t *ec_pdo_mapping_find_pdo_const(
|
||||
|
|
|
|||
|
|
@ -64,15 +64,16 @@ void ec_pdo_mapping_clear(ec_pdo_mapping_t *);
|
|||
|
||||
void ec_pdo_mapping_clear_pdos(ec_pdo_mapping_t *);
|
||||
|
||||
ec_pdo_t *ec_pdo_mapping_add_pdo(ec_pdo_mapping_t *, uint16_t,
|
||||
ec_direction_t);
|
||||
int ec_pdo_mapping_add_pdo_copy(ec_pdo_mapping_t *, const ec_pdo_t *);
|
||||
int ec_pdo_mapping_add_pdo_info(ec_pdo_mapping_t *, const ec_pdo_info_t *,
|
||||
const ec_slave_config_t *);
|
||||
|
||||
int ec_pdo_mapping_copy(ec_pdo_mapping_t *, const ec_pdo_mapping_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 *);
|
||||
|
||||
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 *,
|
||||
uint16_t);
|
||||
|
||||
|
|
|
|||
|
|
@ -431,6 +431,58 @@ void ec_slave_config_load_default_mapping(ec_slave_config_t *sc)
|
|||
if (!(sync = ec_slave_get_pdo_sync(sc->slave, dir)))
|
||||
continue;
|
||||
ec_pdo_mapping_copy(map, &sync->mapping);
|
||||
map->default_mapping = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Loads the default configuration for a Pdo from the slave object.
|
||||
*/
|
||||
void ec_slave_config_load_default_pdo_config(
|
||||
const ec_slave_config_t *sc,
|
||||
ec_pdo_t *pdo
|
||||
)
|
||||
{
|
||||
const ec_sync_t *sync;
|
||||
const ec_pdo_t *default_pdo;
|
||||
|
||||
pdo->default_config = 1;
|
||||
|
||||
if (!sc->slave) {
|
||||
EC_WARN("Failed to load default Pdo configuration for %u:%u:"
|
||||
" Slave not found.\n", sc->alias, sc->position);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(sync = ec_slave_get_pdo_sync(sc->slave, pdo->dir))) {
|
||||
EC_WARN("Slave %u does not provide a default Pdo"
|
||||
" configuration!\n", sc->slave->ring_position);
|
||||
return;
|
||||
}
|
||||
|
||||
list_for_each_entry(default_pdo, &sync->mapping.pdos, list) {
|
||||
if (default_pdo->index != pdo->index)
|
||||
continue;
|
||||
|
||||
if (sc->master->debug_level)
|
||||
EC_DBG(" Found Pdo name \"%s\".\n",
|
||||
default_pdo->name);
|
||||
|
||||
// try to take Pdo name from mapped one
|
||||
ec_pdo_set_name(pdo, default_pdo->name);
|
||||
|
||||
// copy entries (= default Pdo configuration)
|
||||
if (ec_pdo_copy_entries(pdo, default_pdo))
|
||||
return;
|
||||
|
||||
if (sc->master->debug_level) {
|
||||
const ec_pdo_entry_t *entry;
|
||||
list_for_each_entry(entry, &pdo->entries, list) {
|
||||
EC_DBG(" Entry 0x%04X:%u.\n",
|
||||
entry->index, entry->subindex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -438,16 +490,89 @@ void ec_slave_config_load_default_mapping(ec_slave_config_t *sc)
|
|||
* Realtime interface
|
||||
*****************************************************************************/
|
||||
|
||||
int ecrt_slave_config_pdo(ec_slave_config_t *sc, ec_direction_t dir,
|
||||
uint16_t index)
|
||||
{
|
||||
ec_pdo_mapping_t *pm = &sc->mapping[dir];
|
||||
ec_pdo_t *pdo;
|
||||
|
||||
if (pm->default_mapping) {
|
||||
pm->default_mapping = 0;
|
||||
ec_pdo_mapping_clear_pdos(pm);
|
||||
}
|
||||
|
||||
if (!(pdo = ec_pdo_mapping_add_pdo(pm, index, dir)))
|
||||
return -1;
|
||||
|
||||
ec_slave_config_load_default_pdo_config(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,
|
||||
uint8_t entry_bit_length)
|
||||
{
|
||||
ec_direction_t dir;
|
||||
ec_pdo_t *pdo;
|
||||
|
||||
for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++)
|
||||
if ((pdo = ec_pdo_mapping_find_pdo(&sc->mapping[dir], pdo_index)))
|
||||
break;
|
||||
|
||||
if (pdo->default_config) {
|
||||
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_entries,
|
||||
const ec_pdo_info_t pdo_infos[])
|
||||
{
|
||||
unsigned int i;
|
||||
const ec_pdo_info_t *pi;
|
||||
ec_pdo_mapping_t *pm;
|
||||
ec_pdo_t *pdo;
|
||||
const ec_pdo_entry_info_t *ei;
|
||||
|
||||
for (i = 0; i < n_entries; i++)
|
||||
if (ec_pdo_mapping_add_pdo_info(&sc->mapping[pdo_infos[i].dir],
|
||||
&pdo_infos[i], sc))
|
||||
for (i = 0; i < n_entries; i++) {
|
||||
pi = &pdo_infos[i];
|
||||
pm = &sc->mapping[pi->dir];
|
||||
|
||||
if (pm->default_mapping) {
|
||||
pm->default_mapping = 0;
|
||||
ec_pdo_mapping_clear_pdos(pm);
|
||||
}
|
||||
|
||||
if (sc->master->debug_level)
|
||||
EC_INFO("Adding Pdo 0x%04X to mapping.\n", pi->index);
|
||||
|
||||
if (!(pdo = ec_pdo_mapping_add_pdo(pm, pi->dir, pi->index)))
|
||||
return -1;
|
||||
|
||||
if (pi->n_entries && pi->entries) { // configuration provided
|
||||
if (sc->master->debug_level)
|
||||
EC_DBG(" Pdo configuration information provided.\n");
|
||||
|
||||
for (i = 0; i < pi->n_entries; i++) {
|
||||
ei = &pi->entries[i];
|
||||
if (!ec_pdo_add_entry(pdo, ei->index, ei->subindex,
|
||||
ei->bit_length))
|
||||
return -1;
|
||||
}
|
||||
} else { // use default Pdo configuration
|
||||
if (sc->master->debug_level)
|
||||
EC_DBG(" Using default Pdo configuration.\n");
|
||||
ec_slave_config_load_default_pdo_config(sc, pdo);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -526,6 +651,8 @@ int ecrt_slave_config_sdo32(ec_slave_config_t *slave, uint16_t index,
|
|||
|
||||
/** \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_reg_pdo_entry);
|
||||
EXPORT_SYMBOL(ecrt_slave_config_sdo8);
|
||||
|
|
|
|||
|
|
@ -83,13 +83,12 @@ int ec_slave_config_init(ec_slave_config_t *, ec_master_t *, uint16_t,
|
|||
uint16_t, uint32_t, uint32_t);
|
||||
void ec_slave_config_destroy(ec_slave_config_t *);
|
||||
|
||||
int ec_slave_config_reg_pdo_entry(ec_slave_config_t *, ec_domain_t *,
|
||||
uint16_t, uint8_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 *,
|
||||
ec_pdo_t *);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue