Fixed calculation of expected working counter.
authorFlorian Pose <fp@igh-essen.com>
Tue, 10 Jun 2008 09:54:30 +0000
changeset 985 90bcaf9ce3d5
parent 984 9d9c339cbeb7
child 986 a486591ba86b
Fixed calculation of expected working counter.
master/domain.c
master/domain.h
--- a/master/domain.c	Tue Jun 10 09:12:43 2008 +0000
+++ b/master/domain.c	Tue Jun 10 09:54:30 2008 +0000
@@ -54,14 +54,6 @@
 
 /*****************************************************************************/
 
-/** Working counter increment values for logical read/write operations.
- *
- * \attention This is indexed by ec_direction_t.
- */
-static const unsigned int working_counter_increment[] = {2, 1};
-
-/*****************************************************************************/
-
 /** \cond */
 
 EC_SYSFS_READ_ATTR(image_size);
@@ -98,18 +90,17 @@
 {
     domain->master = master;
     domain->index = index;
+    INIT_LIST_HEAD(&domain->fmmu_configs);
     domain->data_size = 0;
-    domain->expected_working_counter = 0x0000;
     domain->data = NULL;
     domain->data_origin = EC_ORIG_INTERNAL;
-    domain->logical_base_address = 0L;
+    domain->logical_base_address = 0x00000000;
+    INIT_LIST_HEAD(&domain->datagrams);
     domain->working_counter = 0xFFFF;
+    domain->expected_working_counter = 0x0000;
     domain->working_counter_changes = 0;
     domain->notify_jiffies = 0;
 
-    INIT_LIST_HEAD(&domain->datagrams);
-    INIT_LIST_HEAD(&domain->fmmu_configs);
-
     // init kobject and add it to the hierarchy
     memset(&domain->kobj, 0x00, sizeof(struct kobject));
     kobject_init(&domain->kobj);
@@ -197,26 +188,23 @@
         ec_fmmu_config_t *fmmu /**< FMMU configuration. */
         )
 {
-    unsigned int wc_increment;
     fmmu->domain = domain;
 
     domain->data_size += fmmu->data_size;
-    wc_increment = working_counter_increment[fmmu->dir];
-    domain->expected_working_counter += wc_increment;
-    
     list_add_tail(&fmmu->list, &domain->fmmu_configs);
 
     if (domain->master->debug_level)
-        EC_DBG("Domain %u: Added %u bytes (now %u) with dir %u -> WC %u"
-                " (now %u).\n", domain->index, fmmu->data_size,
-                domain->data_size, fmmu->dir, wc_increment,
-                domain->expected_working_counter);
+        EC_DBG("Domain %u: Added %u bytes, total %u.\n", domain->index,
+                fmmu->data_size, domain->data_size);
 }
 
 /*****************************************************************************/
 
 /** Allocates a domain datagram and appends it to the list.
  *
+ * The datagram type and expected working counters are determined by the
+ * number of input and output fmmus that share the datagram.
+ *
  * \return 0 in case of success, else < 0
  */
 int ec_domain_add_datagram(
@@ -243,16 +231,22 @@
             kfree(datagram);
             return -1;
         }
+        // If LRW is used, output FMMUs increment the working counter by 2,
+        // while input FMMUs increment it by 1.
+        domain->expected_working_counter =
+            used[EC_DIR_OUTPUT] * 2 + used[EC_DIR_INPUT];
     } else if (used[EC_DIR_OUTPUT]) { // outputs only
         if (ec_datagram_lwr(datagram, logical_offset, data_size, data)) {
             kfree(datagram);
             return -1;
         }
+        domain->expected_working_counter = used[EC_DIR_OUTPUT];
     } else { // inputs only (or nothing)
         if (ec_datagram_lrd(datagram, logical_offset, data_size, data)) {
             kfree(datagram);
             return -1;
         }
+        domain->expected_working_counter = used[EC_DIR_INPUT];
     }
 
     list_add_tail(&datagram->list, &domain->datagrams);
@@ -278,9 +272,8 @@
 {
     uint32_t datagram_offset;
     size_t datagram_size;
-    unsigned int datagram_count, i;
+    unsigned int datagram_count;
     unsigned int datagram_used[2];
-    ec_slave_config_t *sc;
     ec_fmmu_config_t *fmmu;
     const ec_datagram_t *datagram;
 
@@ -295,43 +288,39 @@
         }
     }
 
-    // Cycle through all domain FMMUS, correct the logical base addresses and
-    // set up the datagrams to carry the process data.
+    // Cycle through all domain FMMUS and
+    // - correct the logical base addresses
+    // - set up the datagrams to carry the process data
     datagram_offset = 0;
     datagram_size = 0;
     datagram_count = 0;
     datagram_used[EC_DIR_OUTPUT] = 0;
     datagram_used[EC_DIR_INPUT] = 0;
 
