diff --git a/include/EtherCAT_si.h b/include/EtherCAT_si.h
index 8b08b56a564e8118dcd8d4fba3eb06b0a9f30ed4..54f69e6cd71e51c83b1e18a4f1d1e61e095183f4 100644
--- a/include/EtherCAT_si.h
+++ b/include/EtherCAT_si.h
@@ -8,64 +8,76 @@
  *
  *****************************************************************************/
 
-#define EC_PROC_DATA(SLAVE) ((unsigned char *) ((SLAVE)->process_data))
-
 /*****************************************************************************/
 
-#define EC_READ_EL10XX(SLAVE, CHANNEL) \
-    ((EC_PROC_DATA(SLAVE)[0] >> (CHANNEL)) & 0x01)
+// Bitwise read/write macros
 
-/*****************************************************************************/
+#define EC_READ_BIT(PD, CH) (*((uint8_t *) (PD)) >> (CH)) & 0x01)
 
-#define EC_WRITE_EL200X(SLAVE, CHANNEL, VALUE) \
+#define EC_WRITE_BIT(PD, CH, VAL) \
     do { \
-        if (VALUE) EC_PROC_DATA(SLAVE)[0] |=  (1 << (CHANNEL)); \
-        else       EC_PROC_DATA(SLAVE)[0] &= ~(1 << (CHANNEL)); \
+        if (VAL) *((uint8_t *) (PD)) |=  (1 << (CH)); \
+        else     *((uint8_t *) (PD)) &= ~(1 << (CH)); \
     } while (0)
 
 /*****************************************************************************/
 
-#define EC_READ_EL310X(SLAVE, CHANNEL) \
-    ((signed short int) ((EC_PROC_DATA(SLAVE)[(CHANNEL) * 3 + 2] << 8) | \
-                          EC_PROC_DATA(SLAVE)[(CHANNEL) * 3 + 1]))
+// Read macros
 
-#define EC_READ_EL316X(SLAVE, CHANNEL) \
-    ((unsigned short int) ((EC_PROC_DATA(SLAVE)[(CHANNEL) * 3 + 2] << 8) | \
-                            EC_PROC_DATA(SLAVE)[(CHANNEL) * 3 + 1]))
+#define EC_READ_U8(PD) \
+    (*((uint8_t *) (PD)))
 
-/*****************************************************************************/
+#define EC_READ_S8(PD) \
+    ((int8_t) *((uint8_t *) (PD)))
 
-#define EC_WRITE_EL410X(SLAVE, CHANNEL, VALUE) \
-    do { \
-        EC_PROC_DATA(SLAVE)[(CHANNEL) * 3 + 1] = ((VALUE) & 0xFF00) >> 8; \
-        EC_PROC_DATA(SLAVE)[(CHANNEL) * 3 + 2] =  (VALUE) & 0xFF; \
-    } while (0)
+#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_CONF_EL5001_BAUD (0x4067)
+// Write macros
 
-#define EC_READ_EL5001_STATE(SLAVE) \
-    ((unsigned char) EC_PROC_DATA(SLAVE)[0])
+#define EC_WRITE_U8(PD, VAL) \
+    do { \
+        *((uint8_t *)(PD)) = ((uint8_t) (VAL)); \
+    } while (0)
 
-#define EC_READ_EL5001_VALUE(SLAVE) \
-    ((unsigned int) (EC_PROC_DATA(SLAVE)[1] | \
-                     (EC_PROC_DATA(SLAVE)[2] << 8) | \
-                     (EC_PROC_DATA(SLAVE)[3] << 16) | \
-                     (EC_PROC_DATA(SLAVE)[4] << 24)))
+#define EC_WRITE_S8(PD, VAL) EC_WRITE_U8(PD, VAL)
 
-/*****************************************************************************/
+#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; \
+    } while (0)
 
-#define EC_READ_EL5101_STATE(SLAVE) \
-    ((unsigned char) EC_PROC_DATA(SLAVE)[0])
+#define EC_WRITE_S16(PD, VAL) EC_WRITE_U16(PD, VAL)
 
-#define EC_READ_EL5101_VALUE(SLAVE) \
-    ((unsigned int) (EC_PROC_DATA(SLAVE)[1] | \
-                     (EC_PROC_DATA(SLAVE)[2] << 8)))
+#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; \
+    } while (0)
 
-#define EC_READ_EL5101_LATCH(SLAVE) \
-    ((unsigned int) (EC_PROC_DATA(SLAVE)[3] | \
-                     (EC_PROC_DATA(SLAVE)[4] << 8)))
+#define EC_WRITE_S32(PD, VAL) EC_WRITE_U32(PD, VAL)
 
 /*****************************************************************************/
 
