master/fsm_slave.c
changeset 2597 0e145bb05859
parent 2589 2b9c78543663
child 2629 a2701af27fde
--- a/master/fsm_slave.c	Thu Nov 06 08:55:35 2014 +0100
+++ b/master/fsm_slave.c	Wed Nov 12 14:42:17 2014 +0100
@@ -52,6 +52,8 @@
 void ec_fsm_slave_state_foe_request(ec_fsm_slave_t *, ec_datagram_t *);
 int ec_fsm_slave_action_process_soe(ec_fsm_slave_t *, ec_datagram_t *);
 void ec_fsm_slave_state_soe_request(ec_fsm_slave_t *, ec_datagram_t *);
+int ec_fsm_slave_action_process_eoe(ec_fsm_slave_t *, ec_datagram_t *);
+void ec_fsm_slave_state_eoe_request(ec_fsm_slave_t *, ec_datagram_t *);
 
 /*****************************************************************************/
 
@@ -71,11 +73,13 @@
     fsm->reg_request = NULL;
     fsm->foe_request = NULL;
     fsm->soe_request = NULL;
+    fsm->eoe_request = NULL;
 
     // Init sub-state-machines
     ec_fsm_coe_init(&fsm->fsm_coe);
     ec_fsm_foe_init(&fsm->fsm_foe);
     ec_fsm_soe_init(&fsm->fsm_soe);
+    ec_fsm_eoe_init(&fsm->fsm_eoe);
 }
 
 /*****************************************************************************/
@@ -108,10 +112,16 @@
         wake_up_all(&fsm->slave->master->request_queue);
     }
 
+    if (fsm->eoe_request) {
+        fsm->soe_request->state = EC_INT_REQUEST_FAILURE;
+        wake_up_all(&fsm->slave->master->request_queue);
+    }
+
     // clear sub-state machines
     ec_fsm_coe_clear(&fsm->fsm_coe);
     ec_fsm_foe_clear(&fsm->fsm_foe);
     ec_fsm_soe_clear(&fsm->fsm_soe);
+    ec_fsm_eoe_clear(&fsm->fsm_eoe);
 }
 
 /*****************************************************************************/
@@ -210,6 +220,11 @@
     if (ec_fsm_slave_action_process_soe(fsm, datagram)) {
         return;
     }
+
+    // Check for pending EoE IP parameter requests
+    if (ec_fsm_slave_action_process_eoe(fsm, datagram)) {
+        return;
+    }
 }
 
 /*****************************************************************************/
@@ -240,7 +255,7 @@
         request->state = EC_INT_REQUEST_FAILURE;
         wake_up_all(&slave->master->request_queue);
         fsm->state = ec_fsm_slave_state_idle;
-        return 1;
+        return 0;
     }
 
     if (slave->current_state == EC_SLAVE_STATE_INIT) {
@@ -248,7 +263,7 @@
         request->state = EC_INT_REQUEST_FAILURE;
         wake_up_all(&slave->master->request_queue);
         fsm->state = ec_fsm_slave_state_idle;
-        return 1;
+        return 0;
     }
 
     fsm->sdo_request = request;
@@ -342,7 +357,7 @@
         wake_up_all(&slave->master->request_queue);
         fsm->reg_request = NULL;
         fsm->state = ec_fsm_slave_state_idle;
-        return 1;
+        return 0;
     }
 
     // Found pending register request. Execute it!
@@ -444,7 +459,7 @@
         request->state = EC_INT_REQUEST_FAILURE;
         wake_up_all(&slave->master->request_queue);
         fsm->state = ec_fsm_slave_state_idle;
-        return 1;
+        return 0;
     }
 
     request->state = EC_INT_REQUEST_BUSY;
@@ -521,7 +536,7 @@
         req->state = EC_INT_REQUEST_FAILURE;
         wake_up_all(&slave->master->request_queue);
         fsm->state = ec_fsm_slave_state_idle;
-        return 1;
+        return 0;
     }
 
     if (slave->current_state == EC_SLAVE_STATE_INIT) {
@@ -580,3 +595,85 @@
 }
 
 /*****************************************************************************/
+
+/** Check for pending EoE IP parameter requests and process one.
+ *
+ * \return non-zero, if a request is processed.
+ */
+int ec_fsm_slave_action_process_eoe(
+        ec_fsm_slave_t *fsm, /**< Slave state machine. */
+        ec_datagram_t *datagram /**< Datagram to use. */
+        )
+{
+    ec_slave_t *slave = fsm->slave;
+    ec_eoe_request_t *request;
+
+    if (list_empty(&slave->eoe_requests)) {
+        return 0;
+    }
+
+    // take the first request to be processed
+    request = list_entry(slave->eoe_requests.next, ec_eoe_request_t, list);
+    list_del_init(&request->list); // dequeue
+
+    if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
+        EC_SLAVE_WARN(slave, "Aborting EoE request,"
+                " slave has error flag set.\n");
+        request->state = EC_INT_REQUEST_FAILURE;
+        wake_up_all(&slave->master->request_queue);
+        fsm->state = ec_fsm_slave_state_idle;
+        return 0;
+    }
+
+    if (slave->current_state == EC_SLAVE_STATE_INIT) {
+        EC_SLAVE_WARN(slave, "Aborting EoE request, slave is in INIT.\n");
+        request->state = EC_INT_REQUEST_FAILURE;
+        wake_up_all(&slave->master->request_queue);
+        fsm->state = ec_fsm_slave_state_idle;
+        return 0;
+    }
+
+    fsm->eoe_request = request;
+    request->state = EC_INT_REQUEST_BUSY;
+
+    // Found pending request. Execute it!
+    EC_SLAVE_DBG(slave, 1, "Processing EoE request...\n");
+
+    // Start EoE command
+    fsm->state = ec_fsm_slave_state_eoe_request;
+    ec_fsm_eoe_set_ip_param(&fsm->fsm_eoe, slave, request);
+    ec_fsm_eoe_exec(&fsm->fsm_eoe, datagram); // execute immediately
+    return 1;
+}
+
+/*****************************************************************************/
+
+/** Slave state: EOE_REQUEST.
+ */
+void ec_fsm_slave_state_eoe_request(
+        ec_fsm_slave_t *fsm, /**< Slave state machine. */
+        ec_datagram_t *datagram /**< Datagram to use. */
+        )
+{
+    ec_slave_t *slave = fsm->slave;
+    ec_eoe_request_t *req = fsm->eoe_request;
+
+    if (ec_fsm_eoe_exec(&fsm->fsm_eoe, datagram)) {
+        return;
+    }
+
+    if (ec_fsm_eoe_success(&fsm->fsm_eoe)) {
+		req->state = EC_INT_REQUEST_SUCCESS;
+		EC_SLAVE_DBG(slave, 1, "Finished EoE request.\n");
+    }
+	else {
+        req->state = EC_INT_REQUEST_FAILURE;
+        EC_SLAVE_ERR(slave, "Failed to process EoE request.\n");
+	}
+
+    wake_up_all(&slave->master->request_queue);
+    fsm->eoe_request = NULL;
+    fsm->state = ec_fsm_slave_state_ready;
+}
+
+/*****************************************************************************/