master/domain.c
changeset 416 4f007cd2a79d
parent 410 3b8e94d623ab
child 446 8fede404c01f
equal deleted inserted replaced
415:0918aa9bfd0b 416:4f007cd2a79d
   186         EC_ERR("No sync manager for PDO 0x%04X:%i.",
   186         EC_ERR("No sync manager for PDO 0x%04X:%i.",
   187                pdo->index, entry->subindex);
   187                pdo->index, entry->subindex);
   188         return -1;
   188         return -1;
   189     }
   189     }
   190 
   190 
   191     // Calculate offset for process data pointer
   191     // Calculate offset (in sync manager) for process data pointer
   192     bit_offset = 0;
   192     bit_offset = 0;
   193     byte_offset = 0;
   193     byte_offset = 0;
   194     list_for_each_entry(other_pdo, &slave->sii_pdos, list) {
   194     list_for_each_entry(other_pdo, &slave->sii_pdos, list) {
   195         if (other_pdo->sync_index != sync->index) continue;
   195         if (other_pdo->sync_index != sync->index) continue;
   196 
   196 
   218 
   218 
   219     data_reg->slave = slave;
   219     data_reg->slave = slave;
   220     data_reg->sync = sync;
   220     data_reg->sync = sync;
   221     data_reg->sync_offset = byte_offset;
   221     data_reg->sync_offset = byte_offset;
   222     data_reg->data_ptr = data_ptr;
   222     data_reg->data_ptr = data_ptr;
       
   223 
       
   224     list_add_tail(&data_reg->list, &domain->data_regs);
       
   225     return 0;
       
   226 }
       
   227 
       
   228 /*****************************************************************************/
       
   229 
       
   230 /**
       
   231    Registeres a PDO range.
       
   232    \return 0 in case of success, else < 0
       
   233 */
       
   234 
       
   235 int ec_domain_reg_pdo_range(ec_domain_t *domain, /**< EtherCAT domain */
       
   236                             ec_slave_t *slave, /**< slave */
       
   237                             ec_direction_t dir, /**< data direction */
       
   238                             uint16_t offset, /**< offset */
       
   239                             uint16_t length, /**< length */
       
   240                             void **data_ptr /**< pointer to the process data
       
   241                                                pointer */
       
   242                             )
       
   243 {
       
   244     ec_data_reg_t *data_reg;
       
   245     ec_sii_sync_t *sync;
       
   246     unsigned int sync_found, sync_index;
       
   247     uint16_t sync_length;
       
   248 
       
   249     switch (dir) {
       
   250         case EC_DIR_OUTPUT: sync_index = 2; break;
       
   251         case EC_DIR_INPUT:  sync_index = 3; break;
       
   252         default:
       
   253             EC_ERR("Invalid direction!\n");
       
   254             return -1;
       
   255     }
       
   256 
       
   257     // Find sync manager
       
   258     sync_found = 0;
       
   259     list_for_each_entry(sync, &slave->sii_syncs, list) {
       
   260         if (sync->index == sync_index) {
       
   261             sync_found = 1;
       
   262             break;
       
   263         }
       
   264     }
       
   265 
       
   266     if (!sync_found) {
       
   267         EC_ERR("No sync manager found for PDO range.\n");
       
   268         return -1;
       
   269     }
       
   270 
       
   271      // Allocate memory for data registration object
       
   272     if (!(data_reg =
       
   273           (ec_data_reg_t *) kmalloc(sizeof(ec_data_reg_t), GFP_KERNEL))) {
       
   274         EC_ERR("Failed to allocate data registration.\n");
       
   275         return -1;
       
   276     }
       
   277 
       
   278     if (ec_slave_prepare_fmmu(slave, domain, sync)) {
       
   279         EC_ERR("FMMU configuration failed.\n");
       
   280         kfree(data_reg);
       
   281         return -1;
       
   282     }
       
   283 
       
   284     data_reg->slave = slave;
       
   285     data_reg->sync = sync;
       
   286     data_reg->sync_offset = offset;
       
   287     data_reg->data_ptr = data_ptr;
       
   288 
       
   289     // estimate sync manager length
       
   290     sync_length = offset + length;
       
   291     if (sync->est_length < sync_length) {
       
   292         sync->est_length = sync_length;
       
   293         if (domain->master->debug_level) {
       
   294             EC_DBG("Estimating length of sync manager %i of slave %i to %i.\n",
       
   295                    sync->index, slave->ring_position, sync_length);
       
   296         }
       
   297     }
   223 
   298 
   224     list_add_tail(&data_reg->list, &domain->data_regs);
   299     list_add_tail(&data_reg->list, &domain->data_regs);
   225     return 0;
   300     return 0;
   226 }
   301 }
   227 
   302 
   497 }
   572 }
   498 
   573 
   499 /*****************************************************************************/
   574 /*****************************************************************************/
   500 
   575 
   501 /**
   576 /**
       
   577    Registers a PDO range in a domain.
       
   578    - If \a data_ptr is NULL, the slave is only validated.
       
   579    \return pointer to the slave on success, else NULL
       
   580    \ingroup RealtimeInterface
       
   581 */
       
   582 
       
   583 ec_slave_t *ecrt_domain_register_pdo_range(ec_domain_t *domain,
       
   584                                            /**< EtherCAT domain */
       
   585                                            const char *address,
       
   586                                            /**< ASCII address of the slave,
       
   587                                               see ecrt_master_get_slave() */
       
   588                                            uint32_t vendor_id,
       
   589                                            /**< vendor ID */
       
   590                                            uint32_t product_code,
       
   591                                            /**< product code */
       
   592                                            ec_direction_t direction,
       
   593                                            /**< data direction */
       
   594                                            uint16_t offset,
       
   595                                            /**< offset in slave's PDO range */
       
   596                                            uint16_t length,
       
   597                                            /**< length of this range */
       
   598                                            void **data_ptr
       
   599                                            /**< address of the process data
       
   600                                               pointer */
       
   601                                            )
       
   602 {
       
   603     ec_slave_t *slave;
       
   604     ec_master_t *master;
       
   605 
       
   606     master = domain->master;
       
   607 
       
   608     // translate address and validate slave
       
   609     if (!(slave = ecrt_master_get_slave(master, address))) return NULL;
       
   610     if (ec_slave_validate(slave, vendor_id, product_code)) return NULL;
       
   611 
       
   612     if (!data_ptr) {
       
   613         // data_ptr is NULL => mark slave as "registered" (do not warn)
       
   614         slave->registered = 1;
       
   615         return slave;
       
   616     }
       
   617 
       
   618     if (ec_domain_reg_pdo_range(domain, slave,
       
   619                                 direction, offset, length, data_ptr)) {
       
   620         return NULL;
       
   621     }
       
   622 
       
   623     return slave;
       
   624 }
       
   625 
       
   626 /*****************************************************************************/
       
   627 
       
   628 /**
   502    Processes received process data and requeues the domain datagram(s).
   629    Processes received process data and requeues the domain datagram(s).
   503    \ingroup RealtimeInterface
   630    \ingroup RealtimeInterface
   504 */
   631 */
   505 
   632 
   506 void ecrt_domain_process(ec_domain_t *domain /**< EtherCAT domain */)
   633 void ecrt_domain_process(ec_domain_t *domain /**< EtherCAT domain */)
   559 
   686 
   560 /** \cond */
   687 /** \cond */
   561 
   688 
   562 EXPORT_SYMBOL(ecrt_domain_register_pdo);
   689 EXPORT_SYMBOL(ecrt_domain_register_pdo);
   563 EXPORT_SYMBOL(ecrt_domain_register_pdo_list);
   690 EXPORT_SYMBOL(ecrt_domain_register_pdo_list);
       
   691 EXPORT_SYMBOL(ecrt_domain_register_pdo_range);
   564 EXPORT_SYMBOL(ecrt_domain_process);
   692 EXPORT_SYMBOL(ecrt_domain_process);
   565 EXPORT_SYMBOL(ecrt_domain_state);
   693 EXPORT_SYMBOL(ecrt_domain_state);
   566 
   694 
   567 /** \endcond */
   695 /** \endcond */
   568 
   696