--- a/master/fsm.c Mon Jun 26 16:07:07 2006 +0000
+++ b/master/fsm.c Wed Aug 02 12:25:25 2006 +0000
@@ -46,32 +46,30 @@
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_slave_start_reading(ec_fsm_t *);
-void ec_fsm_slave_read_status(ec_fsm_t *);
-void ec_fsm_slave_read_base(ec_fsm_t *);
-void ec_fsm_slave_read_dl(ec_fsm_t *);
-void ec_fsm_slave_eeprom_size(ec_fsm_t *);
-void ec_fsm_slave_fetch_eeprom(ec_fsm_t *);
-void ec_fsm_slave_fetch_eeprom2(ec_fsm_t *);
-void ec_fsm_slave_end(ec_fsm_t *);
-
-void ec_fsm_slave_conf(ec_fsm_t *);
-void ec_fsm_slave_sync(ec_fsm_t *);
-void ec_fsm_slave_preop(ec_fsm_t *);
-void ec_fsm_slave_fmmu(ec_fsm_t *);
-void ec_fsm_slave_saveop(ec_fsm_t *);
-void ec_fsm_slave_op(ec_fsm_t *);
-void ec_fsm_slave_op2(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_slavescan_start(ec_fsm_t *);
+void ec_fsm_slavescan_address(ec_fsm_t *);
+void ec_fsm_slavescan_state(ec_fsm_t *);
+void ec_fsm_slavescan_base(ec_fsm_t *);
+void ec_fsm_slavescan_datalink(ec_fsm_t *);
+void ec_fsm_slavescan_eeprom_size(ec_fsm_t *);
+void ec_fsm_slavescan_eeprom_data(ec_fsm_t *);
+void ec_fsm_slavescan_end(ec_fsm_t *);
+
+void ec_fsm_slaveconf_init(ec_fsm_t *);
+void ec_fsm_slaveconf_sync(ec_fsm_t *);
+void ec_fsm_slaveconf_preop(ec_fsm_t *);
+void ec_fsm_slaveconf_fmmu(ec_fsm_t *);
+void ec_fsm_slaveconf_saveop(ec_fsm_t *);
+void ec_fsm_slaveconf_op(ec_fsm_t *);
+void ec_fsm_slaveconf_end(ec_fsm_t *);
void ec_fsm_sii_start_reading(ec_fsm_t *);
void ec_fsm_sii_read_check(ec_fsm_t *);
@@ -87,7 +85,7 @@
void ec_fsm_change_status(ec_fsm_t *);
void ec_fsm_change_code(ec_fsm_t *);
void ec_fsm_change_ack(ec_fsm_t *);
-void ec_fsm_change_ack2(ec_fsm_t *);
+void ec_fsm_change_check_ack(ec_fsm_t *);
void ec_fsm_change_end(ec_fsm_t *);
void ec_fsm_change_error(ec_fsm_t *);
@@ -99,7 +97,7 @@
int ec_fsm_init(ec_fsm_t *fsm, /**< finite state machine */
ec_master_t *master /**< EtherCAT master */
- )
+ )
{
fsm->master = master;
fsm->master_state = ec_fsm_master_start;
@@ -107,9 +105,9 @@
fsm->master_slave_states = EC_SLAVE_STATE_UNKNOWN;
fsm->master_validation = 0;
- ec_command_init(&fsm->command);
- if (ec_command_prealloc(&fsm->command, EC_MAX_DATA_SIZE)) {
- EC_ERR("FSM failed to allocate FSM command.\n");
+ ec_datagram_init(&fsm->datagram);
+ if (ec_datagram_prealloc(&fsm->datagram, EC_MAX_DATA_SIZE)) {
+ EC_ERR("Failed to allocate FSM datagram.\n");
return -1;
}
@@ -124,7 +122,7 @@
void ec_fsm_clear(ec_fsm_t *fsm /**< finite state machine */)
{
- ec_command_clear(&fsm->command);
+ ec_datagram_clear(&fsm->datagram);
}
/*****************************************************************************/
@@ -162,8 +160,8 @@
void ec_fsm_master_start(ec_fsm_t *fsm)
{
- ec_command_brd(&fsm->command, 0x0130, 2);
- ec_master_queue_command(fsm->master, &fsm->command);
+ ec_datagram_brd(&fsm->datagram, 0x0130, 2);
+ ec_master_queue_datagram(fsm->master, &fsm->datagram);
fsm->master_state = ec_fsm_master_broadcast;
}
@@ -176,12 +174,12 @@
void ec_fsm_master_broadcast(ec_fsm_t *fsm /**< finite state machine */)
{
- ec_command_t *command = &fsm->command;
+ ec_datagram_t *datagram = &fsm->datagram;
unsigned int topology_change, states_change, i;
ec_slave_t *slave;
ec_master_t *master = fsm->master;
- if (command->state != EC_CMD_RECEIVED) {
+ if (datagram->state != EC_CMD_RECEIVED) {
if (!master->device->link_state) {
fsm->master_slaves_responding = 0;
list_for_each_entry(slave, &master->slaves, list) {
@@ -193,12 +191,12 @@
return;
}
- topology_change = (command->working_counter !=
+ topology_change = (datagram->working_counter !=
fsm->master_slaves_responding);
- states_change = (EC_READ_U8(command->data) != fsm->master_slave_states);
-
- fsm->master_slave_states = EC_READ_U8(command->data);
- fsm->master_slaves_responding = command->working_counter;
+ states_change = (EC_READ_U8(datagram->data) != fsm->master_slave_states);
+
+ fsm->master_slave_states = EC_READ_U8(datagram->data);
+ fsm->master_slaves_responding = datagram->working_counter;
if (topology_change) {
EC_INFO("%i slave%s responding.\n",
@@ -221,8 +219,8 @@
printk(".\n");
}
- // topology change in free-run mode: clear all slaves and scan the bus
- if (topology_change && master->mode == EC_MASTER_MODE_FREERUN) {
+ // topology change in idle mode: clear all slaves and scan the bus
+ if (topology_change && master->mode == EC_MASTER_MODE_IDLE) {
EC_INFO("Scanning bus.\n");
ec_master_eoe_stop(master);
@@ -264,17 +262,84 @@
// 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->slave_state = ec_fsm_slavescan_start;
+ fsm->master_state = ec_fsm_master_scan_slaves;
fsm->master_state(fsm); // execute immediately
return;
}
// fetch state from each slave
fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
- ec_command_nprd(&fsm->command, fsm->slave->station_address, 0x0130, 2);
- ec_master_queue_command(master, &fsm->command);
- fsm->master_state = ec_fsm_master_states;
+ ec_datagram_nprd(&fsm->datagram, fsm->slave->station_address, 0x0130, 2);
+ ec_master_queue_datagram(master, &fsm->datagram);
+ 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_slaveconf_init;
+ 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_IDLE) {
+ // 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,37 +354,38 @@
ec_master_t *master = fsm->master;
ec_slave_t *slave = fsm->slave;
- // have all states been read?
- if (slave->list.next == &master->slaves) {
-
- // 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) {
- if (slave->online) continue;
-
- // At least one slave is offline. validate!
- EC_INFO("Validating bus.\n");
- fsm->slave = list_entry(master->slaves.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
- return;
- }
+ // 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_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) {
+ if (slave->online) continue;
+
+ // At least one slave is offline. validate!
+ EC_INFO("Validating bus.\n");
+ fsm->slave = list_entry(master->slaves.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
+ return;
}
-
- fsm->master_state = ec_fsm_master_proc_states;
- fsm->master_state(fsm); // execute immediately
- return;
- }
-
- // process next slave
- fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
- ec_command_nprd(&fsm->command, fsm->slave->station_address, 0x0130, 2);
- ec_master_queue_command(master, &fsm->command);
- fsm->master_state = ec_fsm_master_states;
+ }
+
+ ec_fsm_master_action_process_states(fsm);
}
/*****************************************************************************/
@@ -329,20 +395,20 @@
Fetches the AL- and online state of a slave.
*/
-void ec_fsm_master_states(ec_fsm_t *fsm /**< finite state machine */)
-{
- ec_slave_t *slave = fsm->slave;
- ec_command_t *command = &fsm->command;
+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;
uint8_t new_state;
- if (command->state != EC_CMD_RECEIVED) {
+ if (datagram->state != EC_CMD_RECEIVED) {
fsm->master_state = ec_fsm_master_start;
fsm->master_state(fsm); // execute immediately
return;
}
// did the slave not respond to its station address?
- if (command->working_counter != 1) {
+ if (datagram->working_counter != 1) {
if (slave->online) {
slave->online = 0;
EC_INFO("Slave %i: offline.\n", slave->ring_position);
@@ -352,10 +418,10 @@
}
// slave responded
- new_state = EC_READ_U8(command->data);
+ new_state = EC_READ_U8(datagram->data);
if (!slave->online) { // slave was offline before
slave->online = 1;
- slave->state_error = 0;
+ slave->error_flag = 0; // clear error flag
slave->current_state = new_state;
EC_INFO("Slave %i: online (", slave->ring_position);
ec_print_states(new_state);
@@ -376,62 +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->state_error || !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;
-
- // 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.
*/
@@ -443,6 +453,7 @@
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 vendor ID of slave %i.\n",
slave->ring_position);
fsm->master_state = ec_fsm_master_start;
@@ -470,62 +481,14 @@
/*****************************************************************************/
/**
- 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) {
- 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 */)
-{
- ec_command_t *command = &fsm->command;
+void ec_fsm_master_action_addresses(ec_fsm_t *fsm /**< finite state machine */)
+{
+ ec_datagram_t *datagram = &fsm->datagram;
while (fsm->slave->online) {
if (fsm->slave->list.next == &fsm->master->slaves) { // last slave?
@@ -540,10 +503,60 @@
EC_INFO("Reinitializing slave %i.\n", fsm->slave->ring_position);
// write station address
- ec_command_apwr(command, fsm->slave->ring_position, 0x0010, 2);
- EC_WRITE_U16(command->data, fsm->slave->station_address);
- ec_master_queue_command(fsm->master, command);
- fsm->master_state = ec_fsm_master_address;
+ 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_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
}
/*****************************************************************************/
@@ -553,12 +566,14 @@
Checks, if the new station address has been written to the slave.
*/
-void ec_fsm_master_address(ec_fsm_t *fsm /**< finite state machine */)
-{
- ec_slave_t *slave = fsm->slave;
- ec_command_t *command = &fsm->command;
-
- if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
+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;
+
+ if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
EC_ERR("Failed to write station address on slave %i.\n",
slave->ring_position);
}
@@ -571,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);
}
/*****************************************************************************/
@@ -582,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;
@@ -592,7 +607,7 @@
fsm->slave_state(fsm); // execute slave state machine
- if (fsm->slave_state != ec_fsm_slave_end) return;
+ if (fsm->slave_state != ec_fsm_slavescan_end) return;
// have all slaves been fetched?
if (slave->list.next == &master->slaves) {
@@ -619,7 +634,7 @@
}
if (!slave->type) {
- EC_WARN("FSM: Unknown slave device (vendor 0x%08X,"
+ EC_WARN("Unknown slave device (vendor 0x%08X,"
" code 0x%08X) at position %i.\n",
slave->sii_vendor_id, slave->sii_product_code,
slave->ring_position);
@@ -636,7 +651,9 @@
}
// determine initial state.
- if ((slave->type && slave->type->special == EC_TYPE_BUS_COUPLER)) {
+ if ((slave->type &&
+ (slave->type->special == EC_TYPE_BUS_COUPLER ||
+ slave->type->special == EC_TYPE_INFRA))) {
slave->requested_state = EC_SLAVE_STATE_OP;
}
else {
@@ -645,7 +662,7 @@
else
slave->requested_state = EC_SLAVE_STATE_INIT;
}
- slave->state_error = 0;
+ slave->error_flag = 0;
// calculate coupler-based slave address
slave->coupler_index = current_coupler_index;
@@ -653,7 +670,7 @@
coupler_subindex++;
}
- if (master->mode == EC_MASTER_MODE_FREERUN) {
+ if (master->mode == EC_MASTER_MODE_IDLE) {
// start EoE processing
ec_master_eoe_start(master);
}
@@ -665,7 +682,7 @@
// process next slave
fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
- fsm->slave_state = ec_fsm_slave_start_reading;
+ fsm->slave_state = ec_fsm_slavescan_start;
fsm->slave_state(fsm); // execute immediately
}
@@ -676,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
+ if (fsm->slave_state != ec_fsm_slaveconf_end) return;
+
+ ec_fsm_master_action_process_states(fsm);
}
/*****************************************************************************/
@@ -690,13 +709,14 @@
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;
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 write EEPROM contents to slave %i.\n",
slave->ring_position);
kfree(slave->new_eeprom_data);
@@ -722,13 +742,13 @@
slave->new_eeprom_data = NULL;
// restart master state machine.
- fsm->master_state = ec_fsm_master_start;
+ fsm->master_state = ec_fsm_master_start; // TODO: Evaluate new contents!
fsm->master_state(fsm); // execute immediately
return;
}
/******************************************************************************
- * slave state machine
+ * slave scan sub state machine
*****************************************************************************/
/**
@@ -737,126 +757,129 @@
slave, according to its ring position.
*/
-void ec_fsm_slave_start_reading(ec_fsm_t *fsm /**< finite state machine */)
-{
- ec_command_t *command = &fsm->command;
+void ec_fsm_slavescan_start(ec_fsm_t *fsm /**< finite state machine */)
+{
+ ec_datagram_t *datagram = &fsm->datagram;
// write station address
- ec_command_apwr(command, fsm->slave->ring_position, 0x0010, 2);
- EC_WRITE_U16(command->data, fsm->slave->station_address);
- ec_master_queue_command(fsm->master, command);
- fsm->slave_state = ec_fsm_slave_read_status;
-}
-
-/*****************************************************************************/
-
-/**
- Slave state: READ_STATUS.
-*/
-
-void ec_fsm_slave_read_status(ec_fsm_t *fsm /**< finite state machine */)
-{
- ec_command_t *command = &fsm->command;
-
- if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
- EC_ERR("FSM failed to write station address of slave %i.\n",
+ 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->slave_state = ec_fsm_slavescan_address;
+}
+
+/*****************************************************************************/
+
+/**
+ Slave state: ADDRESS.
+*/
+
+void ec_fsm_slavescan_address(ec_fsm_t *fsm /**< finite state machine */)
+{
+ ec_datagram_t *datagram = &fsm->datagram;
+
+ if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
+ fsm->slave->error_flag = 1;
+ fsm->slave_state = ec_fsm_slavescan_end;
+ EC_ERR("Failed to write station address of slave %i.\n",
fsm->slave->ring_position);
- fsm->slave_state = ec_fsm_slave_end;
- return;
- }
-
- // read AL status
- ec_command_nprd(command, fsm->slave->station_address, 0x0130, 2);
- ec_master_queue_command(fsm->master, command);
- fsm->slave_state = ec_fsm_slave_read_base;
-}
-
-/*****************************************************************************/
-
-/**
- Slave state: READ_BASE.
-*/
-
-void ec_fsm_slave_read_base(ec_fsm_t *fsm /**< finite state machine */)
-{
- ec_command_t *command = &fsm->command;
- ec_slave_t *slave = fsm->slave;
-
- if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
- EC_ERR("FSM failed to read AL status of slave %i.\n",
+ return;
+ }
+
+ // Read AL state
+ ec_datagram_nprd(datagram, fsm->slave->station_address, 0x0130, 2);
+ ec_master_queue_datagram(fsm->master, datagram);
+ fsm->slave_state = ec_fsm_slavescan_state;
+}
+
+/*****************************************************************************/
+
+/**
+ Slave state: STATE.
+*/
+
+void ec_fsm_slavescan_state(ec_fsm_t *fsm /**< finite state machine */)
+{
+ ec_datagram_t *datagram = &fsm->datagram;
+ ec_slave_t *slave = fsm->slave;
+
+ if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
+ fsm->slave->error_flag = 1;
+ fsm->slave_state = ec_fsm_slavescan_end;
+ EC_ERR("Failed to read AL state of slave %i.\n",
fsm->slave->ring_position);
- fsm->slave_state = ec_fsm_slave_end;
- return;
- }
-
- slave->current_state = EC_READ_U8(command->data);
+ return;
+ }
+
+ slave->current_state = EC_READ_U8(datagram->data);
if (slave->current_state & EC_ACK) {
- EC_WARN("Slave %i has status error bit set (0x%02X)!\n",
+ EC_WARN("Slave %i has state error bit set (0x%02X)!\n",
slave->ring_position, slave->current_state);
slave->current_state &= 0x0F;
}
// read base data
- ec_command_nprd(command, fsm->slave->station_address, 0x0000, 6);
- ec_master_queue_command(fsm->master, command);
- fsm->slave_state = ec_fsm_slave_read_dl;
-}
-
-/*****************************************************************************/
-
-/**
- Slave state: READ_DL.
-*/
-
-void ec_fsm_slave_read_dl(ec_fsm_t *fsm /**< finite state machine */)
-{
- ec_command_t *command = &fsm->command;
- ec_slave_t *slave = fsm->slave;
-
- if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
- EC_ERR("FSM failed to read base data of slave %i.\n",
+ ec_datagram_nprd(datagram, fsm->slave->station_address, 0x0000, 6);
+ ec_master_queue_datagram(fsm->master, datagram);
+ fsm->slave_state = ec_fsm_slavescan_base;
+}
+
+/*****************************************************************************/
+
+/**
+ Slave state: BASE.
+*/
+
+void ec_fsm_slavescan_base(ec_fsm_t *fsm /**< finite state machine */)
+{
+ ec_datagram_t *datagram = &fsm->datagram;
+ ec_slave_t *slave = fsm->slave;
+
+ if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
+ fsm->slave->error_flag = 1;
+ fsm->slave_state = ec_fsm_slavescan_end;
+ EC_ERR("Failed to read base data of slave %i.\n",
slave->ring_position);
- fsm->slave_state = ec_fsm_slave_end;
- return;
- }
-
- slave->base_type = EC_READ_U8 (command->data);
- slave->base_revision = EC_READ_U8 (command->data + 1);
- slave->base_build = EC_READ_U16(command->data + 2);
- slave->base_fmmu_count = EC_READ_U8 (command->data + 4);
- slave->base_sync_count = EC_READ_U8 (command->data + 5);
+ return;
+ }
+
+ slave->base_type = EC_READ_U8 (datagram->data);
+ slave->base_revision = EC_READ_U8 (datagram->data + 1);
+ slave->base_build = EC_READ_U16(datagram->data + 2);
+ slave->base_fmmu_count = EC_READ_U8 (datagram->data + 4);
+ slave->base_sync_count = EC_READ_U8 (datagram->data + 5);
if (slave->base_fmmu_count > EC_MAX_FMMUS)
slave->base_fmmu_count = EC_MAX_FMMUS;
// read data link status
- ec_command_nprd(command, slave->station_address, 0x0110, 2);
- ec_master_queue_command(slave->master, command);
- fsm->slave_state = ec_fsm_slave_eeprom_size;
-}
-
-/*****************************************************************************/
-
-/**
- Slave state: EEPROM_SIZE.
- Read the actual size of the EEPROM to allocate the EEPROM image.
-*/
-
-void ec_fsm_slave_eeprom_size(ec_fsm_t *fsm /**< finite state machine */)
-{
- ec_command_t *command = &fsm->command;
+ ec_datagram_nprd(datagram, slave->station_address, 0x0110, 2);
+ ec_master_queue_datagram(slave->master, datagram);
+ fsm->slave_state = ec_fsm_slavescan_datalink;
+}
+
+/*****************************************************************************/
+
+/**
+ Slave state: DATALINK.
+*/
+
+void ec_fsm_slavescan_datalink(ec_fsm_t *fsm /**< finite state machine */)
+{
+ ec_datagram_t *datagram = &fsm->datagram;
ec_slave_t *slave = fsm->slave;
uint16_t dl_status;
unsigned int i;
- if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
- EC_ERR("FSM failed to read DL status of slave %i.\n",
+ if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
+ fsm->slave->error_flag = 1;
+ fsm->slave_state = ec_fsm_slavescan_end;
+ EC_ERR("Failed to read DL status of slave %i.\n",
slave->ring_position);
- fsm->slave_state = ec_fsm_slave_end;
- return;
- }
-
- dl_status = EC_READ_U16(command->data);
+ return;
+ }
+
+ dl_status = EC_READ_U16(datagram->data);
for (i = 0; i < 4; i++) {
slave->dl_link[i] = dl_status & (1 << (4 + i)) ? 1 : 0;
slave->dl_loop[i] = dl_status & (1 << (8 + i * 2)) ? 1 : 0;
@@ -868,17 +891,17 @@
fsm->sii_offset = 0x0040; // first category header
fsm->sii_mode = 1;
fsm->sii_state = ec_fsm_sii_start_reading;
- fsm->slave_state = ec_fsm_slave_fetch_eeprom;
+ fsm->slave_state = ec_fsm_slavescan_eeprom_size;
fsm->slave_state(fsm); // execute state immediately
}
/*****************************************************************************/
/**
- Slave state: FETCH_EEPROM.
-*/
-
-void ec_fsm_slave_fetch_eeprom(ec_fsm_t *fsm /**< finite state machine */)
+ Slave state: EEPROM_SIZE.
+*/
+
+void ec_fsm_slavescan_eeprom_size(ec_fsm_t *fsm /**< finite state machine */)
{
ec_slave_t *slave = fsm->slave;
uint16_t cat_type, cat_size;
@@ -887,7 +910,8 @@
fsm->sii_state(fsm);
if (fsm->sii_state == ec_fsm_sii_error) {
- fsm->slave_state = ec_fsm_slave_end;
+ fsm->slave->error_flag = 1;
+ fsm->slave_state = ec_fsm_slavescan_end;
EC_ERR("Failed to read EEPROM size of slave %i.\n",
slave->ring_position);
return;
@@ -915,9 +939,10 @@
if (!(slave->eeprom_data =
(uint8_t *) kmalloc(slave->eeprom_size, GFP_ATOMIC))) {
+ fsm->slave->error_flag = 1;
+ fsm->slave_state = ec_fsm_slavescan_end;
EC_ERR("Failed to allocate EEPROM data on slave %i.\n",
slave->ring_position);
- fsm->slave_state = ec_fsm_slave_end;
return;
}
@@ -926,17 +951,17 @@
fsm->sii_offset = 0x0000;
fsm->sii_mode = 1;
fsm->sii_state = ec_fsm_sii_start_reading;
- fsm->slave_state = ec_fsm_slave_fetch_eeprom2;
+ fsm->slave_state = ec_fsm_slavescan_eeprom_data;
fsm->slave_state(fsm); // execute state immediately
}
/*****************************************************************************/
/**
- Slave state: FETCH_EEPROM2.
-*/
-
-void ec_fsm_slave_fetch_eeprom2(ec_fsm_t *fsm /**< finite state machine */)
+ Slave state: EEPROM_DATA.
+*/
+
+void ec_fsm_slavescan_eeprom_data(ec_fsm_t *fsm /**< finite state machine */)
{
ec_slave_t *slave = fsm->slave;
uint16_t *cat_word, cat_type, cat_size;
@@ -945,7 +970,8 @@
fsm->sii_state(fsm);
if (fsm->sii_state == ec_fsm_sii_error) {
- fsm->slave_state = ec_fsm_slave_end;
+ fsm->slave->error_flag = 1;
+ fsm->slave_state = ec_fsm_slavescan_end;
EC_ERR("Failed to fetch EEPROM contents of slave %i.\n",
slave->ring_position);
return;
@@ -1033,26 +1059,45 @@
cat_word += cat_size + 2;
}
- end:
- fsm->slave_state = ec_fsm_slave_end;
-}
-
-/*****************************************************************************/
-
-/**
- Slave state: CONF.
-*/
-
-void ec_fsm_slave_conf(ec_fsm_t *fsm /**< finite state machine */)
-{
- ec_slave_t *slave = fsm->slave;
- ec_master_t *master = fsm->master;
- ec_command_t *command = &fsm->command;
+ fsm->slave_state = ec_fsm_slavescan_end;
+
+end:
+ fsm->slave->error_flag = 1;
+ fsm->slave_state = ec_fsm_slavescan_end;
+}
+
+/*****************************************************************************/
+
+/**
+ Slave state: END.
+ End state of the slave state machine.
+*/
+
+void ec_fsm_slavescan_end(ec_fsm_t *fsm /**< finite state machine */)
+{
+}
+
+/******************************************************************************
+ * slave configuration sub state machine
+ *****************************************************************************/
+
+/**
+ Slave state: INIT.
+*/
+
+void ec_fsm_slaveconf_init(ec_fsm_t *fsm /**< finite state machine */)
+{
+ ec_slave_t *slave = fsm->slave;
+ ec_datagram_t *datagram = &fsm->datagram;
+ const ec_sync_t *sync;
+ ec_eeprom_sync_t *eeprom_sync, mbox_sync;
+ unsigned int j;
fsm->change_state(fsm); // execute state change state machine
if (fsm->change_state == ec_fsm_change_error) {
- fsm->slave_state = ec_fsm_slave_end;
+ slave->error_flag = 1;
+ fsm->slave_state = ec_fsm_slaveconf_end;
return;
}
@@ -1060,7 +1105,7 @@
// slave is now in INIT
if (slave->current_state == slave->requested_state) {
- fsm->slave_state = ec_fsm_slave_end;
+ fsm->slave_state = ec_fsm_slaveconf_end; // successful
return;
}
@@ -1071,150 +1116,114 @@
// check and reset CRC fault counters
//ec_slave_check_crc(slave);
-
- if (!slave->base_fmmu_count) { // no fmmus
- fsm->slave_state = ec_fsm_slave_sync;
- fsm->slave_state(fsm); // execute immediately
- return;
- }
-
- // reset FMMUs
- ec_command_npwr(command, slave->station_address, 0x0600,
- EC_FMMU_SIZE * slave->base_fmmu_count);
- memset(command->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count);
- ec_master_queue_command(master, command);
- fsm->slave_state = ec_fsm_slave_sync;
-}
-
-/*****************************************************************************/
-
-/**
- Slave state: SYNC.
- Configure sync managers.
-*/
-
-void ec_fsm_slave_sync(ec_fsm_t *fsm /**< finite state machine */)
-{
- ec_command_t *command = &fsm->command;
- ec_slave_t *slave = fsm->slave;
- unsigned int j;
- const ec_sync_t *sync;
- ec_eeprom_sync_t *eeprom_sync, mbox_sync;
-
- if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
- EC_ERR("Failed to reset FMMUs of slave %i.\n",
- slave->ring_position);
- slave->state_error = 1;
- fsm->slave_state = ec_fsm_slave_end;
- return;
- }
+ // TODO!
if (!slave->base_sync_count) { // no sync managers
- fsm->slave_state = ec_fsm_slave_preop;
- fsm->slave_state(fsm); // execute immediately
+ fsm->slave_state = ec_fsm_slaveconf_preop;
+ fsm->change_new = EC_SLAVE_STATE_PREOP;
+ fsm->change_state = ec_fsm_change_start;
+ fsm->change_state(fsm); // execute immediately
return;
}
// configure sync managers
- ec_command_npwr(command, slave->station_address, 0x0800,
- EC_SYNC_SIZE * slave->base_sync_count);
- memset(command->data, 0x00, EC_SYNC_SIZE * slave->base_sync_count);
+ ec_datagram_npwr(datagram, slave->station_address, 0x0800,
+ EC_SYNC_SIZE * slave->base_sync_count);
+ memset(datagram->data, 0x00, EC_SYNC_SIZE * slave->base_sync_count);
+
+ // does the slave supply sync manager configurations in its EEPROM?
+ if (!list_empty(&slave->eeprom_syncs)) {
+ list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) {
+ if (eeprom_sync->index >= slave->base_sync_count) {
+ fsm->slave->error_flag = 1;
+ fsm->slave_state = ec_fsm_slaveconf_end;
+ EC_ERR("Invalid sync manager configuration found!");
+ return;
+ }
+ ec_eeprom_sync_config(eeprom_sync, slave,
+ datagram->data + EC_SYNC_SIZE
+ * eeprom_sync->index);
+ }
+ }
// known slave type, take type's SM information
- if (slave->type) {
+ else if (slave->type) {
for (j = 0; slave->type->sync_managers[j] && j < EC_MAX_SYNC; j++) {
sync = slave->type->sync_managers[j];
- ec_sync_config(sync, slave, command->data + EC_SYNC_SIZE * j);
+ ec_sync_config(sync, slave, datagram->data + EC_SYNC_SIZE * j);
}
}
// unknown type, but slave has mailbox
else if (slave->sii_mailbox_protocols)
{
- // does it supply sync manager configurations in its EEPROM?
- if (!list_empty(&slave->eeprom_syncs)) {
- list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) {
- if (eeprom_sync->index >= slave->base_sync_count) {
- EC_ERR("Invalid sync manager configuration found!");
- fsm->slave_state = ec_fsm_slave_end;
- return;
- }
- ec_eeprom_sync_config(eeprom_sync,
- command->data + EC_SYNC_SIZE
- * eeprom_sync->index);
- }
- }
-
- // no sync manager information; guess mailbox settings
- else {
- mbox_sync.physical_start_address =
- slave->sii_rx_mailbox_offset;
- mbox_sync.length = slave->sii_rx_mailbox_size;
- mbox_sync.control_register = 0x26;
- mbox_sync.enable = 1;
- ec_eeprom_sync_config(&mbox_sync, command->data);
-
- mbox_sync.physical_start_address =
- slave->sii_tx_mailbox_offset;
- mbox_sync.length = slave->sii_tx_mailbox_size;
- mbox_sync.control_register = 0x22;
- mbox_sync.enable = 1;
- ec_eeprom_sync_config(&mbox_sync,
- command->data + EC_SYNC_SIZE);
- }
+ // guess mailbox settings
+ mbox_sync.physical_start_address =
+ slave->sii_rx_mailbox_offset;
+ mbox_sync.length = slave->sii_rx_mailbox_size;
+ mbox_sync.control_register = 0x26;
+ mbox_sync.enable = 1;
+ ec_eeprom_sync_config(&mbox_sync, slave, datagram->data);
+
+ mbox_sync.physical_start_address =
+ slave->sii_tx_mailbox_offset;
+ mbox_sync.length = slave->sii_tx_mailbox_size;
+ mbox_sync.control_register = 0x22;
+ mbox_sync.enable = 1;
+ ec_eeprom_sync_config(&mbox_sync, slave,
+ datagram->data + EC_SYNC_SIZE);
EC_INFO("Mailbox configured for unknown slave %i\n",
slave->ring_position);
}
- ec_master_queue_command(fsm->master, command);
- fsm->slave_state = ec_fsm_slave_preop;
-}
-
-/*****************************************************************************/
-
-/**
- Slave state: PREOP.
- Change slave state to PREOP.
-*/
-
-void ec_fsm_slave_preop(ec_fsm_t *fsm /**< finite state machine */)
-{
- ec_command_t *command = &fsm->command;
- ec_slave_t *slave = fsm->slave;
-
- if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
+ ec_master_queue_datagram(fsm->master, datagram);
+ fsm->slave_state = ec_fsm_slaveconf_sync;
+}
+
+/*****************************************************************************/
+
+/**
+ Slave state: SYNC.
+*/
+
+void ec_fsm_slaveconf_sync(ec_fsm_t *fsm /**< finite state machine */)
+{
+ ec_datagram_t *datagram = &fsm->datagram;
+ ec_slave_t *slave = fsm->slave;
+
+ if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
+ slave->error_flag = 1;
+ fsm->slave_state = ec_fsm_slaveconf_end;
EC_ERR("Failed to set sync managers on slave %i.\n",
slave->ring_position);
- slave->state_error = 1;
- fsm->slave_state = ec_fsm_slave_end;
- return;
- }
-
+ return;
+ }
+
+ fsm->slave_state = ec_fsm_slaveconf_preop;
fsm->change_new = EC_SLAVE_STATE_PREOP;
fsm->change_state = ec_fsm_change_start;
- fsm->slave_state = ec_fsm_slave_fmmu;
fsm->change_state(fsm); // execute immediately
}
/*****************************************************************************/
/**
- Slave state: FMMU.
- Configure FMMUs.
-*/
-
-void ec_fsm_slave_fmmu(ec_fsm_t *fsm /**< finite state machine */)
+ Slave state: PREOP.
+*/
+
+void ec_fsm_slaveconf_preop(ec_fsm_t *fsm /**< finite state machine */)
{
ec_slave_t *slave = fsm->slave;
ec_master_t *master = fsm->master;
- ec_command_t *command = &fsm->command;
+ ec_datagram_t *datagram = &fsm->datagram;
unsigned int j;
fsm->change_state(fsm); // execute state change state machine
if (fsm->change_state == ec_fsm_change_error) {
- fsm->slave_state = ec_fsm_slave_end;
+ slave->error_flag = 1;
+ fsm->slave_state = ec_fsm_slaveconf_end;
return;
}
@@ -1222,57 +1231,57 @@
// slave is now in PREOP
if (slave->current_state == slave->requested_state) {
- fsm->slave_state = ec_fsm_slave_end;
+ fsm->slave_state = ec_fsm_slaveconf_end; // successful
return;
}
// stop activation here for slaves without type
if (!slave->type) {
- fsm->slave_state = ec_fsm_slave_end;
+ fsm->slave_state = ec_fsm_slaveconf_end; // successful
return;
}
if (!slave->base_fmmu_count) {
- fsm->slave_state = ec_fsm_slave_saveop;
- fsm->slave_state(fsm); // execute immediately
+ fsm->slave_state = ec_fsm_slaveconf_saveop;
+ fsm->change_new = EC_SLAVE_STATE_SAVEOP;
+ fsm->change_state = ec_fsm_change_start;
+ fsm->change_state(fsm); // execute immediately
return;
}
// configure FMMUs
- ec_command_npwr(command, slave->station_address,
- 0x0600, EC_FMMU_SIZE * slave->base_fmmu_count);
- memset(command->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count);
+ ec_datagram_npwr(datagram, slave->station_address,
+ 0x0600, EC_FMMU_SIZE * slave->base_fmmu_count);
+ memset(datagram->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count);
for (j = 0; j < slave->fmmu_count; j++) {
ec_fmmu_config(&slave->fmmus[j], slave,
- command->data + EC_FMMU_SIZE * j);
- }
-
- ec_master_queue_command(master, command);
- fsm->slave_state = ec_fsm_slave_saveop;
-}
-
-/*****************************************************************************/
-
-/**
- Slave state: SAVEOP.
- Set slave state to SAVEOP.
-*/
-
-void ec_fsm_slave_saveop(ec_fsm_t *fsm /**< finite state machine */)
-{
- ec_command_t *command = &fsm->command;
-
- if (fsm->slave->base_fmmu_count && (command->state != EC_CMD_RECEIVED ||
- command->working_counter != 1)) {
- EC_ERR("FSM failed to set FMMUs on slave %i.\n",
+ datagram->data + EC_FMMU_SIZE * j);
+ }
+
+ ec_master_queue_datagram(master, datagram);
+ fsm->slave_state = ec_fsm_slaveconf_fmmu;
+}
+
+/*****************************************************************************/
+
+/**
+ Slave state: FMMU.
+*/
+
+void ec_fsm_slaveconf_fmmu(ec_fsm_t *fsm /**< finite state machine */)
+{
+ ec_datagram_t *datagram = &fsm->datagram;
+
+ if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
+ fsm->slave->error_flag = 1;
+ fsm->slave_state = ec_fsm_slaveconf_end;
+ EC_ERR("Failed to set FMMUs on slave %i.\n",
fsm->slave->ring_position);
- fsm->slave->state_error = 1;
- fsm->slave_state = ec_fsm_slave_end;
return;
}
// set state to SAVEOP
- fsm->slave_state = ec_fsm_slave_op;
+ fsm->slave_state = ec_fsm_slaveconf_saveop;
fsm->change_new = EC_SLAVE_STATE_SAVEOP;
fsm->change_state = ec_fsm_change_start;
fsm->change_state(fsm); // execute immediately
@@ -1281,16 +1290,16 @@
/*****************************************************************************/
/**
- Slave state: OP.
- Set slave state to OP.
-*/
-
-void ec_fsm_slave_op(ec_fsm_t *fsm /**< finite state machine */)
+ Slave state: SAVEOP.
+*/
+
+void ec_fsm_slaveconf_saveop(ec_fsm_t *fsm /**< finite state machine */)
{
fsm->change_state(fsm); // execute state change state machine
if (fsm->change_state == ec_fsm_change_error) {
- fsm->slave_state = ec_fsm_slave_end;
+ fsm->slave->error_flag = 1;
+ fsm->slave_state = ec_fsm_slaveconf_end;
return;
}
@@ -1298,12 +1307,12 @@
// slave is now in SAVEOP
if (fsm->slave->current_state == fsm->slave->requested_state) {
- fsm->slave_state = ec_fsm_slave_end;
+ fsm->slave_state = ec_fsm_slaveconf_end; // successful
return;
}
// set state to OP
- fsm->slave_state = ec_fsm_slave_op2;
+ fsm->slave_state = ec_fsm_slaveconf_op;
fsm->change_new = EC_SLAVE_STATE_OP;
fsm->change_state = ec_fsm_change_start;
fsm->change_state(fsm); // execute immediately
@@ -1312,23 +1321,23 @@
/*****************************************************************************/
/**
- Slave state: OP2
- Executes the change state machine, until the OP state is set.
-*/
-
-void ec_fsm_slave_op2(ec_fsm_t *fsm /**< finite state machine */)
+ Slave state: OP
+*/
+
+void ec_fsm_slaveconf_op(ec_fsm_t *fsm /**< finite state machine */)
{
fsm->change_state(fsm); // execute state change state machine
if (fsm->change_state == ec_fsm_change_error) {
- fsm->slave_state = ec_fsm_slave_end;
+ fsm->slave->error_flag = 1;
+ fsm->slave_state = ec_fsm_slaveconf_end;
return;
}
if (fsm->change_state != ec_fsm_change_end) return;
// slave is now in OP
- fsm->slave_state = ec_fsm_slave_end;
+ fsm->slave_state = ec_fsm_slaveconf_end; // successful
}
/*****************************************************************************/
@@ -1338,12 +1347,12 @@
End state of the slave state machine.
*/
-void ec_fsm_slave_end(ec_fsm_t *fsm /**< finite state machine */)
+void ec_fsm_slaveconf_end(ec_fsm_t *fsm /**< finite state machine */)
{
}
/******************************************************************************
- * SII state machine
+ * SII sub state machine
*****************************************************************************/
/**
@@ -1353,20 +1362,20 @@
void ec_fsm_sii_start_reading(ec_fsm_t *fsm /**< finite state machine */)
{
- ec_command_t *command = &fsm->command;
+ ec_datagram_t *datagram = &fsm->datagram;
// initiate read operation
if (fsm->sii_mode) {
- ec_command_npwr(command, fsm->slave->station_address, 0x502, 4);
+ ec_datagram_npwr(datagram, fsm->slave->station_address, 0x502, 4);
}
else {
- ec_command_apwr(command, fsm->slave->ring_position, 0x502, 4);
- }
-
- EC_WRITE_U8 (command->data, 0x00); // read-only access
- EC_WRITE_U8 (command->data + 1, 0x01); // request read operation
- EC_WRITE_U16(command->data + 2, fsm->sii_offset);
- ec_master_queue_command(fsm->master, command);
+ ec_datagram_apwr(datagram, fsm->slave->ring_position, 0x502, 4);
+ }
+
+ EC_WRITE_U8 (datagram->data, 0x00); // read-only access
+ EC_WRITE_U8 (datagram->data + 1, 0x01); // request read operation
+ EC_WRITE_U16(datagram->data + 2, fsm->sii_offset);
+ ec_master_queue_datagram(fsm->master, datagram);
fsm->sii_state = ec_fsm_sii_read_check;
}
@@ -1374,30 +1383,30 @@
/**
SII state: READ_CHECK.
- Checks, if the SII-read-command has been sent and issues a fetch command.
+ Checks, if the SII-read-datagram has been sent and issues a fetch datagram.
*/
void ec_fsm_sii_read_check(ec_fsm_t *fsm /**< finite state machine */)
{
- ec_command_t *command = &fsm->command;
-
- if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
- EC_ERR("SII: Reception of read command failed.\n");
+ ec_datagram_t *datagram = &fsm->datagram;
+
+ if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
+ EC_ERR("SII: Reception of read datagram failed.\n");
fsm->sii_state = ec_fsm_sii_error;
return;
}
fsm->sii_start = get_cycles();
- // issue check/fetch command
+ // issue check/fetch datagram
if (fsm->sii_mode) {
- ec_command_nprd(command, fsm->slave->station_address, 0x502, 10);
+ ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 10);
}
else {
- ec_command_aprd(command, fsm->slave->ring_position, 0x502, 10);
- }
-
- ec_master_queue_command(fsm->master, command);
+ ec_datagram_aprd(datagram, fsm->slave->ring_position, 0x502, 10);
+ }
+
+ ec_master_queue_datagram(fsm->master, datagram);
fsm->sii_state = ec_fsm_sii_read_fetch;
}
@@ -1405,55 +1414,55 @@
/**
SII state: READ_FETCH.
- Fetches the result of an SII-read command.
+ Fetches the result of an SII-read datagram.
*/
void ec_fsm_sii_read_fetch(ec_fsm_t *fsm /**< finite state machine */)
{
- ec_command_t *command = &fsm->command;
-
- if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
- EC_ERR("SII: Reception of check/fetch command failed.\n");
+ ec_datagram_t *datagram = &fsm->datagram;
+
+ if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
+ EC_ERR("SII: Reception of check/fetch datagram failed.\n");
fsm->sii_state = ec_fsm_sii_error;
return;
}
// check "busy bit"
- if (EC_READ_U8(command->data + 1) & 0x81) {
+ if (EC_READ_U8(datagram->data + 1) & 0x81) {
// still busy... timeout?
if (get_cycles() - fsm->sii_start >= (cycles_t) 10 * cpu_khz) {
EC_ERR("SII: Timeout.\n");
fsm->sii_state = ec_fsm_sii_error;
#if 0
EC_DBG("SII busy: %02X %02X %02X %02X\n",
- EC_READ_U8(command->data + 0),
- EC_READ_U8(command->data + 1),
- EC_READ_U8(command->data + 2),
- EC_READ_U8(command->data + 3));
+ EC_READ_U8(datagram->data + 0),
+ EC_READ_U8(datagram->data + 1),
+ EC_READ_U8(datagram->data + 2),
+ EC_READ_U8(datagram->data + 3));
#endif
}
- // issue check/fetch command again
+ // issue check/fetch datagram again
if (fsm->sii_mode) {
- ec_command_nprd(command, fsm->slave->station_address, 0x502, 10);
+ ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 10);
}
else {
- ec_command_aprd(command, fsm->slave->ring_position, 0x502, 10);
+ ec_datagram_aprd(datagram, fsm->slave->ring_position, 0x502, 10);
}
- ec_master_queue_command(fsm->master, command);
+ ec_master_queue_datagram(fsm->master, datagram);
return;
}
#if 0
EC_DBG("SII rec: %02X %02X %02X %02X - %02X %02X %02X %02X\n",
- EC_READ_U8(command->data + 0), EC_READ_U8(command->data + 1),
- EC_READ_U8(command->data + 2), EC_READ_U8(command->data + 3),
- EC_READ_U8(command->data + 6), EC_READ_U8(command->data + 7),
- EC_READ_U8(command->data + 8), EC_READ_U8(command->data + 9));
+ EC_READ_U8(datagram->data + 0), EC_READ_U8(datagram->data + 1),
+ EC_READ_U8(datagram->data + 2), EC_READ_U8(datagram->data + 3),
+ EC_READ_U8(datagram->data + 6), EC_READ_U8(datagram->data + 7),
+ EC_READ_U8(datagram->data + 8), EC_READ_U8(datagram->data + 9));
#endif
// SII value received.
- memcpy(fsm->sii_value, command->data + 6, 4);
+ memcpy(fsm->sii_value, datagram->data + 6, 4);
fsm->sii_state = ec_fsm_sii_end;
}
@@ -1466,15 +1475,15 @@
void ec_fsm_sii_start_writing(ec_fsm_t *fsm /**< finite state machine */)
{
- ec_command_t *command = &fsm->command;
+ ec_datagram_t *datagram = &fsm->datagram;
// initiate write operation
- ec_command_npwr(command, fsm->slave->station_address, 0x502, 8);
- EC_WRITE_U8 (command->data, 0x01); // enable write access
- EC_WRITE_U8 (command->data + 1, 0x02); // request write operation
- EC_WRITE_U32(command->data + 2, fsm->sii_offset);
- memcpy(command->data + 6, fsm->sii_value, 2);
- ec_master_queue_command(fsm->master, command);
+ ec_datagram_npwr(datagram, fsm->slave->station_address, 0x502, 8);
+ EC_WRITE_U8 (datagram->data, 0x01); // enable write access
+ EC_WRITE_U8 (datagram->data + 1, 0x02); // request write operation
+ EC_WRITE_U32(datagram->data + 2, fsm->sii_offset);
+ memcpy(datagram->data + 6, fsm->sii_value, 2);
+ ec_master_queue_datagram(fsm->master, datagram);
fsm->sii_state = ec_fsm_sii_write_check;
}
@@ -1486,19 +1495,19 @@
void ec_fsm_sii_write_check(ec_fsm_t *fsm /**< finite state machine */)
{
- ec_command_t *command = &fsm->command;
-
- if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
- EC_ERR("SII: Reception of write command failed.\n");
+ ec_datagram_t *datagram = &fsm->datagram;
+
+ if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
+ EC_ERR("SII: Reception of write datagram failed.\n");
fsm->sii_state = ec_fsm_sii_error;
return;
}
fsm->sii_start = get_cycles();
- // issue check/fetch command
- ec_command_nprd(command, fsm->slave->station_address, 0x502, 2);
- ec_master_queue_command(fsm->master, command);
+ // issue check/fetch datagram
+ ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 2);
+ ec_master_queue_datagram(fsm->master, datagram);
fsm->sii_state = ec_fsm_sii_write_check2;
}
@@ -1510,25 +1519,25 @@
void ec_fsm_sii_write_check2(ec_fsm_t *fsm /**< finite state machine */)
{
- ec_command_t *command = &fsm->command;
-
- if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
- EC_ERR("SII: Reception of write check command failed.\n");
+ ec_datagram_t *datagram = &fsm->datagram;
+
+ if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
+ EC_ERR("SII: Reception of write check datagram failed.\n");
fsm->sii_state = ec_fsm_sii_error;
return;
}
- if (EC_READ_U8(command->data + 1) & 0x82) {
+ if (EC_READ_U8(datagram->data + 1) & 0x82) {
// still busy... timeout?
if (get_cycles() - fsm->sii_start >= (cycles_t) 10 * cpu_khz) {
EC_ERR("SII: Write timeout.\n");
fsm->sii_state = ec_fsm_sii_error;
}
- // issue check/fetch command again
- ec_master_queue_command(fsm->master, command);
- }
- else if (EC_READ_U8(command->data + 1) & 0x40) {
+ // issue check/fetch datagram again
+ ec_master_queue_datagram(fsm->master, datagram);
+ }
+ else if (EC_READ_U8(datagram->data + 1) & 0x40) {
EC_ERR("SII: Write operation failed!\n");
fsm->sii_state = ec_fsm_sii_error;
}
@@ -1560,7 +1569,7 @@
}
/******************************************************************************
- * state change state machine
+ * state change sub state machine
*****************************************************************************/
/**
@@ -1569,13 +1578,13 @@
void ec_fsm_change_start(ec_fsm_t *fsm /**< finite state machine */)
{
- ec_command_t *command = &fsm->command;
+ ec_datagram_t *datagram = &fsm->datagram;
ec_slave_t *slave = fsm->slave;
// write new state to slave
- ec_command_npwr(command, slave->station_address, 0x0120, 2);
- EC_WRITE_U16(command->data, fsm->change_new);
- ec_master_queue_command(fsm->master, command);
+ ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2);
+ EC_WRITE_U16(datagram->data, fsm->change_new);
+ ec_master_queue_datagram(fsm->master, datagram);
fsm->change_state = ec_fsm_change_check;
}
@@ -1587,53 +1596,50 @@
void ec_fsm_change_check(ec_fsm_t *fsm /**< finite state machine */)
{
- ec_command_t *command = &fsm->command;
- ec_slave_t *slave = fsm->slave;
-
- if (command->state != EC_CMD_RECEIVED) {
- EC_ERR("Failed to send state command to slave %i!\n",
+ ec_datagram_t *datagram = &fsm->datagram;
+ ec_slave_t *slave = fsm->slave;
+
+ if (datagram->state != EC_CMD_RECEIVED) {
+ fsm->change_state = ec_fsm_change_error;
+ EC_ERR("Failed to send state datagram to slave %i!\n",
fsm->slave->ring_position);
- slave->state_error = 1;
+ return;
+ }
+
+ if (datagram->working_counter != 1) {
fsm->change_state = ec_fsm_change_error;
- return;
- }
-
- if (command->working_counter != 1) {
EC_ERR("Failed to set state 0x%02X on slave %i: Slave did not"
" respond.\n", fsm->change_new, fsm->slave->ring_position);
- slave->state_error = 1;
+ return;
+ }
+
+ fsm->change_start = get_cycles();
+
+ // read AL status from slave
+ ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2);
+ ec_master_queue_datagram(fsm->master, datagram);
+ fsm->change_state = ec_fsm_change_status;
+}
+
+/*****************************************************************************/
+
+/**
+ Change state: STATUS.
+*/
+
+void ec_fsm_change_status(ec_fsm_t *fsm /**< finite state machine */)
+{
+ ec_datagram_t *datagram = &fsm->datagram;
+ ec_slave_t *slave = fsm->slave;
+
+ if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
fsm->change_state = ec_fsm_change_error;
- return;
- }
-
- fsm->change_start = get_cycles();
-
- // read AL status from slave
- ec_command_nprd(command, slave->station_address, 0x0130, 2);
- ec_master_queue_command(fsm->master, command);
- fsm->change_state = ec_fsm_change_status;
-}
-
-/*****************************************************************************/
-
-/**
- Change state: STATUS.
-*/
-
-void ec_fsm_change_status(ec_fsm_t *fsm /**< finite state machine */)
-{
- ec_command_t *command = &fsm->command;
- ec_slave_t *slave = fsm->slave;
-
- if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
EC_ERR("Failed to check state 0x%02X on slave %i.\n",
fsm->change_new, slave->ring_position);
- slave->state_error = 1;
- fsm->change_state = ec_fsm_change_error;
- return;
- }
-
- slave->current_state = EC_READ_U8(command->data);
+ return;
+ }
+
+ slave->current_state = EC_READ_U8(datagram->data);
if (slave->current_state == fsm->change_new) {
// state has been set successfully
@@ -1648,15 +1654,14 @@
" (code 0x%02X)!\n", fsm->change_new, slave->ring_position,
slave->current_state);
// fetch AL status error code
- ec_command_nprd(command, slave->station_address, 0x0134, 2);
- ec_master_queue_command(fsm->master, command);
+ ec_datagram_nprd(datagram, slave->station_address, 0x0134, 2);
+ ec_master_queue_datagram(fsm->master, datagram);
fsm->change_state = ec_fsm_change_code;
return;
}
if (get_cycles() - fsm->change_start >= (cycles_t) 10 * cpu_khz) {
// timeout while checking
- slave->state_error = 1;
fsm->change_state = ec_fsm_change_error;
EC_ERR("Timeout while setting state 0x%02X on slave %i.\n",
fsm->change_new, slave->ring_position);
@@ -1664,8 +1669,8 @@
}
// still old state: check again
- ec_command_nprd(command, slave->station_address, 0x0130, 2);
- ec_master_queue_command(fsm->master, command);
+ ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2);
+ ec_master_queue_datagram(fsm->master, datagram);
}
/*****************************************************************************/
@@ -1687,10 +1692,24 @@
{0x0019, "No valid outputs"},
{0x001A, "Synchronisation error"},
{0x001B, "Sync manager watchdog"},
+ {0x001C, "Invalid sync manager types"},
+ {0x001D, "Invalid output configuration"},
+ {0x001E, "Invalid input configuration"},
+ {0x001F, "Invalid watchdog configuration"},
{0x0020, "Slave needs cold start"},
{0x0021, "Slave needs INIT"},
{0x0022, "Slave needs PREOP"},
{0x0023, "Slave needs SAVEOP"},
+ {0x0030, "Invalid DC SYNCH configuration"},
+ {0x0031, "Invalid DC latch configuration"},
+ {0x0032, "PLL error"},
+ {0x0033, "Invalid DC IO error"},
+ {0x0034, "Invalid DC timeout error"},
+ {0x0042, "MBOX EOE"},
+ {0x0043, "MBOX COE"},
+ {0x0044, "MBOX FOE"},
+ {0x0045, "MBOX SOE"},
+ {0x004F, "MBOX VOE"},
{}
};
@@ -1702,19 +1721,18 @@
void ec_fsm_change_code(ec_fsm_t *fsm /**< finite state machine */)
{
- ec_command_t *command = &fsm->command;
+ ec_datagram_t *datagram = &fsm->datagram;
ec_slave_t *slave = fsm->slave;
uint32_t code;
const ec_code_msg_t *al_msg;
- if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
- EC_ERR("Reception of AL status code command failed.\n");
- slave->state_error = 1;
+ if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
fsm->change_state = ec_fsm_change_error;
- return;
- }
-
- if ((code = EC_READ_U16(command->data))) {
+ EC_ERR("Reception of AL status code datagram failed.\n");
+ return;
+ }
+
+ if ((code = EC_READ_U16(datagram->data))) {
for (al_msg = al_status_messages; al_msg->code; al_msg++) {
if (al_msg->code != code) continue;
EC_ERR("AL status message 0x%04X: \"%s\".\n",
@@ -1726,9 +1744,9 @@
}
// acknowledge "old" slave state
- ec_command_npwr(command, slave->station_address, 0x0120, 2);
- EC_WRITE_U16(command->data, slave->current_state);
- ec_master_queue_command(fsm->master, command);
+ ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2);
+ EC_WRITE_U16(datagram->data, slave->current_state);
+ ec_master_queue_datagram(fsm->master, datagram);
fsm->change_state = ec_fsm_change_ack;
}
@@ -1740,55 +1758,62 @@
void ec_fsm_change_ack(ec_fsm_t *fsm /**< finite state machine */)
{
- ec_command_t *command = &fsm->command;
- ec_slave_t *slave = fsm->slave;
-
- if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
- EC_ERR("Reception of state ack command failed.\n");
- slave->state_error = 1;
+ ec_datagram_t *datagram = &fsm->datagram;
+ ec_slave_t *slave = fsm->slave;
+
+ if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
fsm->change_state = ec_fsm_change_error;
- return;
- }
+ EC_ERR("Reception of state ack datagram failed.\n");
+ return;
+ }
+
+ fsm->change_start = get_cycles();
// read new AL status
- ec_command_nprd(command, slave->station_address, 0x0130, 2);
- ec_master_queue_command(fsm->master, command);
- fsm->change_state = ec_fsm_change_ack2;
-}
-
-/*****************************************************************************/
-
-/**
- Change state: ACK.
- Acknowledge 2.
-*/
-
-void ec_fsm_change_ack2(ec_fsm_t *fsm /**< finite state machine */)
-{
- ec_command_t *command = &fsm->command;
- ec_slave_t *slave = fsm->slave;
-
- if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
- EC_ERR("Reception of state ack check command failed.\n");
- slave->state_error = 1;
+ ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2);
+ ec_master_queue_datagram(fsm->master, datagram);
+ fsm->change_state = ec_fsm_change_check_ack;
+}
+
+/*****************************************************************************/
+
+/**
+ Change state: CHECK ACK.
+*/
+
+void ec_fsm_change_check_ack(ec_fsm_t *fsm /**< finite state machine */)
+{
+ ec_datagram_t *datagram = &fsm->datagram;
+ ec_slave_t *slave = fsm->slave;
+ ec_slave_state_t ack_state;
+
+ if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
fsm->change_state = ec_fsm_change_error;
- return;
- }
-
- slave->current_state = EC_READ_U8(command->data);
-
- if (slave->current_state == fsm->change_new) {
+ EC_ERR("Reception of state ack check datagram failed.\n");
+ return;
+ }
+
+ ack_state = EC_READ_U8(datagram->data);
+
+ if (ack_state == slave->current_state) {
+ fsm->change_state = ec_fsm_change_error;
EC_INFO("Acknowleged state 0x%02X on slave %i.\n",
slave->current_state, slave->ring_position);
- slave->state_error = 1;
+ return;
+ }
+
+ if (get_cycles() - fsm->change_start >= (cycles_t) 100 * cpu_khz) {
+ // timeout while checking
+ slave->current_state = EC_SLAVE_STATE_UNKNOWN;
fsm->change_state = ec_fsm_change_error;
- return;
- }
-
- EC_WARN("Failed to acknowledge state 0x%02X on slave %i"
- " - Timeout!\n", fsm->change_new, slave->ring_position);
- slave->state_error = 1;
- fsm->change_state = ec_fsm_change_error;
+ EC_ERR("Timeout while acknowleging state 0x%02X on slave %i.\n",
+ fsm->change_new, slave->ring_position);
+ return;
+ }
+
+ // reread new AL status
+ ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2);
+ ec_master_queue_datagram(fsm->master, datagram);
}
/*****************************************************************************/