IgH EtherCAT Master 1.5.2
fsm_coe.c
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * $Id$
4 *
5 * Copyright (C) 2006-2008 Florian Pose, Ingenieurgemeinschaft IgH
6 *
7 * This file is part of the IgH EtherCAT Master.
8 *
9 * The IgH EtherCAT Master is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License version 2, as
11 * published by the Free Software Foundation.
12 *
13 * The IgH EtherCAT Master is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16 * Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with the IgH EtherCAT Master; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 *
22 * ---
23 *
24 * The license mentioned above concerns the source code only. Using the
25 * EtherCAT technology and brand is only permitted in compliance with the
26 * industrial property and similar rights of Beckhoff Automation GmbH.
27 *
28 *****************************************************************************/
29
34/*****************************************************************************/
35
36#include "globals.h"
37#include "master.h"
38#include "mailbox.h"
39#include "fsm_coe.h"
40#include "slave_config.h"
41
42/*****************************************************************************/
43
46#define EC_FSM_COE_DICT_TIMEOUT 1000
47
50#define EC_COE_DOWN_REQ_HEADER_SIZE 10
51
54#define EC_COE_DOWN_SEG_REQ_HEADER_SIZE 3
55
58#define EC_COE_DOWN_SEG_MIN_DATA_SIZE 7
59
62#define DEBUG_RETRIES 0
63
66#define DEBUG_LONG 0
67
68/*****************************************************************************/
69
80
87
95
98
99/*****************************************************************************/
100
108 {0x05030000, "Toggle bit not changed"},
109 {0x05040000, "SDO protocol timeout"},
110 {0x05040001, "Client/Server command specifier not valid or unknown"},
111 {0x05040005, "Out of memory"},
112 {0x06010000, "Unsupported access to an object"},
113 {0x06010001, "Attempt to read a write-only object"},
114 {0x06010002, "Attempt to write a read-only object"},
115 {0x06020000, "This object does not exist in the object directory"},
116 {0x06040041, "The object cannot be mapped into the PDO"},
117 {0x06040042, "The number and length of the objects to be mapped would"
118 " exceed the PDO length"},
119 {0x06040043, "General parameter incompatibility reason"},
120 {0x06040047, "Gerneral internal incompatibility in device"},
121 {0x06060000, "Access failure due to a hardware error"},
122 {0x06070010, "Data type does not match, length of service parameter does"
123 " not match"},
124 {0x06070012, "Data type does not match, length of service parameter too"
125 " high"},
126 {0x06070013, "Data type does not match, length of service parameter too"
127 " low"},
128 {0x06090011, "Subindex does not exist"},
129 {0x06090030, "Value range of parameter exceeded"},
130 {0x06090031, "Value of parameter written too high"},
131 {0x06090032, "Value of parameter written too low"},
132 {0x06090036, "Maximum value is less than minimum value"},
133 {0x08000000, "General error"},
134 {0x08000020, "Data cannot be transferred or stored to the application"},
135 {0x08000021, "Data cannot be transferred or stored to the application"
136 " because of local control"},
137 {0x08000022, "Data cannot be transferred or stored to the application"
138 " because of the present device state"},
139 {0x08000023, "Object dictionary dynamic generation fails or no object"
140 " dictionary is present"},
141 {}
142};
143
144/*****************************************************************************/
145
149 const ec_slave_t *slave,
150 uint32_t abort_code
151 )
152{
153 const ec_code_msg_t *abort_msg;
154
155 for (abort_msg = sdo_abort_messages; abort_msg->code; abort_msg++) {
156 if (abort_msg->code == abort_code) {
157 EC_SLAVE_ERR(slave, "SDO abort message 0x%08X: \"%s\".\n",
158 abort_msg->code, abort_msg->message);
159 return;
160 }
161 }
162
163 EC_SLAVE_ERR(slave, "Unknown SDO abort code 0x%08X.\n", abort_code);
164}
165
166/*****************************************************************************/
167
171 ec_fsm_coe_t *fsm
172 )
173{
174 fsm->state = NULL;
175 fsm->datagram = NULL;
176}
177
178/*****************************************************************************/
179
183 ec_fsm_coe_t *fsm
184 )
185{
186}
187
188/*****************************************************************************/
189
193 ec_fsm_coe_t *fsm,
194 ec_slave_t *slave
195 )
196{
197 fsm->slave = slave;
199}
200
201/*****************************************************************************/
202
206 ec_fsm_coe_t *fsm,
207 ec_slave_t *slave,
208 ec_sdo_request_t *request
209 )
210{
211 fsm->slave = slave;
212 fsm->request = request;
213
214 if (request->dir == EC_DIR_OUTPUT) {
216 }
217 else {
219 }
220}
221
222/*****************************************************************************/
223
229 ec_fsm_coe_t *fsm,
230 ec_datagram_t *datagram
231 )
232{
233 int datagram_used = 0;
234
235 if (fsm->datagram &&
236 (fsm->datagram->state == EC_DATAGRAM_INIT ||
238 fsm->datagram->state == EC_DATAGRAM_SENT)) {
239 // datagram not received yet
240 return datagram_used;
241 }
242
243 fsm->state(fsm, datagram);
244
245 datagram_used =
246 fsm->state != ec_fsm_coe_end && fsm->state != ec_fsm_coe_error;
247
248 if (datagram_used) {
249 fsm->datagram = datagram;
250 } else {
251 fsm->datagram = NULL;
252 }
253
254 return datagram_used;
255}
256
257/*****************************************************************************/
258
263 const ec_fsm_coe_t *fsm
264 )
265{
266 return fsm->state == ec_fsm_coe_end;
267}
268
269/*****************************************************************************/
270
278 ec_fsm_coe_t *fsm,
279 const uint8_t *data,
280 size_t size
281 )
282{
283 if (size < 2 || ((EC_READ_U16(data) >> 12) & 0x0F) != 0x01)
284 return 0;
285
286 if (size < 10) {
287 EC_SLAVE_WARN(fsm->slave, "Received incomplete CoE Emergency"
288 " request:\n");
289 ec_print_data(data, size);
290 return 1;
291 }
292
293 {
294 ec_slave_config_t *sc = fsm->slave->config;
295 if (sc) {
296 ec_coe_emerg_ring_push(&sc->emerg_ring, data + 2);
297 }
298 }
299
300 EC_SLAVE_WARN(fsm->slave, "CoE Emergency Request received:\n"
301 "Error code 0x%04X, Error register 0x%02X, data:\n",
302 EC_READ_U16(data + 2), EC_READ_U8(data + 4));
303 ec_print_data(data + 5, 5);
304 return 1;
305}
306
307/******************************************************************************
308 * CoE dictionary state machine
309 *****************************************************************************/
310
316 ec_fsm_coe_t *fsm,
317 ec_datagram_t *datagram
318 )
319{
320 ec_slave_t *slave = fsm->slave;
321 uint8_t *data = ec_slave_mbox_prepare_send(slave, datagram,
322 EC_MBOX_TYPE_COE, 8);
323 if (IS_ERR(data)) {
324 return PTR_ERR(data);
325 }
326
327 EC_WRITE_U16(data, 0x8 << 12); // SDO information
328 EC_WRITE_U8 (data + 2, 0x01); // Get OD List Request
329 EC_WRITE_U8 (data + 3, 0x00);
330 EC_WRITE_U16(data + 4, 0x0000);
331 EC_WRITE_U16(data + 6, 0x0001); // deliver all SDOs!
332
334 return 0;
335}
336
337/*****************************************************************************/
338
342 ec_fsm_coe_t *fsm,
343 ec_datagram_t *datagram
344 )
345{
346 ec_slave_t *slave = fsm->slave;
347
348 if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
349 EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
350 fsm->state = ec_fsm_coe_error;
351 return;
352 }
353
354 if (slave->sii.has_general && !slave->sii.coe_details.enable_sdo_info) {
355 EC_SLAVE_ERR(slave, "Slave does not support"
356 " SDO information service!\n");
357 fsm->state = ec_fsm_coe_error;
358 return;
359 }
360
361 fsm->retries = EC_FSM_RETRIES;
362
363 if (ec_fsm_coe_prepare_dict(fsm, datagram)) {
364 fsm->state = ec_fsm_coe_error;
365 }
366}
367
368/*****************************************************************************/
369
374 ec_fsm_coe_t *fsm,
375 ec_datagram_t *datagram
376 )
377{
378 ec_slave_t *slave = fsm->slave;
379
380 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
381 if (ec_fsm_coe_prepare_dict(fsm, datagram)) {
382 fsm->state = ec_fsm_coe_error;
383 }
384 return;
385 }
386
387 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
388 fsm->state = ec_fsm_coe_error;
389 EC_SLAVE_ERR(slave, "Failed to receive CoE dictionary"
390 " request datagram: ");
392 return;
393 }
394
395 if (fsm->datagram->working_counter != 1) {
396 fsm->state = ec_fsm_coe_error;
397 EC_SLAVE_ERR(slave, "Reception of CoE dictionary request failed: ");
399 return;
400 }
401
403
404 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
405 fsm->retries = EC_FSM_RETRIES;
407}
408
409/*****************************************************************************/
410
414 ec_fsm_coe_t *fsm,
415 ec_datagram_t *datagram
416 )
417{
418 ec_slave_t *slave = fsm->slave;
419
420 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
421 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
422 return;
423 }
424
425 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
426 fsm->state = ec_fsm_coe_error;
427 EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
429 return;
430 }
431
432 if (fsm->datagram->working_counter != 1) {
433 fsm->state = ec_fsm_coe_error;
434 EC_SLAVE_ERR(slave,"Reception of CoE mailbox check"
435 " datagram failed: ");
437 return;
438 }
439
440 if (!ec_slave_mbox_check(fsm->datagram)) {
441 unsigned long diff_ms =
443 1000 / HZ;
444 if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
445 fsm->state = ec_fsm_coe_error;
446 EC_SLAVE_ERR(slave, "Timeout while waiting for"
447 " SDO dictionary list response.\n");
448 return;
449 }
450
451 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
452 fsm->retries = EC_FSM_RETRIES;
453 return;
454 }
455
456 // Fetch response
457 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
458 fsm->retries = EC_FSM_RETRIES;
460}
461
462/*****************************************************************************/
463
469 ec_fsm_coe_t *fsm,
470 ec_datagram_t *datagram
471 )
472{
473 ec_slave_t *slave = fsm->slave;
474 u8 *data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
475 8);
476 if (IS_ERR(data)) {
477 return PTR_ERR(data);
478 }
479
480 EC_WRITE_U16(data, 0x8 << 12); // SDO information
481 EC_WRITE_U8 (data + 2, 0x03); // Get object description request
482 EC_WRITE_U8 (data + 3, 0x00);
483 EC_WRITE_U16(data + 4, 0x0000);
484 EC_WRITE_U16(data + 6, fsm->sdo->index); // SDO index
485
487 return 0;
488}
489
490/*****************************************************************************/
491
498 ec_fsm_coe_t *fsm,
499 ec_datagram_t *datagram
500 )
501{
502 ec_slave_t *slave = fsm->slave;
503 uint8_t *data, mbox_prot;
504 size_t rec_size;
505 unsigned int sdo_count, i;
506 uint16_t sdo_index, fragments_left;
507 ec_sdo_t *sdo;
508 bool first_segment;
509 size_t index_list_offset;
510
511 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
512 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
513 return;
514 }
515
516 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
517 fsm->state = ec_fsm_coe_error;
518 EC_SLAVE_ERR(slave, "Failed to receive CoE dictionary"
519 " response datagram: ");
521 return;
522 }
523
524 if (fsm->datagram->working_counter != 1) {
525 fsm->state = ec_fsm_coe_error;
526 EC_SLAVE_ERR(slave, "Reception of CoE dictionary response failed: ");
528 return;
529 }
530
531 data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
532 if (IS_ERR(data)) {
533 fsm->state = ec_fsm_coe_error;
534 return;
535 }
536
537 if (mbox_prot != EC_MBOX_TYPE_COE) {
538 EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
539 mbox_prot);
540 fsm->state = ec_fsm_coe_error;
541 return;
542 }
543
544 if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
545 // check for CoE response again
546 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
547 fsm->retries = EC_FSM_RETRIES;
549 return;
550 }
551
552 if (rec_size < 3) {
553 EC_SLAVE_ERR(slave, "Received corrupted SDO dictionary response"
554 " (size %zu).\n", rec_size);
555 fsm->state = ec_fsm_coe_error;
556 return;
557 }
558
559 if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
560 (EC_READ_U8(data + 2) & 0x7F) == 0x07) { // error response
561 EC_SLAVE_ERR(slave, "SDO information error response!\n");
562 if (rec_size < 10) {
563 EC_SLAVE_ERR(slave, "Incomplete SDO information"
564 " error response:\n");
565 ec_print_data(data, rec_size);
566 } else {
567 ec_canopen_abort_msg(slave, EC_READ_U32(data + 6));
568 }
569 fsm->state = ec_fsm_coe_error;
570 return;
571 }
572
573 if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
574 (EC_READ_U8 (data + 2) & 0x7F) != 0x02) { // Get OD List response
575 if (fsm->slave->master->debug_level) {
576 EC_SLAVE_DBG(slave, 1, "Invalid SDO list response!"
577 " Retrying...\n");
578 ec_print_data(data, rec_size);
579 }
580 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
581 fsm->retries = EC_FSM_RETRIES;
583 return;
584 }
585
586 first_segment = list_empty(&slave->sdo_dictionary) ? true : false;
587 index_list_offset = first_segment ? 8 : 6;
588
589 if (rec_size < index_list_offset || rec_size % 2) {
590 EC_SLAVE_ERR(slave, "Invalid data size %zu!\n", rec_size);
591 ec_print_data(data, rec_size);
592 fsm->state = ec_fsm_coe_error;
593 return;
594 }
595
596 sdo_count = (rec_size - index_list_offset) / 2;
597
598 for (i = 0; i < sdo_count; i++) {
599 sdo_index = EC_READ_U16(data + index_list_offset + i * 2);
600 if (!sdo_index) {
601 EC_SLAVE_DBG(slave, 1, "SDO dictionary contains index 0x0000.\n");
602 continue;
603 }
604
605 if (!(sdo = (ec_sdo_t *) kmalloc(sizeof(ec_sdo_t), GFP_KERNEL))) {
606 EC_SLAVE_ERR(slave, "Failed to allocate memory for SDO!\n");
607 fsm->state = ec_fsm_coe_error;
608 return;
609 }
610
611 ec_sdo_init(sdo, slave, sdo_index);
612 list_add_tail(&sdo->list, &slave->sdo_dictionary);
613 }
614
615 fragments_left = EC_READ_U16(data + 4);
616 if (fragments_left) {
617 EC_SLAVE_DBG(slave, 1, "SDO list fragments left: %u\n",
618 fragments_left);
619 }
620
621 if (EC_READ_U8(data + 2) & 0x80 || fragments_left) {
622 // more messages waiting. check again.
624 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
625 fsm->retries = EC_FSM_RETRIES;
627 return;
628 }
629
630 if (list_empty(&slave->sdo_dictionary)) {
631 // no SDOs in dictionary. finished.
632 fsm->state = ec_fsm_coe_end; // success
633 return;
634 }
635
636 // fetch SDO descriptions
637 fsm->sdo = list_entry(slave->sdo_dictionary.next, ec_sdo_t, list);
638
639 fsm->retries = EC_FSM_RETRIES;
640 if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
641 fsm->state = ec_fsm_coe_error;
642 }
643}
644
645/*****************************************************************************/
646
653 ec_fsm_coe_t *fsm,
654 ec_datagram_t *datagram
655 )
656{
657 ec_slave_t *slave = fsm->slave;
658
659 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
660 if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
661 fsm->state = ec_fsm_coe_error;
662 }
663 return;
664 }
665
666 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
667 fsm->state = ec_fsm_coe_error;
668 EC_SLAVE_ERR(slave, "Failed to receive CoE SDO"
669 " description request datagram: ");
671 return;
672 }
673
674 if (fsm->datagram->working_counter != 1) {
675 fsm->state = ec_fsm_coe_error;
676 EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
677 " request failed: ");
679 return;
680 }
681
683
684 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
685 fsm->retries = EC_FSM_RETRIES;
687}
688
689/*****************************************************************************/
690
696 ec_fsm_coe_t *fsm,
697 ec_datagram_t *datagram
698 )
699{
700 ec_slave_t *slave = fsm->slave;
701
702 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
703 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
704 return;
705 }
706
707 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
708 fsm->state = ec_fsm_coe_error;
709 EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
711 return;
712 }
713
714 if (fsm->datagram->working_counter != 1) {
715 fsm->state = ec_fsm_coe_error;
716 EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
717 " datagram failed: ");
719 return;
720 }
721
722 if (!ec_slave_mbox_check(fsm->datagram)) {
723 unsigned long diff_ms =
725 1000 / HZ;
726 if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
727 fsm->state = ec_fsm_coe_error;
728 EC_SLAVE_ERR(slave, "Timeout while waiting for"
729 " SDO 0x%04x object description response.\n",
730 fsm->sdo->index);
731 return;
732 }
733
734 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
735 fsm->retries = EC_FSM_RETRIES;
736 return;
737 }
738
739 // Fetch response
740 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
741 fsm->retries = EC_FSM_RETRIES;
743}
744
745/*****************************************************************************/
746
752 ec_fsm_coe_t *fsm,
753 ec_datagram_t *datagram
754 )
755{
756 ec_slave_t *slave = fsm->slave;
757 u8 *data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
758 10);
759 if (IS_ERR(data)) {
760 return PTR_ERR(data);
761 }
762
763 EC_WRITE_U16(data, 0x8 << 12); // SDO information
764 EC_WRITE_U8 (data + 2, 0x05); // Get entry description request
765 EC_WRITE_U8 (data + 3, 0x00);
766 EC_WRITE_U16(data + 4, 0x0000);
767 EC_WRITE_U16(data + 6, fsm->sdo->index); // SDO index
768 EC_WRITE_U8 (data + 8, fsm->subindex); // SDO subindex
769 EC_WRITE_U8 (data + 9, 0x01); // value info (access rights only)
770
772 return 0;
773}
774
775/*****************************************************************************/
776
783 ec_fsm_coe_t *fsm,
784 ec_datagram_t *datagram
785 )
786{
787 ec_slave_t *slave = fsm->slave;
788 ec_sdo_t *sdo = fsm->sdo;
789 uint8_t *data, mbox_prot;
790 size_t rec_size, name_size;
791
792 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
793 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
794 return;
795 }
796
797 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
798 fsm->state = ec_fsm_coe_error;
799 EC_SLAVE_ERR(slave, "Failed to receive CoE SDO description"
800 " response datagram: ");
802 return;
803 }
804
805 if (fsm->datagram->working_counter != 1) {
806 fsm->state = ec_fsm_coe_error;
807 EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
808 " response failed: ");
810 return;
811 }
812
813 data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
814 if (IS_ERR(data)) {
815 fsm->state = ec_fsm_coe_error;
816 return;
817 }
818
819 if (mbox_prot != EC_MBOX_TYPE_COE) {
820 EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
821 mbox_prot);
822 fsm->state = ec_fsm_coe_error;
823 return;
824 }
825
826 if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
827 // check for CoE response again
828 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
829 fsm->retries = EC_FSM_RETRIES;
831 return;
832 }
833
834 if (rec_size < 3) {
835 EC_SLAVE_ERR(slave, "Received corrupted SDO description response"
836 " (size %zu).\n", rec_size);
837 fsm->state = ec_fsm_coe_error;
838 return;
839 }
840
841 if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
842 (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
843 EC_SLAVE_ERR(slave, "SDO information error response while"
844 " fetching SDO 0x%04X!\n", sdo->index);
845 ec_canopen_abort_msg(slave, EC_READ_U32(data + 6));
846 fsm->state = ec_fsm_coe_error;
847 return;
848 }
849
850 if (rec_size < 8) {
851 EC_SLAVE_ERR(slave, "Received corrupted SDO"
852 " description response (size %zu).\n", rec_size);
853 fsm->state = ec_fsm_coe_error;
854 return;
855 }
856
857 if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
858 (EC_READ_U8 (data + 2) & 0x7F) != 0x04 || // Object desc. response
859 EC_READ_U16(data + 6) != sdo->index) { // SDO index
860 if (fsm->slave->master->debug_level) {
861 EC_SLAVE_DBG(slave, 1, "Invalid object description response while"
862 " fetching SDO 0x%04X!\n", sdo->index);
863 ec_print_data(data, rec_size);
864 }
865 // check for CoE response again
866 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
867 fsm->retries = EC_FSM_RETRIES;
869 return;
870 }
871
872 if (rec_size < 12) {
873 EC_SLAVE_ERR(slave, "Invalid data size!\n");
874 ec_print_data(data, rec_size);
875 fsm->state = ec_fsm_coe_error;
876 return;
877 }
878
879 sdo->max_subindex = EC_READ_U8(data + 10);
880 sdo->object_code = EC_READ_U8(data + 11);
881
882 name_size = rec_size - 12;
883 if (name_size) {
884 if (!(sdo->name = kmalloc(name_size + 1, GFP_KERNEL))) {
885 EC_SLAVE_ERR(slave, "Failed to allocate SDO name!\n");
886 fsm->state = ec_fsm_coe_error;
887 return;
888 }
889
890 memcpy(sdo->name, data + 12, name_size);
891 sdo->name[name_size] = 0;
892 }
893
894 if (EC_READ_U8(data + 2) & 0x80) {
895 EC_SLAVE_ERR(slave, "Fragment follows (not implemented)!\n");
896 fsm->state = ec_fsm_coe_error;
897 return;
898 }
899
900 // start fetching entries
901
902 fsm->subindex = 0;
903 fsm->retries = EC_FSM_RETRIES;
904
905 if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
906 fsm->state = ec_fsm_coe_error;
907 }
908}
909
910/*****************************************************************************/
911
918 ec_fsm_coe_t *fsm,
919 ec_datagram_t *datagram
920 )
921{
922 ec_slave_t *slave = fsm->slave;
923
924 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
925 if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
926 fsm->state = ec_fsm_coe_error;
927 }
928 return;
929 }
930
931 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
932 fsm->state = ec_fsm_coe_error;
933 EC_SLAVE_ERR(slave, "Failed to receive CoE SDO entry"
934 " request datagram: ");
936 return;
937 }
938
939 if (fsm->datagram->working_counter != 1) {
940 fsm->state = ec_fsm_coe_error;
941 EC_SLAVE_ERR(slave, "Reception of CoE SDO entry request failed: ");
943 return;
944 }
945
947
948 ec_slave_mbox_prepare_check(slave, datagram); // can not fail
949 fsm->retries = EC_FSM_RETRIES;
951}
952
953/*****************************************************************************/
954
960 ec_fsm_coe_t *fsm,
961 ec_datagram_t *datagram
962 )
963{
964 ec_slave_t *slave = fsm->slave;
965
966 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
967 ec_slave_mbox_prepare_check(slave, datagram); // can not fail
968 return;
969 }
970
971 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
972 fsm->state = ec_fsm_coe_error;
973 EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
975 return;
976 }
977
978 if (fsm->datagram->working_counter != 1) {
979 fsm->state = ec_fsm_coe_error;
980 EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
981 " datagram failed: ");
983 return;
984 }
985
986 if (!ec_slave_mbox_check(fsm->datagram)) {
987 unsigned long diff_ms =
989 1000 / HZ;
990 if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
991 fsm->state = ec_fsm_coe_error;
992 EC_SLAVE_ERR(slave, "Timeout while waiting for"
993 " SDO entry 0x%04x:%x description response.\n",
994 fsm->sdo->index, fsm->subindex);
995 return;
996 }
997
998 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
999 fsm->retries = EC_FSM_RETRIES;
1000 return;
1001 }
1002
1003 // Fetch response
1004 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1005 fsm->retries = EC_FSM_RETRIES;
1007}
1008
1009/*****************************************************************************/
1010
1017 ec_fsm_coe_t *fsm,
1018 ec_datagram_t *datagram
1019 )
1020{
1021 ec_slave_t *slave = fsm->slave;
1022 ec_sdo_t *sdo = fsm->sdo;
1023 uint8_t *data, mbox_prot;
1024 size_t rec_size, data_size;
1025 ec_sdo_entry_t *entry;
1026 u16 word;
1027
1028 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1029 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1030 return;
1031 }
1032
1033 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1034 fsm->state = ec_fsm_coe_error;
1035 EC_SLAVE_ERR(slave, "Failed to receive CoE SDO"
1036 " description response datagram: ");
1038 return;
1039 }
1040
1041 if (fsm->datagram->working_counter != 1) {
1042 fsm->state = ec_fsm_coe_error;
1043 EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
1044 " response failed: ");
1046 return;
1047 }
1048
1049 data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
1050 if (IS_ERR(data)) {
1051 fsm->state = ec_fsm_coe_error;
1052 return;
1053 }
1054
1055 if (mbox_prot != EC_MBOX_TYPE_COE) {
1056 EC_SLAVE_ERR(slave, "Received mailbox protocol"
1057 " 0x%02X as response.\n", mbox_prot);
1058 fsm->state = ec_fsm_coe_error;
1059 return;
1060 }
1061
1062 if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
1063 // check for CoE response again
1064 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1065 fsm->retries = EC_FSM_RETRIES;
1067 return;
1068 }
1069
1070 if (rec_size < 3) {
1071 EC_SLAVE_ERR(slave, "Received corrupted SDO entry"
1072 " description response (size %zu).\n", rec_size);
1073 fsm->state = ec_fsm_coe_error;
1074 return;
1075 }
1076
1077 if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
1078 (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
1079 EC_SLAVE_WARN(slave, "SDO information error response while"
1080 " fetching SDO entry 0x%04X:%02X!\n",
1081 sdo->index, fsm->subindex);
1082 ec_canopen_abort_msg(slave, EC_READ_U32(data + 6));
1083
1084 /* There may be gaps in the subindices, so try to continue with next
1085 * subindex. */
1086
1087 } else {
1088
1089 if (rec_size < 9) {
1090 EC_SLAVE_ERR(slave, "Received corrupted SDO entry"
1091 " description response (size %zu).\n", rec_size);
1092 fsm->state = ec_fsm_coe_error;
1093 return;
1094 }
1095
1096 if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
1097 (EC_READ_U8(data + 2) & 0x7F) != 0x06 || // Entry desc. response
1098 EC_READ_U16(data + 6) != sdo->index || // SDO index
1099 EC_READ_U8(data + 8) != fsm->subindex) { // SDO subindex
1100 if (fsm->slave->master->debug_level) {
1101 EC_SLAVE_DBG(slave, 1, "Invalid entry description response"
1102 " while fetching SDO entry 0x%04X:%02X!\n",
1103 sdo->index, fsm->subindex);
1104 ec_print_data(data, rec_size);
1105 }
1106 // check for CoE response again
1107 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1108 fsm->retries = EC_FSM_RETRIES;
1110 return;
1111 }
1112
1113 if (rec_size < 16) {
1114 EC_SLAVE_ERR(slave, "Invalid data size %zu!\n", rec_size);
1115 ec_print_data(data, rec_size);
1116 fsm->state = ec_fsm_coe_error;
1117 return;
1118 }
1119
1120 data_size = rec_size - 16;
1121
1122 if (!(entry = (ec_sdo_entry_t *)
1123 kmalloc(sizeof(ec_sdo_entry_t), GFP_KERNEL))) {
1124 EC_SLAVE_ERR(slave, "Failed to allocate entry!\n");
1125 fsm->state = ec_fsm_coe_error;
1126 return;
1127 }
1128
1129 ec_sdo_entry_init(entry, sdo, fsm->subindex);
1130 entry->data_type = EC_READ_U16(data + 10);
1131 entry->bit_length = EC_READ_U16(data + 12);
1132
1133 // read access rights
1134 word = EC_READ_U16(data + 14);
1135 entry->read_access[EC_SDO_ENTRY_ACCESS_PREOP] = word & 0x0001;
1137 (word >> 1) & 0x0001;
1138 entry->read_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 2) & 0x0001;
1139 entry->write_access[EC_SDO_ENTRY_ACCESS_PREOP] = (word >> 3) & 0x0001;
1141 (word >> 4) & 0x0001;
1142 entry->write_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 5) & 0x0001;
1143
1144 if (data_size) {
1145 uint8_t *desc;
1146 if (!(desc = kmalloc(data_size + 1, GFP_KERNEL))) {
1147 EC_SLAVE_ERR(slave, "Failed to allocate SDO entry name!\n");
1148 fsm->state = ec_fsm_coe_error;
1149 return;
1150 }
1151 memcpy(desc, data + 16, data_size);
1152 desc[data_size] = 0;
1153 entry->description = desc;
1154 }
1155
1156 list_add_tail(&entry->list, &sdo->entries);
1157 }
1158
1159 if (fsm->subindex < sdo->max_subindex) {
1160
1161 fsm->subindex++;
1162 fsm->retries = EC_FSM_RETRIES;
1163
1164 if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
1165 fsm->state = ec_fsm_coe_error;
1166 }
1167
1168 return;
1169 }
1170
1171 // another SDO description to fetch?
1172 if (fsm->sdo->list.next != &slave->sdo_dictionary) {
1173
1174 fsm->sdo = list_entry(fsm->sdo->list.next, ec_sdo_t, list);
1175 fsm->retries = EC_FSM_RETRIES;
1176
1177 if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
1178 fsm->state = ec_fsm_coe_error;
1179 }
1180
1181 return;
1182 }
1183
1184 fsm->state = ec_fsm_coe_end;
1185}
1186
1187/******************************************************************************
1188 * CoE state machine
1189 *****************************************************************************/
1190
1196 ec_fsm_coe_t *fsm,
1197 ec_datagram_t *datagram
1198 )
1199{
1200 u8 *data;
1201 ec_slave_t *slave = fsm->slave;
1202 ec_sdo_request_t *request = fsm->request;
1203 uint8_t data_set_size;
1204
1205 if (request->data_size <= 4) { // use expedited transfer type
1206 data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1208 if (IS_ERR(data)) {
1209 request->errno = PTR_ERR(data);
1210 return PTR_ERR(data);
1211 }
1212
1213 fsm->remaining = 0;
1214
1215 data_set_size = 4 - request->data_size;
1216
1217 EC_WRITE_U16(data, 0x2 << 12); // SDO request
1218 EC_WRITE_U8 (data + 2, (0x3 // size specified, expedited
1219 | data_set_size << 2
1220 | ((request->complete_access ? 1 : 0) << 4)
1221 | 0x1 << 5)); // Download request
1222 EC_WRITE_U16(data + 3, request->index);
1223 EC_WRITE_U8 (data + 5,
1224 request->complete_access ? 0x00 : request->subindex);
1225 memcpy(data + 6, request->data, request->data_size);
1226 memset(data + 6 + request->data_size, 0x00, 4 - request->data_size);
1227
1228 if (slave->master->debug_level) {
1229 EC_SLAVE_DBG(slave, 1, "Expedited download request:\n");
1231 }
1232 }
1233 else { // request->data_size > 4, use normal transfer type
1234 size_t data_size,
1235 max_data_size =
1237 required_data_size =
1239
1240 if (max_data_size < required_data_size) {
1241 // segmenting needed
1242 data_size = max_data_size;
1243 } else {
1244 data_size = required_data_size;
1245 }
1246
1247 data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1248 data_size);
1249 if (IS_ERR(data)) {
1250 request->errno = PTR_ERR(data);
1251 return PTR_ERR(data);
1252 }
1253
1254 fsm->offset = 0;
1255 fsm->remaining = request->data_size;
1256
1257 EC_WRITE_U16(data, 0x2 << 12); // SDO request
1258 EC_WRITE_U8(data + 2,
1259 0x1 // size indicator, normal
1260 | ((request->complete_access ? 1 : 0) << 4)
1261 | 0x1 << 5); // Download request
1262 EC_WRITE_U16(data + 3, request->index);
1263 EC_WRITE_U8 (data + 5,
1264 request->complete_access ? 0x00 : request->subindex);
1265 EC_WRITE_U32(data + 6, request->data_size);
1266
1267 if (data_size > EC_COE_DOWN_REQ_HEADER_SIZE) {
1268 size_t segment_size = data_size - EC_COE_DOWN_REQ_HEADER_SIZE;
1269 memcpy(data + EC_COE_DOWN_REQ_HEADER_SIZE,
1270 request->data, segment_size);
1271 fsm->offset += segment_size;
1272 fsm->remaining -= segment_size;
1273 }
1274
1275 if (slave->master->debug_level) {
1276 EC_SLAVE_DBG(slave, 1, "Normal download request:\n");
1277 ec_print_data(data, data_size);
1278 }
1279 }
1280
1282 return 0;
1283}
1284
1285/****************************************************************************/
1286
1290 ec_fsm_coe_t *fsm,
1291 ec_datagram_t *datagram
1292 )
1293{
1294 ec_slave_t *slave = fsm->slave;
1295 ec_sdo_request_t *request = fsm->request;
1296
1297 if (fsm->slave->master->debug_level) {
1298 char subidxstr[10];
1299 if (request->complete_access) {
1300 subidxstr[0] = 0x00;
1301 } else {
1302 sprintf(subidxstr, ":%02X", request->subindex);
1303 }
1304 EC_SLAVE_DBG(slave, 1, "Downloading SDO 0x%04X%s.\n",
1305 request->index, subidxstr);
1306 ec_print_data(request->data, request->data_size);
1307 }
1308
1309 if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
1310 EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
1311 request->errno = EPROTONOSUPPORT;
1312 fsm->state = ec_fsm_coe_error;
1313 return;
1314 }
1315
1316 if (slave->configured_rx_mailbox_size <
1318 EC_SLAVE_ERR(slave, "Mailbox too small!\n");
1319 request->errno = EOVERFLOW;
1320 fsm->state = ec_fsm_coe_error;
1321 return;
1322 }
1323
1324
1325 fsm->request->jiffies_sent = jiffies;
1326 fsm->retries = EC_FSM_RETRIES;
1327
1328 if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1329 fsm->state = ec_fsm_coe_error;
1330 }
1331}
1332
1333/*****************************************************************************/
1334
1341 ec_fsm_coe_t *fsm,
1342 ec_datagram_t *datagram
1343 )
1344{
1345 ec_slave_t *slave = fsm->slave;
1346 unsigned long diff_ms;
1347
1348 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1349 if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1350 fsm->state = ec_fsm_coe_error;
1351 }
1352 return;
1353 }
1354
1355 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1356 fsm->request->errno = EIO;
1357 fsm->state = ec_fsm_coe_error;
1358 EC_SLAVE_ERR(slave, "Failed to receive CoE download"
1359 " request datagram: ");
1361 return;
1362 }
1363
1364 diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
1365
1366 if (fsm->datagram->working_counter != 1) {
1367 if (!fsm->datagram->working_counter) {
1368 if (diff_ms < fsm->request->response_timeout) {
1369#if DEBUG_RETRIES
1370 EC_SLAVE_DBG(slave, 1, "Slave did not respond to SDO"
1371 " download request. Retrying after %lu ms...\n",
1372 diff_ms);
1373#endif
1374 // no response; send request datagram again
1375 if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1376 fsm->state = ec_fsm_coe_error;
1377 }
1378 return;
1379 }
1380 }
1381 fsm->request->errno = EIO;
1382 fsm->state = ec_fsm_coe_error;
1383 EC_SLAVE_ERR(slave, "Reception of CoE download request"
1384 " for SDO 0x%04x:%x failed with timeout after %lu ms: ",
1385 fsm->request->index, fsm->request->subindex, diff_ms);
1387 return;
1388 }
1389
1390#if DEBUG_LONG
1391 if (diff_ms > 200) {
1392 EC_SLAVE_WARN(slave, "SDO 0x%04x:%x download took %lu ms.\n",
1393 fsm->request->index, fsm->request->subindex, diff_ms);
1394 }
1395#endif
1396
1397 fsm->jiffies_start = fsm->datagram->jiffies_sent;
1398
1399 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1400 fsm->retries = EC_FSM_RETRIES;
1402}
1403
1404/*****************************************************************************/
1405
1409 ec_fsm_coe_t *fsm,
1410 ec_datagram_t *datagram
1411 )
1412{
1413 ec_slave_t *slave = fsm->slave;
1414
1415 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1416 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1417 return;
1418 }
1419
1420 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1421 fsm->request->errno = EIO;
1422 fsm->state = ec_fsm_coe_error;
1423 EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
1424 " datagram: ");
1426 return;
1427 }
1428
1429 if (fsm->datagram->working_counter != 1) {
1430 fsm->request->errno = EIO;
1431 fsm->state = ec_fsm_coe_error;
1432 EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
1433 " datagram failed: ");
1435 return;
1436 }
1437
1438 if (!ec_slave_mbox_check(fsm->datagram)) {
1439 unsigned long diff_ms =
1440 (fsm->datagram->jiffies_received - fsm->jiffies_start) *
1441 1000 / HZ;
1442 if (diff_ms >= fsm->request->response_timeout) {
1443 fsm->request->errno = EIO;
1444 fsm->state = ec_fsm_coe_error;
1445 EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting"
1446 " for SDO 0x%04x:%x download response.\n", diff_ms,
1447 fsm->request->index, fsm->request->subindex);
1448 return;
1449 }
1450
1451 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1452 fsm->retries = EC_FSM_RETRIES;
1453 return;
1454 }
1455
1456 // Fetch response
1457 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1458 fsm->retries = EC_FSM_RETRIES;
1460}
1461
1462/*****************************************************************************/
1463
1467 ec_fsm_coe_t *fsm,
1468 ec_datagram_t *datagram
1469 )
1470{
1471 ec_slave_t *slave = fsm->slave;
1472 ec_sdo_request_t *request = fsm->request;
1473 size_t max_segment_size =
1477 size_t data_size;
1478 uint8_t last_segment, seg_data_size, *data;
1479
1480 if (fsm->remaining > max_segment_size) {
1481 fsm->segment_size = max_segment_size;
1482 last_segment = 0;
1483 } else {
1484 fsm->segment_size = fsm->remaining;
1485 last_segment = 1;
1486 }
1487
1489 seg_data_size = 0x00;
1491 } else {
1492 seg_data_size = EC_COE_DOWN_SEG_MIN_DATA_SIZE - fsm->segment_size;
1495 }
1496
1497 data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1498 data_size);
1499 if (IS_ERR(data)) {
1500 request->errno = PTR_ERR(data);
1501 fsm->state = ec_fsm_coe_error;
1502 return;
1503 }
1504
1505 EC_WRITE_U16(data, 0x2 << 12); // SDO request
1506 EC_WRITE_U8(data + 2, (last_segment ? 1 : 0)
1507 | (seg_data_size << 1)
1508 | (fsm->toggle << 4)
1509 | (0x00 << 5)); // Download segment request
1510 memcpy(data + EC_COE_DOWN_SEG_REQ_HEADER_SIZE,
1511 request->data + fsm->offset, fsm->segment_size);
1513 memset(data + EC_COE_DOWN_SEG_REQ_HEADER_SIZE + fsm->segment_size,
1515 }
1516
1517 if (slave->master->debug_level) {
1518 EC_SLAVE_DBG(slave, 1, "Download segment request:\n");
1519 ec_print_data(data, data_size);
1520 }
1521
1523}
1524
1525/*****************************************************************************/
1526
1533 ec_fsm_coe_t *fsm,
1534 ec_datagram_t *datagram
1535 )
1536{
1537 ec_slave_t *slave = fsm->slave;
1538 uint8_t *data, mbox_prot;
1539 size_t rec_size;
1540 ec_sdo_request_t *request = fsm->request;
1541
1542 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1543 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1544 return;
1545 }
1546
1547 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1548 request->errno = EIO;
1549 fsm->state = ec_fsm_coe_error;
1550 EC_SLAVE_ERR(slave, "Failed to receive CoE download"
1551 " response datagram: ");
1553 return;
1554 }
1555
1556 if (fsm->datagram->working_counter != 1) {
1557 request->errno = EIO;
1558 fsm->state = ec_fsm_coe_error;
1559 EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
1561 return;
1562 }
1563
1564 data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
1565 if (IS_ERR(data)) {
1566 request->errno = PTR_ERR(data);
1567 fsm->state = ec_fsm_coe_error;
1568 return;
1569 }
1570
1571 if (mbox_prot != EC_MBOX_TYPE_COE) {
1572 request->errno = EIO;
1573 fsm->state = ec_fsm_coe_error;
1574 EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
1575 mbox_prot);
1576 return;
1577 }
1578
1579 if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
1580 // check for CoE response again
1581 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1582 fsm->retries = EC_FSM_RETRIES;
1584 return;
1585 }
1586
1587 if (slave->master->debug_level) {
1588 EC_SLAVE_DBG(slave, 1, "Download response:\n");
1589 ec_print_data(data, rec_size);
1590 }
1591
1592 if (rec_size < 6) {
1593 request->errno = EIO;
1594 fsm->state = ec_fsm_coe_error;
1595 EC_SLAVE_ERR(slave, "Received data are too small (%zu bytes):\n",
1596 rec_size);
1597 ec_print_data(data, rec_size);
1598 return;
1599 }
1600
1601 if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
1602 EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
1603 char subidxstr[10];
1604 request->errno = EIO;
1605 fsm->state = ec_fsm_coe_error;
1606 if (request->complete_access) {
1607 subidxstr[0] = 0x00;
1608 } else {
1609 sprintf(subidxstr, ":%02X", request->subindex);
1610 }
1611 EC_SLAVE_ERR(slave, "SDO download 0x%04X%s (%zu bytes) aborted.\n",
1612 request->index, subidxstr, request->data_size);
1613 if (rec_size < 10) {
1614 EC_SLAVE_ERR(slave, "Incomplete abort command:\n");
1615 ec_print_data(data, rec_size);
1616 } else {
1617 fsm->request->abort_code = EC_READ_U32(data + 6);
1619 }
1620 return;
1621 }
1622
1623 if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
1624 EC_READ_U8 (data + 2) >> 5 != 0x3 || // Download response
1625 EC_READ_U16(data + 3) != request->index || // index
1626 EC_READ_U8 (data + 5) != request->subindex) { // subindex
1627 if (slave->master->debug_level) {
1628 EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!"
1629 " Retrying...\n");
1630 ec_print_data(data, rec_size);
1631 }
1632 // check for CoE response again
1633 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1634 fsm->retries = EC_FSM_RETRIES;
1636 return;
1637 }
1638
1639 if (fsm->remaining) { // more segments to download
1640 fsm->toggle = 0;
1642 } else {
1643 fsm->state = ec_fsm_coe_end; // success
1644 }
1645}
1646
1647/*****************************************************************************/
1648
1654 ec_fsm_coe_t *fsm,
1655 ec_datagram_t *datagram
1656 )
1657{
1658 ec_slave_t *slave = fsm->slave;
1659
1660 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
1661 return;
1662
1663 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1664 fsm->request->errno = EIO;
1665 fsm->state = ec_fsm_coe_error;
1666 EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
1668 return;
1669 }
1670
1671 if (fsm->datagram->working_counter != 1) {
1672 fsm->request->errno = EIO;
1673 fsm->state = ec_fsm_coe_error;
1674 EC_SLAVE_ERR(slave, "Reception of CoE mailbox segment check"
1675 " datagram failed: ");
1677 return;
1678 }
1679
1680 if (!ec_slave_mbox_check(fsm->datagram)) {
1681 unsigned long diff_ms =
1682 (fsm->datagram->jiffies_received - fsm->jiffies_start) *
1683 1000 / HZ;
1684 if (diff_ms >= fsm->request->response_timeout) {
1685 fsm->request->errno = EIO;
1686 fsm->state = ec_fsm_coe_error;
1687 EC_SLAVE_ERR(slave, "Timeout while waiting for SDO download"
1688 " segment response.\n");
1689 return;
1690 }
1691
1692 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1693 fsm->retries = EC_FSM_RETRIES;
1694 return;
1695 }
1696
1697 // Fetch response
1698 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1699 fsm->retries = EC_FSM_RETRIES;
1701}
1702
1703/*****************************************************************************/
1704
1711 ec_fsm_coe_t *fsm,
1712 ec_datagram_t *datagram
1713 )
1714{
1715 ec_slave_t *slave = fsm->slave;
1716 uint8_t *data, mbox_prot;
1717 size_t rec_size;
1718 ec_sdo_request_t *request = fsm->request;
1719
1720 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1721 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1722 return;
1723 }
1724
1725 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1726 request->errno = EIO;
1727 fsm->state = ec_fsm_coe_error;
1728 EC_SLAVE_ERR(slave, "Failed to receive CoE download response"
1729 " datagram: ");
1731 return;
1732 }
1733
1734 if (fsm->datagram->working_counter != 1) {
1735 request->errno = EIO;
1736 fsm->state = ec_fsm_coe_error;
1737 EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
1739 return;
1740 }
1741
1742 data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
1743 if (IS_ERR(data)) {
1744 request->errno = PTR_ERR(data);
1745 fsm->state = ec_fsm_coe_error;
1746 return;
1747 }
1748
1749 if (mbox_prot != EC_MBOX_TYPE_COE) {
1750 request->errno = EIO;
1751 fsm->state = ec_fsm_coe_error;
1752 EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
1753 mbox_prot);
1754 return;
1755 }
1756
1757 if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
1758 // check for CoE response again
1759 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1760 fsm->retries = EC_FSM_RETRIES;
1762 return;
1763 }
1764
1765 if (slave->master->debug_level) {
1766 EC_SLAVE_DBG(slave, 1, "Download response:\n");
1767 ec_print_data(data, rec_size);
1768 }
1769
1770 if (rec_size < 6) {
1771 request->errno = EIO;
1772 fsm->state = ec_fsm_coe_error;
1773 EC_SLAVE_ERR(slave, "Received data are too small (%zu bytes):\n",
1774 rec_size);
1775 ec_print_data(data, rec_size);
1776 return;
1777 }
1778
1779 if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
1780 EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
1781 char subidxstr[10];
1782 request->errno = EIO;
1783 fsm->state = ec_fsm_coe_error;
1784 if (request->complete_access) {
1785 subidxstr[0] = 0x00;
1786 } else {
1787 sprintf(subidxstr, ":%02X", request->subindex);
1788 }
1789 EC_SLAVE_ERR(slave, "SDO download 0x%04X%s (%zu bytes) aborted.\n",
1790 request->index, subidxstr, request->data_size);
1791 if (rec_size < 10) {
1792 EC_SLAVE_ERR(slave, "Incomplete abort command:\n");
1793 ec_print_data(data, rec_size);
1794 } else {
1795 fsm->request->abort_code = EC_READ_U32(data + 6);
1797 }
1798 return;
1799 }
1800
1801 if (EC_READ_U16(data) >> 12 != 0x3 ||
1802 ((EC_READ_U8(data + 2) >> 5) != 0x01)) { // segment response
1803 if (slave->master->debug_level) {
1804 EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!"
1805 " Retrying...\n");
1806 ec_print_data(data, rec_size);
1807 }
1808 // check for CoE response again
1809 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1810 fsm->retries = EC_FSM_RETRIES;
1812 return;
1813 }
1814
1815 if (((EC_READ_U8(data + 2) >> 4) & 0x01) != fsm->toggle) {
1816 EC_SLAVE_ERR(slave, "Invalid toggle received during"
1817 " segmented download:\n");
1818 ec_print_data(data, rec_size);
1819 request->errno = EIO;
1820 fsm->state = ec_fsm_coe_error;
1821 return;
1822 }
1823
1824 fsm->offset += fsm->segment_size;
1825 fsm->remaining -= fsm->segment_size;
1826
1827 if (fsm->remaining) { // more segments to download
1828 fsm->toggle = !fsm->toggle;
1830 } else {
1831 fsm->state = ec_fsm_coe_end; // success
1832 }
1833}
1834
1835/*****************************************************************************/
1836
1842 ec_fsm_coe_t *fsm,
1843 ec_datagram_t *datagram
1844 )
1845{
1846 ec_slave_t *slave = fsm->slave;
1847 ec_sdo_request_t *request = fsm->request;
1848 ec_master_t *master = slave->master;
1849
1850 u8 *data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1851 10);
1852 if (IS_ERR(data)) {
1853 request->errno = PTR_ERR(data);
1854 return PTR_ERR(data);
1855 }
1856
1857 EC_WRITE_U16(data, 0x2 << 12); // SDO request
1858 EC_WRITE_U8 (data + 2, 0x2 << 5); // initiate upload request
1859 EC_WRITE_U16(data + 3, request->index);
1860 EC_WRITE_U8 (data + 5, request->subindex);
1861 memset(data + 6, 0x00, 4);
1862
1863 if (master->debug_level) {
1864 EC_SLAVE_DBG(slave, 1, "Upload request:\n");
1865 ec_print_data(data, 10);
1866 }
1867
1869 return 0;
1870}
1871
1872/*****************************************************************************/
1873
1879 ec_fsm_coe_t *fsm,
1880 ec_datagram_t *datagram
1881 )
1882{
1883 ec_slave_t *slave = fsm->slave;
1884 ec_sdo_request_t *request = fsm->request;
1885
1886 EC_SLAVE_DBG(slave, 1, "Uploading SDO 0x%04X:%02X.\n",
1887 request->index, request->subindex);
1888
1889 if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
1890 EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
1891 request->errno = EPROTONOSUPPORT;
1892 fsm->state = ec_fsm_coe_error;
1893 return;
1894 }
1895
1896 fsm->retries = EC_FSM_RETRIES;
1897 fsm->request->jiffies_sent = jiffies;
1898
1899 if (ec_fsm_coe_prepare_up(fsm, datagram)) {
1900 fsm->state = ec_fsm_coe_error;
1901 }
1902}
1903
1904/*****************************************************************************/
1911 ec_fsm_coe_t *fsm,
1912 ec_datagram_t *datagram
1913 )
1914{
1915 ec_slave_t *slave = fsm->slave;
1916 unsigned long diff_ms;
1917
1918 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1919 if (ec_fsm_coe_prepare_up(fsm, datagram)) {
1920 fsm->state = ec_fsm_coe_error;
1921 }
1922 return;
1923 }
1924
1925 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1926 fsm->request->errno = EIO;
1927 fsm->state = ec_fsm_coe_error;
1928 EC_SLAVE_ERR(slave, "Failed to receive CoE upload request: ");
1930 return;
1931 }
1932
1933 diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
1934
1935 if (fsm->datagram->working_counter != 1) {
1936 if (!fsm->datagram->working_counter) {
1937 if (diff_ms < fsm->request->response_timeout) {
1938#if DEBUG_RETRIES
1939 EC_SLAVE_DBG(slave, 1, "Slave did not respond to"
1940 " SDO upload request. Retrying after %lu ms...\n",
1941 diff_ms);
1942#endif
1943 // no response; send request datagram again
1944 if (ec_fsm_coe_prepare_up(fsm, datagram)) {
1945 fsm->state = ec_fsm_coe_error;
1946 }
1947 return;
1948 }
1949 }
1950 fsm->request->errno = EIO;
1951 fsm->state = ec_fsm_coe_error;
1952 EC_SLAVE_ERR(slave, "Reception of CoE upload request for"
1953 " SDO 0x%04x:%x failed with timeout after %lu ms: ",
1954 fsm->request->index, fsm->request->subindex, diff_ms);
1956 return;
1957 }
1958
1959#if DEBUG_LONG
1960 if (diff_ms > 200) {
1961 EC_SLAVE_WARN(slave, "SDO 0x%04x:%x upload took %lu ms.\n",
1962 fsm->request->index, fsm->request->subindex, diff_ms);
1963 }
1964#endif
1965
1966 fsm->jiffies_start = fsm->datagram->jiffies_sent;
1967
1968 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1969 fsm->retries = EC_FSM_RETRIES;
1971}
1972
1973/*****************************************************************************/
1974
1980 ec_fsm_coe_t *fsm,
1981 ec_datagram_t *datagram
1982 )
1983{
1984 ec_slave_t *slave = fsm->slave;
1985
1986 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1987 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1988 return;
1989 }
1990
1991 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1992 fsm->request->errno = EIO;
1993 fsm->state = ec_fsm_coe_error;
1994 EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
1996 return;
1997 }
1998
1999 if (fsm->datagram->working_counter != 1) {
2000 fsm->request->errno = EIO;
2001 fsm->state = ec_fsm_coe_error;
2002 EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
2003 " datagram failed: ");
2005 return;
2006 }
2007
2008 if (!ec_slave_mbox_check(fsm->datagram)) {
2009 unsigned long diff_ms =
2010 (fsm->datagram->jiffies_received - fsm->jiffies_start) *
2011 1000 / HZ;
2012 if (diff_ms >= fsm->request->response_timeout) {
2013 fsm->request->errno = EIO;
2014 fsm->state = ec_fsm_coe_error;
2015 EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting for"
2016 " SDO 0x%04x:%x upload response.\n", diff_ms,
2017 fsm->request->index, fsm->request->subindex);
2018 return;
2019 }
2020
2021 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2022 fsm->retries = EC_FSM_RETRIES;
2023 return;
2024 }
2025
2026 // Fetch response
2027 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2028 fsm->retries = EC_FSM_RETRIES;
2030}
2031
2032/*****************************************************************************/
2033
2037 ec_fsm_coe_t *fsm,
2038 ec_datagram_t *datagram
2039 )
2040{
2041 uint8_t *data =
2042 ec_slave_mbox_prepare_send(fsm->slave, datagram, EC_MBOX_TYPE_COE,
2043 10);
2044 if (IS_ERR(data)) {
2045 fsm->request->errno = PTR_ERR(data);
2046 fsm->state = ec_fsm_coe_error;
2047 return;
2048 }
2049
2050 EC_WRITE_U16(data, 0x2 << 12); // SDO request
2051 EC_WRITE_U8 (data + 2, (fsm->toggle << 4 // toggle
2052 | 0x3 << 5)); // upload segment request
2053 memset(data + 3, 0x00, 7);
2054
2055 if (fsm->slave->master->debug_level) {
2056 EC_SLAVE_DBG(fsm->slave, 1, "Upload segment request:\n");
2057 ec_print_data(data, 10);
2058 }
2059}
2060
2061/*****************************************************************************/
2062
2069 ec_fsm_coe_t *fsm,
2070 ec_datagram_t *datagram
2071 )
2072{
2073 ec_slave_t *slave = fsm->slave;
2074 ec_master_t *master = slave->master;
2075 uint16_t rec_index;
2076 uint8_t *data, mbox_prot, rec_subindex;
2077 size_t rec_size, data_size;
2078 ec_sdo_request_t *request = fsm->request;
2079 unsigned int expedited, size_specified;
2080 int ret;
2081
2082 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2083 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2084 return;
2085 }
2086
2087 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2088 request->errno = EIO;
2089 fsm->state = ec_fsm_coe_error;
2090 EC_SLAVE_ERR(slave, "Failed to receive CoE upload response"
2091 " datagram: ");
2093 return;
2094 }
2095
2096 if (fsm->datagram->working_counter != 1) {
2097 request->errno = EIO;
2098 fsm->state = ec_fsm_coe_error;
2099 EC_SLAVE_ERR(slave, "Reception of CoE upload response failed: ");
2101 return;
2102 }
2103
2104 data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
2105 if (IS_ERR(data)) {
2106 request->errno = PTR_ERR(data);
2107 fsm->state = ec_fsm_coe_error;
2108 return;
2109 }
2110
2111 if (master->debug_level) {
2112 EC_SLAVE_DBG(slave, 1, "Upload response:\n");
2113 ec_print_data(data, rec_size);
2114 }
2115
2116 if (mbox_prot != EC_MBOX_TYPE_COE) {
2117 request->errno = EIO;
2118 fsm->state = ec_fsm_coe_error;
2119 EC_SLAVE_WARN(slave, "Received mailbox protocol 0x%02X"
2120 " as response.\n", mbox_prot);
2121 return;
2122 }
2123
2124 if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
2125 // check for CoE response again
2126 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2127 fsm->retries = EC_FSM_RETRIES;
2129 return;
2130 }
2131
2132 if (rec_size < 6) {
2133 request->errno = EIO;
2134 fsm->state = ec_fsm_coe_error;
2135 EC_SLAVE_ERR(slave, "Received currupted SDO upload response"
2136 " (%zu bytes)!\n", rec_size);
2137 ec_print_data(data, rec_size);
2138 return;
2139 }
2140
2141 if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
2142 EC_READ_U8(data + 2) >> 5 == 0x4) { // abort SDO transfer request
2143 EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X aborted.\n",
2144 request->index, request->subindex);
2145 if (rec_size >= 10) {
2146 request->abort_code = EC_READ_U32(data + 6);
2147 ec_canopen_abort_msg(slave, request->abort_code);
2148 } else {
2149 EC_SLAVE_ERR(slave, "No abort message.\n");
2150 }
2151 request->errno = EIO;
2152 fsm->state = ec_fsm_coe_error;
2153 return;
2154 }
2155
2156 if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
2157 EC_READ_U8(data + 2) >> 5 != 0x2) { // upload response
2158 EC_SLAVE_ERR(slave, "Received unknown response while"
2159 " uploading SDO 0x%04X:%02X.\n",
2160 request->index, request->subindex);
2161 ec_print_data(data, rec_size);
2162 request->errno = EIO;
2163 fsm->state = ec_fsm_coe_error;
2164 return;
2165 }
2166
2167 rec_index = EC_READ_U16(data + 3);
2168 rec_subindex = EC_READ_U8(data + 5);
2169
2170 if (rec_index != request->index || rec_subindex != request->subindex) {
2171 EC_SLAVE_ERR(slave, "Received upload response for wrong SDO"
2172 " (0x%04X:%02X, requested: 0x%04X:%02X).\n",
2173 rec_index, rec_subindex, request->index, request->subindex);
2174 ec_print_data(data, rec_size);
2175
2176 // check for CoE response again
2177 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2178 fsm->retries = EC_FSM_RETRIES;
2180 return;
2181 }
2182
2183 // normal or expedited?
2184 expedited = EC_READ_U8(data + 2) & 0x02;
2185
2186 if (expedited) {
2187 size_specified = EC_READ_U8(data + 2) & 0x01;
2188 if (size_specified) {
2189 fsm->complete_size = 4 - ((EC_READ_U8(data + 2) & 0x0C) >> 2);
2190 } else {
2191 fsm->complete_size = 4;
2192 }
2193
2194 if (rec_size < 6 + fsm->complete_size) {
2195 request->errno = EIO;
2196 fsm->state = ec_fsm_coe_error;
2197 EC_SLAVE_ERR(slave, "Received corrupted SDO expedited upload"
2198 " response (only %zu bytes)!\n", rec_size);
2199 ec_print_data(data, rec_size);
2200 return;
2201 }
2202
2203 ret = ec_sdo_request_copy_data(request, data + 6, fsm->complete_size);
2204 if (ret) {
2205 request->errno = -ret;
2206 fsm->state = ec_fsm_coe_error;
2207 return;
2208 }
2209 } else { // normal
2210 if (rec_size < 10) {
2211 request->errno = EIO;
2212 fsm->state = ec_fsm_coe_error;
2213 EC_SLAVE_ERR(slave, "Received currupted SDO normal upload"
2214 " response (only %zu bytes)!\n", rec_size);
2215 ec_print_data(data, rec_size);
2216 return;
2217 }
2218
2219 data_size = rec_size - 10;
2220 fsm->complete_size = EC_READ_U32(data + 6);
2221
2222 if (!fsm->complete_size) {
2223 request->errno = EIO;
2224 fsm->state = ec_fsm_coe_error;
2225 EC_SLAVE_ERR(slave, "No complete size supplied!\n");
2226 ec_print_data(data, rec_size);
2227 return;
2228 }
2229
2230 ret = ec_sdo_request_alloc(request, fsm->complete_size);
2231 if (ret) {
2232 request->errno = -ret;
2233 fsm->state = ec_fsm_coe_error;
2234 return;
2235 }
2236
2237 ret = ec_sdo_request_copy_data(request, data + 10, data_size);
2238 if (ret) {
2239 request->errno = -ret;
2240 fsm->state = ec_fsm_coe_error;
2241 return;
2242 }
2243
2244 fsm->toggle = 0;
2245
2246 if (data_size < fsm->complete_size) {
2247 EC_SLAVE_DBG(slave, 1, "SDO data incomplete (%zu / %u)."
2248 " Segmenting...\n", data_size, fsm->complete_size);
2250 fsm->retries = EC_FSM_RETRIES;
2252 return;
2253 }
2254 }
2255
2256 if (master->debug_level) {
2257 EC_SLAVE_DBG(slave, 1, "Uploaded data:\n");
2258 ec_print_data(request->data, request->data_size);
2259 }
2260
2261 fsm->state = ec_fsm_coe_end; // success
2262}
2263
2264/*****************************************************************************/
2265
2272 ec_fsm_coe_t *fsm,
2273 ec_datagram_t *datagram
2274 )
2275{
2276 ec_slave_t *slave = fsm->slave;
2277
2278 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2280 return;
2281 }
2282
2283 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2284 fsm->request->errno = EIO;
2285 fsm->state = ec_fsm_coe_error;
2286 EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
2287 " request datagram: ");
2289 return;
2290 }
2291
2292 if (fsm->datagram->working_counter != 1) {
2293 fsm->request->errno = EIO;
2294 fsm->state = ec_fsm_coe_error;
2295 EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
2296 " request failed: ");
2298 return;
2299 }
2300
2301 fsm->jiffies_start = fsm->datagram->jiffies_sent;
2302
2303 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2304 fsm->retries = EC_FSM_RETRIES;
2306}
2307
2308/*****************************************************************************/
2309
2315 ec_fsm_coe_t *fsm,
2316 ec_datagram_t *datagram
2317 )
2318{
2319 ec_slave_t *slave = fsm->slave;
2320
2321 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2322 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2323 return;
2324 }
2325
2326 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2327 fsm->request->errno = EIO;
2328 fsm->state = ec_fsm_coe_error;
2329 EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
2330 " datagram: ");
2332 return;
2333 }
2334
2335 if (fsm->datagram->working_counter != 1) {
2336 fsm->request->errno = EIO;
2337 fsm->state = ec_fsm_coe_error;
2338 EC_SLAVE_ERR(slave, "Reception of CoE mailbox check datagram"
2339 " failed: ");
2341 return;
2342 }
2343
2344 if (!ec_slave_mbox_check(fsm->datagram)) {
2345 unsigned long diff_ms =
2346 (fsm->datagram->jiffies_received - fsm->jiffies_start) *
2347 1000 / HZ;
2348 if (diff_ms >= fsm->request->response_timeout) {
2349 fsm->request->errno = EIO;
2350 fsm->state = ec_fsm_coe_error;
2351 EC_SLAVE_ERR(slave, "Timeout while waiting for SDO upload"
2352 " segment response.\n");
2353 return;
2354 }
2355
2356 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2357 fsm->retries = EC_FSM_RETRIES;
2358 return;
2359 }
2360
2361 // Fetch response
2362 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2363 fsm->retries = EC_FSM_RETRIES;
2365}
2366
2367/*****************************************************************************/
2368
2375 ec_fsm_coe_t *fsm,
2376 ec_datagram_t *datagram
2377 )
2378{
2379 ec_slave_t *slave = fsm->slave;
2380 ec_master_t *master = slave->master;
2381 uint8_t *data, mbox_prot;
2382 size_t rec_size, data_size;
2383 ec_sdo_request_t *request = fsm->request;
2384 unsigned int last_segment;
2385
2386 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2387 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2388 return;
2389 }
2390
2391 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2392 request->errno = EIO;
2393 fsm->state = ec_fsm_coe_error;
2394 EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
2395 " response datagram: ");
2397 return;
2398 }
2399
2400 if (fsm->datagram->working_counter != 1) {
2401 request->errno = EIO;
2402 fsm->state = ec_fsm_coe_error;
2403 EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
2404 " response failed: ");
2406 return;
2407 }
2408
2409 data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
2410 if (IS_ERR(data)) {
2411 request->errno = PTR_ERR(data);
2412 fsm->state = ec_fsm_coe_error;
2413 return;
2414 }
2415
2416 if (master->debug_level) {
2417 EC_SLAVE_DBG(slave, 1, "Upload segment response:\n");
2418 ec_print_data(data, rec_size);
2419 }
2420
2421 if (mbox_prot != EC_MBOX_TYPE_COE) {
2422 EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
2423 mbox_prot);
2424 request->errno = EIO;
2425 fsm->state = ec_fsm_coe_error;
2426 return;
2427 }
2428
2429 if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
2430 // check for CoE response again
2431 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2432 fsm->retries = EC_FSM_RETRIES;
2434 return;
2435 }
2436
2437 if (rec_size < 10) {
2438 EC_SLAVE_ERR(slave, "Received currupted SDO upload"
2439 " segment response!\n");
2440 ec_print_data(data, rec_size);
2441 request->errno = EIO;
2442 fsm->state = ec_fsm_coe_error;
2443 return;
2444 }
2445
2446 if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
2447 EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
2448 EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X aborted.\n",
2449 request->index, request->subindex);
2450 request->abort_code = EC_READ_U32(data + 6);
2451 ec_canopen_abort_msg(slave, request->abort_code);
2452 request->errno = EIO;
2453 fsm->state = ec_fsm_coe_error;
2454 return;
2455 }
2456
2457 if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
2458 EC_READ_U8 (data + 2) >> 5 != 0x0) { // upload segment response
2459 if (fsm->slave->master->debug_level) {
2460 EC_SLAVE_DBG(slave, 1, "Invalid SDO upload segment response!\n");
2461 ec_print_data(data, rec_size);
2462 }
2463 // check for CoE response again
2464 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2465 fsm->retries = EC_FSM_RETRIES;
2467 return;
2468 }
2469
2470 data_size = rec_size - 3; /* Header of segment upload is smaller than
2471 normal upload */
2472 if (rec_size == 10) {
2473 uint8_t seg_size = (EC_READ_U8(data + 2) & 0xE) >> 1;
2474 data_size -= seg_size;
2475 }
2476
2477 if (request->data_size + data_size > fsm->complete_size) {
2478 EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X failed: Fragment"
2479 " exceeding complete size!\n",
2480 request->index, request->subindex);
2481 request->errno = EOVERFLOW;
2482 fsm->state = ec_fsm_coe_error;
2483 return;
2484 }
2485
2486 memcpy(request->data + request->data_size, data + 3, data_size);
2487 request->data_size += data_size;
2488
2489 last_segment = EC_READ_U8(data + 2) & 0x01;
2490 if (!last_segment) {
2491 fsm->toggle = !fsm->toggle;
2493 fsm->retries = EC_FSM_RETRIES;
2495 return;
2496 }
2497
2498 if (request->data_size != fsm->complete_size) {
2499 EC_SLAVE_WARN(slave, "SDO upload 0x%04X:%02X: Assembled data"
2500 " size (%zu) does not match complete size (%u)!\n",
2501 request->index, request->subindex,
2502 request->data_size, fsm->complete_size);
2503 }
2504
2505 if (master->debug_level) {
2506 EC_SLAVE_DBG(slave, 1, "Uploaded data:\n");
2507 ec_print_data(request->data, request->data_size);
2508 }
2509
2510 fsm->state = ec_fsm_coe_end; // success
2511}
2512
2513/*****************************************************************************/
2514
2520 ec_fsm_coe_t *fsm,
2521 ec_datagram_t *datagram
2522 )
2523{
2524}
2525
2526/*****************************************************************************/
2527
2533 ec_fsm_coe_t *fsm,
2534 ec_datagram_t *datagram
2535 )
2536{
2537}
2538
2539/*****************************************************************************/
void ec_coe_emerg_ring_push(ec_coe_emerg_ring_t *ring, const u8 *msg)
Add a new emergency message.
void ec_datagram_print_wc_error(const ec_datagram_t *datagram)
Evaluates the working counter of a single-cast datagram.
Definition: datagram.c:602
void ec_datagram_print_state(const ec_datagram_t *datagram)
Prints the state of a datagram.
Definition: datagram.c:565
@ EC_DATAGRAM_INIT
Initial state of a new datagram.
Definition: datagram.h:75
@ EC_DATAGRAM_RECEIVED
Received (dequeued).
Definition: datagram.h:78
@ EC_DATAGRAM_TIMED_OUT
Timed out (dequeued).
Definition: datagram.h:79
@ EC_DATAGRAM_SENT
Sent (still in the queue).
Definition: datagram.h:77
@ EC_DATAGRAM_QUEUED
Queued for sending.
Definition: datagram.h:76
int ec_fsm_coe_prepare_dict(ec_fsm_coe_t *fsm, ec_datagram_t *datagram)
Prepare a dictionary request.
Definition: fsm_coe.c:315
int ec_fsm_coe_prepare_up(ec_fsm_coe_t *fsm, ec_datagram_t *datagram)
Prepare an upload request.
Definition: fsm_coe.c:1841
void ec_fsm_coe_dict_entry_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT ENTRY CHECK.
Definition: fsm_coe.c:959
const ec_code_msg_t sdo_abort_messages[]
SDO abort messages.
Definition: fsm_coe.c:107
#define EC_COE_DOWN_REQ_HEADER_SIZE
CoE download request header size.
Definition: fsm_coe.c:50
void ec_fsm_coe_up_start(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP START.
Definition: fsm_coe.c:1878
#define EC_COE_DOWN_SEG_MIN_DATA_SIZE
Minimum size of download segment.
Definition: fsm_coe.c:58
void ec_fsm_coe_dict_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT CHECK.
Definition: fsm_coe.c:413
void ec_fsm_coe_dict_desc_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT DESC CHECK.
Definition: fsm_coe.c:695
void ec_fsm_coe_dictionary(ec_fsm_coe_t *fsm, ec_slave_t *slave)
Starts reading a slaves' SDO dictionary.
Definition: fsm_coe.c:192
void ec_fsm_coe_up_seg_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP CHECK.
Definition: fsm_coe.c:2314
void ec_fsm_coe_dict_desc_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT DESC REQUEST.
Definition: fsm_coe.c:652
void ec_fsm_coe_down_prepare_segment_request(ec_fsm_coe_t *fsm, ec_datagram_t *datagram)
Prepare a download segment request.
Definition: fsm_coe.c:1466
int ec_fsm_coe_dict_prepare_desc(ec_fsm_coe_t *fsm, ec_datagram_t *datagram)
Prepare an object description request.
Definition: fsm_coe.c:468
#define EC_COE_DOWN_SEG_REQ_HEADER_SIZE
CoE download segment request header size.
Definition: fsm_coe.c:54
int ec_fsm_coe_dict_prepare_entry(ec_fsm_coe_t *fsm, ec_datagram_t *datagram)
Prepare an entry description request.
Definition: fsm_coe.c:751
void ec_fsm_coe_up_prepare_segment_request(ec_fsm_coe_t *fsm, ec_datagram_t *datagram)
Prepare an SDO upload segment request.
Definition: fsm_coe.c:2036
void ec_fsm_coe_down_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN RESPONSE.
Definition: fsm_coe.c:1532
void ec_fsm_coe_dict_start(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT START.
Definition: fsm_coe.c:341
void ec_fsm_coe_down_start(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN START.
Definition: fsm_coe.c:1289
void ec_fsm_coe_down_seg_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN SEG RESPONSE.
Definition: fsm_coe.c:1710
void ec_fsm_coe_error(ec_fsm_coe_t *, ec_datagram_t *)
State: ERROR.
Definition: fsm_coe.c:2519
int ec_fsm_coe_success(const ec_fsm_coe_t *fsm)
Returns, if the state machine terminated with success.
Definition: fsm_coe.c:262
void ec_fsm_coe_transfer(ec_fsm_coe_t *fsm, ec_slave_t *slave, ec_sdo_request_t *request)
Starts to transfer an SDO to/from a slave.
Definition: fsm_coe.c:205
void ec_fsm_coe_down_seg_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN SEG CHECK.
Definition: fsm_coe.c:1653
void ec_fsm_coe_down_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN REQUEST.
Definition: fsm_coe.c:1340
void ec_canopen_abort_msg(const ec_slave_t *slave, uint32_t abort_code)
Outputs an SDO abort message.
Definition: fsm_coe.c:148
void ec_fsm_coe_end(ec_fsm_coe_t *, ec_datagram_t *)
State: END.
Definition: fsm_coe.c:2532
void ec_fsm_coe_dict_entry_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT ENTRY REQUEST.
Definition: fsm_coe.c:917
int ec_fsm_coe_check_emergency(ec_fsm_coe_t *fsm, const uint8_t *data, size_t size)
Check if the received data are a CoE emergency request.
Definition: fsm_coe.c:277
void ec_fsm_coe_up_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP CHECK.
Definition: fsm_coe.c:1979
#define EC_FSM_COE_DICT_TIMEOUT
Maximum time in ms to wait for responses when reading out the dictionary.
Definition: fsm_coe.c:46
void ec_fsm_coe_dict_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT REQUEST.
Definition: fsm_coe.c:373
void ec_fsm_coe_init(ec_fsm_coe_t *fsm)
Constructor.
Definition: fsm_coe.c:170
void ec_fsm_coe_dict_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT RESPONSE.
Definition: fsm_coe.c:497
int ec_fsm_coe_prepare_down_start(ec_fsm_coe_t *fsm, ec_datagram_t *datagram)
Prepare a donwnload request.
Definition: fsm_coe.c:1195
void ec_fsm_coe_down_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN CHECK.
Definition: fsm_coe.c:1408
void ec_fsm_coe_dict_desc_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT DESC RESPONSE.
Definition: fsm_coe.c:782
void ec_fsm_coe_up_seg_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP REQUEST.
Definition: fsm_coe.c:2271
void ec_fsm_coe_up_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP REQUEST.
Definition: fsm_coe.c:1910
int ec_fsm_coe_exec(ec_fsm_coe_t *fsm, ec_datagram_t *datagram)
Executes the current state of the state machine.
Definition: fsm_coe.c:228
void ec_fsm_coe_clear(ec_fsm_coe_t *fsm)
Destructor.
Definition: fsm_coe.c:182
void ec_fsm_coe_dict_entry_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT ENTRY RESPONSE.
Definition: fsm_coe.c:1016
void ec_fsm_coe_up_seg_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP RESPONSE.
Definition: fsm_coe.c:2374
void ec_fsm_coe_up_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP RESPONSE.
Definition: fsm_coe.c:2068
EtherCAT CoE state machines.
Global definitions and macros.
#define EC_MBOX_HEADER_SIZE
Mailbox header size.
Definition: globals.h:83
#define EC_FSM_RETRIES
Number of state machine retries on datagram timeout.
Definition: globals.h:47
@ EC_SDO_ENTRY_ACCESS_PREOP
Access rights in PREOP.
Definition: globals.h:181
@ EC_SDO_ENTRY_ACCESS_OP
Access rights in OP.
Definition: globals.h:183
@ EC_SDO_ENTRY_ACCESS_SAFEOP
Access rights in SAFEOP.
Definition: globals.h:182
@ EC_MBOX_COE
CANopen over EtherCAT.
Definition: globals.h:137
void ec_print_data(const uint8_t *, size_t)
Outputs frame contents for debugging purposes.
Definition: module.c:344
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2265
#define EC_WRITE_U32(DATA, VAL)
Write a 32-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2299
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2177
#define EC_READ_U8(DATA)
Read an 8-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2161
#define EC_READ_U32(DATA)
Read a 32-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2193
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2282
@ EC_DIR_OUTPUT
Values written by the master.
Definition: ecrt.h:432
uint8_t * ec_slave_mbox_fetch(const ec_slave_t *slave, const ec_datagram_t *datagram, uint8_t *type, size_t *size)
Processes received mailbox data.
Definition: mailbox.c:165
int ec_slave_mbox_prepare_check(const ec_slave_t *slave, ec_datagram_t *datagram)
Prepares a datagram for checking the mailbox state.
Definition: mailbox.c:96
int ec_slave_mbox_prepare_fetch(const ec_slave_t *slave, ec_datagram_t *datagram)
Prepares a datagram to fetch mailbox data.
Definition: mailbox.c:127
uint8_t * ec_slave_mbox_prepare_send(const ec_slave_t *slave, ec_datagram_t *datagram, uint8_t type, size_t size)
Prepares a mailbox-send datagram.
Definition: mailbox.c:51
int ec_slave_mbox_check(const ec_datagram_t *datagram)
Processes a mailbox state checking datagram.
Definition: mailbox.c:115
Mailbox functionality.
EtherCAT master structure.
void ec_sdo_init(ec_sdo_t *sdo, ec_slave_t *slave, uint16_t index)
Constructor.
Definition: sdo.c:47
void ec_sdo_entry_init(ec_sdo_entry_t *entry, ec_sdo_t *sdo, uint8_t subindex)
Constructor.
Definition: sdo_entry.c:45
int ec_sdo_request_alloc(ec_sdo_request_t *req, size_t size)
Pre-allocates the data memory.
Definition: sdo_request.c:127
int ec_sdo_request_copy_data(ec_sdo_request_t *req, const uint8_t *source, size_t size)
Copies SDO data from an external source.
Definition: sdo_request.c:156
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition: slave.h:106
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition: slave.h:76
#define EC_SLAVE_WARN(slave, fmt, args...)
Convenience macro for printing slave-specific warnings to syslog.
Definition: slave.h:90
EtherCAT slave configuration structure.
Code/Message pair.
Definition: globals.h:266
uint32_t code
Code.
Definition: globals.h:267
const char * message
Message belonging to code.
Definition: globals.h:268
EtherCAT datagram.
Definition: datagram.h:87
uint16_t working_counter
Working counter.
Definition: datagram.h:99
unsigned long jiffies_received
Jiffies, when the datagram was received.
Definition: datagram.h:108
unsigned long jiffies_sent
Jiffies, when the datagram was sent.
Definition: datagram.h:104
ec_datagram_state_t state
State.
Definition: datagram.h:100
Finite state machines for the CANopen over EtherCAT protocol.
Definition: fsm_coe.h:52
ec_sdo_request_t * request
SDO request.
Definition: fsm_coe.h:61
ec_sdo_t * sdo
current SDO
Definition: fsm_coe.h:59
ec_datagram_t * datagram
Datagram used in last step.
Definition: fsm_coe.h:57
void(* state)(ec_fsm_coe_t *, ec_datagram_t *)
CoE state function.
Definition: fsm_coe.h:56
ec_slave_t * slave
slave the FSM runs on
Definition: fsm_coe.h:53
uint32_t remaining
Remaining bytes during segmented download.
Definition: fsm_coe.h:65
uint8_t subindex
current subindex
Definition: fsm_coe.h:60
uint32_t complete_size
Used when segmenting.
Definition: fsm_coe.h:62
uint8_t toggle
toggle bit for segment commands
Definition: fsm_coe.h:63
unsigned long jiffies_start
CoE timestamp.
Definition: fsm_coe.h:58
size_t segment_size
Current segment size.
Definition: fsm_coe.h:66
uint32_t offset
Data offset during segmented download.
Definition: fsm_coe.h:64
unsigned int retries
retries upon datagram timeout
Definition: fsm_coe.h:54
EtherCAT master.
Definition: master.h:194
unsigned int debug_level
Master debug level.
Definition: master.h:285
CANopen SDO entry.
Definition: sdo_entry.h:54
uint8_t write_access[EC_SDO_ENTRY_ACCESS_COUNT]
Write access.
Definition: sdo_entry.h:61
struct list_head list
List item.
Definition: sdo_entry.h:55
uint8_t read_access[EC_SDO_ENTRY_ACCESS_COUNT]
Read access.
Definition: sdo_entry.h:60
char * description
Description.
Definition: sdo_entry.h:62
uint16_t bit_length
Data size in bit.
Definition: sdo_entry.h:59
uint16_t data_type
Data type.
Definition: sdo_entry.h:58
CANopen SDO request.
Definition: sdo_request.h:48
uint32_t response_timeout
Maximum time in ms, the transfer is retried, if the slave does not respond.
Definition: sdo_request.h:58
int errno
Error number.
Definition: sdo_request.h:67
uint8_t complete_access
SDO shall be transferred completely.
Definition: sdo_request.h:55
size_t data_size
Size of SDO data.
Definition: sdo_request.h:54
uint8_t * data
Pointer to SDO data.
Definition: sdo_request.h:52
uint32_t abort_code
SDO request abort code.
Definition: sdo_request.h:68
ec_direction_t dir
Direction.
Definition: sdo_request.h:60
unsigned long jiffies_sent
Jiffies, when the upload/download request was sent.
Definition: sdo_request.h:65
uint16_t index
SDO index.
Definition: sdo_request.h:50
uint8_t subindex
SDO subindex.
Definition: sdo_request.h:51
CANopen SDO.
Definition: sdo.h:49
uint16_t index
SDO index.
Definition: sdo.h:52
struct list_head list
List item.
Definition: sdo.h:50
char * name
SDO name.
Definition: sdo.h:54
struct list_head entries
List of entries.
Definition: sdo.h:56
uint8_t object_code
Object code.
Definition: sdo.h:53
uint8_t max_subindex
Maximum subindex.
Definition: sdo.h:55
uint8_t enable_sdo_info
SDO information service available.
Definition: globals.h:147
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:147
ec_sii_coe_details_t coe_details
CoE detail flags.
Definition: slave.h:160
unsigned int has_general
General category present.
Definition: slave.h:154
EtherCAT slave configuration.
Definition: slave_config.h:119
ec_coe_emerg_ring_t emerg_ring
CoE emergency ring buffer.
Definition: slave_config.h:151
EtherCAT slave.
Definition: slave.h:177
uint16_t configured_rx_mailbox_size
Configured receive mailbox size.
Definition: slave.h:197
ec_sii_t sii
Extracted SII data.
Definition: slave.h:223
struct list_head sdo_dictionary
SDO dictionary list.
Definition: slave.h:225
ec_slave_config_t * config
Current configuration.
Definition: slave.h:190
ec_master_t * master
Master owning the slave.
Definition: slave.h:178