Fixed EtherCAT addressing problem on big-endian systems. The slaves
authorFlorian Pose <fp@igh-essen.com>
Thu, 06 Sep 2007 09:28:38 +0000
changeset 708 90bdb315f560
parent 707 9ae68af8e17a
child 709 a69fd2491fa8
Fixed EtherCAT addressing problem on big-endian systems. The slaves
address is now a four-byte-array, that is filled with little-endian
(EtherCAT) values on datagram creation.
master/datagram.c
master/datagram.h
master/domain.c
master/globals.h
master/master.c
--- a/master/datagram.c	Thu Sep 06 09:23:56 2007 +0000
+++ b/master/datagram.c	Thu Sep 06 09:28:38 2007 +0000
@@ -71,7 +71,7 @@
 {
     INIT_LIST_HEAD(&datagram->queue); // mark as unqueued
     datagram->type = EC_DATAGRAM_NONE;
-    datagram->address.logical = 0x00000000;
+    memset(datagram->address, 0x00, EC_ADDR_LEN);
     datagram->data = NULL;
     datagram->mem_size = 0;
     datagram->data_size = 0;
@@ -147,8 +147,8 @@
 
     EC_FUNC_HEADER;
     datagram->type = EC_DATAGRAM_NPRD;
-    datagram->address.physical.slave = node_address;
-    datagram->address.physical.mem = offset;
+    EC_WRITE_U16(datagram->address, node_address);
+    EC_WRITE_U16(datagram->address + 2, offset);
     EC_FUNC_FOOTER;
 }
 
@@ -175,8 +175,8 @@
 
     EC_FUNC_HEADER;
     datagram->type = EC_DATAGRAM_NPWR;
-    datagram->address.physical.slave = node_address;
-    datagram->address.physical.mem = offset;
+    EC_WRITE_U16(datagram->address, node_address);
+    EC_WRITE_U16(datagram->address + 2, offset);
     EC_FUNC_FOOTER;
 }
 
@@ -200,8 +200,8 @@
 {
     EC_FUNC_HEADER;
     datagram->type = EC_DATAGRAM_APRD;
-    datagram->address.physical.slave = (int16_t) ring_position * (-1);
-    datagram->address.physical.mem = offset;
+    EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1));
+    EC_WRITE_U16(datagram->address + 2, offset);
     EC_FUNC_FOOTER;
 }
 
@@ -225,8 +225,8 @@
 {
     EC_FUNC_HEADER;
     datagram->type = EC_DATAGRAM_APWR;
-    datagram->address.physical.slave = (int16_t) ring_position * (-1);
-    datagram->address.physical.mem = offset;
+    EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1));
+    EC_WRITE_U16(datagram->address + 2, offset);
     EC_FUNC_FOOTER;
 }
 
@@ -248,8 +248,8 @@
 {
     EC_FUNC_HEADER;
     datagram->type = EC_DATAGRAM_BRD;
-    datagram->address.physical.slave = 0x0000;
-    datagram->address.physical.mem = offset;
+    EC_WRITE_U16(datagram->address, 0x0000);
+    EC_WRITE_U16(datagram->address + 2, offset);
     EC_FUNC_FOOTER;
 }
 
@@ -271,8 +271,8 @@
 {
     EC_FUNC_HEADER;
     datagram->type = EC_DATAGRAM_BWR;
-    datagram->address.physical.slave = 0x0000;
-    datagram->address.physical.mem = offset;
+    EC_WRITE_U16(datagram->address, 0x0000);
+    EC_WRITE_U16(datagram->address + 2, offset);
     EC_FUNC_FOOTER;
 }
 
