EC_READ/WRITE-Makros verwenden Makros aud asm/byteorder.h und werden konsequent verwendet.
authorFlorian Pose <fp@igh-essen.com>
Fri, 24 Feb 2006 10:19:26 +0000
changeset 77 677967864795
parent 76 9dc136e3801c
child 78 3d74183d6c6b
EC_READ/WRITE-Makros verwenden Makros aud asm/byteorder.h und werden konsequent verwendet.
include/EtherCAT_rt.h
include/EtherCAT_si.h
master/canopen.c
master/frame.c
master/frame.h
master/master.c
master/slave.c
--- a/include/EtherCAT_rt.h	Thu Feb 23 14:51:45 2006 +0000
+++ b/include/EtherCAT_rt.h	Fri Feb 24 10:19:26 2006 +0000
@@ -87,10 +87,10 @@
 // Slave Methods
 
 int EtherCAT_rt_canopen_sdo_write(ec_slave_t *slave,
-                                  unsigned int sdo_index,
-                                  unsigned char sdo_subindex,
-                                  unsigned int value,
-                                  unsigned int size);
+                                  uint16_t sdo_index,
+                                  uint8_t sdo_subindex,
+                                  uint32_t value,
+                                  size_t size);
 
 /*****************************************************************************/
 
--- a/include/EtherCAT_si.h	Thu Feb 23 14:51:45 2006 +0000
+++ b/include/EtherCAT_si.h	Fri Feb 24 10:19:26 2006 +0000
@@ -8,6 +8,8 @@
  *
  *****************************************************************************/
 
+#include <asm/byteorder.h>
+
 /*****************************************************************************/
 
 // Bitwise read/write macros
@@ -24,31 +26,14 @@
 
 // Read macros
 
-#define EC_READ_U8(PD) \
-    (*((uint8_t *) (PD)))
+#define EC_READ_U8(PD) ((uint8_t) *((uint8_t *) (PD)))
+#define EC_READ_S8(PD) ((int8_t)  *((uint8_t *) (PD)))
 
-#define EC_READ_S8(PD) \
-    ((int8_t) *((uint8_t *) (PD)))
+#define EC_READ_U16(PD) ((uint16_t) le16_to_cpup((void *) (PD)))
+#define EC_READ_S16(PD) ((int16_t)  le16_to_cpup((void *) (PD)))
 
-#define EC_READ_U16(PD) \
-    ((uint16_t) (*((uint8_t *) (PD) + 0) << 0 | \
-                 *((uint8_t *) (PD) + 1) << 8))
-
-#define EC_READ_S16(PD) \
-    ((int16_t) (*((uint8_t *) (PD) + 0) << 0 | \
-                *((uint8_t *) (PD) + 1) << 8))
-
-#define EC_READ_U32(PD) \
-    ((uint32_t) (*((uint8_t *) (PD) + 0) <<  0 | \
-                 *((uint8_t *) (PD) + 1) <<  8 | \
-                 *((uint8_t *) (PD) + 2) << 16 | \
-                 *((uint8_t *) (PD) + 3) << 24))
-
-#define EC_READ_S32(PD) \
-    ((int32_t) (*((uint8_t *) (PD) + 0) <<  0 | \
-                *((uint8_t *) (PD) + 1) <<  8 | \
-                *((uint8_t *) (PD) + 2) << 16 | \
-                *((uint8_t *) (PD) + 3) << 24))
+#define EC_READ_U32(PD) ((uint32_t) le32_to_cpup((void *) (PD)))
+#define EC_READ_S32(PD) ((int32_t)  le32_to_cpup((void *) (PD)))
 
 /*****************************************************************************/
 