diff --git a/master/master.c b/master/master.c
index 4242cf23acbcfdb287c2557c2a0a4941e1046b78..3d7c11e7302cfcfba48c2f746dd63f2d60ace0ce 100644
--- a/master/master.c
+++ b/master/master.c
@@ -71,14 +71,7 @@ void ec_master_reset(ec_master_t *master
 {
     unsigned int i;
 
-    if (master->slaves) {
-        for (i = 0; i < master->slave_count; i++) {
-            ec_slave_clear(master->slaves + i);
-        }
-        kfree(master->slaves);
-        master->slaves = NULL;
-    }
-    master->slave_count = 0;
+    ec_master_clear_slaves(master);
 
     for (i = 0; i < master->domain_count; i++) {
         ec_domain_clear(master->domains[i]);
@@ -95,6 +88,26 @@ void ec_master_reset(ec_master_t *master
 
 /*****************************************************************************/
 
+/**
+   Entfernt alle Slaves.
+*/
+
+void ec_master_clear_slaves(ec_master_t *master /**< EtherCAT-Master */)
+{
+    unsigned int i;
+
+    if (master->slaves) {
+        for (i = 0; i < master->slave_count; i++) {
+            ec_slave_clear(master->slaves + i);
+        }
+        kfree(master->slaves);
+        master->slaves = NULL;
+    }
+    master->slave_count = 0;
+}
+
+/*****************************************************************************/
+
 /**
    Öffnet das EtherCAT-Geraet des Masters.
 
@@ -152,10 +165,9 @@ int ec_scan_for_slaves(ec_master_t *master /**< EtherCAT-Master */)
     unsigned int i;
     unsigned char data[2];
 
-    if (master->slaves || master->slave_count) {
-        printk(KERN_ERR "EtherCAT: Slave scan already done!\n");
-        return -1;
-    }
+    if (master->slaves || master->slave_count)
+        printk(KERN_WARNING "EtherCAT: Slave scan already done!\n");
+    ec_master_clear_slaves(master);
 
     // Determine number of slaves on bus
 
@@ -434,6 +446,8 @@ ec_domain_t *EtherCAT_rt_master_register_domain(ec_master_t *master,
     return domain;
 }
 
+/*****************************************************************************/
+
 /**
    Konfiguriert alle Slaves und setzt den Operational-Zustand.
 
@@ -486,6 +500,9 @@ int EtherCAT_rt_master_activate(ec_master_t *master /**< EtherCAT-Master */)
 
         type = slave->type;
 
+        // Check and reset CRC fault counters
+        ec_slave_check_crc(slave);
+
         // Resetting FMMU's
         if (slave->base_fmmu_count) {
             memset(data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count);
@@ -581,6 +598,9 @@ int EtherCAT_rt_master_deactivate(ec_master_t *master /**< EtherCAT-Master */)
     {
         slave = master->slaves + i;
 
+        // CRC-Zählerstände ausgeben
+        ec_slave_check_crc(slave);
+
         if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_INIT) != 0))
             return -1;
     }
diff --git a/master/master.h b/master/master.h
index 98c0655fe6e8fb567d9d5520968c9fc038fe3da3..e570d9e9ace9ab5fd3b4061bd161a6e1f3e7e908 100644
--- a/master/master.h
+++ b/master/master.h
@@ -47,6 +47,7 @@ struct ec_master
 void ec_master_init(ec_master_t *);
 void ec_master_clear(ec_master_t *);
 void ec_master_reset(ec_master_t *);
+void ec_master_clear_slaves(ec_master_t *);
 
 // Registration of devices
 int ec_master_open(ec_master_t *);
diff --git a/master/slave.c b/master/slave.c
index 8abe49d42ef0ffc1a9ef803a6586f95206697544..185e502f900862953910b518b5954a201bc21b69 100644
--- a/master/slave.c
+++ b/master/slave.c
@@ -432,6 +432,61 @@ void ec_slave_print(const ec_slave_t *slave /**< EtherCAT-Slave */)
 
 /*****************************************************************************/
 
+/**
+   Gibt die Zählerstände der CRC-Fault-Counter aus und setzt diese zurück.
+
+   \return 0 bei Erfolg, sonst < 0
+*/
+
+int ec_slave_check_crc(ec_slave_t *slave /**< EtherCAT-Slave */)
+{
+    ec_frame_t frame;
+    uint8_t data[4];
+    uint16_t crc[2];
+
+    ec_frame_init_nprd(&frame, slave->master, slave->station_address, 0x0300,
+                       4);
+
+    if (unlikely(ec_frame_send_receive(&frame))) {
+        printk(KERN_WARNING "EtherCAT: Reading CRC fault counters failed"
+               " on slave %i - Could not send command!\n",
+               slave->ring_position);
+        return -1;
+    }
+
+    if (unlikely(frame.working_counter != 1)) {
+        printk(KERN_WARNING "EtherCAT: Reading CRC fault counters -"
+               " Slave %i did not respond!\n", slave->ring_position);
+        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;
+
+    printk(KERN_INFO "EtherCAT: CRC faults on slave %i. A: %i, B: %i\n",
+           slave->ring_position, crc[0], crc[1]);
+
+    // Reset CRC counters
+    memset(data, 0x00, 4);
+    ec_frame_init_npwr(&frame, slave->master, slave->station_address, 0x0300,
+                       4, data);
+
+    if (unlikely(ec_frame_send_receive(&frame))) return -1;
+
+    if (unlikely(frame.working_counter != 1)) {
+        printk(KERN_ERR "EtherCAT: Resetting CRC fault counters - Slave"
+               " %i did not respond!\n", slave->ring_position);
+        return -1;
+    }
+
+    return 0;
+}
+
+/*****************************************************************************/
+
 /* Emacs-Konfiguration
 ;;; Local Variables: ***
 ;;; c-basic-offset:4 ***
diff --git a/master/slave.h b/master/slave.h
index 9187511cc72e4d86129e250c2ef41f8d6da695c4..f9b139708ea7153dd8f70f496d439819b345fba8 100644
--- a/master/slave.h
+++ b/master/slave.h
@@ -77,6 +77,7 @@ int ec_slave_set_fmmu(ec_slave_t *, const ec_domain_t *, const ec_sync_t *);
 
 // Misc
 void ec_slave_print(const ec_slave_t *);
+int ec_slave_check_crc(ec_slave_t *);
 
 /*****************************************************************************/