--- a/master/fsm.c Tue Jul 18 16:48:05 2006 +0000
+++ b/master/fsm.c Wed Jul 19 12:57:41 2006 +0000
@@ -46,15 +46,13 @@
void ec_fsm_master_start(ec_fsm_t *);
void ec_fsm_master_broadcast(ec_fsm_t *);
-void ec_fsm_master_proc_states(ec_fsm_t *);
-void ec_fsm_master_scan(ec_fsm_t *);
-void ec_fsm_master_states(ec_fsm_t *);
+void ec_fsm_master_read_states(ec_fsm_t *);
void ec_fsm_master_validate_vendor(ec_fsm_t *);
void ec_fsm_master_validate_product(ec_fsm_t *);
-void ec_fsm_master_reconfigure(ec_fsm_t *);
-void ec_fsm_master_address(ec_fsm_t *);
-void ec_fsm_master_conf(ec_fsm_t *);
-void ec_fsm_master_eeprom(ec_fsm_t *);
+void ec_fsm_master_rewrite_addresses(ec_fsm_t *);
+void ec_fsm_master_configure_slave(ec_fsm_t *);
+void ec_fsm_master_scan_slaves(ec_fsm_t *);
+void ec_fsm_master_write_eeprom(ec_fsm_t *);
void ec_fsm_slave_start_reading(ec_fsm_t *);
void ec_fsm_slave_read_state(ec_fsm_t *);
@@ -265,7 +263,7 @@
// begin scanning of slaves
fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
fsm->slave_state = ec_fsm_slave_start_reading;
- fsm->master_state = ec_fsm_master_scan;
+ fsm->master_state = ec_fsm_master_scan_slaves;
fsm->master_state(fsm); // execute immediately
return;
}
@@ -274,7 +272,74 @@
fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
ec_datagram_nprd(&fsm->datagram, fsm->slave->station_address, 0x0130, 2);
ec_master_queue_datagram(master, &fsm->datagram);
- fsm->master_state = ec_fsm_master_states;
+ fsm->master_state = ec_fsm_master_read_states;
+}
+
+/*****************************************************************************/
+
+/**
+ Master action: PROC_STATES.
+ Processes the slave states.
+*/
+
+void ec_fsm_master_action_process_states(ec_fsm_t *fsm
+ /**< finite state machine */
+ )
+{
+ ec_master_t *master = fsm->master;
+ ec_slave_t *slave;
+
+ // check if any slaves are not in the state, they're supposed to be
+ list_for_each_entry(slave, &master->slaves, list) {
+ if (slave->error_flag ||
+ !slave->online ||
+ slave->requested_state == EC_SLAVE_STATE_UNKNOWN ||
+ slave->current_state == slave->requested_state) continue;
+
+ EC_INFO("Changing state of slave %i from ", slave->ring_position);
+ ec_print_states(slave->current_state);
+ printk(" to ");
+ ec_print_states(slave->requested_state);
+ printk(".\n");
+
+ fsm->slave = slave;
+ fsm->slave_state = ec_fsm_slave_conf;
+ fsm->change_new = EC_SLAVE_STATE_INIT;
+ fsm->change_state = ec_fsm_change_start;
+ fsm->master_state = ec_fsm_master_configure_slave;
+ fsm->master_state(fsm); // execute immediately
+ return;
+ }
+
+ if (master->mode == EC_MASTER_MODE_FREERUN) {
+ // nothing to configure. check for pending EEPROM write operations.
+ list_for_each_entry(slave, &master->slaves, list) {
+ if (!slave->new_eeprom_data) continue;
+
+ if (!slave->online || slave->error_flag) {
+ kfree(slave->new_eeprom_data);
+ slave->new_eeprom_data = NULL;
+ EC_ERR("Discarding EEPROM data, slave %i not ready.\n",
+ slave->ring_position);
+ continue;
+ }
+
+ // found pending EEPROM write operation. execute it!
+ EC_INFO("Writing EEPROM of slave %i...\n", slave->ring_position);
+ fsm->sii_offset = 0x0000;
+ memcpy(fsm->sii_value, slave->new_eeprom_data, 2);
+ fsm->sii_mode = 1;
+ fsm->sii_state = ec_fsm_sii_start_writing;
+ fsm->slave = slave;
+ fsm->master_state = ec_fsm_master_write_eeprom;
+ fsm->master_state(fsm); // execute immediately
+ return;
+ }
+ }
+
+ // nothing to do. restart master state machine.
+ fsm->master_state = ec_fsm_master_start;
+ fsm->master_state(fsm); // execute immediately
}
/*****************************************************************************/
@@ -289,18 +354,20 @@
ec_master_t *master = fsm->master;
ec_slave_t *slave = fsm->slave;
- // have all states been read?
+ // is there another slave to query?
if (slave->list.next != &master->slaves) {
// process next slave
fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
ec_datagram_nprd(&fsm->datagram, fsm->slave->station_address,
0x0130, 2);
ec_master_queue_datagram(master, &fsm->datagram);
- fsm->master_state = ec_fsm_master_states;
- return;
- }
-
- // all slave stated read; check, if a bus validation has to be done
+ fsm->master_state = ec_fsm_master_read_states;
+ return;
+ }
+
+ // all slave states read
+
+ // check, if a bus validation has to be done
if (fsm->master_validation) {
fsm->master_validation = 0;
list_for_each_entry(slave, &master->slaves, list) {
@@ -318,8 +385,7 @@
}
}
- fsm->master_state = ec_fsm_master_proc_states;
- fsm->master_state(fsm); // execute immediately
+ ec_fsm_master_action_process_states(fsm);
}
/*****************************************************************************/
@@ -329,7 +395,7 @@
Fetches the AL- and online state of a slave.
*/
-void ec_fsm_master_states(ec_fsm_t *fsm /**< finite state machine */)
+void ec_fsm_master_read_states(ec_fsm_t *fsm /**< finite state machine */)
{
ec_slave_t *slave = fsm->slave;
ec_datagram_t *datagram = &fsm->datagram;
@@ -376,71 +442,6 @@
/*****************************************************************************/
/**
- Master state: PROC_STATES.
- Processes the slave states.
-*/
-
-void ec_fsm_master_proc_states(ec_fsm_t *fsm /**< finite state machine */)
-{
- ec_master_t *master = fsm->master;
- ec_slave_t *slave;
-
- // check if any slaves are not in the state, they're supposed to be
- list_for_each_entry(slave, &master->slaves, list) {
- if (slave->error_flag ||
- !slave->online ||
- slave->requested_state == EC_SLAVE_STATE_UNKNOWN ||
- slave->current_state == slave->requested_state) continue;
-
- EC_INFO("Changing state of slave %i from ", slave->ring_position);
- ec_print_states(slave->current_state);
- printk(" to ");
- ec_print_states(slave->requested_state);
- printk(".\n");
-
- fsm->slave = slave;
- fsm->slave_state = ec_fsm_slave_conf;
- fsm->change_new = EC_SLAVE_STATE_INIT;
- fsm->change_state = ec_fsm_change_start;
- fsm->master_state = ec_fsm_master_conf;
- fsm->master_state(fsm); // execute immediately
- return;
- }
-
- if (master->mode == EC_MASTER_MODE_FREERUN) {
- // nothing to configure. check for pending EEPROM write operations.
- list_for_each_entry(slave, &master->slaves, list) {
- if (!slave->new_eeprom_data) continue;
-
- if (!slave->online || slave->error_flag) {
- kfree(slave->new_eeprom_data);
- slave->new_eeprom_data = NULL;
- EC_ERR("Discarding EEPROM data, slave %i not ready.\n",
- slave->ring_position);
- continue;
- }
-
- // found pending EEPROM write operation. execute it!
- EC_INFO("Writing EEPROM of slave %i...\n", slave->ring_position);
- fsm->sii_offset = 0x0000;
- memcpy(fsm->sii_value, slave->new_eeprom_data, 2);
- fsm->sii_mode = 1;
- fsm->sii_state = ec_fsm_sii_start_writing;
- fsm->slave = slave;
- fsm->master_state = ec_fsm_master_eeprom;
- fsm->master_state(fsm); // execute immediately
- return;
- }
- }
-
- // nothing to do. restart master state machine.
- fsm->master_state = ec_fsm_master_start;
- fsm->master_state(fsm); // execute immediately
-}
-
-/*****************************************************************************/
-
-/**
Master state: VALIDATE_VENDOR.
Validates the vendor ID of a slave.
*/
@@ -480,61 +481,12 @@
/*****************************************************************************/
/**
- Master state: VALIDATE_PRODUCT.
- Validates the product ID of a slave.
-*/
-
-void ec_fsm_master_validate_product(ec_fsm_t *fsm /**< finite state machine */)
-{
- ec_slave_t *slave = fsm->slave;
-
- fsm->sii_state(fsm); // execute SII state machine
-
- if (fsm->sii_state == ec_fsm_sii_error) {
- fsm->slave->error_flag = 1;
- EC_ERR("Failed to validate product code of slave %i.\n",
- slave->ring_position);
- fsm->master_state = ec_fsm_master_start;
- fsm->master_state(fsm); // execute immediately
- return;
- }
-
- if (fsm->sii_state != ec_fsm_sii_end) return;
-
- if (EC_READ_U32(fsm->sii_value) != slave->sii_product_code) {
- EC_ERR("Slave %i: invalid product code!\n", slave->ring_position);
- EC_ERR("expected 0x%08X, got 0x%08X.\n", slave->sii_product_code,
- EC_READ_U32(fsm->sii_value));
- fsm->master_state = ec_fsm_master_start;
- fsm->master_state(fsm); // execute immediately
- return;
- }
-
- // have all states been validated?
- if (slave->list.next == &fsm->master->slaves) {
- fsm->slave = list_entry(fsm->master->slaves.next, ec_slave_t, list);
- fsm->master_state = ec_fsm_master_reconfigure;
- return;
- }
-
- // validate next slave
- fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
- fsm->master_state = ec_fsm_master_validate_vendor;
- fsm->sii_offset = 0x0008; // vendor ID
- fsm->sii_mode = 0;
- fsm->sii_state = ec_fsm_sii_start_reading;
- fsm->sii_state(fsm); // execute immediately
-}
-
-/*****************************************************************************/
-
-/**
- Master state: RECONFIGURE.
+ Master action: ADDRESS.
Looks for slave, that have lost their configuration and writes
their station address, so that they can be reconfigured later.
*/
-void ec_fsm_master_reconfigure(ec_fsm_t *fsm /**< finite state machine */)
+void ec_fsm_master_action_addresses(ec_fsm_t *fsm /**< finite state machine */)
{
ec_datagram_t *datagram = &fsm->datagram;
@@ -554,7 +506,57 @@
ec_datagram_apwr(datagram, fsm->slave->ring_position, 0x0010, 2);
EC_WRITE_U16(datagram->data, fsm->slave->station_address);
ec_master_queue_datagram(fsm->master, datagram);
- fsm->master_state = ec_fsm_master_address;
+ fsm->master_state = ec_fsm_master_rewrite_addresses;
+}
+
+/*****************************************************************************/
+
+/**
+ Master state: VALIDATE_PRODUCT.
+ Validates the product ID of a slave.
+*/
+
+void ec_fsm_master_validate_product(ec_fsm_t *fsm /**< finite state machine */)
+{
+ ec_slave_t *slave = fsm->slave;
+
+ fsm->sii_state(fsm); // execute SII state machine
+
+ if (fsm->sii_state == ec_fsm_sii_error) {
+ fsm->slave->error_flag = 1;
+ EC_ERR("Failed to validate product code of slave %i.\n",
+ slave->ring_position);
+ fsm->master_state = ec_fsm_master_start;
+ fsm->master_state(fsm); // execute immediately
+ return;
+ }
+
+ if (fsm->sii_state != ec_fsm_sii_end) return;
+
+ if (EC_READ_U32(fsm->sii_value) != slave->sii_product_code) {
+ EC_ERR("Slave %i: invalid product code!\n", slave->ring_position);
+ EC_ERR("expected 0x%08X, got 0x%08X.\n", slave->sii_product_code,
+ EC_READ_U32(fsm->sii_value));
+ fsm->master_state = ec_fsm_master_start;
+ fsm->master_state(fsm); // execute immediately
+ return;
+ }
+
+ // have all states been validated?
+ if (slave->list.next == &fsm->master->slaves) {
+ fsm->slave = list_entry(fsm->master->slaves.next, ec_slave_t, list);
+ // start writing addresses to offline slaves
+ ec_fsm_master_action_addresses(fsm);
+ return;
+ }
+
+ // validate next slave
+ fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
+ fsm->master_state = ec_fsm_master_validate_vendor;
+ fsm->sii_offset = 0x0008; // vendor ID
+ fsm->sii_mode = 0;
+ fsm->sii_state = ec_fsm_sii_start_reading;
+ fsm->sii_state(fsm); // execute immediately
}
/*****************************************************************************/
@@ -564,7 +566,9 @@
Checks, if the new station address has been written to the slave.
*/
-void ec_fsm_master_address(ec_fsm_t *fsm /**< finite state machine */)
+void ec_fsm_master_rewrite_addresses(ec_fsm_t *fsm
+ /**< finite state machine */
+ )
{
ec_slave_t *slave = fsm->slave;
ec_datagram_t *datagram = &fsm->datagram;
@@ -582,8 +586,8 @@
// check next slave
fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
- fsm->master_state = ec_fsm_master_reconfigure;
- fsm->master_state(fsm); // execute immediately
+ // Write new station address to slave
+ ec_fsm_master_action_addresses(fsm);
}
/*****************************************************************************/
@@ -593,7 +597,7 @@
Executes the sub-statemachine for the scanning of a slave.
*/
-void ec_fsm_master_scan(ec_fsm_t *fsm /**< finite state machine */)
+void ec_fsm_master_scan_slaves(ec_fsm_t *fsm /**< finite state machine */)
{
ec_master_t *master = fsm->master;
ec_slave_t *slave = fsm->slave;
@@ -689,12 +693,14 @@
Starts configuring a slave.
*/
-void ec_fsm_master_conf(ec_fsm_t *fsm /**< finite state machine */)
+void ec_fsm_master_configure_slave(ec_fsm_t *fsm
+ /**< finite state machine */
+ )
{
fsm->slave_state(fsm); // execute slave's state machine
if (fsm->slave_state != ec_fsm_slave_end) return;
- fsm->master_state = ec_fsm_master_proc_states;
- fsm->master_state(fsm); // execute immediately
+
+ ec_fsm_master_action_process_states(fsm);
}
/*****************************************************************************/
@@ -703,7 +709,7 @@
Master state: EEPROM.
*/
-void ec_fsm_master_eeprom(ec_fsm_t *fsm /**< finite state machine */)
+void ec_fsm_master_write_eeprom(ec_fsm_t *fsm /**< finite state machine */)
{
ec_slave_t *slave = fsm->slave;
@@ -736,7 +742,7 @@
slave->new_eeprom_data = NULL;
// restart master state machine.
- fsm->master_state = ec_fsm_master_start;
+ fsm->master_state = ec_fsm_master_start; // TODO: Scan slaves!
fsm->master_state(fsm); // execute immediately
return;
}