diff -r 1a7067207637 -r 7bc131b92039 master/domain.c --- a/master/domain.c Fri Aug 10 15:08:44 2007 +0000 +++ b/master/domain.c Fri Aug 10 15:27:08 2007 +0000 @@ -54,7 +54,7 @@ { struct list_head list; /**< list item */ ec_slave_t *slave; /**< slave */ - const ec_sii_sync_t *sync; /**< sync manager */ + const ec_sync_t *sync; /**< sync manager */ off_t sync_offset; /**< pdo offset */ void **data_ptr; /**< pointer to process data pointer(s) */ } @@ -182,46 +182,26 @@ /*****************************************************************************/ /** - Registeres a PDO entry. - \return 0 in case of success, else < 0 -*/ - -int ec_domain_reg_pdo_entry(ec_domain_t *domain, /**< EtherCAT domain */ - ec_slave_t *slave, /**< slave */ - const ec_sii_pdo_t *pdo, /**< PDO */ - const ec_sii_pdo_entry_t *entry, - /**< PDO registration entry */ - void **data_ptr /**< pointer to the process data - pointer */ - ) + * Registers a PDO entry. + * \return 0 in case of success, else < 0 + */ + +int ec_domain_reg_pdo_entry( + ec_domain_t *domain, /**< EtherCAT domain */ + ec_sync_t *sync, /**< sync manager */ + const ec_pdo_entry_t *entry, /**< PDO entry to register */ + void **data_ptr /**< pointer to the process data pointer */ + ) { ec_data_reg_t *data_reg; - const ec_sii_sync_t *sync; - const ec_sii_pdo_t *other_pdo; - const ec_sii_pdo_entry_t *other_entry; - unsigned int bit_offset, byte_offset, sync_found; - - // Find sync manager for PDO - sync_found = 0; - list_for_each_entry(sync, &slave->sii_syncs, list) { - if (sync->index == pdo->sync_index) { - sync_found = 1; - break; - } - } - - if (!sync_found) { - EC_ERR("No sync manager for PDO 0x%04X:%i.", - pdo->index, entry->subindex); - return -1; - } + const ec_pdo_t *other_pdo; + const ec_pdo_entry_t *other_entry; + unsigned int bit_offset, byte_offset; // Calculate offset (in sync manager) for process data pointer bit_offset = 0; byte_offset = 0; - list_for_each_entry(other_pdo, &slave->sii_pdos, list) { - if (other_pdo->sync_index != sync->index) continue; - + list_for_each_entry(other_pdo, &sync->pdos, list) { list_for_each_entry(other_entry, &other_pdo->entries, list) { if (other_entry == entry) { byte_offset = bit_offset / 8; @@ -238,99 +218,18 @@ return -1; } - if (ec_slave_prepare_fmmu(slave, domain, sync)) { + if (ec_slave_prepare_fmmu(sync->slave, domain, sync)) { EC_ERR("FMMU configuration failed.\n"); kfree(data_reg); return -1; } - data_reg->slave = slave; + data_reg->slave = sync->slave; data_reg->sync = sync; data_reg->sync_offset = byte_offset; data_reg->data_ptr = data_ptr; - list_add_tail(&data_reg->list, &domain->data_regs); - ec_slave_request_state(slave, EC_SLAVE_STATE_OP); - - return 0; -} - -/*****************************************************************************/ - -/** - Registeres a PDO range. - \return 0 in case of success, else < 0 -*/ - -int ec_domain_reg_pdo_range(ec_domain_t *domain, /**< EtherCAT domain */ - ec_slave_t *slave, /**< slave */ - ec_direction_t dir, /**< data direction */ - uint16_t offset, /**< offset */ - uint16_t length, /**< length */ - void **data_ptr /**< pointer to the process data - pointer */ - ) -{ - ec_data_reg_t *data_reg; - ec_sii_sync_t *sync; - unsigned int sync_found, sync_index; - uint16_t sync_length; - - switch (dir) { - case EC_DIR_OUTPUT: sync_index = 2; break; - case EC_DIR_INPUT: sync_index = 3; break; - default: - EC_ERR("Invalid direction!\n"); - return -1; - } - - // Find sync manager - sync_found = 0; - list_for_each_entry(sync, &slave->sii_syncs, list) { - if (sync->index == sync_index) { - sync_found = 1; - break; - } - } - - if (!sync_found) { - EC_ERR("No sync manager found for PDO range.\n"); - return -1; - } - - // Allocate memory for data registration object - if (!(data_reg = - (ec_data_reg_t *) kmalloc(sizeof(ec_data_reg_t), GFP_KERNEL))) { - EC_ERR("Failed to allocate data registration.\n"); - return -1; - } - - if (ec_slave_prepare_fmmu(slave, domain, sync)) { - EC_ERR("FMMU configuration failed.\n"); - kfree(data_reg); - return -1; - } - - data_reg->slave = slave; - data_reg->sync = sync; - data_reg->sync_offset = offset; - data_reg->data_ptr = data_ptr; - - // estimate sync manager length - sync_length = offset + length; - if (sync->est_length < sync_length) { - sync->est_length = sync_length; - if (domain->master->debug_level) { - EC_DBG("Estimating length of sync manager %i of slave %i to %i.\n", - sync->index, slave->ring_position, sync_length); - } - } - - list_add_tail(&data_reg->list, &domain->data_regs); - - ec_slave_request_state(slave, EC_SLAVE_STATE_OP); - return 0; } @@ -415,7 +314,7 @@ fmmu = &slave->fmmus[j]; if (fmmu->domain == domain) { fmmu->logical_start_address = base_address + domain->data_size; - sync_size = ec_slave_calc_sync_size(slave, fmmu->sync); + sync_size = ec_sync_size(fmmu->sync); domain->data_size += sync_size; if (datagram_data_size + sync_size > EC_MAX_DATA_SIZE) { if (ec_domain_add_datagram(domain, datagram_offset, @@ -502,130 +401,134 @@ *****************************************************************************/ /** - Registers a PDO in a domain. - \return pointer to the slave on success, else NULL - \ingroup RealtimeInterface -*/ - -ec_slave_t *ecrt_domain_register_pdo(ec_domain_t *domain, - /**< EtherCAT domain */ - const char *address, - /**< ASCII address of the slave, - see ecrt_master_get_slave() */ - uint32_t vendor_id, - /**< vendor ID */ - uint32_t product_code, - /**< product code */ - uint16_t pdo_index, - /**< PDO index */ - uint8_t pdo_subindex, - /**< PDO subindex */ - void **data_ptr - /**< address of the process data - pointer */ - ) -{ + * Registers a PDO for a domain. + * \return 0 on success, else non-zero + * \ingroup RealtimeInterface + */ + +int ecrt_domain_register_pdo( + ec_domain_t *domain, /**< EtherCAT domain */ + ec_slave_t *slave, /**< EtherCAT slave */ + uint16_t pdo_entry_index, /**< PDO entry index */ + uint8_t pdo_entry_subindex, /**< PDO entry subindex */ + void **data_ptr /**< address of the process data pointer */ + ) +{ + ec_sync_t *sync; + const ec_pdo_t *pdo; + const ec_pdo_entry_t *entry; + unsigned int i; + + // search for PDO entry + for (i = 0; i < slave->sii_sync_count; i++) { + sync = &slave->sii_syncs[i]; + list_for_each_entry(pdo, &sync->pdos, list) { + list_for_each_entry(entry, &pdo->entries, list) { + if (entry->index != pdo_entry_index || + entry->subindex != pdo_entry_subindex) continue; + + // PDO entry found + if (ec_domain_reg_pdo_entry(domain, sync, entry, data_ptr)) { + return -1; + } + + return 0; + } + } + } + + EC_ERR("PDO entry 0x%04X:%u is not mapped in slave %u.\n", + pdo_entry_index, pdo_entry_subindex, slave->ring_position); + return -1; +} + +/*****************************************************************************/ + +/** + * Registers a bunch of data fields. + * \attention The list has to be terminated with a NULL structure ({})! + * \return 0 in case of success, else < 0 + * \ingroup RealtimeInterface + */ + +int ecrt_domain_register_pdo_list( + ec_domain_t *domain, /**< EtherCAT domain */ + const ec_pdo_reg_t *pdo_regs /**< array of PDO registrations */ + ) +{ + const ec_pdo_reg_t *reg; ec_slave_t *slave; - ec_master_t *master; - const ec_sii_pdo_t *pdo; - const ec_sii_pdo_entry_t *entry; - - master = domain->master; - - // translate address and validate slave - if (!(slave = ecrt_master_get_slave(master, address))) return NULL; - if (ec_slave_validate(slave, vendor_id, product_code)) return NULL; - - list_for_each_entry(pdo, &slave->sii_pdos, list) { - list_for_each_entry(entry, &pdo->entries, list) { - if (entry->index != pdo_index - || entry->subindex != pdo_subindex) continue; - - if (ec_domain_reg_pdo_entry(domain, slave, pdo, entry, data_ptr)) { - return NULL; - } - - return slave; - } - } - - EC_ERR("Slave %i does not provide PDO 0x%04X:%i.\n", - slave->ring_position, pdo_index, pdo_subindex); - return NULL; -} - -/*****************************************************************************/ - -/** - Registeres a bunch of data fields. - \attention The list has to be terminated with a NULL structure ({})! - \return 0 in case of success, else < 0 - \ingroup RealtimeInterface -*/ - -int ecrt_domain_register_pdo_list(ec_domain_t *domain, - /**< EtherCAT domain */ - const ec_pdo_reg_t *pdos - /**< array of PDO registrations */ - ) -{ - const ec_pdo_reg_t *pdo; - - for (pdo = pdos; pdo->slave_address; pdo++) - if (!ecrt_domain_register_pdo(domain, pdo->slave_address, - pdo->vendor_id, - pdo->product_code, - pdo->pdo_index, - pdo->pdo_subindex, - pdo->data_ptr)) + + for (reg = pdo_regs; reg->slave_address; reg++) { + if (!(slave = ecrt_master_get_slave(domain->master, + reg->slave_address, reg->vendor_id, + reg->product_code))) return -1; + if (ecrt_domain_register_pdo(domain, slave, reg->pdo_entry_index, + reg->pdo_entry_subindex, reg->data_ptr)) + return -1; + } + return 0; } /*****************************************************************************/ /** - Registers a PDO range in a domain. - \return pointer to the slave on success, else NULL - \ingroup RealtimeInterface -*/ - -ec_slave_t *ecrt_domain_register_pdo_range(ec_domain_t *domain, - /**< EtherCAT domain */ - const char *address, - /**< ASCII address of the slave, - see ecrt_master_get_slave() */ - uint32_t vendor_id, - /**< vendor ID */ - uint32_t product_code, - /**< product code */ - ec_direction_t direction, - /**< data direction */ - uint16_t offset, - /**< offset in slave's PDO range */ - uint16_t length, - /**< length of this range */ - void **data_ptr - /**< address of the process data - pointer */ - ) -{ - ec_slave_t *slave; - ec_master_t *master; - - master = domain->master; - - // translate address and validate slave - if (!(slave = ecrt_master_get_slave(master, address))) return NULL; - if (ec_slave_validate(slave, vendor_id, product_code)) return NULL; - - if (ec_domain_reg_pdo_range(domain, slave, - direction, offset, length, data_ptr)) { - return NULL; - } - - return slave; + * Registers a PDO range in a domain. + * \return 0 on success, else non-zero + * \ingroup RealtimeInterface + */ + +int ecrt_domain_register_pdo_range( + ec_domain_t *domain, /**< EtherCAT domain */ + ec_slave_t *slave, /**< EtherCAT slave */ + ec_direction_t dir, /**< data direction */ + uint16_t offset, /**< offset in slave's PDO range */ + uint16_t length, /**< length of this range */ + void **data_ptr /**< address of the process data pointer */ + ) +{ + ec_data_reg_t *data_reg; + ec_sync_t *sync; + uint16_t sync_length; + + if (!(sync = ec_slave_get_pdo_sync(slave, dir))) { + EC_ERR("No sync manager found for PDO range.\n"); + return -1; + } + + // Allocate memory for data registration object + if (!(data_reg = + (ec_data_reg_t *) kmalloc(sizeof(ec_data_reg_t), GFP_KERNEL))) { + EC_ERR("Failed to allocate data registration.\n"); + return -1; + } + + if (ec_slave_prepare_fmmu(slave, domain, sync)) { + EC_ERR("FMMU configuration failed.\n"); + kfree(data_reg); + return -1; + } + + data_reg->slave = slave; + data_reg->sync = sync; + data_reg->sync_offset = offset; + data_reg->data_ptr = data_ptr; + + // estimate sync manager length + sync_length = offset + length; + if (sync->est_length < sync_length) { + sync->est_length = sync_length; + if (domain->master->debug_level) { + EC_DBG("Estimating length of sync manager %i of slave %i to %i.\n", + sync->index, slave->ring_position, sync_length); + } + } + + list_add_tail(&data_reg->list, &domain->data_regs); + return 0; } /*****************************************************************************/