diff -r 7bc131b92039 -r 07fd94c5119d master/fsm_master.c --- 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);