master/domain.c
branchstable-1.1
changeset 1715 e675450f2174
parent 294 feea8d850c65
child 1716 9440f4ff25c7
equal deleted inserted replaced
1714:f149465f4c63 1715:e675450f2174
    44 #include "domain.h"
    44 #include "domain.h"
    45 #include "master.h"
    45 #include "master.h"
    46 
    46 
    47 /*****************************************************************************/
    47 /*****************************************************************************/
    48 
    48 
    49 void ec_domain_clear_field_regs(ec_domain_t *);
    49 /**
       
    50    Data registration type.
       
    51 */
       
    52 
       
    53 typedef struct
       
    54 {
       
    55     struct list_head list; /**< list item */
       
    56     ec_slave_t *slave; /**< slave */
       
    57     const ec_sii_sync_t *sync; /**< sync manager */
       
    58     off_t sync_offset; /**< pdo offset */
       
    59     void **data_ptr; /**< pointer to process data pointer(s) */
       
    60 }
       
    61 ec_data_reg_t;
       
    62 
       
    63 /*****************************************************************************/
       
    64 
       
    65 void ec_domain_clear_data_regs(ec_domain_t *);
    50 ssize_t ec_show_domain_attribute(struct kobject *, struct attribute *, char *);
    66 ssize_t ec_show_domain_attribute(struct kobject *, struct attribute *, char *);
    51 
    67 
    52 /*****************************************************************************/
    68 /*****************************************************************************/
    53 
    69 
    54 /** \cond */
    70 /** \cond */
    55 
    71 
    56 EC_SYSFS_READ_ATTR(data_size);
    72 EC_SYSFS_READ_ATTR(image_size);
    57 
    73 
    58 static struct attribute *def_attrs[] = {
    74 static struct attribute *def_attrs[] = {
    59     &attr_data_size,
    75     &attr_image_size,
    60     NULL,
    76     NULL,
    61 };
    77 };
    62 
    78 
    63 static struct sysfs_ops sysfs_ops = {
    79 static struct sysfs_ops sysfs_ops = {
    64     .show = &ec_show_domain_attribute,
    80     .show = &ec_show_domain_attribute,
    89     domain->index = index;
   105     domain->index = index;
    90     domain->data_size = 0;
   106     domain->data_size = 0;
    91     domain->base_address = 0;
   107     domain->base_address = 0;
    92     domain->response_count = 0xFFFFFFFF;
   108     domain->response_count = 0xFFFFFFFF;
    93 
   109 
    94     INIT_LIST_HEAD(&domain->field_regs);
   110     INIT_LIST_HEAD(&domain->data_regs);
    95     INIT_LIST_HEAD(&domain->datagrams);
   111     INIT_LIST_HEAD(&domain->datagrams);
    96 
   112 
    97     // init kobject and add it to the hierarchy
   113     // init kobject and add it to the hierarchy
    98     memset(&domain->kobj, 0x00, sizeof(struct kobject));
   114     memset(&domain->kobj, 0x00, sizeof(struct kobject));
    99     kobject_init(&domain->kobj);
   115     kobject_init(&domain->kobj);
   125     list_for_each_entry_safe(datagram, next, &domain->datagrams, list) {
   141     list_for_each_entry_safe(datagram, next, &domain->datagrams, list) {
   126         ec_datagram_clear(datagram);
   142         ec_datagram_clear(datagram);
   127         kfree(datagram);
   143         kfree(datagram);
   128     }
   144     }
   129 
   145 
   130     ec_domain_clear_field_regs(domain);
   146     ec_domain_clear_data_regs(domain);
   131 
   147 
   132     kfree(domain);
   148     kfree(domain);
   133 }
   149 }
   134 
   150 
   135 /*****************************************************************************/
   151 /*****************************************************************************/
   137 /**
   153 /**
   138    Registeres a data field in a domain.
   154    Registeres a data field in a domain.
   139    \return 0 in case of success, else < 0
   155    \return 0 in case of success, else < 0
   140 */
   156 */
   141 
   157 
   142 int ec_domain_reg_field(ec_domain_t *domain, /**< EtherCAT domain */
   158 int ec_domain_reg_pdo_entry(ec_domain_t *domain, /**< EtherCAT domain */
   143                         ec_slave_t *slave, /**< slave */
   159                             ec_slave_t *slave, /**< slave */
   144                         const ec_sync_t *sync, /**< sync manager */
   160                             const ec_sii_pdo_t *pdo,
   145                         uint32_t field_offset, /**< data field offset */
   161                             const ec_sii_pdo_entry_t *entry,
   146                         void **data_ptr /**< pointer to the process data
   162                             /**< PDO registration entry */
   147                                            pointer */
   163                             void **data_ptr /**< pointer to the process data
   148                         )
   164                                                pointer */
   149 {
   165                             )
   150     ec_field_reg_t *field_reg;
   166 {
   151 
   167     ec_data_reg_t *data_reg;
   152     if (!(field_reg =
   168     const ec_sii_sync_t *sync;
   153           (ec_field_reg_t *) kmalloc(sizeof(ec_field_reg_t), GFP_KERNEL))) {
   169     const ec_sii_pdo_t *other_pdo;
   154         EC_ERR("Failed to allocate field registration.\n");
   170     const ec_sii_pdo_entry_t *other_entry;
       
   171     unsigned int bit_offset, byte_offset, sync_found;
       
   172 
       
   173     // Find sync manager for PDO
       
   174     sync_found = 0;
       
   175     list_for_each_entry(sync, &slave->sii_syncs, list) {
       
   176         if (sync->index == pdo->sync_index) {
       
   177             sync_found = 1;
       
   178             break;
       
   179         }
       
   180     }
       
   181 
       
   182     if (!sync_found) {
       
   183         EC_ERR("No sync manager for PDO 0x%04X:%i.",
       
   184                pdo->index, entry->subindex);
       
   185         return -1;
       
   186     }
       
   187 
       
   188     // Calculate offset for process data pointer
       
   189     bit_offset = 0;
       
   190     byte_offset = 0;
       
   191     list_for_each_entry(other_pdo, &slave->sii_pdos, list) {
       
   192         if (other_pdo->sync_index != sync->index) continue;
       
   193 
       
   194         list_for_each_entry(other_entry, &pdo->entries, list) {
       
   195             if (other_entry == entry) {
       
   196                 byte_offset = bit_offset / 8;
       
   197                 break;
       
   198             }
       
   199             bit_offset += other_entry->bit_length;
       
   200         }
       
   201     }
       
   202 
       
   203     // Allocate memory for data registration object
       
   204     if (!(data_reg =
       
   205           (ec_data_reg_t *) kmalloc(sizeof(ec_data_reg_t), GFP_KERNEL))) {
       
   206         EC_ERR("Failed to allocate data registration.\n");
   155         return -1;
   207         return -1;
   156     }
   208     }
   157 
   209 
   158     if (ec_slave_prepare_fmmu(slave, domain, sync)) {
   210     if (ec_slave_prepare_fmmu(slave, domain, sync)) {
   159         EC_ERR("FMMU configuration failed.\n");
   211         EC_ERR("FMMU configuration failed.\n");
   160         kfree(field_reg);
   212         kfree(data_reg);
   161         return -1;
   213         return -1;
   162     }
   214     }
   163 
   215 
   164     field_reg->slave = slave;
   216     data_reg->slave = slave;
   165     field_reg->sync = sync;
   217     data_reg->sync = sync;
   166     field_reg->field_offset = field_offset;
   218     data_reg->sync_offset = byte_offset;
   167     field_reg->data_ptr = data_ptr;
   219     data_reg->data_ptr = data_ptr;
   168 
   220 
   169     list_add_tail(&field_reg->list, &domain->field_regs);
   221     list_add_tail(&data_reg->list, &domain->data_regs);
   170     return 0;
   222     return 0;
   171 }
   223 }
   172 
   224 
   173 /*****************************************************************************/
   225 /*****************************************************************************/
   174 
   226 
   175 /**
   227 /**
   176    Clears the list of the registered data fields.
   228    Clears the list of the registered data fields.
   177 */
   229 */
   178 
   230 
   179 void ec_domain_clear_field_regs(ec_domain_t *domain /**< EtherCAT domain */)
   231 void ec_domain_clear_data_regs(ec_domain_t *domain /**< EtherCAT domain */)
   180 {
   232 {
   181     ec_field_reg_t *field_reg, *next;
   233     ec_data_reg_t *data_reg, *next;
   182 
   234 
   183     list_for_each_entry_safe(field_reg, next, &domain->field_regs, list) {
   235     list_for_each_entry_safe(data_reg, next, &domain->data_regs, list) {
   184         list_del(&field_reg->list);
   236         list_del(&data_reg->list);
   185         kfree(field_reg);
   237         kfree(data_reg);
   186     }
   238     }
   187 }
   239 }
   188 
   240 
   189 /*****************************************************************************/
   241 /*****************************************************************************/
   190 
   242 
   220 
   272 
   221 /**
   273 /**
   222    Creates a domain.
   274    Creates a domain.
   223    Reserves domain memory, calculates the logical addresses of the
   275    Reserves domain memory, calculates the logical addresses of the
   224    corresponding FMMUs and sets the process data pointer of the registered
   276    corresponding FMMUs and sets the process data pointer of the registered
   225    data fields.
   277    process data.
   226    \return 0 in case of success, else < 0
   278    \return 0 in case of success, else < 0
   227 */
   279 */
   228 
   280 
   229 int ec_domain_alloc(ec_domain_t *domain, /**< EtherCAT domain */
   281 int ec_domain_alloc(ec_domain_t *domain, /**< EtherCAT domain */
   230                     uint32_t base_address /**< logical base address */
   282                     uint32_t base_address /**< logical base address */
   231                     )
   283                     )
   232 {
   284 {
   233     ec_field_reg_t *field_reg;
   285     ec_data_reg_t *data_reg;
   234     ec_slave_t *slave;
   286     ec_slave_t *slave;
   235     ec_fmmu_t *fmmu;
   287     ec_fmmu_t *fmmu;
   236     unsigned int i, j, cmd_count;
   288     unsigned int i, j, datagram_count;
   237     uint32_t field_off, field_off_cmd;
   289     uint32_t pdo_off, pdo_off_datagram;
   238     uint32_t cmd_offset;
   290     uint32_t datagram_offset;
   239     size_t cmd_data_size, sync_size;
   291     size_t datagram_data_size, sync_size;
   240     ec_datagram_t *datagram;
   292     ec_datagram_t *datagram;
   241 
   293 
   242     domain->base_address = base_address;
   294     domain->base_address = base_address;
   243 
   295 
   244     // calculate size of process data and allocate memory
   296     // calculate size of process data and allocate memory
   245     domain->data_size = 0;
   297     domain->data_size = 0;
   246     cmd_offset = base_address;
   298     datagram_offset = base_address;
   247     cmd_data_size = 0;
   299     datagram_data_size = 0;
   248     cmd_count = 0;
   300     datagram_count = 0;
   249     list_for_each_entry(slave, &domain->master->slaves, list) {
   301     list_for_each_entry(slave, &domain->master->slaves, list) {
   250         for (j = 0; j < slave->fmmu_count; j++) {
   302         for (j = 0; j < slave->fmmu_count; j++) {
   251             fmmu = &slave->fmmus[j];
   303             fmmu = &slave->fmmus[j];
   252             if (fmmu->domain == domain) {
   304             if (fmmu->domain == domain) {
   253                 fmmu->logical_start_address = base_address + domain->data_size;
   305                 fmmu->logical_start_address = base_address + domain->data_size;
   254                 sync_size = ec_slave_calc_sync_size(slave, fmmu->sync);
   306                 sync_size = ec_slave_calc_sync_size(slave, fmmu->sync);
   255                 domain->data_size += sync_size;
   307                 domain->data_size += sync_size;
   256                 if (cmd_data_size + sync_size > EC_MAX_DATA_SIZE) {
   308                 if (datagram_data_size + sync_size > EC_MAX_DATA_SIZE) {
   257                     if (ec_domain_add_datagram(domain, cmd_offset,
   309                     if (ec_domain_add_datagram(domain, datagram_offset,
   258                                                cmd_data_size)) return -1;
   310                                                datagram_data_size)) return -1;
   259                     cmd_offset += cmd_data_size;
   311                     datagram_offset += datagram_data_size;
   260                     cmd_data_size = 0;
   312                     datagram_data_size = 0;
   261                     cmd_count++;
   313                     datagram_count++;
   262                 }
   314                 }
   263                 cmd_data_size += sync_size;
   315                 datagram_data_size += sync_size;
   264             }
   316             }
   265         }
   317         }
   266     }
   318     }
   267 
   319 
   268     // allocate last datagram
   320     // allocate last datagram
   269     if (cmd_data_size) {
   321     if (datagram_data_size) {
   270         if (ec_domain_add_datagram(domain, cmd_offset, cmd_data_size))
   322         if (ec_domain_add_datagram(domain, datagram_offset,
       
   323                                    datagram_data_size))
   271             return -1;
   324             return -1;
   272         cmd_count++;
   325         datagram_count++;
   273     }
   326     }
   274 
   327 
   275     if (!cmd_count) {
   328     if (!datagram_count) {
   276         EC_WARN("Domain %i contains no data!\n", domain->index);
   329         EC_WARN("Domain %i contains no data!\n", domain->index);
   277         ec_domain_clear_field_regs(domain);
   330         ec_domain_clear_data_regs(domain);
   278         return 0;
   331         return 0;
   279     }
   332     }
   280 
   333 
   281     // set all process data pointers
   334     // set all process data pointers
   282     list_for_each_entry(field_reg, &domain->field_regs, list) {
   335     list_for_each_entry(data_reg, &domain->data_regs, list) {
   283         for (i = 0; i < field_reg->slave->fmmu_count; i++) {
   336         for (i = 0; i < data_reg->slave->fmmu_count; i++) {
   284             fmmu = &field_reg->slave->fmmus[i];
   337             fmmu = &data_reg->slave->fmmus[i];
   285             if (fmmu->domain == domain && fmmu->sync == field_reg->sync) {
   338             if (fmmu->domain == domain && fmmu->sync == data_reg->sync) {
   286                 field_off = fmmu->logical_start_address +
   339                 pdo_off = fmmu->logical_start_address + data_reg->sync_offset;
   287                     field_reg->field_offset;
       
   288                 // search datagram
   340                 // search datagram
   289                 list_for_each_entry(datagram, &domain->datagrams, list) {
   341                 list_for_each_entry(datagram, &domain->datagrams, list) {
   290                     field_off_cmd = field_off - datagram->address.logical;
   342                     pdo_off_datagram = pdo_off - datagram->address.logical;
   291                     if (field_off >= datagram->address.logical &&
   343                     if (pdo_off >= datagram->address.logical &&
   292                         field_off_cmd < datagram->mem_size) {
   344                         pdo_off_datagram < datagram->mem_size) {
   293                         *field_reg->data_ptr = datagram->data + field_off_cmd;
   345                         *data_reg->data_ptr = datagram->data +
       
   346                             pdo_off_datagram;
   294                     }
   347                     }
   295                 }
   348                 }
   296                 if (!field_reg->data_ptr) {
   349                 if (!data_reg->data_ptr) {
   297                     EC_ERR("Failed to assign data pointer!\n");
   350                     EC_ERR("Failed to assign data pointer!\n");
   298                     return -1;
   351                     return -1;
   299                 }
   352                 }
   300                 break;
   353                 break;
   301             }
   354             }
   302         }
   355         }
   303     }
   356     }
   304 
   357 
   305     EC_INFO("Domain %i - Allocated %i bytes in %i datagram%s\n",
   358     EC_INFO("Domain %i - Allocated %i bytes in %i datagram%s\n",
   306             domain->index, domain->data_size, cmd_count,
   359             domain->index, domain->data_size, datagram_count,
   307             cmd_count == 1 ? "" : "s");
   360             datagram_count == 1 ? "" : "s");
   308 
   361 
   309     ec_domain_clear_field_regs(domain);
   362     ec_domain_clear_data_regs(domain);
   310 
   363 
   311     return 0;
   364     return 0;
   312 }
   365 }
   313 
   366 
   314 /*****************************************************************************/
   367 /*****************************************************************************/
   315 
   368 
   316 /**
   369 /**
   317    Sets the number of responding slaves and outputs it on demand.
   370    Places all process data datagrams in the masters datagram queue.
   318    This number isn't really the number of responding slaves, but the sum of
   371 */
   319    the working counters of all domain datagrams. Some slaves increase the
   372 
   320    working counter by 2, some by 1.
   373 void ec_domain_queue(ec_domain_t *domain /**< EtherCAT domain */)
   321 */
   374 {
   322 
   375     ec_datagram_t *datagram;
   323 void ec_domain_response_count(ec_domain_t *domain, /**< EtherCAT domain */
   376 
   324                               unsigned int count /**< new WC sum */
   377     list_for_each_entry(datagram, &domain->datagrams, list) {
   325                               )
   378         ec_master_queue_datagram(domain->master, datagram);
   326 {
       
   327     if (count != domain->response_count) {
       
   328         domain->response_count = count;
       
   329         EC_INFO("Domain %i working counter change: %i\n", domain->index,
       
   330                 count);
       
   331     }
   379     }
   332 }
   380 }
   333 
   381 
   334 /*****************************************************************************/
   382 /*****************************************************************************/
   335 
   383 
   343                                  char *buffer /**< memory to store data in */
   391                                  char *buffer /**< memory to store data in */
   344                                  )
   392                                  )
   345 {
   393 {
   346     ec_domain_t *domain = container_of(kobj, ec_domain_t, kobj);
   394     ec_domain_t *domain = container_of(kobj, ec_domain_t, kobj);
   347 
   395 
   348     if (attr == &attr_data_size) {
   396     if (attr == &attr_image_size) {
   349         return sprintf(buffer, "%i\n", domain->data_size);
   397         return sprintf(buffer, "%i\n", domain->data_size);
   350     }
   398     }
   351 
   399 
   352     return 0;
   400     return 0;
   353 }
   401 }
   355 /******************************************************************************
   403 /******************************************************************************
   356  *  Realtime interface
   404  *  Realtime interface
   357  *****************************************************************************/
   405  *****************************************************************************/
   358 
   406 
   359 /**
   407 /**
   360    Registers a data field in a domain.
   408    Registers a PDO in a domain.
   361    - If \a data_ptr is NULL, the slave is only checked against its type.
   409    - If \a data_ptr is NULL, the slave is only validated.
   362    - If \a field_count is 0, it is assumed that one data field is to be
       
   363    registered.
       
   364    - If \a field_count is greater then 1, it is assumed that \a data_ptr
       
   365    is an array of the respective size.
       
   366    \return pointer to the slave on success, else NULL
   410    \return pointer to the slave on success, else NULL
   367    \ingroup RealtimeInterface
   411    \ingroup RealtimeInterface
   368 */
   412 */
   369 
   413 
   370 ec_slave_t *ecrt_domain_register_field(ec_domain_t *domain,
   414 ec_slave_t *ecrt_domain_register_pdo(ec_domain_t *domain,
   371                                        /**< EtherCAT domain */
   415                                      /**< EtherCAT domain */
   372                                        const char *address,
   416                                      const char *address,
   373                                        /**< ASCII address of the slave,
   417                                      /**< ASCII address of the slave,
   374                                           see ecrt_master_get_slave() */
   418                                         see ecrt_master_get_slave() */
   375                                        const char *vendor_name,
   419                                      uint32_t vendor_id,
   376                                        /**< vendor name */
   420                                      /**< vendor ID */
   377                                        const char *product_name,
   421                                      uint32_t product_code,
   378                                        /**< product name */
   422                                      /**< product code */
   379                                        void **data_ptr,
   423                                      uint16_t pdo_index,
   380                                        /**< address of the process data
   424                                      /**< PDO index */
   381                                           pointer */
   425                                      uint8_t pdo_subindex,
   382                                        const char *field_name,
   426                                      /**< PDO subindex */
   383                                        /**< data field name */
   427                                      void **data_ptr
   384                                        unsigned int field_index,
   428                                      /**< address of the process data
   385                                        /**< offset of data fields with
   429                                         pointer */
   386                                           \a field_type  */
   430                                      )
   387                                        unsigned int field_count
       
   388                                        /**< number of data fields (with
       
   389                                           the same type) to register */
       
   390                                        )
       
   391 {
   431 {
   392     ec_slave_t *slave;
   432     ec_slave_t *slave;
   393     const ec_slave_type_t *type;
       
   394     ec_master_t *master;
   433     ec_master_t *master;
   395     const ec_sync_t *sync;
   434     const ec_sii_pdo_t *pdo;
   396     const ec_field_t *field;
   435     const ec_sii_pdo_entry_t *entry;
   397     unsigned int field_counter, i, j, orig_field_index, orig_field_count;
       
   398     uint32_t field_offset;
       
   399 
   436 
   400     master = domain->master;
   437     master = domain->master;
   401 
   438 
   402     // translate address
   439     // translate address
   403     if (!(slave = ecrt_master_get_slave(master, address))) return NULL;
   440     if (!(slave = ecrt_master_get_slave(master, address))) return NULL;
   404 
   441 
   405     if (!(type = slave->type)) {
   442     if (vendor_id != slave->sii_vendor_id ||
   406         EC_ERR("Slave \"%s\" (position %i) has unknown type!\n", address,
   443         product_code != slave->sii_product_code) {
   407                slave->ring_position);
   444         EC_ERR("Invalid slave type at position %i - Requested: 0x%08X 0x%08X,"
   408         return NULL;
   445                " found: 0x%08X 0x%08X\".\n", slave->ring_position, vendor_id,
   409     }
   446                product_code, slave->sii_vendor_id, slave->sii_product_code);
   410 
       
   411     if (strcmp(vendor_name, type->vendor_name) ||
       
   412         strcmp(product_name, type->product_name)) {
       
   413         EC_ERR("Invalid slave type at position %i - Requested: \"%s %s\","
       
   414                " found: \"%s %s\".\n", slave->ring_position, vendor_name,
       
   415                product_name, type->vendor_name, type->product_name);
       
   416         return NULL;
   447         return NULL;
   417     }
   448     }
   418 
   449 
   419     if (!data_ptr) {
   450     if (!data_ptr) {
   420         // data_ptr is NULL => mark slave as "registered" (do not warn)
   451         // data_ptr is NULL => mark slave as "registered" (do not warn)
   421         slave->registered = 1;
   452         slave->registered = 1;
   422     }
   453     }
   423 
   454 
   424     if (!field_count) field_count = 1;
   455     list_for_each_entry(pdo, &slave->sii_pdos, list) {
   425     orig_field_index = field_index;
   456         list_for_each_entry(entry, &pdo->entries, list) {
   426     orig_field_count = field_count;
   457             if (entry->index != pdo_index
   427 
   458                 || entry->subindex != pdo_subindex) continue;
   428     field_counter = 0;
   459 
   429     for (i = 0; type->sync_managers[i]; i++) {
   460             if (data_ptr) {
   430         sync = type->sync_managers[i];
   461                 ec_domain_reg_pdo_entry(domain, slave, pdo, entry, data_ptr);
   431         field_offset = 0;
       
   432         for (j = 0; sync->fields[j]; j++) {
       
   433             field = sync->fields[j];
       
   434             if (!strcmp(field->name, field_name)) {
       
   435                 if (field_counter++ == field_index) {
       
   436                     if (data_ptr)
       
   437                         ec_domain_reg_field(domain, slave, sync, field_offset,
       
   438                                             data_ptr++);
       
   439                     if (!(--field_count)) return slave;
       
   440                     field_index++;
       
   441                 }
       
   442             }
   462             }
   443             field_offset += field->size;
   463 
       
   464             return slave;
   444         }
   465         }
   445     }
   466     }
   446 
   467 
   447     EC_ERR("Slave %i (\"%s %s\") registration mismatch: Field \"%s\","
   468     EC_ERR("Slave %i does not provide PDO 0x%04X:%i.\n",
   448            " index %i, count %i.\n", slave->ring_position, vendor_name,
   469            slave->ring_position, pdo_index, pdo_subindex);
   449            product_name, field_name, orig_field_index, orig_field_count);
   470     slave->registered = 0;
   450     return NULL;
   471     return NULL;
   451 }
   472 }
   452 
   473 
   453 /*****************************************************************************/
   474 /*****************************************************************************/
   454 
   475 
   457    Caution! The list has to be terminated with a NULL structure ({})!
   478    Caution! The list has to be terminated with a NULL structure ({})!
   458    \return 0 in case of success, else < 0
   479    \return 0 in case of success, else < 0
   459    \ingroup RealtimeInterface
   480    \ingroup RealtimeInterface
   460 */
   481 */
   461 
   482 
   462 int ecrt_domain_register_field_list(ec_domain_t *domain,
   483 int ecrt_domain_register_pdo_list(ec_domain_t *domain,
   463                                     /**< EtherCAT domain */
   484                                   /**< EtherCAT domain */
   464                                     const ec_field_init_t *fields
   485                                   const ec_pdo_reg_t *pdos
   465                                     /**< array of data field registrations */
   486                                   /**< array of PDO registrations */
   466                                     )
   487                                   )
   467 {
   488 {
   468     const ec_field_init_t *field;
   489     const ec_pdo_reg_t *pdo;
   469 
   490 
   470     for (field = fields; field->slave_address; field++)
   491     for (pdo = pdos; pdo->slave_address; pdo++)
   471         if (!ecrt_domain_register_field(domain, field->slave_address,
   492         if (!ecrt_domain_register_pdo(domain, pdo->slave_address,
   472                                         field->vendor_name,
   493                                       pdo->vendor_id,
   473                                         field->product_name, field->data_ptr,
   494                                       pdo->product_code,
   474                                         field->field_name, field->field_index,
   495                                       pdo->pdo_index,
   475                                         field->field_count))
   496                                       pdo->pdo_subindex,
       
   497                                       pdo->data_ptr))
   476             return -1;
   498             return -1;
   477 
   499 
   478     return 0;
   500     return 0;
   479 }
   501 }
   480 
   502 
   481 /*****************************************************************************/
   503 /*****************************************************************************/
   482 
   504 
   483 /**
   505 /**
   484    Places all process data datagrams in the masters datagram queue.
   506    Processes received process data and requeues the domain datagram(s).
   485    \ingroup RealtimeInterface
       
   486 */
       
   487 
       
   488 void ecrt_domain_queue(ec_domain_t *domain /**< EtherCAT domain */)
       
   489 {
       
   490     ec_datagram_t *datagram;
       
   491 
       
   492     list_for_each_entry(datagram, &domain->datagrams, list) {
       
   493         ec_master_queue_datagram(domain->master, datagram);
       
   494     }
       
   495 }
       
   496 
       
   497 /*****************************************************************************/
       
   498 
       
   499 /**
       
   500    Processes received process data.
       
   501    \ingroup RealtimeInterface
   507    \ingroup RealtimeInterface
   502 */
   508 */
   503 
   509 
   504 void ecrt_domain_process(ec_domain_t *domain /**< EtherCAT domain */)
   510 void ecrt_domain_process(ec_domain_t *domain /**< EtherCAT domain */)
   505 {
   511 {
   506     unsigned int working_counter_sum;
   512     unsigned int working_counter_sum;
   507     ec_datagram_t *datagram;
   513     ec_datagram_t *datagram;
   508 
   514 
   509     working_counter_sum = 0;
   515     working_counter_sum = 0;
   510 
       
   511     list_for_each_entry(datagram, &domain->datagrams, list) {
   516     list_for_each_entry(datagram, &domain->datagrams, list) {
   512         if (datagram->state == EC_CMD_RECEIVED) {
   517         if (datagram->state == EC_DATAGRAM_RECEIVED) {
   513             working_counter_sum += datagram->working_counter;
   518             working_counter_sum += datagram->working_counter;
   514         }
   519         }
   515     }
   520     }
   516 
   521 
   517     ec_domain_response_count(domain, working_counter_sum);
   522     if (working_counter_sum != domain->response_count) {
       
   523         domain->response_count = working_counter_sum;
       
   524         EC_INFO("Domain %i working counter change: %i\n", domain->index,
       
   525                 domain->response_count);
       
   526     }
       
   527 
       
   528     ec_domain_queue(domain);
   518 }
   529 }
   519 
   530 
   520 /*****************************************************************************/
   531 /*****************************************************************************/
   521 
   532 
   522 /**
   533 /**
   523    Returns the state of a domain.
   534    Returns the state of a domain.
   524    \return 0 if all datagrams were received, else -1.
   535    \return 0 if all datagrams were received, else -1.
   525    \ingroup RealtimeInterface
   536    \ingroup RealtimeInterface
   526 */
   537 */
   527 
   538 
   528 int ecrt_domain_state(ec_domain_t *domain /**< EtherCAT domain */)
   539 int ecrt_domain_state(const ec_domain_t *domain /**< EtherCAT domain */)
   529 {
   540 {
   530     ec_datagram_t *datagram;
   541     ec_datagram_t *datagram;
   531 
   542 
   532     list_for_each_entry(datagram, &domain->datagrams, list) {
   543     list_for_each_entry(datagram, &domain->datagrams, list) {
   533         if (datagram->state != EC_CMD_RECEIVED) return -1;
   544         if (datagram->state != EC_DATAGRAM_RECEIVED) return -1;
   534     }
   545     }
   535 
   546 
   536     return 0;
   547     return 0;
   537 }
   548 }
   538 
   549 
   539 /*****************************************************************************/
   550 /*****************************************************************************/
   540 
   551 
   541 /** \cond */
   552 /** \cond */
   542 
   553 
   543 EXPORT_SYMBOL(ecrt_domain_register_field);
   554 EXPORT_SYMBOL(ecrt_domain_register_pdo);
   544 EXPORT_SYMBOL(ecrt_domain_register_field_list);
   555 EXPORT_SYMBOL(ecrt_domain_register_pdo_list);
   545 EXPORT_SYMBOL(ecrt_domain_queue);
       
   546 EXPORT_SYMBOL(ecrt_domain_process);
   556 EXPORT_SYMBOL(ecrt_domain_process);
   547 EXPORT_SYMBOL(ecrt_domain_state);
   557 EXPORT_SYMBOL(ecrt_domain_state);
   548 
   558 
   549 /** \endcond */
   559 /** \endcond */
   550 
   560