master/fsm_master.c
branchstable-1.3
changeset 1745 07fd94c5119d
parent 1744 7bc131b92039
child 1746 72e7507b3f1b
--- a/master/fsm_master.c	Fri Aug 10 15:27:08 2007 +0000
+++ b/master/fsm_master.c	Thu Sep 13 11:08:46 2007 +0000
@@ -41,7 +41,9 @@
 #include "globals.h"
 #include "master.h"
 #include "mailbox.h"
+#ifdef EC_EOE
 #include "ethernet.h"
+#endif
 #include "fsm_master.h"
 
 /*****************************************************************************/
@@ -54,6 +56,7 @@
 void ec_fsm_master_state_validate_product(ec_fsm_master_t *);
 void ec_fsm_master_state_rewrite_addresses(ec_fsm_master_t *);
 void ec_fsm_master_state_configure_slave(ec_fsm_master_t *);
+void ec_fsm_master_state_clear_addresses(ec_fsm_master_t *);
 void ec_fsm_master_state_scan_slaves(ec_fsm_master_t *);
 void ec_fsm_master_state_write_eeprom(ec_fsm_master_t *);
 void ec_fsm_master_state_sdodict(ec_fsm_master_t *);
@@ -238,8 +241,10 @@
             fsm->idle = 0;
             fsm->scan_jiffies = jiffies;
 
+#ifdef EC_EOE
             ec_master_eoe_stop(master);
             ec_master_clear_eoe_handlers(master);
+#endif
             ec_master_destroy_slaves(master);
 
             master->slave_count = datagram->working_counter;
@@ -276,13 +281,13 @@
                 list_add_tail(&slave->list, &master->slaves);
             }
 
-            EC_INFO("Scanning bus.\n");
-
-            // begin scanning of slaves
-            fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
-            fsm->state = ec_fsm_master_state_scan_slaves;
-            ec_fsm_slave_start_scan(&fsm->fsm_slave, fsm->slave);
-            ec_fsm_slave_exec(&fsm->fsm_slave); // execute immediately
+            if (master->debug_level)
+                EC_DBG("Clearing station addresses...\n");
+
+            ec_datagram_bwr(datagram, 0x0010, 2);
+            EC_WRITE_U16(datagram->data, 0x0000);
+            fsm->retries = EC_FSM_RETRIES;
+            fsm->state = ec_fsm_master_state_clear_addresses;
             return;
         }
     }
@@ -587,18 +592,21 @@
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         EC_ERR("Failed to receive AL state datagram for slave %i"
-                " (datagram state %i)\n", slave->ring_position, datagram->state);
+                " (datagram state %i)\n",
+                slave->ring_position, datagram->state);
         fsm->state = ec_fsm_master_state_error;
         return;
     }
 
     // did the slave not respond to its station address?
-    if (datagram->working_counter != 1) {
+    if (datagram->working_counter == 0) {
         ec_slave_set_online_state(slave, EC_SLAVE_OFFLINE);
         ec_fsm_master_action_next_slave_state(fsm);
         return;
     }
 
+    // FIXME what to to on multiple response?
+
     // slave responded
     ec_slave_set_state(slave, EC_READ_U8(datagram->data)); // set app state first
     ec_slave_set_online_state(slave, EC_SLAVE_ONLINE);
@@ -774,8 +782,9 @@
     }
 
     if (datagram->working_counter != 1) {
-        EC_ERR("Failed to write station address - slave %i did not respond.\n",
+        EC_ERR("Failed to write station address of slave %i: ",
                slave->ring_position);
+        ec_datagram_print_wc_error(datagram);
         fsm->state = ec_fsm_master_state_error;
         return;
     }
@@ -794,6 +803,43 @@
 /*****************************************************************************/
 
 /**
+ * Master state: CLEAR ADDRESSES.
+ */
+
+void ec_fsm_master_state_clear_addresses(
+        ec_fsm_master_t *fsm /**< master state machine */
+        )
+{
+    ec_master_t *master = fsm->master;
+    ec_datagram_t *datagram = fsm->datagram;
+
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
+
+    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+        EC_ERR("Failed to receive address clearing datagram (state %i).\n",
+                datagram->state);
+        fsm->state = ec_fsm_master_state_error;
+        return;
+    }
+
+    if (datagram->working_counter != master->slave_count) {
+        EC_WARN("Failed to clear all station addresses: Cleared %u of %u",
+                datagram->working_counter, master->slave_count);
+    }
+
+    EC_INFO("Scanning bus.\n");
+
+    // begin scanning of slaves
+    fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
+    fsm->state = ec_fsm_master_state_scan_slaves;
+    ec_fsm_slave_start_scan(&fsm->fsm_slave, fsm->slave);
+    ec_fsm_slave_exec(&fsm->fsm_slave); // execute immediately
+}
+
+/*****************************************************************************/
+
+/**
  * Master state: SCAN SLAVES.
  * Executes the sub-statemachine for the scanning of a slave.
  */
@@ -808,6 +854,7 @@
     if (ec_fsm_slave_exec(&fsm->fsm_slave)) // execute slave state machine
         return;
 
+#ifdef EC_EOE
     if (slave->sii_mailbox_protocols & EC_MBOX_EOE) {
         // create EoE handler for this slave
         ec_eoe_t *eoe;
@@ -824,6 +871,7 @@
             list_add_tail(&eoe->list, &master->eoe_handlers);
         }
     }
+#endif
 
     // another slave to fetch?
     if (slave->list.next != &master->slaves) {
@@ -836,8 +884,10 @@
     EC_INFO("Bus scanning completed in %u ms.\n",
             (u32) (jiffies - fsm->scan_jiffies) * 1000 / HZ);
 
+#ifdef EC_EOE
     // check if EoE processing has to be started
     ec_master_eoe_start(master);
+#endif
 
     master->scan_state = EC_REQUEST_COMPLETE;
     wake_up_interruptible(&master->scan_queue);