master/master.c
branchstable-1.0
changeset 1624 9dc190591c0f
parent 1621 4bbe090553f7
--- a/master/master.c	Mon Jun 26 16:07:07 2006 +0000
+++ b/master/master.c	Wed Aug 02 12:25:25 2006 +0000
@@ -50,12 +50,12 @@
 #include "slave.h"
 #include "types.h"
 #include "device.h"
-#include "command.h"
+#include "datagram.h"
 #include "ethernet.h"
 
 /*****************************************************************************/
 
-void ec_master_freerun(void *);
+void ec_master_idle_run(void *);
 void ec_master_eoe_run(unsigned long);
 ssize_t ec_show_master_attribute(struct kobject *, struct attribute *, char *);
 ssize_t ec_store_master_attribute(struct kobject *, struct attribute *,
@@ -68,11 +68,13 @@
 EC_SYSFS_READ_ATTR(slave_count);
 EC_SYSFS_READ_ATTR(mode);
 EC_SYSFS_READ_WRITE_ATTR(eeprom_write_enable);
+EC_SYSFS_READ_WRITE_ATTR(debug_level);
 
 static struct attribute *ec_def_attrs[] = {
     &attr_slave_count,
     &attr_mode,
     &attr_eeprom_write_enable,
+    &attr_debug_level,
     NULL,
 };
 
@@ -98,7 +100,7 @@
 
 int ec_master_init(ec_master_t *master, /**< EtherCAT master */
                    unsigned int index, /**< master index */
-                   unsigned int eoe_devices /**< number of EoE devices */
+                   unsigned int eoeif_count /**< number of EoE interfaces */
                    )
 {
     ec_eoe_t *eoe, *next_eoe;
@@ -110,11 +112,11 @@
     master->device = NULL;
     master->reserved = 0;
     INIT_LIST_HEAD(&master->slaves);
-    INIT_LIST_HEAD(&master->command_queue);
+    INIT_LIST_HEAD(&master->datagram_queue);
     INIT_LIST_HEAD(&master->domains);
     INIT_LIST_HEAD(&master->eoe_handlers);
-    ec_command_init(&master->simple_command);
-    INIT_WORK(&master->freerun_work, ec_master_freerun, (void *) master);
+    ec_datagram_init(&master->simple_datagram);
+    INIT_WORK(&master->idle_work, ec_master_idle_run, (void *) master);
     init_timer(&master->eoe_timer);
     master->eoe_timer.function = ec_master_eoe_run;
     master->eoe_timer.data = (unsigned long) master;
@@ -128,7 +130,7 @@
     }
 
     // create EoE handlers
-    for (i = 0; i < eoe_devices; i++) {
+    for (i = 0; i < eoeif_count; i++) {
         if (!(eoe = (ec_eoe_t *) kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) {
             EC_ERR("Failed to allocate EoE-Object.\n");
             goto out_clear_eoe;
@@ -171,7 +173,7 @@
 
 /**
    Master destructor.
-   Removes all pending commands, clears the slave list, clears all domains
+   Removes all pending datagrams, clears the slave list, clears all domains
    and frees the device.
 */
 
@@ -184,7 +186,7 @@
 
     ec_master_reset(master);
     ec_fsm_clear(&master->fsm);
-    ec_command_clear(&master->simple_command);
+    ec_datagram_clear(&master->simple_datagram);
     destroy_workqueue(master->workqueue);
 
     // clear EoE objects
@@ -212,17 +214,18 @@
 
 void ec_master_reset(ec_master_t *master /**< EtherCAT master */)
 {
-    ec_command_t *command, *next_c;
+    ec_datagram_t *datagram, *next_c;
     ec_domain_t *domain, *next_d;
 
     ec_master_eoe_stop(master);
-    ec_master_freerun_stop(master);
+    ec_master_idle_stop(master);
     ec_master_clear_slaves(master);
 
-    // empty command queue
-    list_for_each_entry_safe(command, next_c, &master->command_queue, queue) {
-        list_del_init(&command->queue);
-        command->state = EC_CMD_ERROR;
+    // empty datagram queue
+    list_for_each_entry_safe(datagram, next_c,
+                             &master->datagram_queue, queue) {
+        list_del_init(&datagram->queue);
+        datagram->state = EC_CMD_ERROR;
     }
 
     // clear domains
@@ -232,7 +235,7 @@
         kobject_put(&domain->kobj);
     }
 
-    master->command_index = 0;
+    master->datagram_index = 0;
     master->debug_level = 0;
     master->timeout = 500; // 500us
 
@@ -242,7 +245,7 @@
     master->stats.unmatched = 0;
     master->stats.t_last = 0;
 
-    master->mode = EC_MASTER_MODE_IDLE;
+    master->mode = EC_MASTER_MODE_ORPHANED;
 
     master->request_cb = NULL;
     master->release_cb = NULL;
@@ -274,101 +277,101 @@
 /*****************************************************************************/
 
 /**
-   Places a command in the command queue.
-*/
-
-void ec_master_queue_command(ec_master_t *master, /**< EtherCAT master */
-                             ec_command_t *command /**< command */
-                             )
-{
-    ec_command_t *queued_command;
-
-    // check, if the command is already queued
-    list_for_each_entry(queued_command, &master->command_queue, queue) {
-        if (queued_command == command) {
-            command->state = EC_CMD_QUEUED;
+   Places a datagram in the datagram queue.
+*/
+
+void ec_master_queue_datagram(ec_master_t *master, /**< EtherCAT master */
+                              ec_datagram_t *datagram /**< datagram */
+                              )
+{
+    ec_datagram_t *queued_datagram;
+
+    // check, if the datagram is already queued
+    list_for_each_entry(queued_datagram, &master->datagram_queue, queue) {
+        if (queued_datagram == datagram) {
+            datagram->state = EC_CMD_QUEUED;
             if (unlikely(master->debug_level))
-                EC_WARN("command already queued.\n");
+                EC_WARN("datagram already queued.\n");
             return;
         }
     }
 
-    list_add_tail(&command->queue, &master->command_queue);
-    command->state = EC_CMD_QUEUED;
-}
-
-/*****************************************************************************/
-
-/**
-   Sends the commands in the queue.
+    list_add_tail(&datagram->queue, &master->datagram_queue);
+    datagram->state = EC_CMD_QUEUED;
+}
+
+/*****************************************************************************/
+
+/**
+   Sends the datagrams in the queue.
    \return 0 in case of success, else < 0
 */
 
-void ec_master_send_commands(ec_master_t *master /**< EtherCAT master */)
-{
-    ec_command_t *command;
-    size_t command_size;
+void ec_master_send_datagrams(ec_master_t *master /**< EtherCAT master */)
+{
+    ec_datagram_t *datagram;
+    size_t datagram_size;
     uint8_t *frame_data, *cur_data;
     void *follows_word;
     cycles_t t_start, t_end;
-    unsigned int frame_count, more_commands_waiting;
+    unsigned int frame_count, more_datagrams_waiting;
 
     frame_count = 0;
     t_start = get_cycles();
 
-    if (unlikely(master->debug_level > 0))
-        EC_DBG("ec_master_send_commands\n");
+    if (unlikely(master->debug_level > 1))
+        EC_DBG("ec_master_send_datagrams\n");
 
     do {
         // fetch pointer to transmit socket buffer
         frame_data = ec_device_tx_data(master->device);
         cur_data = frame_data + EC_FRAME_HEADER_SIZE;
         follows_word = NULL;
-        more_commands_waiting = 0;
-
-        // fill current frame with commands
-        list_for_each_entry(command, &master->command_queue, queue) {
-            if (command->state != EC_CMD_QUEUED) continue;
-
-            // does the current command fit in the frame?
-            command_size = EC_COMMAND_HEADER_SIZE + command->data_size
-                + EC_COMMAND_FOOTER_SIZE;
-            if (cur_data - frame_data + command_size > ETH_DATA_LEN) {
-                more_commands_waiting = 1;
+        more_datagrams_waiting = 0;
+
+        // fill current frame with datagrams
+        list_for_each_entry(datagram, &master->datagram_queue, queue) {
+            if (datagram->state != EC_CMD_QUEUED) continue;
+
+            // does the current datagram fit in the frame?
+            datagram_size = EC_DATAGRAM_HEADER_SIZE + datagram->data_size
+                + EC_DATAGRAM_FOOTER_SIZE;
+            if (cur_data - frame_data + datagram_size > ETH_DATA_LEN) {
+                more_datagrams_waiting = 1;
                 break;
             }
 
-            command->state = EC_CMD_SENT;
-            command->t_sent = t_start;
-            command->index = master->command_index++;
-
-            if (unlikely(master->debug_level > 0))
-                EC_DBG("adding command 0x%02X\n", command->index);
-
-            // set "command following" flag in previous frame
+            datagram->state = EC_CMD_SENT;
+            datagram->t_sent = t_start;
+            datagram->index = master->datagram_index++;
+
+            if (unlikely(master->debug_level > 1))
+                EC_DBG("adding datagram 0x%02X\n", datagram->index);
+
+            // set "datagram following" flag in previous frame
             if (follows_word)
                 EC_WRITE_U16(follows_word, EC_READ_U16(follows_word) | 0x8000);
 
-            // EtherCAT command header
-            EC_WRITE_U8 (cur_data,     command->type);
-            EC_WRITE_U8 (cur_data + 1, command->index);
-            EC_WRITE_U32(cur_data + 2, command->address.logical);
-            EC_WRITE_U16(cur_data + 6, command->data_size & 0x7FF);
+            // 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);
+            EC_WRITE_U16(cur_data + 6, datagram->data_size & 0x7FF);
             EC_WRITE_U16(cur_data + 8, 0x0000);
             follows_word = cur_data + 6;
-            cur_data += EC_COMMAND_HEADER_SIZE;
-
-            // EtherCAT command data
-            memcpy(cur_data, command->data, command->data_size);
-            cur_data += command->data_size;
-
-            // EtherCAT command footer
+            cur_data += EC_DATAGRAM_HEADER_SIZE;
+
+            // EtherCAT datagram data
+            memcpy(cur_data, datagram->data, datagram->data_size);
+            cur_data += datagram->data_size;
+
+            // EtherCAT datagram footer
             EC_WRITE_U16(cur_data, 0x0000); // reset working counter
-            cur_data += EC_COMMAND_FOOTER_SIZE;
+            cur_data += EC_DATAGRAM_FOOTER_SIZE;
         }
 
         if (cur_data - frame_data == EC_FRAME_HEADER_SIZE) {
-            if (unlikely(master->debug_level > 0))
+            if (unlikely(master->debug_level > 1))
                 EC_DBG("nothing to send.\n");
             break;
         }
@@ -381,19 +384,19 @@
         while (cur_data - frame_data < ETH_ZLEN - ETH_HLEN)
             EC_WRITE_U8(cur_data++, 0x00);
 
-        if (unlikely(master->debug_level > 0))
+        if (unlikely(master->debug_level > 1))
             EC_DBG("frame size: %i\n", cur_data - frame_data);
 
         // send frame
         ec_device_send(master->device, cur_data - frame_data);
         frame_count++;
     }
-    while (more_commands_waiting);
-
-    if (unlikely(master->debug_level > 0)) {
+    while (more_datagrams_waiting);
+
+    if (unlikely(master->debug_level > 1)) {
         t_end = get_cycles();
-        EC_DBG("ec_master_send_commands sent %i frames in %ius.\n",
-               frame_count, (u32) (t_end - t_start) * 1000 / cpu_khz);
+        EC_DBG("ec_master_send_datagrams sent %i frames in %ius.\n",
+               frame_count, (unsigned int) (t_end - t_start) * 1000 / cpu_khz);
     }
 }
 
@@ -411,10 +414,10 @@
                        )
 {
     size_t frame_size, data_size;
-    uint8_t command_type, command_index;
+    uint8_t datagram_type, datagram_index;
     unsigned int cmd_follows, matched;
     const uint8_t *cur_data;
-    ec_command_t *command;
+    ec_datagram_t *datagram;
 
     if (unlikely(size < EC_FRAME_HEADER_SIZE)) {
         master->stats.corrupted++;
@@ -436,64 +439,64 @@
 
     cmd_follows = 1;
     while (cmd_follows) {
-        // process command header
-        command_type  = EC_READ_U8 (cur_data);
-        command_index = EC_READ_U8 (cur_data + 1);
-        data_size     = EC_READ_U16(cur_data + 6) & 0x07FF;
-        cmd_follows   = EC_READ_U16(cur_data + 6) & 0x8000;
-        cur_data += EC_COMMAND_HEADER_SIZE;
+        // process datagram header
+        datagram_type  = EC_READ_U8 (cur_data);
+        datagram_index = EC_READ_U8 (cur_data + 1);
+        data_size      = EC_READ_U16(cur_data + 6) & 0x07FF;
+        cmd_follows    = EC_READ_U16(cur_data + 6) & 0x8000;
+        cur_data += EC_DATAGRAM_HEADER_SIZE;
 
         if (unlikely(cur_data - frame_data
-                     + data_size + EC_COMMAND_FOOTER_SIZE > size)) {
+                     + data_size + EC_DATAGRAM_FOOTER_SIZE > size)) {
             master->stats.corrupted++;
             ec_master_output_stats(master);
             return;
         }
 
-        // search for matching command in the queue
+        // search for matching datagram in the queue
         matched = 0;
-        list_for_each_entry(command, &master->command_queue, queue) {
-            if (command->state == EC_CMD_SENT
-                && command->type == command_type
-                && command->index == command_index
-                && command->data_size == data_size) {
+        list_for_each_entry(datagram, &master->datagram_queue, queue) {
+            if (datagram->state == EC_CMD_SENT
+                && datagram->type == datagram_type
+                && datagram->index == datagram_index
+                && datagram->data_size == data_size) {
                 matched = 1;
                 break;
             }
         }
 
-        // no matching command was found
+        // no matching datagram was found
         if (!matched) {
             master->stats.unmatched++;
             ec_master_output_stats(master);
-            cur_data += data_size + EC_COMMAND_FOOTER_SIZE;
+            cur_data += data_size + EC_DATAGRAM_FOOTER_SIZE;
             continue;
         }
 
-        // copy received data in the command memory
-        memcpy(command->data, cur_data, data_size);
+        // copy received data in the datagram memory
+        memcpy(datagram->data, cur_data, data_size);
         cur_data += data_size;
 
-        // set the command's working counter
-        command->working_counter = EC_READ_U16(cur_data);
-        cur_data += EC_COMMAND_FOOTER_SIZE;
-
-        // dequeue the received command
-        command->state = EC_CMD_RECEIVED;
-        list_del_init(&command->queue);
-    }
-}
-
-/*****************************************************************************/
-
-/**
-   Sends a single command and waits for its reception.
-   If the slave doesn't respond, the command is sent again.
+        // set the datagram's working counter
+        datagram->working_counter = EC_READ_U16(cur_data);
+        cur_data += EC_DATAGRAM_FOOTER_SIZE;
+
+        // dequeue the received datagram
+        datagram->state = EC_CMD_RECEIVED;
+        list_del_init(&datagram->queue);
+    }
+}
+
+/*****************************************************************************/
+
+/**
+   Sends a single datagram and waits for its reception.
+   If the slave doesn't respond, the datagram is sent again.
    \return 0 in case of success, else < 0
 */
 
 int ec_master_simple_io(ec_master_t *master, /**< EtherCAT master */
-                        ec_command_t *command /**< command */
+                        ec_datagram_t *datagram /**< datagram */
                         )
 {
     unsigned int response_tries_left;
@@ -502,19 +505,19 @@
 
     while (1)
     {
-        ec_master_queue_command(master, command);
+        ec_master_queue_datagram(master, datagram);
         ecrt_master_sync_io(master);
 
-        if (command->state == EC_CMD_RECEIVED) {
-            if (likely(command->working_counter))
+        if (datagram->state == EC_CMD_RECEIVED) {
+            if (likely(datagram->working_counter))
                 return 0;
         }
-        else if (command->state == EC_CMD_TIMEOUT) {
+        else if (datagram->state == EC_CMD_TIMEOUT) {
             EC_ERR("Simple-IO TIMEOUT!\n");
             return -1;
         }
-        else if (command->state == EC_CMD_ERROR) {
-            EC_ERR("Simple-IO command error!\n");
+        else if (datagram->state == EC_CMD_ERROR) {
+            EC_ERR("Simple-IO datagram error!\n");
             return -1;
         }
 
@@ -540,7 +543,7 @@
 {
     ec_slave_t *slave;
     ec_slave_ident_t *ident;
-    ec_command_t *command;
+    ec_datagram_t *datagram;
     unsigned int i;
     uint16_t coupler_index, coupler_subindex;
     uint16_t reverse_coupler_index, current_coupler_index;
@@ -550,12 +553,12 @@
         return -1;
     }
 
-    command = &master->simple_command;
+    datagram = &master->simple_datagram;
 
     // determine number of slaves on bus
-    if (ec_command_brd(command, 0x0000, 4)) return -1;
-    if (unlikely(ec_master_simple_io(master, command))) return -1;
-    master->slave_count = command->working_counter;
+    if (ec_datagram_brd(datagram, 0x0000, 4)) return -1;
+    if (unlikely(ec_master_simple_io(master, datagram))) return -1;
+    master->slave_count = datagram->working_counter;
     EC_INFO("Found %i slaves on bus.\n", master->slave_count);
 
     if (!master->slave_count) return 0;
@@ -588,10 +591,10 @@
     list_for_each_entry(slave, &master->slaves, list) {
 
         // write station address
-        if (ec_command_apwr(command, slave->ring_position, 0x0010,
+        if (ec_datagram_apwr(datagram, slave->ring_position, 0x0010,
                             sizeof(uint16_t))) goto out_free;
-        EC_WRITE_U16(command->data, slave->station_address);
-        if (unlikely(ec_master_simple_io(master, command))) {
+        EC_WRITE_U16(datagram->data, slave->station_address);
+        if (unlikely(ec_master_simple_io(master, datagram))) {
             EC_ERR("Writing station address failed on slave %i!\n",
                    slave->ring_position);
             goto out_free;
@@ -650,7 +653,7 @@
 
     if (unlikely((u32) (t_now - master->stats.t_last) / cpu_khz > 1000)) {
         if (master->stats.timeouts) {
-            EC_WARN("%i commands TIMED OUT!\n", master->stats.timeouts);
+            EC_WARN("%i datagrams TIMED OUT!\n", master->stats.timeouts);
             master->stats.timeouts = 0;
         }
         if (master->stats.delayed) {
@@ -662,7 +665,7 @@
             master->stats.corrupted = 0;
         }
         if (master->stats.unmatched) {
-            EC_WARN("%i command(s) UNMATCHED!\n", master->stats.unmatched);
+            EC_WARN("%i datagram(s) UNMATCHED!\n", master->stats.unmatched);
             master->stats.unmatched = 0;
         }
         master->stats.t_last = t_now;
@@ -672,41 +675,43 @@
 /*****************************************************************************/
 
 /**
-   Starts the Free-Run mode.
-*/
-
-void ec_master_freerun_start(ec_master_t *master /**< EtherCAT master */)
-{
-    if (master->mode == EC_MASTER_MODE_FREERUN) return;
+   Starts the Idle mode.
+*/
+
+void ec_master_idle_start(ec_master_t *master /**< EtherCAT master */)
+{
+    if (master->mode == EC_MASTER_MODE_IDLE) return;
 
     if (master->mode == EC_MASTER_MODE_RUNNING) {
-        EC_ERR("ec_master_freerun_start: Master already running!\n");
+        EC_ERR("ec_master_idle_start: Master already running!\n");
         return;
     }
 
-    EC_INFO("Starting Free-Run mode.\n");
-
-    master->mode = EC_MASTER_MODE_FREERUN;
+    EC_INFO("Starting Idle mode.\n");
+
+    master->mode = EC_MASTER_MODE_IDLE;
     ec_fsm_reset(&master->fsm);
-    queue_delayed_work(master->workqueue, &master->freerun_work, 1);
-}
-
-/*****************************************************************************/
-
-/**
-   Stops the Free-Run mode.
-*/
-
-void ec_master_freerun_stop(ec_master_t *master /**< EtherCAT master */)
-{
-    if (master->mode != EC_MASTER_MODE_FREERUN) return;
+    queue_delayed_work(master->workqueue, &master->idle_work, 1);
+}
+
+/*****************************************************************************/
+
+/**
+   Stops the Idle mode.
+*/
+
+void ec_master_idle_stop(ec_master_t *master /**< EtherCAT master */)
+{
+    if (master->mode != EC_MASTER_MODE_IDLE) return;
 
     ec_master_eoe_stop(master);
 
-    EC_INFO("Stopping Free-Run mode.\n");
-    master->mode = EC_MASTER_MODE_IDLE;
-
-    if (!cancel_delayed_work(&master->freerun_work)) {
+    EC_INFO("Stopping Idle mode.\n");
+    master->mode = EC_MASTER_MODE_ORPHANED; // this is important for the
+                                            // IDLE work function to not
+                                            // queue itself again
+
+    if (!cancel_delayed_work(&master->idle_work)) {
         flush_workqueue(master->workqueue);
     }
 
@@ -716,10 +721,10 @@
 /*****************************************************************************/
 
 /**
-   Free-Run mode function.
-*/
-
-void ec_master_freerun(void *data /**< master pointer */)
+   Idle mode function.
+*/
+
+void ec_master_idle_run(void *data /**< master pointer */)
 {
     ec_master_t *master = (ec_master_t *) data;
 
@@ -736,8 +741,8 @@
     // release master lock
     spin_unlock_bh(&master->internal_lock);
 
-    if (master->mode == EC_MASTER_MODE_FREERUN)
-        queue_delayed_work(master->workqueue, &master->freerun_work, 1);
+    if (master->mode == EC_MASTER_MODE_IDLE)
+        queue_delayed_work(master->workqueue, &master->idle_work, 1);
 }
 
 /*****************************************************************************/
@@ -771,11 +776,24 @@
 */
 
 void ec_eeprom_sync_config(const ec_eeprom_sync_t *sync, /**< sync manager */
+                           const ec_slave_t *slave, /**< EtherCAT slave */
                            uint8_t *data /**> configuration memory */
                            )
 {
+    size_t sync_size;
+
+    sync_size = ec_slave_calc_eeprom_sync_size(slave, sync);
+
+    if (slave->master->debug_level) {
+        EC_INFO("Slave %i, sync manager %i:\n", slave->ring_position,
+                sync->index);
+        EC_INFO("  Address: 0x%04X\n", sync->physical_start_address);
+        EC_INFO("     Size: %i\n", sync_size);
+        EC_INFO("  Control: 0x%02X\n", sync->control_register);
+    }
+
     EC_WRITE_U16(data,     sync->physical_start_address);
-    EC_WRITE_U16(data + 2, sync->length);
+    EC_WRITE_U16(data + 2, sync_size);
     EC_WRITE_U8 (data + 4, sync->control_register);
     EC_WRITE_U8 (data + 5, 0x00); // status byte (read only)
     EC_WRITE_U16(data + 6, sync->enable ? 0x0001 : 0x0000); // enable
@@ -827,14 +845,20 @@
     }
     else if (attr == &attr_mode) {
         switch (master->mode) {
+            case EC_MASTER_MODE_ORPHANED:
+                return sprintf(buffer, "ORPHANED\n");
             case EC_MASTER_MODE_IDLE:
                 return sprintf(buffer, "IDLE\n");
-            case EC_MASTER_MODE_FREERUN:
-                return sprintf(buffer, "FREERUN\n");
             case EC_MASTER_MODE_RUNNING:
                 return sprintf(buffer, "RUNNING\n");
         }
     }
+    else if (attr == &attr_debug_level) {
+        return sprintf(buffer, "%i\n", master->debug_level);
+    }
+    else if (attr == &attr_eeprom_write_enable) {
+        return sprintf(buffer, "%i\n", master->eeprom_write_enable);
+    }
 
     return 0;
 }
@@ -873,6 +897,24 @@
             EC_INFO("Slave EEPROM writing disabled.\n");
         }
     }
+    else if (attr == &attr_debug_level) {
+        if (!strcmp(buffer, "0\n")) {
+            master->debug_level = 0;
+        }
+        else if (!strcmp(buffer, "1\n")) {
+            master->debug_level = 1;
+        }
+        else if (!strcmp(buffer, "2\n")) {
+            master->debug_level = 2;
+        }
+        else {
+            EC_ERR("Invalid debug level value!\n");
+            return -EINVAL;
+        }
+
+        EC_INFO("Master debug level set to %i.\n", master->debug_level);
+        return size;
+    }
 
     return -EINVAL;
 }
@@ -914,14 +956,14 @@
             else {
                 slave->requested_state = EC_SLAVE_STATE_INIT;
             }
-            slave->state_error = 0;
+            slave->error_flag = 0;
             break;
         }
 
         if (!found) {
             EC_WARN("No EoE handler for slave %i!\n", slave->ring_position);
             slave->requested_state = EC_SLAVE_STATE_INIT;
-            slave->state_error = 0;
+            slave->error_flag = 0;
         }
     }
 
@@ -959,7 +1001,7 @@
     list_for_each_entry(eoe, &master->eoe_handlers, list) {
         if (eoe->slave) {
             eoe->slave->requested_state = EC_SLAVE_STATE_INIT;
-            eoe->slave->state_error = 0;
+            eoe->slave->error_flag = 0;
             eoe->slave = NULL;
         }
     }
@@ -989,7 +1031,7 @@
         if (master->request_cb(master->cb_data))
             goto queue_timer;
     }
-    else if (master->mode == EC_MASTER_MODE_FREERUN) {
+    else if (master->mode == EC_MASTER_MODE_IDLE) {
         spin_lock(&master->internal_lock);
     }
     else
@@ -1006,7 +1048,7 @@
     if (master->mode == EC_MASTER_MODE_RUNNING) {
         master->release_cb(master->cb_data);
     }
-    else if (master->mode == EC_MASTER_MODE_FREERUN) {
+    else if (master->mode == EC_MASTER_MODE_IDLE) {
         spin_unlock(&master->internal_lock);
     }
 
@@ -1075,7 +1117,7 @@
 {
     unsigned int j;
     ec_slave_t *slave;
-    ec_command_t *command;
+    ec_datagram_t *datagram;
     const ec_sync_t *sync;
     const ec_slave_type_t *type;
     const ec_fmmu_t *fmmu;
@@ -1083,7 +1125,7 @@
     ec_domain_t *domain;
     ec_eeprom_sync_t *eeprom_sync, mbox_sync;
 
-    command = &master->simple_command;
+    datagram = &master->simple_datagram;
 
     // allocate all domains
     domain_offset = 0;
@@ -1112,11 +1154,12 @@
 
         // reset FMMUs
         if (slave->base_fmmu_count) {
-            if (ec_command_npwr(command, slave->station_address, 0x0600,
-                                EC_FMMU_SIZE * slave->base_fmmu_count))
+            if (ec_datagram_npwr(datagram, slave->station_address, 0x0600,
+                                 EC_FMMU_SIZE * slave->base_fmmu_count))
                 return -1;
-            memset(command->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count);
-            if (unlikely(ec_master_simple_io(master, command))) {
+            memset(datagram->data, 0x00,
+                   EC_FMMU_SIZE * slave->base_fmmu_count);
+            if (unlikely(ec_master_simple_io(master, datagram))) {
                 EC_ERR("Resetting FMMUs failed on slave %i!\n",
                        slave->ring_position);
                 return -1;
@@ -1125,11 +1168,12 @@
 
         // reset sync managers
         if (slave->base_sync_count) {
-            if (ec_command_npwr(command, slave->station_address, 0x0800,
+            if (ec_datagram_npwr(datagram, slave->station_address, 0x0800,
                                 EC_SYNC_SIZE * slave->base_sync_count))
                 return -1;
-            memset(command->data, 0x00, EC_SYNC_SIZE * slave->base_sync_count);
-            if (unlikely(ec_master_simple_io(master, command))) {
+            memset(datagram->data, 0x00,
+                   EC_SYNC_SIZE * slave->base_sync_count);
+            if (unlikely(ec_master_simple_io(master, datagram))) {
                 EC_ERR("Resetting sync managers failed on slave %i!\n",
                        slave->ring_position);
                 return -1;
@@ -1137,68 +1181,67 @@
         }
 
         // configure sync managers
-        if (type) { // known slave type, take type's SM information
+
+        // does the slave provide sync manager information?
+        if (!list_empty(&slave->eeprom_syncs)) {
+            list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) {
+                if (ec_datagram_npwr(datagram, slave->station_address,
+                                     0x800 + eeprom_sync->index *
+                                     EC_SYNC_SIZE,
+                                     EC_SYNC_SIZE)) return -1;
+                ec_eeprom_sync_config(eeprom_sync, slave, datagram->data);
+                if (unlikely(ec_master_simple_io(master, datagram))) {
+                    EC_ERR("Setting sync manager %i failed on slave %i!\n",
+                           eeprom_sync->index, slave->ring_position);
+                    return -1;
+                }
+            }
+        }
+
+        else if (type) { // known slave type, take type's SM information
             for (j = 0; type->sync_managers[j] && j < EC_MAX_SYNC; j++) {
                 sync = type->sync_managers[j];
-                if (ec_command_npwr(command, slave->station_address,
-                                    0x0800 + j * EC_SYNC_SIZE, EC_SYNC_SIZE))
+                if (ec_datagram_npwr(datagram, slave->station_address,
+                                     0x0800 + j * EC_SYNC_SIZE, EC_SYNC_SIZE))
                     return -1;
-                ec_sync_config(sync, slave, command->data);
-                if (unlikely(ec_master_simple_io(master, command))) {
+                ec_sync_config(sync, slave, datagram->data);
+                if (unlikely(ec_master_simple_io(master, datagram))) {
                     EC_ERR("Setting sync manager %i failed on slave %i!\n",
                            j, slave->ring_position);
                     return -1;
                 }
             }
         }
-        else if (slave->sii_mailbox_protocols) { // unknown type, but mailbox
-            // does the device supply SM configurations in its EEPROM?
-	    if (!list_empty(&slave->eeprom_syncs)) {
-		list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) {
-		    EC_INFO("Sync manager %i...\n", eeprom_sync->index);
-		    if (ec_command_npwr(command, slave->station_address,
-					0x800 + eeprom_sync->index *
-					EC_SYNC_SIZE,
-					EC_SYNC_SIZE)) return -1;
-		    ec_eeprom_sync_config(eeprom_sync, command->data);
-		    if (unlikely(ec_master_simple_io(master, command))) {
-			EC_ERR("Setting sync manager %i failed on slave %i!\n",
-			       eeprom_sync->index, slave->ring_position);
-			return -1;
-		    }
-		}
+
+        // no sync manager information; guess mailbox settings
+        else if (slave->sii_mailbox_protocols) { 
+            mbox_sync.physical_start_address =
+                slave->sii_rx_mailbox_offset;
+            mbox_sync.length = slave->sii_rx_mailbox_size;
+            mbox_sync.control_register = 0x26;
+            mbox_sync.enable = 1;
+            if (ec_datagram_npwr(datagram, slave->station_address,
+                                 0x800,EC_SYNC_SIZE)) return -1;
+            ec_eeprom_sync_config(&mbox_sync, slave, datagram->data);
+            if (unlikely(ec_master_simple_io(master, datagram))) {
+                EC_ERR("Setting sync manager 0 failed on slave %i!\n",
+                       slave->ring_position);
+                return -1;
             }
-	    else { // no sync manager information; guess mailbox settings
-		mbox_sync.physical_start_address =
-                    slave->sii_rx_mailbox_offset;
-		mbox_sync.length = slave->sii_rx_mailbox_size;
-		mbox_sync.control_register = 0x26;
-		mbox_sync.enable = 1;
-		if (ec_command_npwr(command, slave->station_address,
-				    0x800,EC_SYNC_SIZE)) return -1;
-		ec_eeprom_sync_config(&mbox_sync, command->data);
-		if (unlikely(ec_master_simple_io(master, command))) {
-		    EC_ERR("Setting sync manager 0 failed on slave %i!\n",
-			   slave->ring_position);
-		    return -1;
-		}
-
-		mbox_sync.physical_start_address =
-                    slave->sii_tx_mailbox_offset;
-		mbox_sync.length = slave->sii_tx_mailbox_size;
-		mbox_sync.control_register = 0x22;
-		mbox_sync.enable = 1;
-		if (ec_command_npwr(command, slave->station_address,
-				    0x808, EC_SYNC_SIZE)) return -1;
-		ec_eeprom_sync_config(&mbox_sync, command->data);
-		if (unlikely(ec_master_simple_io(master, command))) {
+
+            mbox_sync.physical_start_address =
+                slave->sii_tx_mailbox_offset;
+            mbox_sync.length = slave->sii_tx_mailbox_size;
+            mbox_sync.control_register = 0x22;
+            mbox_sync.enable = 1;
+            if (ec_datagram_npwr(datagram, slave->station_address,
+                                 0x808, EC_SYNC_SIZE)) return -1;
+            ec_eeprom_sync_config(&mbox_sync, slave, datagram->data);
+            if (unlikely(ec_master_simple_io(master, datagram))) {
 		    EC_ERR("Setting sync manager 1 failed on slave %i!\n",
 			   slave->ring_position);
 		    return -1;
-		}
-	    }
-	    EC_INFO("Mailbox configured for unknown slave %i\n",
-		    slave->ring_position);
+            }
         }
 
         // change state to PREOP
@@ -1218,11 +1261,11 @@
         // configure FMMUs
         for (j = 0; j < slave->fmmu_count; j++) {
             fmmu = &slave->fmmus[j];
-            if (ec_command_npwr(command, slave->station_address,
-                                0x0600 + j * EC_FMMU_SIZE, EC_FMMU_SIZE))
+            if (ec_datagram_npwr(datagram, slave->station_address,
+                                 0x0600 + j * EC_FMMU_SIZE, EC_FMMU_SIZE))
                 return -1;
-            ec_fmmu_config(fmmu, slave, command->data);
-            if (unlikely(ec_master_simple_io(master, command))) {
+            ec_fmmu_config(fmmu, slave, datagram->data);
+            if (unlikely(ec_master_simple_io(master, datagram))) {
                 EC_ERR("Setting FMMU %i failed on slave %i!\n",
                        j, slave->ring_position);
                 return -1;
@@ -1288,17 +1331,17 @@
 /*****************************************************************************/
 
 /**
-   Sends queued commands and waits for their reception.
+   Sends queued datagrams and waits for their reception.
    \ingroup RealtimeInterface
 */
 
 void ecrt_master_sync_io(ec_master_t *master /**< EtherCAT master */)
 {
-    ec_command_t *command, *n;
-    unsigned int commands_sent;
+    ec_datagram_t *datagram, *n;
+    unsigned int datagrams_sent;
     cycles_t t_start, t_end, t_timeout;
 
-    // send commands
+    // send datagrams
     ecrt_master_async_send(master);
 
     t_start = get_cycles(); // measure io time
@@ -1310,23 +1353,23 @@
         t_end = get_cycles(); // take current time
         if (t_end - t_start >= t_timeout) break; // timeout!
 
-        commands_sent = 0;
-        list_for_each_entry_safe(command, n, &master->command_queue, queue) {
-            if (command->state == EC_CMD_RECEIVED)
-                list_del_init(&command->queue);
-            else if (command->state == EC_CMD_SENT)
-                commands_sent++;
-        }
-
-        if (!commands_sent) break;
-    }
-
-    // timeout; dequeue all commands
-    list_for_each_entry_safe(command, n, &master->command_queue, queue) {
-        switch (command->state) {
+        datagrams_sent = 0;
+        list_for_each_entry_safe(datagram, n, &master->datagram_queue, queue) {
+            if (datagram->state == EC_CMD_RECEIVED)
+                list_del_init(&datagram->queue);
+            else if (datagram->state == EC_CMD_SENT)
+                datagrams_sent++;
+        }
+
+        if (!datagrams_sent) break;
+    }
+
+    // timeout; dequeue all datagrams
+    list_for_each_entry_safe(datagram, n, &master->datagram_queue, queue) {
+        switch (datagram->state) {
             case EC_CMD_SENT:
             case EC_CMD_QUEUED:
-                command->state = EC_CMD_TIMEOUT;
+                datagram->state = EC_CMD_TIMEOUT;
                 master->stats.timeouts++;
                 ec_master_output_stats(master);
                 break;
@@ -1337,26 +1380,26 @@
             default:
                 break;
         }
-        list_del_init(&command->queue);
-    }
-}
-
-/*****************************************************************************/
-
-/**
-   Asynchronous sending of commands.
+        list_del_init(&datagram->queue);
+    }
+}
+
+/*****************************************************************************/
+
+/**
+   Asynchronous sending of datagrams.
    \ingroup RealtimeInterface
 */
 
 void ecrt_master_async_send(ec_master_t *master /**< EtherCAT master */)
 {
-    ec_command_t *command, *n;
+    ec_datagram_t *datagram, *n;
 
     if (unlikely(!master->device->link_state)) {
-        // link is down, no command can be sent
-        list_for_each_entry_safe(command, n, &master->command_queue, queue) {
-            command->state = EC_CMD_ERROR;
-            list_del_init(&command->queue);
+        // link is down, no datagram can be sent
+        list_for_each_entry_safe(datagram, n, &master->datagram_queue, queue) {
+            datagram->state = EC_CMD_ERROR;
+            list_del_init(&datagram->queue);
         }
 
         // query link state
@@ -1365,19 +1408,19 @@
     }
 
     // send frames
-    ec_master_send_commands(master);
-}
-
-/*****************************************************************************/
-
-/**
-   Asynchronous receiving of commands.
+    ec_master_send_datagrams(master);
+}
+
+/*****************************************************************************/
+
+/**
+   Asynchronous receiving of datagrams.
    \ingroup RealtimeInterface
 */
 
 void ecrt_master_async_receive(ec_master_t *master /**< EtherCAT master */)
 {
-    ec_command_t *command, *next;
+    ec_datagram_t *datagram, *next;
     cycles_t t_received, t_timeout;
 
     ec_device_call_isr(master->device);
@@ -1385,18 +1428,19 @@
     t_received = get_cycles();
     t_timeout = (cycles_t) master->timeout * (cpu_khz / 1000);
 
-    // dequeue all received commands
-    list_for_each_entry_safe(command, next, &master->command_queue, queue)
-        if (command->state == EC_CMD_RECEIVED) list_del_init(&command->queue);
-
-    // dequeue all commands that timed out
-    list_for_each_entry_safe(command, next, &master->command_queue, queue) {
-        switch (command->state) {
+    // dequeue all received datagrams
+    list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue)
+        if (datagram->state == EC_CMD_RECEIVED)
+            list_del_init(&datagram->queue);
+
+    // dequeue all datagrams that timed out
+    list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) {
+        switch (datagram->state) {
             case EC_CMD_SENT:
             case EC_CMD_QUEUED:
-                if (t_received - command->t_sent > t_timeout) {
-                    list_del_init(&command->queue);
-                    command->state = EC_CMD_TIMEOUT;
+                if (t_received - datagram->t_sent > t_timeout) {
+                    list_del_init(&datagram->queue);
+                    datagram->state = EC_CMD_TIMEOUT;
                     master->stats.timeouts++;
                     ec_master_output_stats(master);
                 }
@@ -1411,7 +1455,7 @@
 
 /**
    Prepares synchronous IO.
-   Queues all domain commands and sends them. Then waits a certain time, so
+   Queues all domain datagrams and sends them. Then waits a certain time, so
    that ecrt_master_sasync_receive() can be called securely.
    \ingroup RealtimeInterface
 */
@@ -1421,7 +1465,7 @@
     ec_domain_t *domain;
     cycles_t t_start, t_end, t_timeout;
 
-    // queue commands of all domains
+    // queue datagrams of all domains
     list_for_each_entry(domain, &master->domains, list)
         ecrt_domain_queue(domain);