157 |
157 |
158 // write new state to slave |
158 // write new state to slave |
159 ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2); |
159 ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2); |
160 EC_WRITE_U16(datagram->data, fsm->requested_state); |
160 EC_WRITE_U16(datagram->data, fsm->requested_state); |
161 ec_master_queue_datagram(fsm->slave->master, datagram); |
161 ec_master_queue_datagram(fsm->slave->master, datagram); |
|
162 fsm->retries = EC_FSM_RETRIES; |
162 fsm->state = ec_fsm_change_state_check; |
163 fsm->state = ec_fsm_change_state_check; |
163 } |
164 } |
164 |
165 |
165 /*****************************************************************************/ |
166 /*****************************************************************************/ |
166 |
167 |
172 /**< finite state machine */) |
173 /**< finite state machine */) |
173 { |
174 { |
174 ec_datagram_t *datagram = fsm->datagram; |
175 ec_datagram_t *datagram = fsm->datagram; |
175 ec_slave_t *slave = fsm->slave; |
176 ec_slave_t *slave = fsm->slave; |
176 |
177 |
|
178 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { |
|
179 ec_master_queue_datagram(fsm->slave->master, datagram); |
|
180 return; |
|
181 } |
|
182 |
177 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
183 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
178 fsm->state = ec_fsm_change_state_error; |
184 fsm->state = ec_fsm_change_state_error; |
179 EC_ERR("Failed to send state datagram to slave %i!\n", |
185 EC_ERR("Failed to receive state datagram from slave %i!\n", |
180 fsm->slave->ring_position); |
186 fsm->slave->ring_position); |
181 return; |
187 return; |
182 } |
188 } |
183 |
189 |
184 if (fsm->take_time) { |
190 if (fsm->take_time) { |
198 |
204 |
199 // repeat writing new state to slave |
205 // repeat writing new state to slave |
200 ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2); |
206 ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2); |
201 EC_WRITE_U16(datagram->data, fsm->requested_state); |
207 EC_WRITE_U16(datagram->data, fsm->requested_state); |
202 ec_master_queue_datagram(fsm->slave->master, datagram); |
208 ec_master_queue_datagram(fsm->slave->master, datagram); |
|
209 fsm->retries = EC_FSM_RETRIES; |
203 return; |
210 return; |
204 } |
211 } |
205 |
212 |
206 fsm->take_time = 1; |
213 fsm->take_time = 1; |
207 |
214 |
208 // read AL status from slave |
215 // read AL status from slave |
209 ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2); |
216 ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2); |
210 ec_master_queue_datagram(fsm->slave->master, datagram); |
217 ec_master_queue_datagram(fsm->slave->master, datagram); |
|
218 fsm->retries = EC_FSM_RETRIES; |
211 fsm->state = ec_fsm_change_state_status; |
219 fsm->state = ec_fsm_change_state_status; |
212 } |
220 } |
213 |
221 |
214 /*****************************************************************************/ |
222 /*****************************************************************************/ |
215 |
223 |
221 /**< finite state machine */) |
229 /**< finite state machine */) |
222 { |
230 { |
223 ec_datagram_t *datagram = fsm->datagram; |
231 ec_datagram_t *datagram = fsm->datagram; |
224 ec_slave_t *slave = fsm->slave; |
232 ec_slave_t *slave = fsm->slave; |
225 |
233 |
226 if (datagram->state != EC_DATAGRAM_RECEIVED |
234 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { |
227 || datagram->working_counter != 1) { |
235 ec_master_queue_datagram(fsm->slave->master, datagram); |
|
236 return; |
|
237 } |
|
238 |
|
239 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
|
240 fsm->state = ec_fsm_change_state_error; |
|
241 EC_ERR("Failed to receive state checking datagram from slave %i.\n", |
|
242 slave->ring_position); |
|
243 return; |
|
244 } |
|
245 |
|
246 if (datagram->working_counter != 1) { |
228 char req_state[EC_STATE_STRING_SIZE]; |
247 char req_state[EC_STATE_STRING_SIZE]; |
229 ec_state_string(fsm->requested_state, req_state); |
248 ec_state_string(fsm->requested_state, req_state); |
230 fsm->state = ec_fsm_change_state_error; |
249 fsm->state = ec_fsm_change_state_error; |
231 EC_ERR("Failed to check state %s on slave %i.\n", |
250 EC_ERR("Failed to check state %s on slave %i.\n", |
232 req_state, slave->ring_position); |
251 req_state, slave->ring_position); |
269 EC_ERR("Failed to set %s state, slave %i refused state change (%s).\n", |
288 EC_ERR("Failed to set %s state, slave %i refused state change (%s).\n", |
270 req_state, slave->ring_position, cur_state); |
289 req_state, slave->ring_position, cur_state); |
271 // fetch AL status error code |
290 // fetch AL status error code |
272 ec_datagram_nprd(datagram, slave->station_address, 0x0134, 2); |
291 ec_datagram_nprd(datagram, slave->station_address, 0x0134, 2); |
273 ec_master_queue_datagram(fsm->slave->master, datagram); |
292 ec_master_queue_datagram(fsm->slave->master, datagram); |
|
293 fsm->retries = EC_FSM_RETRIES; |
274 fsm->state = ec_fsm_change_state_code; |
294 fsm->state = ec_fsm_change_state_code; |
275 return; |
295 return; |
276 } |
296 } |
277 |
297 |
278 // still old state |
298 // still old state |
289 |
309 |
290 again: |
310 again: |
291 // no timeout yet. check again |
311 // no timeout yet. check again |
292 ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2); |
312 ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2); |
293 ec_master_queue_datagram(fsm->slave->master, datagram); |
313 ec_master_queue_datagram(fsm->slave->master, datagram); |
|
314 fsm->retries = EC_FSM_RETRIES; |
294 } |
315 } |
295 |
316 |
296 /*****************************************************************************/ |
317 /*****************************************************************************/ |
297 |
318 |
298 /** |
319 /** |
344 { |
365 { |
345 ec_datagram_t *datagram = fsm->datagram; |
366 ec_datagram_t *datagram = fsm->datagram; |
346 uint32_t code; |
367 uint32_t code; |
347 const ec_code_msg_t *al_msg; |
368 const ec_code_msg_t *al_msg; |
348 |
369 |
349 if (datagram->state != EC_DATAGRAM_RECEIVED |
370 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { |
350 || datagram->working_counter != 1) { |
371 ec_master_queue_datagram(fsm->slave->master, datagram); |
|
372 return; |
|
373 } |
|
374 |
|
375 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
|
376 fsm->state = ec_fsm_change_state_error; |
|
377 EC_ERR("Failed to receive AL status code datagram from slave %i.\n", |
|
378 fsm->slave->ring_position); |
|
379 return; |
|
380 } |
|
381 |
|
382 if (datagram->working_counter != 1) { |
351 EC_WARN("Reception of AL status code datagram failed.\n"); |
383 EC_WARN("Reception of AL status code datagram failed.\n"); |
352 } |
384 } |
353 else { |
385 else { |
354 if ((code = EC_READ_U16(datagram->data))) { |
386 if ((code = EC_READ_U16(datagram->data))) { |
355 for (al_msg = al_status_messages; al_msg->code; al_msg++) { |
387 for (al_msg = al_status_messages; al_msg->code; al_msg++) { |
380 ec_datagram_t *datagram = fsm->datagram; |
412 ec_datagram_t *datagram = fsm->datagram; |
381 |
413 |
382 ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2); |
414 ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2); |
383 EC_WRITE_U16(datagram->data, slave->current_state); |
415 EC_WRITE_U16(datagram->data, slave->current_state); |
384 ec_master_queue_datagram(fsm->slave->master, datagram); |
416 ec_master_queue_datagram(fsm->slave->master, datagram); |
|
417 fsm->retries = EC_FSM_RETRIES; |
385 fsm->state = ec_fsm_change_state_ack; |
418 fsm->state = ec_fsm_change_state_ack; |
386 } |
419 } |
387 |
420 |
388 /*****************************************************************************/ |
421 /*****************************************************************************/ |
389 |
422 |
394 void ec_fsm_change_state_ack(ec_fsm_change_t *fsm /**< finite state machine */) |
427 void ec_fsm_change_state_ack(ec_fsm_change_t *fsm /**< finite state machine */) |
395 { |
428 { |
396 ec_datagram_t *datagram = fsm->datagram; |
429 ec_datagram_t *datagram = fsm->datagram; |
397 ec_slave_t *slave = fsm->slave; |
430 ec_slave_t *slave = fsm->slave; |
398 |
431 |
399 if (datagram->state != EC_DATAGRAM_RECEIVED |
432 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { |
400 || datagram->working_counter != 1) { |
433 ec_master_queue_datagram(fsm->slave->master, datagram); |
401 fsm->state = ec_fsm_change_state_error; |
434 return; |
402 EC_ERR("Reception of state ack datagram failed.\n"); |
435 } |
|
436 |
|
437 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
|
438 fsm->state = ec_fsm_change_state_error; |
|
439 EC_ERR("Failed to receive state ack datagram for slave %i.\n", |
|
440 slave->ring_position); |
|
441 return; |
|
442 } |
|
443 |
|
444 if (datagram->working_counter != 1) { |
|
445 fsm->state = ec_fsm_change_state_error; |
|
446 EC_ERR("Reception of state ack datagram failed - slave %i did not" |
|
447 " respond.\n", slave->ring_position); |
403 return; |
448 return; |
404 } |
449 } |
405 |
450 |
406 fsm->take_time = 1; |
451 fsm->take_time = 1; |
407 |
452 |
408 // read new AL status |
453 // read new AL status |
409 ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2); |
454 ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2); |
410 ec_master_queue_datagram(fsm->slave->master, datagram); |
455 ec_master_queue_datagram(fsm->slave->master, datagram); |
|
456 fsm->retries = EC_FSM_RETRIES; |
411 fsm->state = ec_fsm_change_state_check_ack; |
457 fsm->state = ec_fsm_change_state_check_ack; |
412 } |
458 } |
413 |
459 |
414 /*****************************************************************************/ |
460 /*****************************************************************************/ |
415 |
461 |
421 /**< finite state machine */) |
467 /**< finite state machine */) |
422 { |
468 { |
423 ec_datagram_t *datagram = fsm->datagram; |
469 ec_datagram_t *datagram = fsm->datagram; |
424 ec_slave_t *slave = fsm->slave; |
470 ec_slave_t *slave = fsm->slave; |
425 |
471 |
426 if (datagram->state != EC_DATAGRAM_RECEIVED |
472 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { |
427 || datagram->working_counter != 1) { |
473 ec_master_queue_datagram(fsm->slave->master, datagram); |
428 fsm->state = ec_fsm_change_state_error; |
474 return; |
429 EC_ERR("Reception of state ack check datagram failed.\n"); |
475 } |
|
476 |
|
477 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
|
478 fsm->state = ec_fsm_change_state_error; |
|
479 EC_ERR("Failed to receive state ack check datagram from slave %i.\n", |
|
480 slave->ring_position); |
|
481 return; |
|
482 } |
|
483 |
|
484 if (datagram->working_counter != 1) { |
|
485 fsm->state = ec_fsm_change_state_error; |
|
486 EC_ERR("Reception of state ack check datagram failed - slave %i did" |
|
487 " not respond.\n", slave->ring_position); |
430 return; |
488 return; |
431 } |
489 } |
432 |
490 |
433 if (fsm->take_time) { |
491 if (fsm->take_time) { |
434 fsm->take_time = 0; |
492 fsm->take_time = 0; |
462 } |
520 } |
463 |
521 |
464 // reread new AL status |
522 // reread new AL status |
465 ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2); |
523 ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2); |
466 ec_master_queue_datagram(fsm->slave->master, datagram); |
524 ec_master_queue_datagram(fsm->slave->master, datagram); |
|
525 fsm->retries = EC_FSM_RETRIES; |
467 } |
526 } |
468 |
527 |
469 /*****************************************************************************/ |
528 /*****************************************************************************/ |
470 |
529 |
471 /** |
530 /** |