master/slave_config.c
changeset 2068 3001f6523e63
parent 2028 55854f070c4a
child 2101 01b30593e942
--- a/master/slave_config.c	Fri May 13 15:33:16 2011 +0200
+++ b/master/slave_config.c	Fri May 13 15:34:20 2011 +0200
@@ -70,7 +70,7 @@
     sc->product_code = product_code;
     sc->watchdog_divider = 0; // use default
     sc->watchdog_intervals = 0; // use default
-
+    sc->allow_overlapping_pdos = 0; // default not allowed
     sc->slave = NULL;
 
     for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++)
@@ -164,12 +164,15 @@
 {
     unsigned int i;
     ec_fmmu_config_t *fmmu;
+    ec_fmmu_config_t *prev_fmmu;
+    uint32_t fmmu_logical_start_address;
+    size_t tx_size, old_prev_tx_size;
 
     // FMMU configuration already prepared?
     for (i = 0; i < sc->used_fmmus; i++) {
         fmmu = &sc->fmmu_configs[i];
         if (fmmu->domain == domain && fmmu->sync_index == sync_index)
-            return fmmu->logical_start_address;
+            return fmmu->domain_address;
     }
 
     if (sc->used_fmmus == EC_MAX_FMMUS) {
@@ -177,13 +180,29 @@
         return -EOVERFLOW;
     }
 
-    fmmu = &sc->fmmu_configs[sc->used_fmmus++];
-
-    down(&sc->master->master_sem);
-    ec_fmmu_config_init(fmmu, sc, domain, sync_index, dir);
-    up(&sc->master->master_sem);
-
-    return fmmu->logical_start_address;
+    fmmu = &sc->fmmu_configs[sc->used_fmmus];
+
+    ec_mutex_lock(&sc->master->master_mutex);
+    ec_fmmu_config_init(fmmu, sc, sync_index, dir);
+    fmmu_logical_start_address = domain->tx_size;
+    tx_size = fmmu->data_size;
+    if (sc->allow_overlapping_pdos && sc->used_fmmus > 0) {
+        prev_fmmu = &sc->fmmu_configs[sc->used_fmmus-1];
+        if (fmmu->dir != prev_fmmu->dir && prev_fmmu->tx_size != 0) {
+            // prev fmmu has opposite direction
+            // and is not already paired with prev-prev fmmu
+            old_prev_tx_size = prev_fmmu->tx_size;
+            prev_fmmu->tx_size = max(fmmu->data_size,prev_fmmu->data_size);
+            domain->tx_size += prev_fmmu->tx_size - old_prev_tx_size;
+            tx_size = 0;
+            fmmu_logical_start_address = prev_fmmu->logical_start_address;
+        }
+    }
+    ec_fmmu_config_domain(fmmu,domain,fmmu_logical_start_address,tx_size);
+    ec_mutex_unlock(&sc->master->master_mutex);
+
+    ++sc->used_fmmus;
+    return fmmu->domain_address;
 }
 
 /*****************************************************************************/
@@ -227,8 +246,6 @@
     slave->config = sc;
     sc->slave = slave;
 
-    ec_slave_request_state(slave, EC_SLAVE_STATE_OP);
-
     EC_CONFIG_DBG(sc, 1, "Attached slave %u.\n", slave->ring_position);
 
     return 0;
@@ -494,6 +511,18 @@
 
 /*****************************************************************************/
 
+void ecrt_slave_config_overlapping_pdos(ec_slave_config_t *sc,
+        uint8_t allow_overlapping_pdos )
+{
+    if (sc->master->debug_level)
+        EC_DBG("%s(sc = 0x%p, allow_overlapping_pdos = %u)\n",
+                __func__, sc, allow_overlapping_pdos);
+
+    sc->allow_overlapping_pdos = allow_overlapping_pdos;
+}
+
+/*****************************************************************************/
+
 int ecrt_slave_config_pdo_assign_add(ec_slave_config_t *sc,
         uint8_t sync_index, uint16_t pdo_index)
 {
@@ -507,18 +536,18 @@
         return -EINVAL;
     }
 
-    down(&sc->master->master_sem);
+    ec_mutex_lock(&sc->master->master_mutex);
 
     pdo = ec_pdo_list_add_pdo(&sc->sync_configs[sync_index].pdos, pdo_index);
     if (IS_ERR(pdo)) {
-        up(&sc->master->master_sem);
+        ec_mutex_unlock(&sc->master->master_mutex);
         return PTR_ERR(pdo);
     }
     pdo->sync_index = sync_index;
 
     ec_slave_config_load_default_mapping(sc, pdo);
 
-    up(&sc->master->master_sem);
+    ec_mutex_unlock(&sc->master->master_mutex);
     return 0;
 }
 
@@ -535,9 +564,9 @@
         return;
     }
 