@@ -63,18 +48,16 @@
 
 #define EC_WRITE_U16(PD, VAL) \
     do { \
-        *((uint8_t *) (PD) + 0) = ((uint16_t) (VAL) >> 0) & 0xFF; \
-        *((uint8_t *) (PD) + 1) = ((uint16_t) (VAL) >> 8) & 0xFF; \
+        *((uint16_t *) (PD)) = (uint16_t) (VAL); \
+        cpu_to_le16s(PD); \
     } while (0)
 
 #define EC_WRITE_S16(PD, VAL) EC_WRITE_U16(PD, VAL)
 
 #define EC_WRITE_U32(PD, VAL) \
     do { \
-        *((uint8_t *) (PD) + 0) = ((uint32_t) (VAL) >>  0) & 0xFF; \
-        *((uint8_t *) (PD) + 1) = ((uint32_t) (VAL) >>  8) & 0xFF; \
-        *((uint8_t *) (PD) + 2) = ((uint32_t) (VAL) >> 16) & 0xFF; \
-        *((uint8_t *) (PD) + 3) = ((uint32_t) (VAL) >> 24) & 0xFF; \
+        *((uint32_t *) (PD)) = (uint32_t) (VAL); \
+        cpu_to_le16s(PD); \
     } while (0)
 
 #define EC_WRITE_S32(PD, VAL) EC_WRITE_U32(PD, VAL)
--- a/master/canopen.c	Thu Feb 23 14:51:45 2006 +0000
+++ b/master/canopen.c	Fri Feb 24 10:19:26 2006 +0000
@@ -10,6 +10,7 @@
 
 #include <linux/delay.h>
 
+#include "../include/EtherCAT_si.h"
 #include "master.h"
 
 /*****************************************************************************/
@@ -22,13 +23,12 @@
    Schreibt ein CANopen-SDO (service data object).
  */
 
-int EtherCAT_rt_canopen_sdo_write(
-    ec_slave_t *slave, /**< EtherCAT-Slave */
-    unsigned int sdo_index, /**< SDO-Index */
-    unsigned char sdo_subindex, /**< SDO-Subindex */
-    unsigned int value, /**< Neuer Wert */
-    unsigned int size /**< Größe des Datenfeldes */
-    )
+int EtherCAT_rt_canopen_sdo_write(ec_slave_t *slave, /**< EtherCAT-Slave */
+                                  uint16_t sdo_index, /**< SDO-Index */
+                                  uint8_t sdo_subindex, /**< SDO-Subindex */
+                                  uint32_t value, /**< Neuer Wert */
+                                  size_t size /**< Größe des Datenfeldes */
+                                  )
 {
     unsigned char data[0xF6];
     ec_frame_t frame;
@@ -44,24 +44,17 @@
         return -1;
     }
 
-    data[0] = 0x0A; // Length of the Mailbox service data
-    data[1] = 0x00;
-    data[2] = slave->station_address & 0xFF; // Station address
-    data[3] = (slave->station_address >> 8) & 0xFF;
-    data[4] = 0x00; // Channel & priority
-    data[5] = 0x03; // CANopen over EtherCAT
-    data[6] = 0x00; // Number(7-0)
-    data[7] = 0x2 << 4; // Number(8) & Service = SDO Request (0x02)
-    data[8] = 0x01 // Size specified
-        | (0x1 << 1) // Transfer type = Expedited
-        | ((4 - size) << 2) // Data Set Size
-        | (0x1 << 5); // Command specifier = Initiate download request (0x01)
-    data[9] = sdo_index & 0xFF;
-    data[10] = (sdo_index >> 8) & 0xFF;
-    data[11] = sdo_subindex;
+    EC_WRITE_U16(data,      0x000A); // Length of the Mailbox service data
+    EC_WRITE_U16(data + 2,  slave->station_address); // Station address
+    EC_WRITE_U8 (data + 4,  0x00); // Channel & priority
+    EC_WRITE_U8 (data + 5,  0x03); // CANopen over EtherCAT
+    EC_WRITE_U16(data + 6,  0x2000); // Number & Service
+    EC_WRITE_U8 (data + 8,  0x13 | ((4 - size) << 2)); // Spec., exp., init.
+    EC_WRITE_U16(data + 9,  sdo_index);
+    EC_WRITE_U8 (data + 11, sdo_subindex);
 
     for (i = 0; i < size; i++) {
-        data[12 + i] = value & 0xFF;
+        EC_WRITE_U8(data + 12 + i, value & 0xFF);
         value >>= 8;
     }
 
@@ -91,7 +84,7 @@
             return -1;
         }
 
