63 |
63 |
64 void ec_voe_handler_state_read_start(ec_voe_handler_t *); |
64 void ec_voe_handler_state_read_start(ec_voe_handler_t *); |
65 void ec_voe_handler_state_read_check(ec_voe_handler_t *); |
65 void ec_voe_handler_state_read_check(ec_voe_handler_t *); |
66 void ec_voe_handler_state_read_response(ec_voe_handler_t *); |
66 void ec_voe_handler_state_read_response(ec_voe_handler_t *); |
67 |
67 |
|
68 void ec_voe_handler_state_read_nosync_start(ec_voe_handler_t *); |
|
69 void ec_voe_handler_state_read_nosync_response(ec_voe_handler_t *); |
|
70 |
68 void ec_voe_handler_state_end(ec_voe_handler_t *); |
71 void ec_voe_handler_state_end(ec_voe_handler_t *); |
69 void ec_voe_handler_state_error(ec_voe_handler_t *); |
72 void ec_voe_handler_state_error(ec_voe_handler_t *); |
70 |
73 |
71 /*****************************************************************************/ |
74 /*****************************************************************************/ |
72 |
75 |
161 |
164 |
162 void ecrt_voe_handler_read(ec_voe_handler_t *voe) |
165 void ecrt_voe_handler_read(ec_voe_handler_t *voe) |
163 { |
166 { |
164 voe->dir = EC_DIR_INPUT; |
167 voe->dir = EC_DIR_INPUT; |
165 voe->state = ec_voe_handler_state_read_start; |
168 voe->state = ec_voe_handler_state_read_start; |
|
169 voe->request_state = EC_INT_REQUEST_QUEUED; |
|
170 } |
|
171 |
|
172 /*****************************************************************************/ |
|
173 |
|
174 void ecrt_voe_handler_read_nosync(ec_voe_handler_t *voe) |
|
175 { |
|
176 voe->dir = EC_DIR_INPUT; |
|
177 voe->state = ec_voe_handler_state_read_nosync_start; |
166 voe->request_state = EC_INT_REQUEST_QUEUED; |
178 voe->request_state = EC_INT_REQUEST_QUEUED; |
167 } |
179 } |
168 |
180 |
169 /*****************************************************************************/ |
181 /*****************************************************************************/ |
170 |
182 |
425 voe->state = ec_voe_handler_state_end; // success |
437 voe->state = ec_voe_handler_state_end; // success |
426 } |
438 } |
427 |
439 |
428 /*****************************************************************************/ |
440 /*****************************************************************************/ |
429 |
441 |
|
442 /** Start reading VoE data without sending a sync message before. |
|
443 */ |
|
444 void ec_voe_handler_state_read_nosync_start(ec_voe_handler_t *voe) |
|
445 { |
|
446 ec_datagram_t *datagram = &voe->datagram; |
|
447 ec_slave_t *slave = voe->config->slave; |
|
448 |
|
449 if (slave->master->debug_level) |
|
450 EC_DBG("Reading VoE data to slave %u.\n", slave->ring_position); |
|
451 |
|
452 if (!(slave->sii.mailbox_protocols & EC_MBOX_VOE)) { |
|
453 EC_ERR("Slave %u does not support VoE!\n", slave->ring_position); |
|
454 voe->state = ec_voe_handler_state_error; |
|
455 voe->request_state = EC_INT_REQUEST_FAILURE; |
|
456 return; |
|
457 } |
|
458 |
|
459 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail. |
|
460 |
|
461 voe->jiffies_start = jiffies; |
|
462 voe->retries = EC_FSM_RETRIES; |
|
463 voe->state = ec_voe_handler_state_read_nosync_response; |
|
464 } |
|
465 |
|
466 /*****************************************************************************/ |
|
467 |
|
468 /** Read the pending mailbox data without sending a sync message before. This |
|
469 * might lead to an empty reponse from the client. |
|
470 */ |
|
471 void ec_voe_handler_state_read_nosync_response(ec_voe_handler_t *voe) |
|
472 { |
|
473 ec_datagram_t *datagram = &voe->datagram; |
|
474 ec_slave_t *slave = voe->config->slave; |
|
475 ec_master_t *master = voe->config->master; |
|
476 uint8_t *data, mbox_prot; |
|
477 size_t rec_size; |
|
478 |
|
479 if (datagram->state == EC_DATAGRAM_TIMED_OUT && voe->retries--) |
|
480 return; |
|
481 |
|
482 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
|
483 voe->state = ec_voe_handler_state_error; |
|
484 voe->request_state = EC_INT_REQUEST_FAILURE; |
|
485 EC_ERR("Failed to receive VoE read datagram for" |
|
486 " slave %u (datagram state %u).\n", |
|
487 slave->ring_position, datagram->state); |
|
488 return; |
|
489 } |
|
490 |
|
491 if (datagram->working_counter == 0) { |
|
492 voe->state = ec_voe_handler_state_error; |
|
493 voe->request_state = EC_INT_REQUEST_FAILURE; |
|
494 EC_DBG("Slave (%u) did not send data with Mailbox.", |
|
495 slave->ring_position); |
|
496 return; |
|
497 } |
|
498 |
|
499 if (datagram->working_counter != 1) { |
|
500 voe->state = ec_voe_handler_state_error; |
|
501 voe->request_state = EC_INT_REQUEST_FAILURE; |
|
502 EC_WARN("Reception of VoE read response failed on slave %u: ", |
|
503 slave->ring_position); |
|
504 ec_datagram_print_wc_error(datagram); |
|
505 return; |
|
506 } |
|
507 |
|
508 if (!(data = ec_slave_mbox_fetch(slave, datagram, |
|
509 &mbox_prot, &rec_size))) { |
|
510 voe->state = ec_voe_handler_state_error; |
|
511 voe->request_state = EC_INT_REQUEST_FAILURE; |
|
512 return; |
|
513 } |
|
514 |
|
515 if (mbox_prot != EC_MBOX_TYPE_VOE) { |
|
516 voe->state = ec_voe_handler_state_error; |
|
517 voe->request_state = EC_INT_REQUEST_FAILURE; |
|
518 EC_WARN("Received mailbox protocol 0x%02X as response.\n", mbox_prot); |
|
519 ec_print_data(data, rec_size); |
|
520 return; |
|
521 } |
|
522 |
|
523 if (rec_size < EC_VOE_HEADER_SIZE) { |
|
524 voe->state = ec_voe_handler_state_error; |
|
525 voe->request_state = EC_INT_REQUEST_FAILURE; |
|
526 EC_ERR("Received VoE header is incomplete (%u bytes)!\n", rec_size); |
|
527 return; |
|
528 } |
|
529 |
|
530 if (master->debug_level) { |
|
531 EC_DBG("VoE data:\n"); |
|
532 ec_print_data(data, rec_size); |
|
533 } |
|
534 |
|
535 voe->data_size = rec_size - EC_VOE_HEADER_SIZE; |
|
536 voe->request_state = EC_INT_REQUEST_SUCCESS; |
|
537 voe->state = ec_voe_handler_state_end; // success |
|
538 } |
|
539 |
|
540 /*****************************************************************************/ |
|
541 |
430 /** Successful termination state function. |
542 /** Successful termination state function. |
431 */ |
543 */ |
432 void ec_voe_handler_state_end(ec_voe_handler_t *voe) |
544 void ec_voe_handler_state_end(ec_voe_handler_t *voe) |
433 { |
545 { |
434 } |
546 } |