142 {} |
142 {} |
143 }; |
143 }; |
144 |
144 |
145 /*****************************************************************************/ |
145 /*****************************************************************************/ |
146 |
146 |
147 /** |
147 /** Outputs an SDO abort message. |
148 Outputs an SDO abort message. |
148 */ |
149 */ |
149 void ec_canopen_abort_msg(const ec_slave_t *slave, uint32_t abort_code) |
150 |
|
151 void ec_canopen_abort_msg(uint32_t abort_code) |
|
152 { |
150 { |
153 const ec_code_msg_t *abort_msg; |
151 const ec_code_msg_t *abort_msg; |
154 |
152 |
155 for (abort_msg = sdo_abort_messages; abort_msg->code; abort_msg++) { |
153 for (abort_msg = sdo_abort_messages; abort_msg->code; abort_msg++) { |
156 if (abort_msg->code == abort_code) { |
154 if (abort_msg->code == abort_code) { |
157 EC_ERR("SDO abort message 0x%08X: \"%s\".\n", |
155 EC_SLAVE_ERR(slave, "SDO abort message 0x%08X: \"%s\".\n", |
158 abort_msg->code, abort_msg->message); |
156 abort_msg->code, abort_msg->message); |
159 return; |
157 return; |
160 } |
158 } |
161 } |
159 } |
162 |
160 |
163 EC_ERR("Unknown SDO abort code 0x%08X.\n", abort_code); |
161 EC_SLAVE_ERR(slave, "Unknown SDO abort code 0x%08X.\n", abort_code); |
164 } |
162 } |
165 |
163 |
166 /*****************************************************************************/ |
164 /*****************************************************************************/ |
167 |
165 |
168 /** |
166 /** |
263 { |
261 { |
264 if (size < 2 || ((EC_READ_U16(data) >> 12) & 0x0F) != 0x01) |
262 if (size < 2 || ((EC_READ_U16(data) >> 12) & 0x0F) != 0x01) |
265 return 0; |
263 return 0; |
266 |
264 |
267 if (size < 10) { |
265 if (size < 10) { |
268 EC_WARN("Received incomplete CoE Emergency request from slave %u:\n", |
266 EC_SLAVE_WARN(fsm->slave, "Received incomplete CoE Emergency" |
269 fsm->slave->ring_position); |
267 " request:\n"); |
270 ec_print_data(data, size); |
268 ec_print_data(data, size); |
271 return 1; |
269 return 1; |
272 } |
270 } |
273 |
271 |
274 EC_INFO("CoE Emergency Request received from slave %u:\n", |
272 EC_SLAVE_WARN(fsm->slave, "CoE Emergency Request received:\n" |
275 fsm->slave->ring_position); |
273 "Error code 0x%04X, Error register 0x%02X, data:\n", |
276 EC_INFO("Error code 0x%04X, Error register 0x%02X, data:\n", |
|
277 EC_READ_U16(data + 2), EC_READ_U8(data + 4)); |
274 EC_READ_U16(data + 2), EC_READ_U8(data + 4)); |
278 ec_print_data(data + 5, 5); |
275 ec_print_data(data + 5, 5); |
279 return 1; |
276 return 1; |
280 } |
277 } |
281 |
278 |
292 ec_datagram_t *datagram = fsm->datagram; |
289 ec_datagram_t *datagram = fsm->datagram; |
293 ec_slave_t *slave = fsm->slave; |
290 ec_slave_t *slave = fsm->slave; |
294 uint8_t *data; |
291 uint8_t *data; |
295 |
292 |
296 if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) { |
293 if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) { |
297 EC_ERR("Slave %u does not support CoE!\n", slave->ring_position); |
294 EC_SLAVE_ERR(slave, "Slave does not support CoE!\n"); |
298 fsm->state = ec_fsm_coe_error; |
295 fsm->state = ec_fsm_coe_error; |
299 return; |
296 return; |
300 } |
297 } |
301 |
298 |
302 if (slave->sii.has_general && !slave->sii.coe_details.enable_sdo_info) { |
299 if (slave->sii.has_general && !slave->sii.coe_details.enable_sdo_info) { |
303 EC_ERR("Slave %u does not support SDO information service!\n", |
300 EC_SLAVE_ERR(slave, "Slave does not support" |
304 slave->ring_position); |
301 " SDO information service!\n"); |
305 fsm->state = ec_fsm_coe_error; |
302 fsm->state = ec_fsm_coe_error; |
306 return; |
303 return; |
307 } |
304 } |
308 |
305 |
309 data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 8); |
306 data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 8); |
337 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
334 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
338 return; // FIXME: request again? |
335 return; // FIXME: request again? |
339 |
336 |
340 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
337 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
341 fsm->state = ec_fsm_coe_error; |
338 fsm->state = ec_fsm_coe_error; |
342 EC_ERR("Failed to receive CoE dictionary request datagram for" |
339 EC_SLAVE_ERR(slave, "Failed to receive CoE dictionary" |
343 " slave %u: ", slave->ring_position); |
340 " request datagram: "); |
344 ec_datagram_print_state(datagram); |
341 ec_datagram_print_state(datagram); |
345 return; |
342 return; |
346 } |
343 } |
347 |
344 |
348 if (datagram->working_counter != 1) { |
345 if (datagram->working_counter != 1) { |
349 fsm->state = ec_fsm_coe_error; |
346 fsm->state = ec_fsm_coe_error; |
350 EC_ERR("Reception of CoE dictionary request failed on slave %u: ", |
347 EC_SLAVE_ERR(slave, "Reception of CoE dictionary request failed: "); |
351 slave->ring_position); |
|
352 ec_datagram_print_wc_error(datagram); |
348 ec_datagram_print_wc_error(datagram); |
353 return; |
349 return; |
354 } |
350 } |
355 |
351 |
356 fsm->jiffies_start = datagram->jiffies_sent; |
352 fsm->jiffies_start = datagram->jiffies_sent; |
374 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
370 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
375 return; |
371 return; |
376 |
372 |
377 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
373 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
378 fsm->state = ec_fsm_coe_error; |
374 fsm->state = ec_fsm_coe_error; |
379 EC_ERR("Failed to receive CoE mailbox check datagram for slave %u: ", |
375 EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: "); |
380 slave->ring_position); |
|
381 ec_datagram_print_state(datagram); |
376 ec_datagram_print_state(datagram); |
382 return; |
377 return; |
383 } |
378 } |
384 |
379 |
385 if (datagram->working_counter != 1) { |
380 if (datagram->working_counter != 1) { |
386 fsm->state = ec_fsm_coe_error; |
381 fsm->state = ec_fsm_coe_error; |
387 EC_ERR("Reception of CoE mailbox check datagram failed on slave %u: ", |
382 EC_SLAVE_ERR(slave,"Reception of CoE mailbox check" |
388 slave->ring_position); |
383 " datagram failed: "); |
389 ec_datagram_print_wc_error(datagram); |
384 ec_datagram_print_wc_error(datagram); |
390 return; |
385 return; |
391 } |
386 } |
392 |
387 |
393 if (!ec_slave_mbox_check(datagram)) { |
388 if (!ec_slave_mbox_check(datagram)) { |
394 unsigned long diff_ms = |
389 unsigned long diff_ms = |
395 (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; |
390 (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; |
396 if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) { |
391 if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) { |
397 fsm->state = ec_fsm_coe_error; |
392 fsm->state = ec_fsm_coe_error; |
398 EC_ERR("Timeout while waiting for SDO dictionary list response " |
393 EC_SLAVE_ERR(slave, "Timeout while waiting for" |
399 "on slave %u.\n", slave->ring_position); |
394 " SDO dictionary list response.\n"); |
400 return; |
395 return; |
401 } |
396 } |
402 |
397 |
403 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
398 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
404 fsm->retries = EC_FSM_RETRIES; |
399 fsm->retries = EC_FSM_RETRIES; |
431 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
426 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
432 return; // FIXME: request again? |
427 return; // FIXME: request again? |
433 |
428 |
434 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
429 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
435 fsm->state = ec_fsm_coe_error; |
430 fsm->state = ec_fsm_coe_error; |
436 EC_ERR("Failed to receive CoE dictionary response datagram for" |
431 EC_SLAVE_ERR(slave, "Failed to receive CoE dictionary" |
437 " slave %u: ", slave->ring_position); |
432 " response datagram: "); |
438 ec_datagram_print_state(datagram); |
433 ec_datagram_print_state(datagram); |
439 return; |
434 return; |
440 } |
435 } |
441 |
436 |
442 if (datagram->working_counter != 1) { |
437 if (datagram->working_counter != 1) { |
443 fsm->state = ec_fsm_coe_error; |
438 fsm->state = ec_fsm_coe_error; |
444 EC_ERR("Reception of CoE dictionary response failed on slave %u: ", |
439 EC_SLAVE_ERR(slave, "Reception of CoE dictionary response failed: "); |
445 slave->ring_position); |
|
446 ec_datagram_print_wc_error(datagram); |
440 ec_datagram_print_wc_error(datagram); |
447 return; |
441 return; |
448 } |
442 } |
449 |
443 |
450 data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size); |
444 data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size); |
466 fsm->state = ec_fsm_coe_dict_check; |
461 fsm->state = ec_fsm_coe_dict_check; |
467 return; |
462 return; |
468 } |
463 } |
469 |
464 |
470 if (rec_size < 3) { |
465 if (rec_size < 3) { |
471 EC_ERR("Received corrupted SDO dictionary response (size %zu).\n", |
466 EC_SLAVE_ERR(slave, "Received corrupted SDO dictionary response" |
472 rec_size); |
467 " (size %zu).\n", rec_size); |
473 fsm->state = ec_fsm_coe_error; |
468 fsm->state = ec_fsm_coe_error; |
474 return; |
469 return; |
475 } |
470 } |
476 |
471 |
477 if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information |
472 if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information |
478 (EC_READ_U8(data + 2) & 0x7F) == 0x07) { // error response |
473 (EC_READ_U8(data + 2) & 0x7F) == 0x07) { // error response |
479 EC_ERR("SDO information error response at slave %u!\n", |
474 EC_SLAVE_ERR(slave, "SDO information error response!\n"); |
480 slave->ring_position); |
|
481 if (rec_size < 10) { |
475 if (rec_size < 10) { |
482 EC_ERR("Incomplete SDO information error response:\n"); |
476 EC_SLAVE_ERR(slave, "Incomplete SDO information" |
|
477 " error response:\n"); |
483 ec_print_data(data, rec_size); |
478 ec_print_data(data, rec_size); |
484 } else { |
479 } else { |
485 ec_canopen_abort_msg(EC_READ_U32(data + 6)); |
480 ec_canopen_abort_msg(slave, EC_READ_U32(data + 6)); |
486 } |
481 } |
487 fsm->state = ec_fsm_coe_error; |
482 fsm->state = ec_fsm_coe_error; |
488 return; |
483 return; |
489 } |
484 } |
490 |
485 |
491 if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information |
486 if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information |
492 (EC_READ_U8 (data + 2) & 0x7F) != 0x02) { // Get OD List response |
487 (EC_READ_U8 (data + 2) & 0x7F) != 0x02) { // Get OD List response |
493 if (fsm->slave->master->debug_level) { |
488 if (fsm->slave->master->debug_level) { |
494 EC_DBG("Invalid SDO list response at slave %u! Retrying...\n", |
489 EC_SLAVE_DBG(slave, 1, "Invalid SDO list response!" |
495 slave->ring_position); |
490 " Retrying...\n"); |
496 ec_print_data(data, rec_size); |
491 ec_print_data(data, rec_size); |
497 } |
492 } |
498 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
493 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
499 fsm->retries = EC_FSM_RETRIES; |
494 fsm->retries = EC_FSM_RETRIES; |
500 fsm->state = ec_fsm_coe_dict_check; |
495 fsm->state = ec_fsm_coe_dict_check; |
501 return; |
496 return; |
502 } |
497 } |
503 |
498 |
504 if (rec_size < 8 || rec_size % 2) { |
499 if (rec_size < 8 || rec_size % 2) { |
505 EC_ERR("Invalid data size %zu!\n", rec_size); |
500 EC_SLAVE_ERR(slave, "Invalid data size %zu!\n", rec_size); |
506 ec_print_data(data, rec_size); |
501 ec_print_data(data, rec_size); |
507 fsm->state = ec_fsm_coe_error; |
502 fsm->state = ec_fsm_coe_error; |
508 return; |
503 return; |
509 } |
504 } |
510 |
505 |
511 sdo_count = (rec_size - 8) / 2; |
506 sdo_count = (rec_size - 8) / 2; |
512 |
507 |
513 for (i = 0; i < sdo_count; i++) { |
508 for (i = 0; i < sdo_count; i++) { |
514 sdo_index = EC_READ_U16(data + 8 + i * 2); |
509 sdo_index = EC_READ_U16(data + 8 + i * 2); |
515 if (!sdo_index) { |
510 if (!sdo_index) { |
516 if (slave->master->debug_level) |
511 EC_SLAVE_DBG(slave, 1, "SDO dictionary contains index 0x0000.\n"); |
517 EC_WARN("SDO dictionary of slave %u contains index 0x0000.\n", |
|
518 slave->ring_position); |
|
519 continue; |
512 continue; |
520 } |
513 } |
521 |
514 |
522 if (!(sdo = (ec_sdo_t *) kmalloc(sizeof(ec_sdo_t), GFP_KERNEL))) { |
515 if (!(sdo = (ec_sdo_t *) kmalloc(sizeof(ec_sdo_t), GFP_KERNEL))) { |
523 EC_ERR("Failed to allocate memory for SDO!\n"); |
516 EC_SLAVE_ERR(slave, "Failed to allocate memory for SDO!\n"); |
524 fsm->state = ec_fsm_coe_error; |
517 fsm->state = ec_fsm_coe_error; |
525 return; |
518 return; |
526 } |
519 } |
527 |
520 |
528 ec_sdo_init(sdo, slave, sdo_index); |
521 ec_sdo_init(sdo, slave, sdo_index); |
529 list_add_tail(&sdo->list, &slave->sdo_dictionary); |
522 list_add_tail(&sdo->list, &slave->sdo_dictionary); |
530 } |
523 } |
531 |
524 |
532 fragments_left = EC_READ_U16(data + 4); |
525 fragments_left = EC_READ_U16(data + 4); |
533 if (slave->master->debug_level && fragments_left) { |
526 if (fragments_left) { |
534 EC_DBG("SDO list fragments left: %u\n", fragments_left); |
527 EC_SLAVE_DBG(slave, 1, "SDO list fragments left: %u\n", |
535 } |
528 fragments_left); |
536 |
529 } |
537 if (EC_READ_U8(data + 2) & 0x80 || fragments_left) { // more messages waiting. check again. |
530 |
|
531 if (EC_READ_U8(data + 2) & 0x80 || fragments_left) { |
|
532 // more messages waiting. check again. |
538 fsm->jiffies_start = datagram->jiffies_sent; |
533 fsm->jiffies_start = datagram->jiffies_sent; |
539 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
534 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
540 fsm->retries = EC_FSM_RETRIES; |
535 fsm->retries = EC_FSM_RETRIES; |
541 fsm->state = ec_fsm_coe_dict_check; |
536 fsm->state = ec_fsm_coe_dict_check; |
542 return; |
537 return; |
582 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
577 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
583 return; // FIXME: check for response first? |
578 return; // FIXME: check for response first? |
584 |
579 |
585 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
580 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
586 fsm->state = ec_fsm_coe_error; |
581 fsm->state = ec_fsm_coe_error; |
587 EC_ERR("Failed to receive CoE SDO description request datagram for" |
582 EC_SLAVE_ERR(slave, "Failed to receive CoE SDO" |
588 " slave %u: ", slave->ring_position); |
583 " description request datagram: "); |
589 ec_datagram_print_state(datagram); |
584 ec_datagram_print_state(datagram); |
590 return; |
585 return; |
591 } |
586 } |
592 |
587 |
593 if (datagram->working_counter != 1) { |
588 if (datagram->working_counter != 1) { |
594 fsm->state = ec_fsm_coe_error; |
589 fsm->state = ec_fsm_coe_error; |
595 EC_ERR("Reception of CoE SDO description" |
590 EC_SLAVE_ERR(slave, "Reception of CoE SDO description" |
596 " request failed on slave %u: ", slave->ring_position); |
591 " request failed: "); |
597 ec_datagram_print_wc_error(datagram); |
592 ec_datagram_print_wc_error(datagram); |
598 return; |
593 return; |
599 } |
594 } |
600 |
595 |
601 fsm->jiffies_start = datagram->jiffies_sent; |
596 fsm->jiffies_start = datagram->jiffies_sent; |
619 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
614 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
620 return; |
615 return; |
621 |
616 |
622 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
617 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
623 fsm->state = ec_fsm_coe_error; |
618 fsm->state = ec_fsm_coe_error; |
624 EC_ERR("Failed to receive CoE mailbox check datagram from slave %u: ", |
619 EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: "); |
625 slave->ring_position); |
|
626 ec_datagram_print_state(datagram); |
620 ec_datagram_print_state(datagram); |
627 return; |
621 return; |
628 } |
622 } |
629 |
623 |
630 if (datagram->working_counter != 1) { |
624 if (datagram->working_counter != 1) { |
631 fsm->state = ec_fsm_coe_error; |
625 fsm->state = ec_fsm_coe_error; |
632 EC_ERR("Reception of CoE mailbox check" |
626 EC_SLAVE_ERR(slave, "Reception of CoE mailbox check" |
633 " datagram failed on slave %u: ", slave->ring_position); |
627 " datagram failed: "); |
634 ec_datagram_print_wc_error(datagram); |
628 ec_datagram_print_wc_error(datagram); |
635 return; |
629 return; |
636 } |
630 } |
637 |
631 |
638 if (!ec_slave_mbox_check(datagram)) { |
632 if (!ec_slave_mbox_check(datagram)) { |
639 unsigned long diff_ms = |
633 unsigned long diff_ms = |
640 (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; |
634 (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; |
641 if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) { |
635 if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) { |
642 fsm->state = ec_fsm_coe_error; |
636 fsm->state = ec_fsm_coe_error; |
643 EC_ERR("Timeout while waiting for SDO 0x%04x object description " |
637 EC_SLAVE_ERR(slave, "Timeout while waiting for" |
644 "response on slave %u.\n", fsm->sdo->index, |
638 " SDO 0x%04x object description response.\n", |
645 slave->ring_position); |
639 fsm->sdo->index); |
646 return; |
640 return; |
647 } |
641 } |
648 |
642 |
649 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
643 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
650 fsm->retries = EC_FSM_RETRIES; |
644 fsm->retries = EC_FSM_RETRIES; |
676 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
670 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
677 return; // FIXME: request again? |
671 return; // FIXME: request again? |
678 |
672 |
679 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
673 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
680 fsm->state = ec_fsm_coe_error; |
674 fsm->state = ec_fsm_coe_error; |
681 EC_ERR("Failed to receive CoE SDO description response datagram from" |
675 EC_SLAVE_ERR(slave, "Failed to receive CoE SDO description" |
682 " slave %u: ", slave->ring_position); |
676 " response datagram: "); |
683 ec_datagram_print_state(datagram); |
677 ec_datagram_print_state(datagram); |
684 return; |
678 return; |
685 } |
679 } |
686 |
680 |
687 if (datagram->working_counter != 1) { |
681 if (datagram->working_counter != 1) { |
688 fsm->state = ec_fsm_coe_error; |
682 fsm->state = ec_fsm_coe_error; |
689 EC_ERR("Reception of CoE SDO description" |
683 EC_SLAVE_ERR(slave, "Reception of CoE SDO description" |
690 " response failed on slave %u: ", slave->ring_position); |
684 " response failed: "); |
691 ec_datagram_print_wc_error(datagram); |
685 ec_datagram_print_wc_error(datagram); |
692 return; |
686 return; |
693 } |
687 } |
694 |
688 |
695 data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size); |
689 data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size); |
711 fsm->state = ec_fsm_coe_dict_desc_check; |
706 fsm->state = ec_fsm_coe_dict_desc_check; |
712 return; |
707 return; |
713 } |
708 } |
714 |
709 |
715 if (rec_size < 3) { |
710 if (rec_size < 3) { |
716 EC_ERR("Received corrupted SDO description response (size %zu).\n", |
711 EC_SLAVE_ERR(slave, "Received corrupted SDO description response" |
717 rec_size); |
712 " (size %zu).\n", rec_size); |
718 fsm->state = ec_fsm_coe_error; |
713 fsm->state = ec_fsm_coe_error; |
719 return; |
714 return; |
720 } |
715 } |
721 |
716 |
722 if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information |
717 if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information |
723 (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response |
718 (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response |
724 EC_ERR("SDO information error response at slave %u while" |
719 EC_SLAVE_ERR(slave, "SDO information error response while" |
725 " fetching SDO 0x%04X!\n", slave->ring_position, |
720 " fetching SDO 0x%04X!\n", sdo->index); |
726 sdo->index); |
721 ec_canopen_abort_msg(slave, EC_READ_U32(data + 6)); |
727 ec_canopen_abort_msg(EC_READ_U32(data + 6)); |
|
728 fsm->state = ec_fsm_coe_error; |
722 fsm->state = ec_fsm_coe_error; |
729 return; |
723 return; |
730 } |
724 } |
731 |
725 |
732 if (rec_size < 8) { |
726 if (rec_size < 8) { |
733 EC_ERR("Received corrupted SDO description response (size %zu).\n", |
727 EC_SLAVE_ERR(slave, "Received corrupted SDO" |
734 rec_size); |
728 " description response (size %zu).\n", rec_size); |
735 fsm->state = ec_fsm_coe_error; |
729 fsm->state = ec_fsm_coe_error; |
736 return; |
730 return; |
737 } |
731 } |
738 |
732 |
739 if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information |
733 if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information |
740 (EC_READ_U8 (data + 2) & 0x7F) != 0x04 || // Object desc. response |
734 (EC_READ_U8 (data + 2) & 0x7F) != 0x04 || // Object desc. response |
741 EC_READ_U16(data + 6) != sdo->index) { // SDO index |
735 EC_READ_U16(data + 6) != sdo->index) { // SDO index |
742 if (fsm->slave->master->debug_level) { |
736 if (fsm->slave->master->debug_level) { |
743 EC_DBG("Invalid object description response at slave %u while" |
737 EC_SLAVE_DBG(slave, 1, "Invalid object description response while" |
744 " fetching SDO 0x%04X!\n", slave->ring_position, |
738 " fetching SDO 0x%04X!\n", sdo->index); |
745 sdo->index); |
|
746 ec_print_data(data, rec_size); |
739 ec_print_data(data, rec_size); |
747 } |
740 } |
748 // check for CoE response again |
741 // check for CoE response again |
749 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
742 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
750 fsm->retries = EC_FSM_RETRIES; |
743 fsm->retries = EC_FSM_RETRIES; |
751 fsm->state = ec_fsm_coe_dict_desc_check; |
744 fsm->state = ec_fsm_coe_dict_desc_check; |
752 return; |
745 return; |
753 } |
746 } |
754 |
747 |
755 if (rec_size < 12) { |
748 if (rec_size < 12) { |
756 EC_ERR("Invalid data size!\n"); |
749 EC_SLAVE_ERR(slave, "Invalid data size!\n"); |
757 ec_print_data(data, rec_size); |
750 ec_print_data(data, rec_size); |
758 fsm->state = ec_fsm_coe_error; |
751 fsm->state = ec_fsm_coe_error; |
759 return; |
752 return; |
760 } |
753 } |
761 |
754 |
763 sdo->object_code = EC_READ_U8(data + 11); |
756 sdo->object_code = EC_READ_U8(data + 11); |
764 |
757 |
765 name_size = rec_size - 12; |
758 name_size = rec_size - 12; |
766 if (name_size) { |
759 if (name_size) { |
767 if (!(sdo->name = kmalloc(name_size + 1, GFP_KERNEL))) { |
760 if (!(sdo->name = kmalloc(name_size + 1, GFP_KERNEL))) { |
768 EC_ERR("Failed to allocate SDO name!\n"); |
761 EC_SLAVE_ERR(slave, "Failed to allocate SDO name!\n"); |
769 fsm->state = ec_fsm_coe_error; |
762 fsm->state = ec_fsm_coe_error; |
770 return; |
763 return; |
771 } |
764 } |
772 |
765 |
773 memcpy(sdo->name, data + 12, name_size); |
766 memcpy(sdo->name, data + 12, name_size); |
774 sdo->name[name_size] = 0; |
767 sdo->name[name_size] = 0; |
775 } |
768 } |
776 |
769 |
777 if (EC_READ_U8(data + 2) & 0x80) { |
770 if (EC_READ_U8(data + 2) & 0x80) { |
778 EC_ERR("Fragment follows (not implemented)!\n"); |
771 EC_SLAVE_ERR(slave, "Fragment follows (not implemented)!\n"); |
779 fsm->state = ec_fsm_coe_error; |
772 fsm->state = ec_fsm_coe_error; |
780 return; |
773 return; |
781 } |
774 } |
782 |
775 |
783 // start fetching entries |
776 // start fetching entries |
818 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
811 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
819 return; // FIXME: check for response first? |
812 return; // FIXME: check for response first? |
820 |
813 |
821 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
814 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
822 fsm->state = ec_fsm_coe_error; |
815 fsm->state = ec_fsm_coe_error; |
823 EC_ERR("Failed to receive CoE SDO entry request datagram for" |
816 EC_SLAVE_ERR(slave, "Failed to receive CoE SDO entry" |
824 " slave %u: ", slave->ring_position); |
817 " request datagram: "); |
825 ec_datagram_print_state(datagram); |
818 ec_datagram_print_state(datagram); |
826 return; |
819 return; |
827 } |
820 } |
828 |
821 |
829 if (datagram->working_counter != 1) { |
822 if (datagram->working_counter != 1) { |
830 fsm->state = ec_fsm_coe_error; |
823 fsm->state = ec_fsm_coe_error; |
831 EC_ERR("Reception of CoE SDO entry request failed on slave %u: ", |
824 EC_SLAVE_ERR(slave, "Reception of CoE SDO entry request failed: "); |
832 slave->ring_position); |
|
833 ec_datagram_print_wc_error(datagram); |
825 ec_datagram_print_wc_error(datagram); |
834 return; |
826 return; |
835 } |
827 } |
836 |
828 |
837 fsm->jiffies_start = datagram->jiffies_sent; |
829 fsm->jiffies_start = datagram->jiffies_sent; |
856 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
848 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
857 return; |
849 return; |
858 |
850 |
859 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
851 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
860 fsm->state = ec_fsm_coe_error; |
852 fsm->state = ec_fsm_coe_error; |
861 EC_ERR("Failed to receive CoE mailbox check datagram from slave %u" |
853 EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: "); |
862 ": ", slave->ring_position); |
|
863 ec_datagram_print_state(datagram); |
854 ec_datagram_print_state(datagram); |
864 return; |
855 return; |
865 } |
856 } |
866 |
857 |
867 if (datagram->working_counter != 1) { |
858 if (datagram->working_counter != 1) { |
868 fsm->state = ec_fsm_coe_error; |
859 fsm->state = ec_fsm_coe_error; |
869 EC_ERR("Reception of CoE mailbox check" |
860 EC_SLAVE_ERR(slave, "Reception of CoE mailbox check" |
870 " datagram failed on slave %u: ", slave->ring_position); |
861 " datagram failed: "); |
871 ec_datagram_print_wc_error(datagram); |
862 ec_datagram_print_wc_error(datagram); |
872 return; |
863 return; |
873 } |
864 } |
874 |
865 |
875 if (!ec_slave_mbox_check(datagram)) { |
866 if (!ec_slave_mbox_check(datagram)) { |
876 unsigned long diff_ms = |
867 unsigned long diff_ms = |
877 (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; |
868 (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; |
878 if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) { |
869 if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) { |
879 fsm->state = ec_fsm_coe_error; |
870 fsm->state = ec_fsm_coe_error; |
880 EC_ERR("Timeout while waiting for SDO entry 0x%04x:%x" |
871 EC_SLAVE_ERR(slave, "Timeout while waiting for" |
881 " description response on slave %u.\n", |
872 " SDO entry 0x%04x:%x description response.\n", |
882 fsm->sdo->index, fsm->subindex, slave->ring_position); |
873 fsm->sdo->index, fsm->subindex); |
883 return; |
874 return; |
884 } |
875 } |
885 |
876 |
886 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
877 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
887 fsm->retries = EC_FSM_RETRIES; |
878 fsm->retries = EC_FSM_RETRIES; |
915 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
906 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
916 return; // FIXME: request again? |
907 return; // FIXME: request again? |
917 |
908 |
918 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
909 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
919 fsm->state = ec_fsm_coe_error; |
910 fsm->state = ec_fsm_coe_error; |
920 EC_ERR("Failed to receive CoE SDO description response datagram from" |
911 EC_SLAVE_ERR(slave, "Failed to receive CoE SDO" |
921 " slave %u: ", slave->ring_position); |
912 " description response datagram: "); |
922 ec_datagram_print_state(datagram); |
913 ec_datagram_print_state(datagram); |
923 return; |
914 return; |
924 } |
915 } |
925 |
916 |
926 if (datagram->working_counter != 1) { |
917 if (datagram->working_counter != 1) { |
927 fsm->state = ec_fsm_coe_error; |
918 fsm->state = ec_fsm_coe_error; |
928 EC_ERR("Reception of CoE SDO description" |
919 EC_SLAVE_ERR(slave, "Reception of CoE SDO description" |
929 " response failed on slave %u: ", slave->ring_position); |
920 " response failed: "); |
930 ec_datagram_print_wc_error(datagram); |
921 ec_datagram_print_wc_error(datagram); |
931 return; |
922 return; |
932 } |
923 } |
933 |
924 |
934 data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size); |
925 data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size); |
950 fsm->state = ec_fsm_coe_dict_entry_check; |
942 fsm->state = ec_fsm_coe_dict_entry_check; |
951 return; |
943 return; |
952 } |
944 } |
953 |
945 |
954 if (rec_size < 3) { |
946 if (rec_size < 3) { |
955 EC_ERR("Received corrupted SDO entry description response " |
947 EC_SLAVE_ERR(slave, "Received corrupted SDO entry" |
956 "(size %zu).\n", rec_size); |
948 " description response (size %zu).\n", rec_size); |
957 fsm->state = ec_fsm_coe_error; |
949 fsm->state = ec_fsm_coe_error; |
958 return; |
950 return; |
959 } |
951 } |
960 |
952 |
961 if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information |
953 if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information |
962 (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response |
954 (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response |
963 EC_ERR("SDO information error response at slave %u while" |
955 EC_SLAVE_ERR(slave, "SDO information error response while" |
964 " fetching SDO entry 0x%04X:%02X!\n", slave->ring_position, |
956 " fetching SDO entry 0x%04X:%02X!\n", |
965 sdo->index, fsm->subindex); |
957 sdo->index, fsm->subindex); |
966 ec_canopen_abort_msg(EC_READ_U32(data + 6)); |
958 ec_canopen_abort_msg(slave, EC_READ_U32(data + 6)); |
967 fsm->state = ec_fsm_coe_error; |
959 fsm->state = ec_fsm_coe_error; |
968 return; |
960 return; |
969 } |
961 } |
970 |
962 |
971 if (rec_size < 9) { |
963 if (rec_size < 9) { |
972 EC_ERR("Received corrupted SDO entry description response " |
964 EC_SLAVE_ERR(slave, "Received corrupted SDO entry" |
973 "(size %zu).\n", rec_size); |
965 " description response (size %zu).\n", rec_size); |
974 fsm->state = ec_fsm_coe_error; |
966 fsm->state = ec_fsm_coe_error; |
975 return; |
967 return; |
976 } |
968 } |
977 |
969 |
978 if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information |
970 if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information |
979 (EC_READ_U8(data + 2) & 0x7F) != 0x06 || // Entry desc. response |
971 (EC_READ_U8(data + 2) & 0x7F) != 0x06 || // Entry desc. response |
980 EC_READ_U16(data + 6) != sdo->index || // SDO index |
972 EC_READ_U16(data + 6) != sdo->index || // SDO index |
981 EC_READ_U8(data + 8) != fsm->subindex) { // SDO subindex |
973 EC_READ_U8(data + 8) != fsm->subindex) { // SDO subindex |
982 if (fsm->slave->master->debug_level) { |
974 if (fsm->slave->master->debug_level) { |
983 EC_DBG("Invalid entry description response at slave %u while" |
975 EC_SLAVE_DBG(slave, 1, "Invalid entry description response while" |
984 " fetching SDO entry 0x%04X:%02X!\n", slave->ring_position, |
976 " fetching SDO entry 0x%04X:%02X!\n", |
985 sdo->index, fsm->subindex); |
977 sdo->index, fsm->subindex); |
986 ec_print_data(data, rec_size); |
978 ec_print_data(data, rec_size); |
987 } |
979 } |
988 // check for CoE response again |
980 // check for CoE response again |
989 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
981 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
991 fsm->state = ec_fsm_coe_dict_entry_check; |
983 fsm->state = ec_fsm_coe_dict_entry_check; |
992 return; |
984 return; |
993 } |
985 } |
994 |
986 |
995 if (rec_size < 16) { |
987 if (rec_size < 16) { |
996 EC_ERR("Invalid data size %zu!\n", rec_size); |
988 EC_SLAVE_ERR(slave, "Invalid data size %zu!\n", rec_size); |
997 ec_print_data(data, rec_size); |
989 ec_print_data(data, rec_size); |
998 fsm->state = ec_fsm_coe_error; |
990 fsm->state = ec_fsm_coe_error; |
999 return; |
991 return; |
1000 } |
992 } |
1001 |
993 |
1002 data_size = rec_size - 16; |
994 data_size = rec_size - 16; |
1003 |
995 |
1004 if (!(entry = (ec_sdo_entry_t *) |
996 if (!(entry = (ec_sdo_entry_t *) |
1005 kmalloc(sizeof(ec_sdo_entry_t), GFP_KERNEL))) { |
997 kmalloc(sizeof(ec_sdo_entry_t), GFP_KERNEL))) { |
1006 EC_ERR("Failed to allocate entry!\n"); |
998 EC_SLAVE_ERR(slave, "Failed to allocate entry!\n"); |
1007 fsm->state = ec_fsm_coe_error; |
999 fsm->state = ec_fsm_coe_error; |
1008 return; |
1000 return; |
1009 } |
1001 } |
1010 |
1002 |
1011 ec_sdo_entry_init(entry, sdo, fsm->subindex); |
1003 ec_sdo_entry_init(entry, sdo, fsm->subindex); |
1102 if (request->complete_access) { |
1094 if (request->complete_access) { |
1103 subidxstr[0] = 0x00; |
1095 subidxstr[0] = 0x00; |
1104 } else { |
1096 } else { |
1105 sprintf(subidxstr, ":%02X", request->subindex); |
1097 sprintf(subidxstr, ":%02X", request->subindex); |
1106 } |
1098 } |
1107 EC_DBG("Downloading SDO 0x%04X%s to slave %u.\n", |
1099 EC_SLAVE_DBG(slave, 1, "Downloading SDO 0x%04X%s.\n", |
1108 request->index, subidxstr, slave->ring_position); |
1100 request->index, subidxstr); |
1109 ec_print_data(request->data, request->data_size); |
1101 ec_print_data(request->data, request->data_size); |
1110 } |
1102 } |
1111 |
1103 |
1112 if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) { |
1104 if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) { |
1113 EC_ERR("Slave %u does not support CoE!\n", slave->ring_position); |
1105 EC_SLAVE_ERR(slave, "Slave does not support CoE!\n"); |
1114 fsm->state = ec_fsm_coe_error; |
1106 fsm->state = ec_fsm_coe_error; |
1115 return; |
1107 return; |
1116 } |
1108 } |
1117 |
1109 |
1118 if (slave->configured_rx_mailbox_size < |
1110 if (slave->configured_rx_mailbox_size < |
1119 EC_MBOX_HEADER_SIZE + EC_COE_DOWN_REQ_HEADER_SIZE) { |
1111 EC_MBOX_HEADER_SIZE + EC_COE_DOWN_REQ_HEADER_SIZE) { |
1120 EC_ERR("Mailbox too small!\n"); |
1112 EC_SLAVE_ERR(slave, "Mailbox too small!\n"); |
1121 fsm->state = ec_fsm_coe_error; |
1113 fsm->state = ec_fsm_coe_error; |
1122 return; |
1114 return; |
1123 } |
1115 } |
1124 |
1116 |
1125 if (request->data_size <= 4) { // use expedited transfer type |
1117 if (request->data_size <= 4) { // use expedited transfer type |
1219 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
1211 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
1220 return; // FIXME: check for response first? |
1212 return; // FIXME: check for response first? |
1221 |
1213 |
1222 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
1214 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
1223 fsm->state = ec_fsm_coe_error; |
1215 fsm->state = ec_fsm_coe_error; |
1224 EC_ERR("Failed to receive CoE download request datagram for" |
1216 EC_SLAVE_ERR(slave, "Failed to receive CoE download" |
1225 " slave %u: ", slave->ring_position); |
1217 " request datagram: "); |
1226 ec_datagram_print_state(datagram); |
1218 ec_datagram_print_state(datagram); |
1227 return; |
1219 return; |
1228 } |
1220 } |
1229 |
1221 |
1230 diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ; |
1222 diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ; |
1231 |
1223 |
1232 if (datagram->working_counter != 1) { |
1224 if (datagram->working_counter != 1) { |
1233 if (!datagram->working_counter) { |
1225 if (!datagram->working_counter) { |
1234 if (diff_ms < fsm->request->response_timeout) { |
1226 if (diff_ms < fsm->request->response_timeout) { |
1235 #if DEBUG_RETRIES |
1227 #if DEBUG_RETRIES |
1236 if (fsm->slave->master->debug_level) { |
1228 EC_SLAVE_DBG(slave, 1, "Slave did not respond to" |
1237 EC_DBG("Slave %u did not respond to SDO download request. " |
1229 " SDO download request. Retrying after %u ms...\n", |
1238 "Retrying after %u ms...\n", |
1230 (u32) diff_ms); |
1239 slave->ring_position, (u32) diff_ms); |
|
1240 } |
|
1241 #endif |
1231 #endif |
1242 // no response; send request datagram again |
1232 // no response; send request datagram again |
1243 return; |
1233 return; |
1244 } |
1234 } |
1245 } |
1235 } |
1246 fsm->state = ec_fsm_coe_error; |
1236 fsm->state = ec_fsm_coe_error; |
1247 EC_ERR("Reception of CoE download request for SDO 0x%04x:%x failed" |
1237 EC_SLAVE_ERR(slave, "Reception of CoE download request" |
1248 " with timeout after %u ms on slave %u: ", |
1238 " for SDO 0x%04x:%x failed with timeout after %u ms: ", |
1249 fsm->request->index, fsm->request->subindex, (u32) diff_ms, |
1239 fsm->request->index, fsm->request->subindex, (u32) diff_ms); |
1250 fsm->slave->ring_position); |
|
1251 ec_datagram_print_wc_error(datagram); |
1240 ec_datagram_print_wc_error(datagram); |
1252 return; |
1241 return; |
1253 } |
1242 } |
1254 |
1243 |
1255 #if DEBUG_LONG |
1244 #if DEBUG_LONG |
1256 if (diff_ms > 200) { |
1245 if (diff_ms > 200) { |
1257 EC_WARN("SDO 0x%04x:%x download took %u ms on slave %u.\n", |
1246 EC_SLAVE_WARN(slave, "SDO 0x%04x:%x download took %u ms.\n", |
1258 fsm->request->index, fsm->request->subindex, (u32) diff_ms, |
1247 fsm->request->index, fsm->request->subindex, (u32) diff_ms); |
1259 fsm->slave->ring_position); |
|
1260 } |
1248 } |
1261 #endif |
1249 #endif |
1262 |
1250 |
1263 fsm->jiffies_start = datagram->jiffies_sent; |
1251 fsm->jiffies_start = datagram->jiffies_sent; |
1264 |
1252 |
1279 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
1267 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
1280 return; |
1268 return; |
1281 |
1269 |
1282 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
1270 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
1283 fsm->state = ec_fsm_coe_error; |
1271 fsm->state = ec_fsm_coe_error; |
1284 EC_ERR("Failed to receive CoE mailbox check datagram for slave %u: ", |
1272 EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check" |
1285 slave->ring_position); |
1273 " datagram: "); |
1286 ec_datagram_print_state(datagram); |
1274 ec_datagram_print_state(datagram); |
1287 return; |
1275 return; |
1288 } |
1276 } |
1289 |
1277 |
1290 if (datagram->working_counter != 1) { |
1278 if (datagram->working_counter != 1) { |
1291 fsm->state = ec_fsm_coe_error; |
1279 fsm->state = ec_fsm_coe_error; |
1292 EC_ERR("Reception of CoE mailbox check" |
1280 EC_SLAVE_ERR(slave, "Reception of CoE mailbox check" |
1293 " datagram failed on slave %u: ", slave->ring_position); |
1281 " datagram failed: "); |
1294 ec_datagram_print_wc_error(datagram); |
1282 ec_datagram_print_wc_error(datagram); |
1295 return; |
1283 return; |
1296 } |
1284 } |
1297 |
1285 |
1298 if (!ec_slave_mbox_check(datagram)) { |
1286 if (!ec_slave_mbox_check(datagram)) { |
1299 unsigned long diff_ms = |
1287 unsigned long diff_ms = |
1300 (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; |
1288 (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; |
1301 if (diff_ms >= fsm->request->response_timeout) { |
1289 if (diff_ms >= fsm->request->response_timeout) { |
1302 fsm->state = ec_fsm_coe_error; |
1290 fsm->state = ec_fsm_coe_error; |
1303 EC_ERR("Timeout after %u ms while waiting for SDO 0x%04x:%x" |
1291 EC_SLAVE_ERR(slave, "Timeout after %u ms while waiting" |
1304 " download response on slave %u.\n", (u32) diff_ms, |
1292 " for SDO 0x%04x:%x download response.\n", (u32) diff_ms, |
1305 fsm->request->index, fsm->request->subindex, |
1293 fsm->request->index, fsm->request->subindex); |
1306 slave->ring_position); |
|
1307 return; |
1294 return; |
1308 } |
1295 } |
1309 |
1296 |
1310 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
1297 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
1311 fsm->retries = EC_FSM_RETRIES; |
1298 fsm->retries = EC_FSM_RETRIES; |
1401 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
1388 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
1402 return; // FIXME: request again? |
1389 return; // FIXME: request again? |
1403 |
1390 |
1404 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
1391 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
1405 fsm->state = ec_fsm_coe_error; |
1392 fsm->state = ec_fsm_coe_error; |
1406 EC_ERR("Failed to receive CoE download response datagram from" |
1393 EC_SLAVE_ERR(slave, "Failed to receive CoE download" |
1407 " slave %u: ", slave->ring_position); |
1394 " response datagram: "); |
1408 ec_datagram_print_state(datagram); |
1395 ec_datagram_print_state(datagram); |
1409 return; |
1396 return; |
1410 } |
1397 } |
1411 |
1398 |
1412 if (datagram->working_counter != 1) { |
1399 if (datagram->working_counter != 1) { |
1413 fsm->state = ec_fsm_coe_error; |
1400 fsm->state = ec_fsm_coe_error; |
1414 EC_ERR("Reception of CoE download response failed on slave %u: ", |
1401 EC_SLAVE_ERR(slave, "Reception of CoE download response failed: "); |
1415 slave->ring_position); |
|
1416 ec_datagram_print_wc_error(datagram); |
1402 ec_datagram_print_wc_error(datagram); |
1417 return; |
1403 return; |
1418 } |
1404 } |
1419 |
1405 |
1420 data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size); |
1406 data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size); |
1456 if (request->complete_access) { |
1444 if (request->complete_access) { |
1457 subidxstr[0] = 0x00; |
1445 subidxstr[0] = 0x00; |
1458 } else { |
1446 } else { |
1459 sprintf(subidxstr, ":%02X", request->subindex); |
1447 sprintf(subidxstr, ":%02X", request->subindex); |
1460 } |
1448 } |
1461 EC_ERR("SDO download 0x%04X%s (%zu bytes) aborted on slave %u.\n", |
1449 EC_SLAVE_ERR(slave, "SDO download 0x%04X%s (%zu bytes) aborted.\n", |
1462 request->index, subidxstr, request->data_size, |
1450 request->index, subidxstr, request->data_size); |
1463 slave->ring_position); |
|
1464 if (rec_size < 10) { |
1451 if (rec_size < 10) { |
1465 EC_ERR("Incomplete abort command:\n"); |
1452 EC_SLAVE_ERR(slave, "Incomplete abort command:\n"); |
1466 ec_print_data(data, rec_size); |
1453 ec_print_data(data, rec_size); |
1467 } else { |
1454 } else { |
1468 fsm->request->abort_code = EC_READ_U32(data + 6); |
1455 fsm->request->abort_code = EC_READ_U32(data + 6); |
1469 ec_canopen_abort_msg(fsm->request->abort_code); |
1456 ec_canopen_abort_msg(slave, fsm->request->abort_code); |
1470 } |
1457 } |
1471 return; |
1458 return; |
1472 } |
1459 } |
1473 |
1460 |
1474 if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response |
1461 if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response |
1475 EC_READ_U8 (data + 2) >> 5 != 0x3 || // Download response |
1462 EC_READ_U8 (data + 2) >> 5 != 0x3 || // Download response |
1476 EC_READ_U16(data + 3) != request->index || // index |
1463 EC_READ_U16(data + 3) != request->index || // index |
1477 EC_READ_U8 (data + 5) != request->subindex) { // subindex |
1464 EC_READ_U8 (data + 5) != request->subindex) { // subindex |
1478 if (slave->master->debug_level) { |
1465 if (slave->master->debug_level) { |
1479 EC_DBG("Invalid SDO download response at slave %u! Retrying...\n", |
1466 EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!" |
1480 slave->ring_position); |
1467 " Retrying...\n"); |
1481 ec_print_data(data, rec_size); |
1468 ec_print_data(data, rec_size); |
1482 } |
1469 } |
1483 // check for CoE response again |
1470 // check for CoE response again |
1484 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
1471 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
1485 fsm->retries = EC_FSM_RETRIES; |
1472 fsm->retries = EC_FSM_RETRIES; |
1509 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
1496 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
1510 return; |
1497 return; |
1511 |
1498 |
1512 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
1499 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
1513 fsm->state = ec_fsm_coe_error; |
1500 fsm->state = ec_fsm_coe_error; |
1514 EC_ERR("Failed to receive CoE mailbox check datagram for slave %u: ", |
1501 EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: "); |
1515 slave->ring_position); |
|
1516 ec_datagram_print_state(datagram); |
1502 ec_datagram_print_state(datagram); |
1517 return; |
1503 return; |
1518 } |
1504 } |
1519 |
1505 |
1520 if (datagram->working_counter != 1) { |
1506 if (datagram->working_counter != 1) { |
1521 fsm->state = ec_fsm_coe_error; |
1507 fsm->state = ec_fsm_coe_error; |
1522 EC_ERR("Reception of CoE mailbox segment check" |
1508 EC_SLAVE_ERR(slave, "Reception of CoE mailbox segment check" |
1523 " datagram failed on slave %u: ", slave->ring_position); |
1509 " datagram failed: "); |
1524 ec_datagram_print_wc_error(datagram); |
1510 ec_datagram_print_wc_error(datagram); |
1525 return; |
1511 return; |
1526 } |
1512 } |
1527 |
1513 |
1528 if (!ec_slave_mbox_check(datagram)) { |
1514 if (!ec_slave_mbox_check(datagram)) { |
1529 unsigned long diff_ms = |
1515 unsigned long diff_ms = |
1530 (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; |
1516 (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; |
1531 if (diff_ms >= fsm->request->response_timeout) { |
1517 if (diff_ms >= fsm->request->response_timeout) { |
1532 fsm->state = ec_fsm_coe_error; |
1518 fsm->state = ec_fsm_coe_error; |
1533 EC_ERR("Timeout while waiting for SDO download segment response " |
1519 EC_SLAVE_ERR(slave, "Timeout while waiting for SDO download" |
1534 "on slave %u.\n", slave->ring_position); |
1520 " segment response.\n"); |
1535 return; |
1521 return; |
1536 } |
1522 } |
1537 |
1523 |
1538 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
1524 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
1539 fsm->retries = EC_FSM_RETRIES; |
1525 fsm->retries = EC_FSM_RETRIES; |
1566 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
1552 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
1567 return; // FIXME: request again? |
1553 return; // FIXME: request again? |
1568 |
1554 |
1569 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
1555 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
1570 fsm->state = ec_fsm_coe_error; |
1556 fsm->state = ec_fsm_coe_error; |
1571 EC_ERR("Failed to receive CoE download response datagram from" |
1557 EC_SLAVE_ERR(slave, "Failed to receive CoE download response" |
1572 " slave %u: ", slave->ring_position); |
1558 " datagram: "); |
1573 ec_datagram_print_state(datagram); |
1559 ec_datagram_print_state(datagram); |
1574 return; |
1560 return; |
1575 } |
1561 } |
1576 |
1562 |
1577 if (datagram->working_counter != 1) { |
1563 if (datagram->working_counter != 1) { |
1578 fsm->state = ec_fsm_coe_error; |
1564 fsm->state = ec_fsm_coe_error; |
1579 EC_ERR("Reception of CoE download response failed on slave %u: ", |
1565 EC_SLAVE_ERR(slave, "Reception of CoE download response failed: "); |
1580 slave->ring_position); |
|
1581 ec_datagram_print_wc_error(datagram); |
1566 ec_datagram_print_wc_error(datagram); |
1582 return; |
1567 return; |
1583 } |
1568 } |
1584 |
1569 |
1585 data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size); |
1570 data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size); |
1621 if (request->complete_access) { |
1608 if (request->complete_access) { |
1622 subidxstr[0] = 0x00; |
1609 subidxstr[0] = 0x00; |
1623 } else { |
1610 } else { |
1624 sprintf(subidxstr, ":%02X", request->subindex); |
1611 sprintf(subidxstr, ":%02X", request->subindex); |
1625 } |
1612 } |
1626 EC_ERR("SDO download 0x%04X%s (%zu bytes) aborted on slave %u.\n", |
1613 EC_SLAVE_ERR(slave, "SDO download 0x%04X%s (%zu bytes) aborted.\n", |
1627 request->index, subidxstr, request->data_size, |
1614 request->index, subidxstr, request->data_size); |
1628 slave->ring_position); |
|
1629 if (rec_size < 10) { |
1615 if (rec_size < 10) { |
1630 EC_ERR("Incomplete abort command:\n"); |
1616 EC_SLAVE_ERR(slave, "Incomplete abort command:\n"); |
1631 ec_print_data(data, rec_size); |
1617 ec_print_data(data, rec_size); |
1632 } else { |
1618 } else { |
1633 fsm->request->abort_code = EC_READ_U32(data + 6); |
1619 fsm->request->abort_code = EC_READ_U32(data + 6); |
1634 ec_canopen_abort_msg(fsm->request->abort_code); |
1620 ec_canopen_abort_msg(slave, fsm->request->abort_code); |
1635 } |
1621 } |
1636 return; |
1622 return; |
1637 } |
1623 } |
1638 |
1624 |
1639 if (EC_READ_U16(data) >> 12 != 0x3 || |
1625 if (EC_READ_U16(data) >> 12 != 0x3 || |
1640 ((EC_READ_U8(data + 2) >> 5) != 0x01)) { // segment response |
1626 ((EC_READ_U8(data + 2) >> 5) != 0x01)) { // segment response |
1641 if (slave->master->debug_level) { |
1627 if (slave->master->debug_level) { |
1642 EC_DBG("Invalid SDO download response at slave %u! Retrying...\n", |
1628 EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!" |
1643 slave->ring_position); |
1629 " Retrying...\n"); |
1644 ec_print_data(data, rec_size); |
1630 ec_print_data(data, rec_size); |
1645 } |
1631 } |
1646 // check for CoE response again |
1632 // check for CoE response again |
1647 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
1633 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
1648 fsm->retries = EC_FSM_RETRIES; |
1634 fsm->retries = EC_FSM_RETRIES; |
1649 fsm->state = ec_fsm_coe_down_seg_check; |
1635 fsm->state = ec_fsm_coe_down_seg_check; |
1650 return; |
1636 return; |
1651 } |
1637 } |
1652 |
1638 |
1653 if (((EC_READ_U8(data + 2) >> 4) & 0x01) != fsm->toggle) { |
1639 if (((EC_READ_U8(data + 2) >> 4) & 0x01) != fsm->toggle) { |
1654 EC_ERR("Invalid toggle received during segmented download:\n"); |
1640 EC_SLAVE_ERR(slave, "Invalid toggle received during" |
|
1641 " segmented download:\n"); |
1655 ec_print_data(data, rec_size); |
1642 ec_print_data(data, rec_size); |
1656 fsm->state = ec_fsm_coe_error; |
1643 fsm->state = ec_fsm_coe_error; |
1657 return; |
1644 return; |
1658 } |
1645 } |
1659 |
1646 |
1677 ec_slave_t *slave = fsm->slave; |
1664 ec_slave_t *slave = fsm->slave; |
1678 ec_master_t *master = slave->master; |
1665 ec_master_t *master = slave->master; |
1679 ec_sdo_request_t *request = fsm->request; |
1666 ec_sdo_request_t *request = fsm->request; |
1680 uint8_t *data; |
1667 uint8_t *data; |
1681 |
1668 |
1682 if (master->debug_level) |
1669 EC_SLAVE_DBG(slave, 1, "Uploading SDO 0x%04X:%02X.\n", |
1683 EC_DBG("Uploading SDO 0x%04X:%02X from slave %u.\n", |
1670 request->index, request->subindex); |
1684 request->index, request->subindex, slave->ring_position); |
|
1685 |
1671 |
1686 if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) { |
1672 if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) { |
1687 EC_ERR("Slave %u does not support CoE!\n", slave->ring_position); |
1673 EC_SLAVE_ERR(slave, "Slave does not support CoE!\n"); |
1688 fsm->state = ec_fsm_coe_error; |
1674 fsm->state = ec_fsm_coe_error; |
1689 return; |
1675 return; |
1690 } |
1676 } |
1691 |
1677 |
1692 data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10); |
1678 data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10); |
1727 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
1713 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
1728 return; // FIXME: check for response first? |
1714 return; // FIXME: check for response first? |
1729 |
1715 |
1730 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
1716 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
1731 fsm->state = ec_fsm_coe_error; |
1717 fsm->state = ec_fsm_coe_error; |
1732 EC_ERR("Failed to receive CoE upload request for slave %u: ", |
1718 EC_SLAVE_ERR(slave, "Failed to receive CoE upload request: "); |
1733 slave->ring_position); |
|
1734 ec_datagram_print_state(datagram); |
1719 ec_datagram_print_state(datagram); |
1735 return; |
1720 return; |
1736 } |
1721 } |
1737 |
1722 |
1738 diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ; |
1723 diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ; |
1739 |
1724 |
1740 if (datagram->working_counter != 1) { |
1725 if (datagram->working_counter != 1) { |
1741 if (!datagram->working_counter) { |
1726 if (!datagram->working_counter) { |
1742 if (diff_ms < fsm->request->response_timeout) { |
1727 if (diff_ms < fsm->request->response_timeout) { |
1743 #if DEBUG_RETRIES |
1728 #if DEBUG_RETRIES |
1744 if (fsm->slave->master->debug_level) { |
1729 EC_SLAVE_DBG(slave, 1, "Slave did not respond to" |
1745 EC_DBG("Slave %u did not respond to SDO upload request. " |
1730 " SDO upload request. Retrying after %u ms...\n", |
1746 "Retrying after %u ms...\n", |
1731 (u32) diff_ms); |
1747 slave->ring_position, (u32) diff_ms); |
|
1748 } |
|
1749 #endif |
1732 #endif |
1750 // no response; send request datagram again |
1733 // no response; send request datagram again |
1751 return; |
1734 return; |
1752 } |
1735 } |
1753 } |
1736 } |
1754 fsm->state = ec_fsm_coe_error; |
1737 fsm->state = ec_fsm_coe_error; |
1755 EC_ERR("Reception of CoE upload request for SDO 0x%04x:%x failed" |
1738 EC_SLAVE_ERR(slave, "Reception of CoE upload request for" |
1756 " with timeout after %u ms on slave %u: ", |
1739 " SDO 0x%04x:%x failed with timeout after %u ms: ", |
1757 fsm->request->index, fsm->request->subindex, (u32) diff_ms, |
1740 fsm->request->index, fsm->request->subindex, (u32) diff_ms); |
1758 fsm->slave->ring_position); |
|
1759 ec_datagram_print_wc_error(datagram); |
1741 ec_datagram_print_wc_error(datagram); |
1760 return; |
1742 return; |
1761 } |
1743 } |
1762 |
1744 |
1763 #if DEBUG_LONG |
1745 #if DEBUG_LONG |
1764 if (diff_ms > 200) { |
1746 if (diff_ms > 200) { |
1765 EC_WARN("SDO 0x%04x:%x upload took %u ms on slave %u.\n", |
1747 EC_SLAVE_WARN(slave, "SDO 0x%04x:%x upload took %u ms.\n", |
1766 fsm->request->index, fsm->request->subindex, (u32) diff_ms, |
1748 fsm->request->index, fsm->request->subindex, (u32) diff_ms); |
1767 fsm->slave->ring_position); |
|
1768 } |
1749 } |
1769 #endif |
1750 #endif |
1770 |
1751 |
1771 fsm->jiffies_start = datagram->jiffies_sent; |
1752 fsm->jiffies_start = datagram->jiffies_sent; |
1772 |
1753 |
1789 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
1770 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
1790 return; |
1771 return; |
1791 |
1772 |
1792 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
1773 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
1793 fsm->state = ec_fsm_coe_error; |
1774 fsm->state = ec_fsm_coe_error; |
1794 EC_ERR("Failed to receive CoE mailbox check datagram from slave %u: ", |
1775 EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: "); |
1795 slave->ring_position); |
|
1796 ec_datagram_print_state(datagram); |
1776 ec_datagram_print_state(datagram); |
1797 return; |
1777 return; |
1798 } |
1778 } |
1799 |
1779 |
1800 if (datagram->working_counter != 1) { |
1780 if (datagram->working_counter != 1) { |
1801 fsm->state = ec_fsm_coe_error; |
1781 fsm->state = ec_fsm_coe_error; |
1802 EC_ERR("Reception of CoE mailbox check" |
1782 EC_SLAVE_ERR(slave, "Reception of CoE mailbox check" |
1803 " datagram failed on slave %u: ", slave->ring_position); |
1783 " datagram failed: "); |
1804 ec_datagram_print_wc_error(datagram); |
1784 ec_datagram_print_wc_error(datagram); |
1805 return; |
1785 return; |
1806 } |
1786 } |
1807 |
1787 |
1808 if (!ec_slave_mbox_check(datagram)) { |
1788 if (!ec_slave_mbox_check(datagram)) { |
1809 unsigned long diff_ms = |
1789 unsigned long diff_ms = |
1810 (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; |
1790 (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; |
1811 if (diff_ms >= fsm->request->response_timeout) { |
1791 if (diff_ms >= fsm->request->response_timeout) { |
1812 fsm->state = ec_fsm_coe_error; |
1792 fsm->state = ec_fsm_coe_error; |
1813 EC_ERR("Timeout after %u ms while waiting for SDO 0x%04x:%x" |
1793 EC_SLAVE_ERR(slave, "Timeout after %u ms while waiting for" |
1814 " upload response on slave %u.\n", (u32) diff_ms, |
1794 " SDO 0x%04x:%x upload response.\n", (u32) diff_ms, |
1815 fsm->request->index, fsm->request->subindex, |
1795 fsm->request->index, fsm->request->subindex); |
1816 slave->ring_position); |
|
1817 return; |
1796 return; |
1818 } |
1797 } |
1819 |
1798 |
1820 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
1799 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
1821 fsm->retries = EC_FSM_RETRIES; |
1800 fsm->retries = EC_FSM_RETRIES; |
1875 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
1854 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
1876 return; // FIXME: request again? |
1855 return; // FIXME: request again? |
1877 |
1856 |
1878 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
1857 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
1879 fsm->state = ec_fsm_coe_error; |
1858 fsm->state = ec_fsm_coe_error; |
1880 EC_ERR("Failed to receive CoE upload response datagram for" |
1859 EC_SLAVE_ERR(slave, "Failed to receive CoE upload response" |
1881 " slave %u: ", slave->ring_position); |
1860 " datagram: "); |
1882 ec_datagram_print_state(datagram); |
1861 ec_datagram_print_state(datagram); |
1883 return; |
1862 return; |
1884 } |
1863 } |
1885 |
1864 |
1886 if (datagram->working_counter != 1) { |
1865 if (datagram->working_counter != 1) { |
1887 fsm->state = ec_fsm_coe_error; |
1866 fsm->state = ec_fsm_coe_error; |
1888 EC_ERR("Reception of CoE upload response failed on slave %u: ", |
1867 EC_SLAVE_ERR(slave, "Reception of CoE upload response failed: "); |
1889 slave->ring_position); |
|
1890 ec_datagram_print_wc_error(datagram); |
1868 ec_datagram_print_wc_error(datagram); |
1891 return; |
1869 return; |
1892 } |
1870 } |
1893 |
1871 |
1894 data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size); |
1872 data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size); |
1896 fsm->state = ec_fsm_coe_error; |
1874 fsm->state = ec_fsm_coe_error; |
1897 return; |
1875 return; |
1898 } |
1876 } |
1899 |
1877 |
1900 if (master->debug_level) { |
1878 if (master->debug_level) { |
1901 EC_DBG("Upload response:\n"); |
1879 EC_SLAVE_DBG(slave, 1, "Upload response:\n"); |
1902 ec_print_data(data, rec_size); |
1880 ec_print_data(data, rec_size); |
1903 } |
1881 } |
1904 |
1882 |
1905 if (mbox_prot != 0x03) { // CoE |
1883 if (mbox_prot != 0x03) { // CoE |
1906 fsm->state = ec_fsm_coe_error; |
1884 fsm->state = ec_fsm_coe_error; |
1907 EC_WARN("Received mailbox protocol 0x%02X as response.\n", mbox_prot); |
1885 EC_SLAVE_WARN(slave, "Received mailbox protocol 0x%02X" |
|
1886 " as response.\n", mbox_prot); |
1908 return; |
1887 return; |
1909 } |
1888 } |
1910 |
1889 |
1911 if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) { |
1890 if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) { |
1912 // check for CoE response again |
1891 // check for CoE response again |
1916 return; |
1895 return; |
1917 } |
1896 } |
1918 |
1897 |
1919 if (rec_size < 6) { |
1898 if (rec_size < 6) { |
1920 fsm->state = ec_fsm_coe_error; |
1899 fsm->state = ec_fsm_coe_error; |
1921 EC_ERR("Received currupted SDO upload response (%zu bytes)!\n", rec_size); |
1900 EC_SLAVE_ERR(slave, "Received currupted SDO upload response" |
|
1901 " (%zu bytes)!\n", rec_size); |
1922 ec_print_data(data, rec_size); |
1902 ec_print_data(data, rec_size); |
1923 return; |
1903 return; |
1924 } |
1904 } |
1925 |
1905 |
1926 if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request |
1906 if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request |
1927 EC_READ_U8(data + 2) >> 5 == 0x4) { // abort SDO transfer request |
1907 EC_READ_U8(data + 2) >> 5 == 0x4) { // abort SDO transfer request |
1928 EC_ERR("SDO upload 0x%04X:%02X aborted on slave %u.\n", |
1908 EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X aborted.\n", |
1929 request->index, request->subindex, slave->ring_position); |
1909 request->index, request->subindex); |
1930 if (rec_size >= 10) { |
1910 if (rec_size >= 10) { |
1931 request->abort_code = EC_READ_U32(data + 6); |
1911 request->abort_code = EC_READ_U32(data + 6); |
1932 ec_canopen_abort_msg(request->abort_code); |
1912 ec_canopen_abort_msg(slave, request->abort_code); |
1933 } else { |
1913 } else { |
1934 EC_ERR("No abort message.\n"); |
1914 EC_SLAVE_ERR(slave, "No abort message.\n"); |
1935 } |
1915 } |
1936 fsm->state = ec_fsm_coe_error; |
1916 fsm->state = ec_fsm_coe_error; |
1937 return; |
1917 return; |
1938 } |
1918 } |
1939 |
1919 |
1940 if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response |
1920 if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response |
1941 EC_READ_U8(data + 2) >> 5 != 0x2) { // upload response |
1921 EC_READ_U8(data + 2) >> 5 != 0x2) { // upload response |
1942 EC_ERR("Received unknown response while uploading SDO 0x%04X:%02X" |
1922 EC_SLAVE_ERR(slave, "Received unknown response while" |
1943 " from slave %u.\n", request->index, request->subindex, |
1923 " uploading SDO 0x%04X:%02X.\n", |
1944 slave->ring_position); |
1924 request->index, request->subindex); |
1945 ec_print_data(data, rec_size); |
1925 ec_print_data(data, rec_size); |
1946 fsm->state = ec_fsm_coe_error; |
1926 fsm->state = ec_fsm_coe_error; |
1947 return; |
1927 return; |
1948 } |
1928 } |
1949 |
1929 |
1950 rec_index = EC_READ_U16(data + 3); |
1930 rec_index = EC_READ_U16(data + 3); |
1951 rec_subindex = EC_READ_U8(data + 5); |
1931 rec_subindex = EC_READ_U8(data + 5); |
1952 |
1932 |
1953 if (rec_index != request->index || rec_subindex != request->subindex) { |
1933 if (rec_index != request->index || rec_subindex != request->subindex) { |
1954 EC_ERR("Received upload response for wrong SDO (0x%04X:%02X," |
1934 EC_SLAVE_ERR(slave, "Received upload response for wrong SDO" |
1955 " requested: 0x%04X:%02X) from slave %u.\n", |
1935 " (0x%04X:%02X, requested: 0x%04X:%02X).\n", |
1956 rec_index, rec_subindex, request->index, request->subindex, |
1936 rec_index, rec_subindex, request->index, request->subindex); |
1957 slave->ring_position); |
|
1958 ec_print_data(data, rec_size); |
1937 ec_print_data(data, rec_size); |
1959 |
1938 |
1960 // check for CoE response again |
1939 // check for CoE response again |
1961 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
1940 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
1962 fsm->retries = EC_FSM_RETRIES; |
1941 fsm->retries = EC_FSM_RETRIES; |
1988 return; |
1967 return; |
1989 } |
1968 } |
1990 } else { // normal |
1969 } else { // normal |
1991 if (rec_size < 10) { |
1970 if (rec_size < 10) { |
1992 fsm->state = ec_fsm_coe_error; |
1971 fsm->state = ec_fsm_coe_error; |
1993 EC_ERR("Received currupted SDO normal upload" |
1972 EC_SLAVE_ERR(slave, "Received currupted SDO normal upload" |
1994 " response (only %zu bytes)!\n", rec_size); |
1973 " response (only %zu bytes)!\n", rec_size); |
1995 ec_print_data(data, rec_size); |
1974 ec_print_data(data, rec_size); |
1996 return; |
1975 return; |
1997 } |
1976 } |
1998 |
1977 |
1999 data_size = rec_size - 10; |
1978 data_size = rec_size - 10; |
2000 fsm->complete_size = EC_READ_U32(data + 6); |
1979 fsm->complete_size = EC_READ_U32(data + 6); |
2001 |
1980 |
2002 if (!fsm->complete_size) { |
1981 if (!fsm->complete_size) { |
2003 fsm->state = ec_fsm_coe_error; |
1982 fsm->state = ec_fsm_coe_error; |
2004 EC_ERR("No complete size supplied!\n"); |
1983 EC_SLAVE_ERR(slave, "No complete size supplied!\n"); |
2005 ec_print_data(data, rec_size); |
1984 ec_print_data(data, rec_size); |
2006 return; |
1985 return; |
2007 } |
1986 } |
2008 |
1987 |
2009 if (ec_sdo_request_alloc(request, fsm->complete_size)) { |
1988 if (ec_sdo_request_alloc(request, fsm->complete_size)) { |
2017 } |
1996 } |
2018 |
1997 |
2019 fsm->toggle = 0; |
1998 fsm->toggle = 0; |
2020 |
1999 |
2021 if (data_size < fsm->complete_size) { |
2000 if (data_size < fsm->complete_size) { |
2022 if (master->debug_level) |
2001 EC_SLAVE_DBG(slave, 1, "SDO data incomplete (%zu / %u)." |
2023 EC_DBG("SDO data incomplete (%zu / %u). Segmenting...\n", |
2002 " Segmenting...\n", data_size, fsm->complete_size); |
2024 data_size, fsm->complete_size); |
|
2025 |
|
2026 ec_fsm_coe_up_prepare_segment_request(fsm); |
2003 ec_fsm_coe_up_prepare_segment_request(fsm); |
2027 fsm->retries = EC_FSM_RETRIES; |
2004 fsm->retries = EC_FSM_RETRIES; |
2028 fsm->state = ec_fsm_coe_up_seg_request; |
2005 fsm->state = ec_fsm_coe_up_seg_request; |
2029 return; |
2006 return; |
2030 } |
2007 } |
2031 } |
2008 } |
2032 |
2009 |
2033 if (master->debug_level) { |
2010 if (master->debug_level) { |
2034 EC_DBG("Uploaded data:\n"); |
2011 EC_SLAVE_DBG(slave, 1, "Uploaded data:\n"); |
2035 ec_print_data(request->data, request->data_size); |
2012 ec_print_data(request->data, request->data_size); |
2036 } |
2013 } |
2037 |
2014 |
2038 fsm->state = ec_fsm_coe_end; // success |
2015 fsm->state = ec_fsm_coe_end; // success |
2039 } |
2016 } |
2053 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
2030 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
2054 return; // FIXME: check for response first? |
2031 return; // FIXME: check for response first? |
2055 |
2032 |
2056 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
2033 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
2057 fsm->state = ec_fsm_coe_error; |
2034 fsm->state = ec_fsm_coe_error; |
2058 EC_ERR("Failed to receive CoE upload segment request datagram for" |
2035 EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment" |
2059 " slave %u: ", slave->ring_position); |
2036 " request datagram: "); |
2060 ec_datagram_print_state(datagram); |
2037 ec_datagram_print_state(datagram); |
2061 return; |
2038 return; |
2062 } |
2039 } |
2063 |
2040 |
2064 if (datagram->working_counter != 1) { |
2041 if (datagram->working_counter != 1) { |
2065 fsm->state = ec_fsm_coe_error; |
2042 fsm->state = ec_fsm_coe_error; |
2066 EC_ERR("Reception of CoE upload segment" |
2043 EC_SLAVE_ERR(slave, "Reception of CoE upload segment" |
2067 " request failed on slave %u: ", slave->ring_position); |
2044 " request failed: "); |
2068 ec_datagram_print_wc_error(datagram); |
2045 ec_datagram_print_wc_error(datagram); |
2069 return; |
2046 return; |
2070 } |
2047 } |
2071 |
2048 |
2072 fsm->jiffies_start = datagram->jiffies_sent; |
2049 fsm->jiffies_start = datagram->jiffies_sent; |
2090 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
2067 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
2091 return; |
2068 return; |
2092 |
2069 |
2093 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
2070 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
2094 fsm->state = ec_fsm_coe_error; |
2071 fsm->state = ec_fsm_coe_error; |
2095 EC_ERR("Failed to receive CoE mailbox check datagram for slave %u: ", |
2072 EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check" |
2096 slave->ring_position); |
2073 " datagram: "); |
2097 ec_datagram_print_state(datagram); |
2074 ec_datagram_print_state(datagram); |
2098 return; |
2075 return; |
2099 } |
2076 } |
2100 |
2077 |
2101 if (datagram->working_counter != 1) { |
2078 if (datagram->working_counter != 1) { |
2102 fsm->state = ec_fsm_coe_error; |
2079 fsm->state = ec_fsm_coe_error; |
2103 EC_ERR("Reception of CoE mailbox check" |
2080 EC_SLAVE_ERR(slave, "Reception of CoE mailbox check datagram" |
2104 " datagram failed on slave %u: ", slave->ring_position); |
2081 " failed: "); |
2105 ec_datagram_print_wc_error(datagram); |
2082 ec_datagram_print_wc_error(datagram); |
2106 return; |
2083 return; |
2107 } |
2084 } |
2108 |
2085 |
2109 if (!ec_slave_mbox_check(datagram)) { |
2086 if (!ec_slave_mbox_check(datagram)) { |
2110 unsigned long diff_ms = |
2087 unsigned long diff_ms = |
2111 (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; |
2088 (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; |
2112 if (diff_ms >= fsm->request->response_timeout) { |
2089 if (diff_ms >= fsm->request->response_timeout) { |
2113 fsm->state = ec_fsm_coe_error; |
2090 fsm->state = ec_fsm_coe_error; |
2114 EC_ERR("Timeout while waiting for SDO upload segment response " |
2091 EC_SLAVE_ERR(slave, "Timeout while waiting for SDO upload" |
2115 "on slave %u.\n", slave->ring_position); |
2092 " segment response.\n"); |
2116 return; |
2093 return; |
2117 } |
2094 } |
2118 |
2095 |
2119 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
2096 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
2120 fsm->retries = EC_FSM_RETRIES; |
2097 fsm->retries = EC_FSM_RETRIES; |
2147 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
2124 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
2148 return; // FIXME: request again? |
2125 return; // FIXME: request again? |
2149 |
2126 |
2150 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
2127 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
2151 fsm->state = ec_fsm_coe_error; |
2128 fsm->state = ec_fsm_coe_error; |
2152 EC_ERR("Failed to receive CoE upload segment response datagram for" |
2129 EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment" |
2153 " slave %u: ", slave->ring_position); |
2130 " response datagram: "); |
2154 ec_datagram_print_state(datagram); |
2131 ec_datagram_print_state(datagram); |
2155 return; |
2132 return; |
2156 } |
2133 } |
2157 |
2134 |
2158 if (datagram->working_counter != 1) { |
2135 if (datagram->working_counter != 1) { |
2159 fsm->state = ec_fsm_coe_error; |
2136 fsm->state = ec_fsm_coe_error; |
2160 EC_ERR("Reception of CoE upload segment" |
2137 EC_SLAVE_ERR(slave, "Reception of CoE upload segment" |
2161 " response failed on slave %u: ", slave->ring_position); |
2138 " response failed: "); |
2162 ec_datagram_print_wc_error(datagram); |
2139 ec_datagram_print_wc_error(datagram); |
2163 return; |
2140 return; |
2164 } |
2141 } |
2165 |
2142 |
2166 data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size); |
2143 data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size); |
2187 fsm->state = ec_fsm_coe_up_seg_check; |
2165 fsm->state = ec_fsm_coe_up_seg_check; |
2188 return; |
2166 return; |
2189 } |
2167 } |
2190 |
2168 |
2191 if (rec_size < 10) { |
2169 if (rec_size < 10) { |
2192 EC_ERR("Received currupted SDO upload segment response!\n"); |
2170 EC_SLAVE_ERR(slave, "Received currupted SDO upload" |
|
2171 " segment response!\n"); |
2193 ec_print_data(data, rec_size); |
2172 ec_print_data(data, rec_size); |
2194 fsm->state = ec_fsm_coe_error; |
2173 fsm->state = ec_fsm_coe_error; |
2195 return; |
2174 return; |
2196 } |
2175 } |
2197 |
2176 |
2198 if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request |
2177 if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request |
2199 EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request |
2178 EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request |
2200 EC_ERR("SDO upload 0x%04X:%02X aborted on slave %u.\n", |
2179 EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X aborted.\n", |
2201 request->index, request->subindex, slave->ring_position); |
2180 request->index, request->subindex); |
2202 request->abort_code = EC_READ_U32(data + 6); |
2181 request->abort_code = EC_READ_U32(data + 6); |
2203 ec_canopen_abort_msg(request->abort_code); |
2182 ec_canopen_abort_msg(slave, request->abort_code); |
2204 fsm->state = ec_fsm_coe_error; |
2183 fsm->state = ec_fsm_coe_error; |
2205 return; |
2184 return; |
2206 } |
2185 } |
2207 |
2186 |
2208 if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response |
2187 if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response |
2209 EC_READ_U8 (data + 2) >> 5 != 0x0) { // upload segment response |
2188 EC_READ_U8 (data + 2) >> 5 != 0x0) { // upload segment response |
2210 if (fsm->slave->master->debug_level) { |
2189 if (fsm->slave->master->debug_level) { |
2211 EC_DBG("Invalid SDO upload segment response at slave %u!\n", |
2190 EC_SLAVE_DBG(slave, 1, "Invalid SDO upload segment response!\n"); |
2212 slave->ring_position); |
|
2213 ec_print_data(data, rec_size); |
2191 ec_print_data(data, rec_size); |
2214 } |
2192 } |
2215 // check for CoE response again |
2193 // check for CoE response again |
2216 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
2194 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
2217 fsm->retries = EC_FSM_RETRIES; |
2195 fsm->retries = EC_FSM_RETRIES; |
2245 fsm->state = ec_fsm_coe_up_seg_request; |
2223 fsm->state = ec_fsm_coe_up_seg_request; |
2246 return; |
2224 return; |
2247 } |
2225 } |
2248 |
2226 |
2249 if (request->data_size != fsm->complete_size) { |
2227 if (request->data_size != fsm->complete_size) { |
2250 EC_WARN("SDO upload 0x%04X:%02X on slave %u: Assembled data" |
2228 EC_SLAVE_WARN(slave, "SDO upload 0x%04X:%02X: Assembled data" |
2251 " size (%zu) does not match complete size (%u)!\n", |
2229 " size (%zu) does not match complete size (%u)!\n", |
2252 request->index, request->subindex, slave->ring_position, |
2230 request->index, request->subindex, |
2253 request->data_size, fsm->complete_size); |
2231 request->data_size, fsm->complete_size); |
2254 } |
2232 } |
2255 |
2233 |
2256 if (master->debug_level) { |
2234 if (master->debug_level) { |
2257 EC_DBG("Uploaded data:\n"); |
2235 EC_SLAVE_DBG(slave, 1, "Uploaded data:\n"); |
2258 ec_print_data(request->data, request->data_size); |
2236 ec_print_data(request->data, request->data_size); |
2259 } |
2237 } |
2260 |
2238 |
2261 fsm->state = ec_fsm_coe_end; // success |
2239 fsm->state = ec_fsm_coe_end; // success |
2262 } |
2240 } |