-        if (frame.data[5] & 8) { // Written bit is high
+        if (EC_READ_U8(frame.data + 5) & 8) { // Written bit is high
             break;
         }
 
@@ -115,12 +108,11 @@
         return -1;
     }
 
-    if (frame.data[5] != 0x03 // COE
-        || (frame.data[7] >> 4) != 0x03 // SDO response
-        || (frame.data[8] >> 5) != 0x03 // Initiate download response
-        || (frame.data[9] != (sdo_index & 0xFF)) // Index
-        || (frame.data[10] != ((sdo_index >> 8) & 0xFF))
-        || (frame.data[11] != sdo_subindex)) // Subindex
+    if (EC_READ_U8 (frame.data + 5) != 0x03 || // COE
+        EC_READ_U16(frame.data + 6) != 0x3000 || // SDO response
+        EC_READ_U8 (frame.data + 8) >> 5 != 0x03 || // Download response
+        EC_READ_U16(frame.data + 9) != sdo_index || // Index
+        EC_READ_U8 (frame.data + 11) != sdo_subindex) // Subindex
     {
         printk(KERN_ERR "EtherCAT: Illegal mailbox response at slave %i!\n",
                slave->ring_position);
--- a/master/frame.c	Thu Feb 23 14:51:45 2006 +0000
+++ b/master/frame.c	Fri Feb 24 10:19:26 2006 +0000
@@ -11,6 +11,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 
+#include "../include/EtherCAT_si.h"
 #include "frame.h"
 #include "master.h"
 
@@ -27,7 +28,8 @@
     memcpy(frame->data, data, length);
 
 #define EC_FUNC_READ_FOOTER \
-    frame->data_length = length;
+    frame->data_length = length; \
+    memset(frame->data, 0x00, length);
 
 /*****************************************************************************/
 
@@ -289,45 +291,30 @@
     data = ec_device_prepare(&frame->master->device);
 
     // EtherCAT frame header
-    data[0] = command_size & 0xFF;
-    data[1] = ((command_size & 0x700) >> 8) | 0x10;
+    EC_WRITE_U16(data, (command_size & 0x7FF) | 0x1000);
     data += EC_FRAME_HEADER_SIZE;
 
     // EtherCAT command header
-    data[0] = frame->type;
-    data[1] = frame->index;
-    data[2] = frame->address.raw[0];
-    data[3] = frame->address.raw[1];
-    data[4] = frame->address.raw[2];
-    data[5] = frame->address.raw[3];
-    data[6] = frame->data_length & 0xFF;
-    data[7] = (frame->data_length & 0x700) >> 8;
-    data[8] = 0x00;
-    data[9] = 0x00;
+    EC_WRITE_U8 (data,     frame->type);
+    EC_WRITE_U8 (data + 1, frame->index);
+    EC_WRITE_U32(data + 2, frame->address.logical);
+    EC_WRITE_U16(data + 6, frame->data_length & 0x7FF);
+    EC_WRITE_U16(data + 8, 0x0000);
     data += EC_COMMAND_HEADER_SIZE;
 
-    if (likely(frame->type == ec_frame_type_apwr // Write commands
-               || frame->type == ec_frame_type_npwr
-               || frame->type == ec_frame_type_bwr
-               || frame->type == ec_frame_type_lrw)) {
-        memcpy(data, frame->data, frame->data_length);
-    }
-    else { // Read commands
-        memset(data, 0x00, frame->data_length);
-    }
+    // EtherCAT command data
+    memcpy(data, frame->data, frame->data_length);
+    data += frame->data_length;
 
     // EtherCAT command footer
-    data += frame->data_length;
-    data[0] = frame->working_counter & 0xFF;
-    data[1] = (frame->working_counter & 0xFF00) >> 8;
+    EC_WRITE_U16(data, frame->working_counter);
     data += EC_COMMAND_FOOTER_SIZE;
 
     // Pad with zeros
     for (i = EC_FRAME_HEADER_SIZE + EC_COMMAND_HEADER_SIZE
              + frame->data_length + EC_COMMAND_FOOTER_SIZE;
-         i < EC_MIN_FRAME_SIZE; i++) {
-        *data++ = 0x00;
-    }
+         i < EC_MIN_FRAME_SIZE; i++)
+        EC_WRITE_U8(data++, 0x00);
 
     // Send frame
     ec_device_send(&frame->master->device, frame_size);