@@ -294,8 +294,8 @@
 {
     EC_FUNC_HEADER;
     datagram->type = EC_DATAGRAM_LRW;
-    datagram->address.logical = offset;
-    EC_FUNC_FOOTER;
-}
-
-/*****************************************************************************/
+    EC_WRITE_U32(datagram->address, offset);
+    EC_FUNC_FOOTER;
+}
+
+/*****************************************************************************/
--- a/master/datagram.h	Thu Sep 06 09:23:56 2007 +0000
+++ b/master/datagram.h	Thu Sep 06 09:28:38 2007 +0000
@@ -84,28 +84,6 @@
 /*****************************************************************************/
 
 /**
-   EtherCAT address.
-*/
-
-typedef union
-{
-    /**
-     * Physical address.
-     */
-    struct
-    {
-        uint16_t slave; /**< configured or autoincrement address */
-        uint16_t mem; /**< physical memory address */
-    }
-    physical;
-
-    uint32_t logical; /**< logical address */
-}
-ec_address_t;
-
-/*****************************************************************************/
-
-/**
    EtherCAT datagram.
 */
 
@@ -115,7 +93,7 @@
     struct list_head queue; /**< master datagram queue item */
     struct list_head sent; /**< master list item for sent datagrams */
     ec_datagram_type_t type; /**< datagram type (APRD, BWR, etc) */
-    ec_address_t address; /**< recipient address */
+    uint8_t address[EC_ADDR_LEN]; /**< recipient address */
     uint8_t *data; /**< datagram data */
     size_t mem_size; /**< datagram \a data memory size */
     size_t data_size; /**< size of the data in \a data */
--- a/master/domain.c	Thu Sep 06 09:23:56 2007 +0000
+++ b/master/domain.c	Thu Sep 06 09:28:38 2007 +0000
@@ -298,7 +298,7 @@
     ec_fmmu_t *fmmu;
     unsigned int i, j, datagram_count;
     uint32_t pdo_off, pdo_off_datagram;
-    uint32_t datagram_offset;
+    uint32_t datagram_offset, log_addr;
     size_t datagram_data_size, sync_size;
     ec_datagram_t *datagram;
 
@@ -350,8 +350,9 @@
                 pdo_off = fmmu->logical_start_address + data_reg->sync_offset;
                 // search datagram
                 list_for_each_entry(datagram, &domain->datagrams, list) {
-                    pdo_off_datagram = pdo_off - datagram->address.logical;
-                    if (pdo_off >= datagram->address.logical &&
+                    log_addr = EC_READ_U32(datagram->address);
+                    pdo_off_datagram = pdo_off - log_addr;
+                    if (pdo_off >= log_addr &&
                         pdo_off_datagram < datagram->mem_size) {
                         *data_reg->data_ptr = datagram->data +
                             pdo_off_datagram;
--- a/master/globals.h	Thu Sep 06 09:23:56 2007 +0000
+++ b/master/globals.h	Thu Sep 06 09:28:38 2007 +0000
@@ -81,6 +81,9 @@
 /** size of an EtherCAT datagram footer */
 #define EC_DATAGRAM_FOOTER_SIZE 2
 
+/** size of the EtherCAT address field */
+#define EC_ADDR_LEN 4
+
 /** resulting maximum data size of a single datagram in a frame */
 #define EC_MAX_DATA_SIZE (ETH_DATA_LEN - EC_FRAME_HEADER_SIZE \
                           - EC_DATAGRAM_HEADER_SIZE - EC_DATAGRAM_FOOTER_SIZE)
--- a/master/master.c	Thu Sep 06 09:23:56 2007 +0000
+++ b/master/master.c	Thu Sep 06 09:28:38 2007 +0000
@@ -592,7 +592,7 @@
             // EtherCAT datagram header
             EC_WRITE_U8 (cur_data,     datagram->type);
             EC_WRITE_U8 (cur_data + 1, datagram->index);
-            EC_WRITE_U32(cur_data + 2, datagram->address.logical);
+            memcpy(cur_data + 2, datagram->address, EC_ADDR_LEN);
             EC_WRITE_U16(cur_data + 6, datagram->data_size & 0x7FF);
             EC_WRITE_U16(cur_data + 8, 0x0000);
             follows_word = cur_data + 6;