-    list_for_each_entry(sc, &domain->master->configs, list) {
-        for (i = 0; i < sc->used_fmmus; i++) {
-            fmmu = &sc->fmmu_configs[i];
-            if (fmmu->domain != domain)
-                continue;
-
-            // Correct logical FMMU address
-            fmmu->logical_start_address += base_address;
-
-            // Increment Input/Output counter
-            datagram_used[fmmu->dir]++;
-
-            // If the current FMMU's data do not fit in the current datagram,
-            // allocate a new one.
-            if (datagram_size + fmmu->data_size > EC_MAX_DATA_SIZE) {
-                if (ec_domain_add_datagram(domain,
-                            domain->logical_base_address + datagram_offset,
-                            datagram_size, domain->data + datagram_offset,
-                            datagram_used))
-                    return -1;
-                datagram_offset += datagram_size;
-                datagram_size = 0;
-                datagram_count++;
-                datagram_used[EC_DIR_OUTPUT] = 0;
-                datagram_used[EC_DIR_INPUT] = 0;
-            }
-
-            datagram_size += fmmu->data_size;
-        }
+    list_for_each_entry(fmmu, &domain->fmmu_configs, list) {
+        // Correct logical FMMU address
+        fmmu->logical_start_address += base_address;
+
+        // Increment Input/Output counter to determine datagram types
+        // and calculate expected working counters
+        datagram_used[fmmu->dir]++;
+
+        // If the current FMMU's data do not fit in the current datagram,
+        // allocate a new one.
+        if (datagram_size + fmmu->data_size > EC_MAX_DATA_SIZE) {
+            if (ec_domain_add_datagram(domain,
+                        domain->logical_base_address + datagram_offset,
+                        datagram_size, domain->data + datagram_offset,
+                        datagram_used))
+                return -1;
+            datagram_offset += datagram_size;
+            datagram_size = 0;
+            datagram_count++;
+            datagram_used[EC_DIR_OUTPUT] = 0;
+            datagram_used[EC_DIR_INPUT] = 0;
+        }
+
+        datagram_size += fmmu->data_size;
     }
 
     // allocate last datagram, if data are left
@@ -344,10 +333,12 @@
         datagram_count++;
     }
 
-    EC_INFO("Domain %u with logical offset %u contains %u bytes.\n",
-            domain->index, domain->logical_base_address, domain->data_size);
+    EC_INFO("Domain%u: Logical address 0x%08x, %u byte, "
+            "expected working counter %u.\n", domain->index,
+            domain->logical_base_address, domain->data_size,
+            domain->expected_working_counter);
     list_for_each_entry(datagram, &domain->datagrams, list) {
-        EC_INFO("  Datagram %s, logical offset %u, size %u, type %s.\n",
+        EC_INFO("  Datagram %s: Logical offset 0x%08x, %u byte, type %s.\n",
                 datagram->name, EC_READ_U32(datagram->address),
                 datagram->data_size, ec_datagram_type_string(datagram));
     }
@@ -462,10 +453,10 @@
 
 void ecrt_domain_process(ec_domain_t *domain)
 {
-    unsigned int working_counter_sum;
+    uint16_t working_counter_sum;
     ec_datagram_t *datagram;
 
-    working_counter_sum = 0;
+    working_counter_sum = 0x0000;
     list_for_each_entry(datagram, &domain->datagrams, list) {
         ec_datagram_output_stats(datagram);
         if (datagram->state == EC_DATAGRAM_RECEIVED) {
@@ -485,8 +476,7 @@
             EC_INFO("Domain %u: Working counter changed to %u/%u.\n",
                     domain->index, domain->working_counter,
                     domain->expected_working_counter);
-        }
-        else {
+        } else {
             EC_INFO("Domain %u: %u working counter changes. Currently %u/%u.\n",
                     domain->index, domain->working_counter_changes,
                     domain->working_counter, domain->expected_working_counter);
--- a/master/domain.h	Tue Jun 10 09:12:43 2008 +0000
+++ b/master/domain.h	Tue Jun 10 09:54:30 2008 +0000
@@ -63,18 +63,20 @@
     struct list_head list; /**< List item. */
     ec_master_t *master; /**< EtherCAT master owning the domain. */
     unsigned int index; /**< Index (just a number). */
+
+    struct list_head fmmu_configs; /**< FMMU configurations contained. */
     size_t data_size; /**< Size of the process data. */
-    uint16_t expected_working_counter; /**< Expected working counter. */
     uint8_t *data; /**< Memory for the process data. */
     ec_origin_t data_origin; /**< Origin of the \a data memory. */
-    struct list_head datagrams; /**< Datagrams for process data exchange. */
     uint32_t logical_base_address; /**< Logical offset address of the
                                      process data. */
+    struct list_head datagrams; /**< Datagrams for process data exchange. */
+
     uint16_t working_counter; /**< Last working counter value. */
+    uint16_t expected_working_counter; /**< Expected working counter. */
     unsigned int working_counter_changes; /**< Working counter changes
                                              since last notification. */
     unsigned long notify_jiffies; /**< Time of last notification. */
-    struct list_head fmmu_configs; /**< FMMU configurations contained. */
 };
 
 /*****************************************************************************/