@@ -371,7 +358,8 @@
     data = ec_device_data(device);
 
     // Länge des gesamten Frames prüfen
-    frame_length = (data[0] & 0xFF) | ((data[1] & 0x07) << 8);
+    frame_length = EC_READ_U16(data) & 0x07FF;
+    data += EC_FRAME_HEADER_SIZE;
 
     if (unlikely(frame_length > received_length)) {
         printk(KERN_ERR "EtherCAT: Received corrupted frame (length does"
@@ -381,10 +369,10 @@
     }
 
     // Command header
-    data += EC_FRAME_HEADER_SIZE;
-    command_type = data[0];
-    command_index = data[1];
-    data_length = (data[6] & 0xFF) | ((data[7] & 0x07) << 8);
+    command_type =  EC_READ_U8(data);
+    command_index = EC_READ_U8(data + 1);
+    data_length =   EC_READ_U16(data + 6) & 0x07FF;
+    data += EC_COMMAND_HEADER_SIZE;
 
     if (unlikely(EC_FRAME_HEADER_SIZE + EC_COMMAND_HEADER_SIZE
                  + data_length + EC_COMMAND_FOOTER_SIZE > received_length)) {
@@ -399,7 +387,7 @@
                  || frame->data_length != data_length))
     {
         printk(KERN_WARNING "EtherCAT: WARNING - Send/Receive anomaly!\n");
-        ec_frame_print(frame);
+        ec_frame_print(frame); // FIXME uninteressant...
         ec_device_call_isr(device); // Empfangenes "vergessen"
         return -1;
     }
@@ -407,12 +395,11 @@
     frame->state = ec_frame_received;
 
     // Empfangene Daten in Kommandodatenspeicher kopieren
-    data += EC_COMMAND_HEADER_SIZE;
     memcpy(frame->data, data, data_length);
     data += data_length;
 
     // Working-Counter setzen
-    frame->working_counter = (data[0] & 0xFF) | ((data[1] & 0xFF) << 8);
+    frame->working_counter = EC_READ_U16(data);
 
     if (unlikely(frame->master->debug_level > 1)) {
         ec_frame_print(frame);
--- a/master/frame.h	Thu Feb 23 14:51:45 2006 +0000
+++ b/master/frame.h	Fri Feb 24 10:19:26 2006 +0000
@@ -68,13 +68,12 @@
 {
   struct
   {
-      uint16_t slave; /**< Adresse des Slaves */
+      uint16_t slave; /**< Adresse des Slaves (Ringposition oder Knoten) */
       uint16_t mem; /**< Physikalische Speicheradresse im Slave */
   }
   physical; /**< Physikalische Adresse */
 
   uint32_t logical; /**< Logische Adresse */
-  uint8_t raw[4]; /**< Rohdaten für die Generierung des Frames */
 }
 ec_address_t;
 
--- a/master/master.c	Thu Feb 23 14:51:45 2006 +0000
+++ b/master/master.c	Fri Feb 24 10:19:26 2006 +0000
@@ -15,6 +15,7 @@
 #include <linux/delay.h>
 
 #include "../include/EtherCAT_rt.h"
+#include "../include/EtherCAT_si.h"
 #include "globals.h"
 #include "master.h"
 #include "slave.h"
@@ -201,11 +202,10 @@
         slave = master->slaves + i;
 
         // Write station address
-        data[0] = slave->station_address & 0x00FF;
-        data[1] = (slave->station_address & 0xFF00) >> 8;
-
-        ec_frame_init_apwr(&frame, master, slave->ring_position, 0x0010, 2,
-                           data);
+        EC_WRITE_U16(data, slave->station_address);
+
+        ec_frame_init_apwr(&frame, master, slave->ring_position, 0x0010,
+                           sizeof(uint16_t), data);
 
         if (unlikely(ec_frame_send_receive(&frame) < 0)) return -1;
 
@@ -366,14 +366,11 @@
                     uint8_t *data /**> Zeiger auf Konfigurationsspeicher */
                     )
 {
-    data[0] = sync->physical_start_address & 0xFF;
-    data[1] = (sync->physical_start_address >> 8) & 0xFF;
-    data[2] = sync->size & 0xFF;
-    data[3] = (sync->size >> 8) & 0xFF;
-    data[4] = sync->control_byte;
-    data[5] = 0x00;
-    data[6] = 0x01; // enable
-    data[7] = 0x00;
+    EC_WRITE_U16(data,     sync->physical_start_address);
+    EC_WRITE_U16(data + 2, sync->size);
+    EC_WRITE_U8 (data + 4, sync->control_byte);
+    EC_WRITE_U8 (data + 5, 0x00); // status byte (read only)
+    EC_WRITE_U16(data + 6, 0x0001); // enable
 }
 
 /*****************************************************************************/