-    down(&sc->master->master_sem);
+    ec_mutex_lock(&sc->master->master_mutex);
     ec_pdo_list_clear_pdos(&sc->sync_configs[sync_index].pdos);
-    up(&sc->master->master_sem);
+    ec_mutex_unlock(&sc->master->master_mutex);
 }
 
 /*****************************************************************************/
@@ -563,10 +592,10 @@
             break;
 
     if (pdo) {
-        down(&sc->master->master_sem);
+        ec_mutex_lock(&sc->master->master_mutex);
         entry = ec_pdo_add_entry(pdo, entry_index, entry_subindex,
                 entry_bit_length);
-        up(&sc->master->master_sem);
+        ec_mutex_unlock(&sc->master->master_mutex);
         if (IS_ERR(entry))
             retval = PTR_ERR(entry);
     } else {
@@ -594,9 +623,9 @@
             break;
 
     if (pdo) {
-        down(&sc->master->master_sem);
+        ec_mutex_lock(&sc->master->master_mutex);
         ec_pdo_clear_entries(pdo);
-        up(&sc->master->master_sem);
+        ec_mutex_unlock(&sc->master->master_mutex);
     } else {
         EC_CONFIG_WARN(sc, "PDO 0x%04X is not assigned.\n", pdo_index);
     }
@@ -685,10 +714,6 @@
     ec_pdo_entry_t *entry;
     int sync_offset;
 
-    EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
-            "subindex = 0x%02X, domain = 0x%p, bit_position = 0x%p)\n",
-            __func__, sc, index, subindex, domain, bit_position);
-
     for (sync_index = 0; sync_index < EC_MAX_SYNC_MANAGERS; sync_index++) {
         sync_config = &sc->sync_configs[sync_index];
         bit_offset = 0;
@@ -712,7 +737,11 @@
                     if (sync_offset < 0)
                         return sync_offset;
 
-                    return sync_offset + bit_offset / 8;
+                    EC_CONFIG_DBG(sc, 1, "%s(index = 0x%04X, "
+                                  "subindex = 0x%02X, domain = %u, bytepos=%u, bitpos=%u)\n",
+                                  __func__,index, subindex,
+                                  domain->index, sync_offset + bit_offset / 8, bit_pos);
+					return sync_offset + bit_offset / 8;
                 }
             }
         }
@@ -776,9 +805,9 @@
         return ret;
     }
         
-    down(&sc->master->master_sem);
+    ec_mutex_lock(&sc->master->master_mutex);
     list_add_tail(&req->list, &sc->sdo_configs);
-    up(&sc->master->master_sem);
+    ec_mutex_unlock(&sc->master->master_mutex);
     return 0;
 }
 
@@ -861,9 +890,9 @@
         return ret;
     }
         
-    down(&sc->master->master_sem);
+    ec_mutex_lock(&sc->master->master_mutex);
     list_add_tail(&req->list, &sc->sdo_configs);
-    up(&sc->master->master_sem);
+    ec_mutex_unlock(&sc->master->master_mutex);
     return 0;
 }
 
@@ -902,9 +931,9 @@
     memset(req->data, 0x00, size);
     req->data_size = size;
     
-    down(&sc->master->master_sem);
+    ec_mutex_lock(&sc->master->master_mutex);
     list_add_tail(&req->list, &sc->sdo_requests);
-    up(&sc->master->master_sem);
+    ec_mutex_unlock(&sc->master->master_mutex);
 
     return req; 
 }
@@ -944,9 +973,9 @@
         return ERR_PTR(ret);
     }
 
-    down(&sc->master->master_sem);
+    ec_mutex_lock(&sc->master->master_mutex);
     list_add_tail(&voe->list, &sc->voe_handlers);
-    up(&sc->master->master_sem);
+    ec_mutex_unlock(&sc->master->master_mutex);
 
     return voe; 
 }
@@ -1027,9 +1056,9 @@
         return ret;
     }
         
-    down(&sc->master->master_sem);
+    ec_mutex_lock(&sc->master->master_mutex);
     list_add_tail(&req->list, &sc->soe_configs);
-    up(&sc->master->master_sem);
+    ec_mutex_unlock(&sc->master->master_mutex);
     return 0;
 }
 
@@ -1039,6 +1068,7 @@
 
 EXPORT_SYMBOL(ecrt_slave_config_sync_manager);
 EXPORT_SYMBOL(ecrt_slave_config_watchdog);
+EXPORT_SYMBOL(ecrt_slave_config_overlapping_pdos);
 EXPORT_SYMBOL(ecrt_slave_config_pdo_assign_add);
 EXPORT_SYMBOL(ecrt_slave_config_pdo_assign_clear);
 EXPORT_SYMBOL(ecrt_slave_config_pdo_mapping_add);