223 ec_datagram_t *datagram = fsm->datagram; |
223 ec_datagram_t *datagram = fsm->datagram; |
224 ec_slave_t *slave = fsm->slave; |
224 ec_slave_t *slave = fsm->slave; |
225 |
225 |
226 if (datagram->state != EC_DATAGRAM_RECEIVED |
226 if (datagram->state != EC_DATAGRAM_RECEIVED |
227 || datagram->working_counter != 1) { |
227 || datagram->working_counter != 1) { |
228 fsm->state = ec_fsm_change_state_error; |
228 char req_state[EC_STATE_STRING_SIZE]; |
229 EC_ERR("Failed to check state 0x%02X on slave %i.\n", |
229 ec_state_string(fsm->requested_state, req_state); |
230 fsm->requested_state, slave->ring_position); |
230 fsm->state = ec_fsm_change_state_error; |
|
231 EC_ERR("Failed to check state %s on slave %i.\n", |
|
232 req_state, slave->ring_position); |
231 return; |
233 return; |
232 } |
234 } |
233 |
235 |
234 if (fsm->take_time) { |
236 if (fsm->take_time) { |
235 fsm->take_time = 0; |
237 fsm->take_time = 0; |
245 } |
247 } |
246 |
248 |
247 if (slave->current_state != fsm->old_state) { // state changed |
249 if (slave->current_state != fsm->old_state) { // state changed |
248 char req_state[EC_STATE_STRING_SIZE], cur_state[EC_STATE_STRING_SIZE]; |
250 char req_state[EC_STATE_STRING_SIZE], cur_state[EC_STATE_STRING_SIZE]; |
249 |
251 |
|
252 ec_state_string(slave->current_state, cur_state); |
|
253 |
|
254 if ((slave->current_state & 0x0F) != (fsm->old_state & 0x0F)) { |
|
255 // Slave spontaneously changed its state just before the new state |
|
256 // was written. Accept current state as old state and wait for |
|
257 // state change |
|
258 fsm->old_state = slave->current_state; |
|
259 EC_WARN("Slave %i changed to %s in the meantime.\n", |
|
260 slave->ring_position, cur_state); |
|
261 goto again; |
|
262 } |
|
263 |
|
264 // state change error |
|
265 |
250 slave->error_flag = 1; |
266 slave->error_flag = 1; |
251 ec_state_string(fsm->requested_state, req_state); |
267 ec_state_string(fsm->requested_state, req_state); |
252 ec_state_string(slave->current_state, cur_state); |
268 |
253 |
269 EC_ERR("Failed to set %s state, slave %i refused state change (%s).\n", |
254 if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) { |
270 req_state, slave->ring_position, cur_state); |
255 // state change error |
271 // fetch AL status error code |
256 EC_ERR("Failed to set %s state," |
272 ec_datagram_nprd(datagram, slave->station_address, 0x0134, 2); |
257 " slave %i refused state change (%s).\n", |
273 ec_master_queue_datagram(fsm->slave->master, datagram); |
258 req_state, slave->ring_position, cur_state); |
274 fsm->state = ec_fsm_change_state_code; |
259 // fetch AL status error code |
|
260 ec_datagram_nprd(datagram, slave->station_address, 0x0134, 2); |
|
261 ec_master_queue_datagram(fsm->slave->master, datagram); |
|
262 fsm->state = ec_fsm_change_state_code; |
|
263 return; |
|
264 } |
|
265 |
|
266 // state change to unrequested state |
|
267 EC_ERR("Slave %i changed to unrequested state %s!\n", |
|
268 slave->ring_position, cur_state); |
|
269 fsm->state = ec_fsm_change_state_error; |
|
270 return; |
275 return; |
271 } |
276 } |
272 |
277 |
273 // still old state |
278 // still old state |
274 |
279 |
280 EC_ERR("Timeout while setting state %s on slave %i.\n", |
285 EC_ERR("Timeout while setting state %s on slave %i.\n", |
281 state_str, slave->ring_position); |
286 state_str, slave->ring_position); |
282 return; |
287 return; |
283 } |
288 } |
284 |
289 |
285 // check again |
290 again: |
|
291 // no timeout yet. check again |
286 ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2); |
292 ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2); |
287 ec_master_queue_datagram(fsm->slave->master, datagram); |
293 ec_master_queue_datagram(fsm->slave->master, datagram); |
288 } |
294 } |
289 |
295 |
290 /*****************************************************************************/ |
296 /*****************************************************************************/ |