@@ -389,22 +386,15 @@
                     uint8_t *data /**> Zeiger auf Konfigurationsspeicher */
                     )
 {
-    data[0] = fmmu->logical_start_address & 0xFF;
-    data[1] = (fmmu->logical_start_address >> 8) & 0xFF;
-    data[2] = (fmmu->logical_start_address >> 16) & 0xFF;
-    data[3] = (fmmu->logical_start_address >> 24) & 0xFF;
-    data[4] = fmmu->sync->size & 0xFF;
-    data[5] = (fmmu->sync->size >> 8) & 0xFF;
-    data[6] = 0x00; // Logical start bit
-    data[7] = 0x07; // Logical end bit
-    data[8] = fmmu->sync->physical_start_address & 0xFF;
-    data[9] = (fmmu->sync->physical_start_address >> 8) & 0xFF;
-    data[10] = 0x00; // Physical start bit
-    data[11] = (fmmu->sync->control_byte & 0x04) ? 0x02 : 0x01;
-    data[12] = 0x01; // Enable
-    data[13] = 0x00; // res.
-    data[14] = 0x00; // res.
-    data[15] = 0x00; // res.
+    EC_WRITE_U32(data,      fmmu->logical_start_address);
+    EC_WRITE_U16(data + 4,  fmmu->sync->size);
+    EC_WRITE_U8 (data + 6,  0x00); // Logical start bit
+    EC_WRITE_U8 (data + 7,  0x07); // Logical end bit
+    EC_WRITE_U16(data + 8,  fmmu->sync->physical_start_address);
+    EC_WRITE_U8 (data + 10, 0x00); // Physical start bit
+    EC_WRITE_U8 (data + 11, (fmmu->sync->control_byte & 0x04) ? 0x02 : 0x01);
+    EC_WRITE_U16(data + 12, 0x0001); // Enable
+    EC_WRITE_U16(data + 14, 0x0000); // res.
 }
 
 /******************************************************************************
--- a/master/slave.c	Thu Feb 23 14:51:45 2006 +0000
+++ b/master/slave.c	Fri Feb 24 10:19:26 2006 +0000
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 
+#include "../include/EtherCAT_si.h"
 #include "globals.h"
 #include "slave.h"
 #include "frame.h"
@@ -75,11 +76,11 @@
         return -1;
     }
 
-    slave->base_type = frame.data[0];
-    slave->base_revision = frame.data[1];
-    slave->base_build = frame.data[2] | (frame.data[3] << 8);
-    slave->base_fmmu_count = frame.data[4];
-    slave->base_sync_count = frame.data[5];
+    slave->base_type =       EC_READ_U8 (frame.data);
+    slave->base_revision =   EC_READ_U8 (frame.data + 1);
+    slave->base_build =      EC_READ_U16(frame.data + 2);
+    slave->base_fmmu_count = EC_READ_U8 (frame.data + 4);
+    slave->base_sync_count = EC_READ_U8 (frame.data + 5);
 
     if (slave->base_fmmu_count > EC_MAX_FMMUS)
         slave->base_fmmu_count = EC_MAX_FMMUS;
@@ -135,12 +136,10 @@
 
     // Initiate read operation
 
-    data[0] = 0x00;
-    data[1] = 0x01;
-    data[2] = offset & 0xFF;
-    data[3] = (offset & 0xFF00) >> 8;
-    data[4] = 0x00;
-    data[5] = 0x00;
+    EC_WRITE_U8 (data,     0x00);
+    EC_WRITE_U8 (data + 1, 0x01);
+    EC_WRITE_U16(data + 2, offset);
+    EC_WRITE_U16(data + 4, 0x0000);
 
     ec_frame_init_npwr(&frame, slave->master, slave->station_address, 0x502, 6,
                        data);
@@ -173,7 +172,7 @@
             return -1;
         }
 
-        if (likely((frame.data[1] & 0x81) == 0)) {
+        if (likely((EC_READ_U8(frame.data + 1) & 0x81) == 0)) {
             memcpy(target, frame.data + 6, 4);
             break;
         }
@@ -208,8 +207,7 @@
     unsigned char data[2];
     unsigned int tries_left;
 
-    data[0] = state | EC_ACK;
-    data[1] = 0x00;
+    EC_WRITE_U16(data, state | EC_ACK);
 
     ec_frame_init_npwr(&frame, slave->master, slave->station_address, 0x0120,
                        2, data);
@@ -247,14 +245,14 @@
             return;
         }
 
-        if (unlikely(frame.data[0] != state)) {
+        if (unlikely(EC_READ_U8(frame.data) != state)) {
             printk(KERN_ERR "EtherCAT: Could not acknowledge state %02X on"
                    " slave %i (code %02X)!\n", state, slave->ring_position,
-                   frame.data[0]);
+                   EC_READ_U8(frame.data));
             return;
         }
 
-        if (likely(frame.data[0] == state)) {
+        if (likely(EC_READ_U8(frame.data) == state)) {
             printk(KERN_INFO "EtherCAT: Acknowleged state %02X on slave %i.\n",
                    state, slave->ring_position);
             return;
@@ -289,8 +287,7 @@
     unsigned char data[2];
     unsigned int tries_left;
 
-    data[0] = state;
-    data[1] = 0x00;
+    EC_WRITE_U16(data, state);
 
     ec_frame_init_npwr(&frame, slave->master, slave->station_address, 0x0120,
                        2, data);
@@ -327,15 +324,15 @@
             return -1;
         }
 
-        if (unlikely(frame.data[0] & 0x10)) { // State change error
+        if (unlikely(EC_READ_U8(frame.data) & 0x10)) { // State change error
             printk(KERN_ERR "EtherCAT: Could not set state %02X - Slave %i"
                    " refused state change (code %02X)!\n", state,
-                   slave->ring_position, frame.data[0]);
-            ec_slave_state_ack(slave, frame.data[0] & 0x0F);
+                   slave->ring_position, EC_READ_U8(frame.data));
+            ec_slave_state_ack(slave, EC_READ_U8(frame.data) & 0x0F);
             return -1;
         }
 
-        if (likely(frame.data[0] == (state & 0x0F))) {
+        if (likely(EC_READ_U8(frame.data) == (state & 0x0F))) {
             // State change successful
             break;
         }
@@ -442,7 +439,6 @@
 {
     ec_frame_t frame;
     uint8_t data[4];
-    uint16_t crc[2];
 
     ec_frame_init_nprd(&frame, slave->master, slave->station_address, 0x0300,
                        4);
@@ -460,17 +456,16 @@
         return -1;
     }
 
-    crc[0] = frame.data[0] | (frame.data[1] << 8);
-    crc[1] = frame.data[2] | (frame.data[3] << 8);
-
     // No CRC faults.
-    if (!crc[0] && !crc[1]) return 0;
+    if (!EC_READ_U16(frame.data) && !EC_READ_U16(frame.data + 2)) return 0;
 
     printk(KERN_INFO "EtherCAT: CRC faults on slave %i. A: %i, B: %i\n",
-           slave->ring_position, crc[0], crc[1]);
+           slave->ring_position, EC_READ_U16(frame.data),
+           EC_READ_U16(frame.data + 2));
 
     // Reset CRC counters
-    memset(data, 0x00, 4);
+    EC_WRITE_U16(data,     0x0000);
+    EC_WRITE_U16(data + 2, 0x0000);
     ec_frame_init_npwr(&frame, slave->master, slave->station_address, 0x0300,
                        4, data);