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.
--- 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;