Support for slaves that don't support the LRW datagram type.
authorFlorian Pose <fp@igh-essen.com>
Fri, 22 Feb 2008 16:04:23 +0000
changeset 817 118dea2fa505
parent 816 d02761e14eb0
child 818 b6c87ae254c9
Support for slaves that don't support the LRW datagram type.
NEWS
TODO
master/domain.c
--- a/NEWS	Fri Feb 22 16:03:08 2008 +0000
+++ b/NEWS	Fri Feb 22 16:04:23 2008 +0000
@@ -43,6 +43,8 @@
 * Pdo configuration is now supported.
 * Added 8139too driver for kernel 2.6.22, thanks to Erwin Burgstaller.
 * Added e1000 driver for kernel 2.6.22.
+* Added support for slaves that do not support the LRW datagram type. Separate
+  domains have to be used for inputs and output.
 * Allow gaps in PDO mapping read from CoE.
 * Fixed bug in CoE code.
 * Improved handling of large EEPROM contents.
--- a/TODO	Fri Feb 22 16:03:08 2008 +0000
+++ b/TODO	Fri Feb 22 16:04:23 2008 +0000
@@ -21,7 +21,6 @@
 * READMEs for examples.
 * Calculate expected working counter for domains.
 * Distributed clocks.
-* Support slaves, that don't support the LRW datagram, only LRD/LWR.
 
 Future issues:
 
--- a/master/domain.c	Fri Feb 22 16:03:08 2008 +0000
+++ b/master/domain.c	Fri Feb 22 16:04:23 2008 +0000
@@ -190,7 +190,8 @@
         ec_domain_t *domain, /**< EtherCAT domain. */
         uint32_t logical_offset, /**< Logical offset. */
         size_t data_size, /**< Size of the data. */
-        uint8_t *data /**< Process data. */
+        uint8_t *data, /**< Process data. */
+        const unsigned int used[] /**< Used by inputs/outputs. */
         )
 {
     ec_datagram_t *datagram;
@@ -204,9 +205,21 @@
     snprintf(datagram->name, EC_DATAGRAM_NAME_SIZE,
             "domain%u-%u", domain->index, logical_offset);
 
-    if (ec_datagram_lrw(datagram, logical_offset, data_size, data)) {
-        kfree(datagram);
-        return -1;
+    if (used[EC_DIR_OUTPUT] && used[EC_DIR_INPUT]) { // inputs and outputs
+        if (ec_datagram_lrw(datagram, logical_offset, data_size, data)) {
+            kfree(datagram);
+            return -1;
+        }
+    } else if (used[EC_DIR_OUTPUT]) { // outputs only
+        if (ec_datagram_lwr(datagram, logical_offset, data_size, data)) {
+            kfree(datagram);
+            return -1;
+        }
+    } else { // inputs only (or nothing)
+        if (ec_datagram_lrd(datagram, logical_offset, data_size, data)) {
+            kfree(datagram);
+            return -1;
+        }
     }
 
     list_add_tail(&datagram->list, &domain->datagrams);
@@ -233,8 +246,10 @@
     uint32_t datagram_offset;
     size_t datagram_size;
     unsigned int datagram_count, i;
+    unsigned int datagram_used[2];
     ec_slave_config_t *sc;
     ec_fmmu_config_t *fmmu;
+    const ec_datagram_t *datagram;
 
     domain->logical_base_address = base_address;
 
@@ -252,6 +267,9 @@
     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];
@@ -261,16 +279,22 @@
             // 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_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;
@@ -281,14 +305,20 @@
     if (datagram_size) {
         if (ec_domain_add_datagram(domain,
                     domain->logical_base_address + datagram_offset,
-                    datagram_size, domain->data + datagram_offset))
+                    datagram_size, domain->data + datagram_offset,
+                    datagram_used))
             return -1;
         datagram_count++;
     }
 
-    EC_INFO("Domain %u with logical offset %u contains %u bytes in %u"
-            " datagram%s.\n", domain->index, domain->logical_base_address,
-            domain->data_size, datagram_count, datagram_count == 1 ? "" : "s");
+    EC_INFO("Domain %u with logical offset %u contains %u bytes.\n",
+            domain->index, domain->logical_base_address, domain->data_size);
+    list_for_each_entry(datagram, &domain->datagrams, list) {
+        EC_INFO("  Datagram %s, logical offset %u, size %u, type %s.\n",
+                datagram->name, EC_READ_U32(datagram->address),
+                datagram->data_size, ec_datagram_type_string(datagram));
+    }
+    
     return 0;
 }