master/slave.c
changeset 114 e4b4b5a85e75
parent 113 a3dbd6bc8fce
child 118 dc71ce4cc641
--- a/master/slave.c	Mon Mar 20 13:36:10 2006 +0000
+++ b/master/slave.c	Mon Mar 20 15:28:25 2006 +0000
@@ -34,6 +34,7 @@
     slave->base_sync_count = 0;
     slave->ring_position = 0;
     slave->station_address = 0;
+    slave->sii_alias = 0;
     slave->sii_vendor_id = 0;
     slave->sii_product_code = 0;
     slave->sii_revision_number = 0;
@@ -85,6 +86,12 @@
 
     // Read identification from "Slave Information Interface" (SII)
 
+    if (unlikely(ec_slave_sii_read(slave, 0x0004,
+                                   (uint32_t *) &slave->sii_alias))) {
+        EC_ERR("Could not read SII alias!\n");
+        return -1;
+    }
+
     if (unlikely(ec_slave_sii_read(slave, 0x0008, &slave->sii_vendor_id))) {
         EC_ERR("Could not read SII vendor id!\n");
         return -1;
@@ -134,10 +141,9 @@
 
     // Initiate read operation
 
-    EC_WRITE_U8 (data,     0x00);
-    EC_WRITE_U8 (data + 1, 0x01);
-    EC_WRITE_U16(data + 2, offset);
-    EC_WRITE_U16(data + 4, 0x0000);
+    EC_WRITE_U8 (data,     0x00); // read-only access
+    EC_WRITE_U8 (data + 1, 0x01); // request read operation
+    EC_WRITE_U32(data + 2, offset);
 
     ec_command_init_npwr(&command, slave->station_address, 0x502, 6, data);
     if (unlikely(ec_master_simple_io(slave->master, &command))) {
@@ -166,7 +172,7 @@
         end = get_cycles();
 
         if (likely((EC_READ_U8(command.data + 1) & 0x81) == 0)) {
-            memcpy(target, command.data + 6, 4);
+            *target = EC_READ_U32(command.data + 6);
             return 0;
         }
 
@@ -180,6 +186,81 @@
 /*****************************************************************************/
 
 /**
+   Schreibt Daten in das Slave-Information-Interface
+   eines EtherCAT-Slaves.
+
+   \return 0 bei Erfolg, sonst < 0
+*/
+
+int ec_slave_sii_write(ec_slave_t *slave,
+                       /**< EtherCAT-Slave */
+                       uint16_t offset,
+                       /**< Adresse des zu lesenden SII-Registers */
+                       uint16_t value
+                       /**< Zu schreibender Wert */
+                       )
+{
+    ec_command_t command;
+    uint8_t data[8];
+    cycles_t start, end, timeout;
+
+    EC_INFO("SII-write (slave %i, offset 0x%04X, value 0x%04X)\n",
+            slave->ring_position, offset, value);
+
+    // Initiate write operation
+
+    EC_WRITE_U8 (data,     0x01); // enable write access
+    EC_WRITE_U8 (data + 1, 0x02); // request write operation
+    EC_WRITE_U32(data + 2, offset);
+    EC_WRITE_U16(data + 6, value);
+
+    ec_command_init_npwr(&command, slave->station_address, 0x502, 8, data);
+    if (unlikely(ec_master_simple_io(slave->master, &command))) {
+        EC_ERR("SII-write failed on slave %i!\n", slave->ring_position);
+        return -1;
+    }
+
+    // Der Slave legt die Informationen des Slave-Information-Interface
+    // in das Datenregister und löscht daraufhin ein Busy-Bit. Solange
+    // den Status auslesen, bis das Bit weg ist.
+
+    start = get_cycles();
+    timeout = cpu_khz; // 1ms
+
+    while (1)
+    {
+        udelay(10);
+
+        ec_command_init_nprd(&command, slave->station_address, 0x502, 2);
+        if (unlikely(ec_master_simple_io(slave->master, &command))) {
+            EC_ERR("Getting SII-write status failed on slave %i!\n",
+                   slave->ring_position);
+            return -1;
+        }
+
+        end = get_cycles();
+
+        if (likely((EC_READ_U8(command.data + 1) & 0x82) == 0)) {
+            if (EC_READ_U8(command.data + 1) & 0x40) {
+                EC_ERR("SII-write failed!\n");
+                return -1;
+            }
+            else {
+                EC_INFO("SII-write succeeded!\n");
+                return 0;
+            }
+        }
+
+        if (unlikely((end - start) >= timeout)) {
+            EC_ERR("SSI-write: Slave %i timed out!\n", slave->ring_position);
+            return -1;
+        }
+    }
+}
+
+/*****************************************************************************/
+
+/**
    Bestätigt einen Fehler beim Zustandswechsel.
 
    \todo Funktioniert noch nicht...
@@ -377,6 +458,8 @@
             slave->base_fmmu_count, slave->base_sync_count);
 
     EC_INFO("  Slave information interface:\n");
+    EC_INFO("    Configured station alias: 0x%04X (%i)\n", slave->sii_alias,
+            slave->sii_alias);
     EC_INFO("    Vendor-ID: 0x%08X, Product code: 0x%08X\n",
             slave->sii_vendor_id, slave->sii_product_code);
     EC_INFO("    Revision number: 0x%08X, Serial number: 0x%08X\n",
@@ -429,3 +512,4 @@
 ;;; c-basic-offset:4 ***
 ;;; End: ***
 */
+