master/fsm_master.c
changeset 1335 09c6fce1ae45
parent 1327 4d179b06dd3c
child 1336 e27b37e80a99
--- a/master/fsm_master.c	Mon Jan 26 11:59:32 2009 +0000
+++ b/master/fsm_master.c	Mon Jan 26 13:01:58 2009 +0000
@@ -39,6 +39,7 @@
 #endif
 
 #include "fsm_master.h"
+#include "fsm_foe.h"
 
 /*****************************************************************************/
 
@@ -53,6 +54,7 @@
 void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *);
 void ec_fsm_master_state_sdo_request(ec_fsm_master_t *);
 void ec_fsm_master_state_phy_request(ec_fsm_master_t *);
+void ec_fsm_master_state_foe_request(ec_fsm_master_t *);
 
 /*****************************************************************************/
 
@@ -74,6 +76,7 @@
 
     // init sub-state-machines
     ec_fsm_coe_init(&fsm->fsm_coe, fsm->datagram);
+    ec_fsm_foe_init(&fsm->fsm_foe, fsm->datagram);
     ec_fsm_pdo_init(&fsm->fsm_pdo, &fsm->fsm_coe);
     ec_fsm_change_init(&fsm->fsm_change, fsm->datagram);
     ec_fsm_slave_config_init(&fsm->fsm_slave_config, fsm->datagram,
@@ -93,6 +96,7 @@
 {
     // clear sub-state machines
     ec_fsm_coe_clear(&fsm->fsm_coe);
+    ec_fsm_foe_clear(&fsm->fsm_foe);
     ec_fsm_pdo_clear(&fsm->fsm_pdo);
     ec_fsm_change_clear(&fsm->fsm_change);
     ec_fsm_slave_config_clear(&fsm->fsm_slave_config);
@@ -211,7 +215,7 @@
         } else {
             master->scan_busy = 1;
             up(&master->scan_sem);
-            
+
             // topology change when scan is allowed:
             // clear all slaves and scan the bus
             fsm->topology_change_pending = 0;
@@ -281,7 +285,7 @@
 /*****************************************************************************/
 
 /** Check for pending SII write requests and process one.
- * 
+ *
  * \return non-zero, if an SII write request is processed.
  */
 int ec_fsm_master_action_process_sii(
@@ -375,7 +379,7 @@
 /*****************************************************************************/
 
 /** Check for pending SDO requests and process one.
- * 
+ *
  * \return non-zero, if an SDO request is processed.
  */
 int ec_fsm_master_action_process_sdo(
@@ -424,7 +428,7 @@
             }
         }
     }
-    
+
     // search the first external request to be processed
     while (1) {
         if (list_empty(&master->slave_sdo_requests))
@@ -465,6 +469,50 @@
 
 /*****************************************************************************/
 
+/** Check for pending FoE requests and process one.
+ *
+ * \return non-zero, if an FoE request is processed.
+ */
+int ec_fsm_master_action_process_foe(
+        ec_fsm_master_t *fsm /**< Master state machine. */
+        )
+{
+    ec_master_t *master = fsm->master;
+    ec_slave_t *slave;
+    ec_master_foe_request_t *request;
+
+    // search the first request to be processed
+    while (1) {
+        if (list_empty(&master->foe_requests))
+            break;
+
+        // get first request
+        request = list_entry(master->foe_requests.next,
+                ec_master_foe_request_t, list);
+        list_del_init(&request->list); // dequeue
+        request->req.state = EC_REQUEST_BUSY;
+        slave = request->slave;
+
+        EC_DBG("---- Master read command from queue ----\n");
+        // found pending FOE write operation. execute it!
+        if (master->debug_level)
+            EC_DBG("Writing FOE data to slave %u...\n",
+                    request->slave->ring_position);
+
+        fsm->foe_request = &request->req;
+        fsm->slave = slave;
+        fsm->state = ec_fsm_master_state_foe_request;
+        ec_fsm_foe_transfer(&fsm->fsm_foe, slave, &request->req);
+        //(&fsm->fsm_foe, request->slave, request->offset, request->words);
+        ec_fsm_foe_exec(&fsm->fsm_foe);
+        return 1;
+    }
+
+    return 0;
+}
+
+/*****************************************************************************/
+
 /** Master action: IDLE.
  *
  * Does secondary work.
@@ -721,8 +769,9 @@
         )
 {
     ec_master_t *master = fsm->master;
+#ifdef EC_EOE
     ec_slave_t *slave = fsm->slave;
-
+#endif
     if (ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan))
         return;
 
@@ -840,7 +889,7 @@
         slave->sii.alias = EC_READ_U16(request->words + 4);
     }
     // TODO: Evaluate other SII contents!
-    
+
     request->state = EC_INT_REQUEST_SUCCESS;
     wake_up(&master->sii_queue);
 
@@ -853,6 +902,40 @@
 
 /*****************************************************************************/
 
+/** Master state: WRITE FOE.
+ */
+void ec_fsm_master_state_foe_request(
+		ec_fsm_master_t *fsm /**< Master state machine. */
+        )
+{
+    ec_master_t *master = fsm->master;
+    ec_foe_request_t *request = fsm->foe_request;
+    ec_slave_t *slave = fsm->slave;
+
+    if (ec_fsm_foe_exec(&fsm->fsm_foe)) return;
+
+    if (!ec_fsm_foe_success(&fsm->fsm_foe)) {
+        EC_ERR("Failed to handle FOE request to slave %u.\n",
+                slave->ring_position);
+        request->state = EC_INT_REQUEST_FAILURE;
+        wake_up(&master->foe_queue);
+        ec_fsm_master_restart(fsm);
+        return;
+    }
+
+    // finished writing FOE
+    if (master->debug_level)
+        EC_DBG("Finished writing %u words of FOE data to slave %u.\n",
+                request->data_size, slave->ring_position);
+
+    request->state = EC_INT_REQUEST_SUCCESS;
+    wake_up(&master->foe_queue);
+
+    ec_fsm_master_restart(fsm);
+}
+
+/*****************************************************************************/
+
 /** Master state: SDO DICTIONARY.
  */
 void ec_fsm_master_state_sdo_dictionary(
@@ -906,7 +989,7 @@
         return;
     }
 
-    // SDO request finished 
+    // SDO request finished
     request->state = EC_INT_REQUEST_SUCCESS;
     wake_up(&master->sdo_queue);