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 > 0 && request->data_size <= 4) {
1206 // use expedited transfer mode for lengths between 1 and 4 bytes
1207 data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1209 if (IS_ERR(data)) {
1210 request->errno = PTR_ERR(data);
1211 return PTR_ERR(data);
1212 }
1213
1214 fsm->remaining = 0;
1215
1216 data_set_size = 4 - request->data_size;
1217
1218 EC_WRITE_U16(data, 0x2 << 12); // SDO request
1219 EC_WRITE_U8 (data + 2, (0x3 // size specified, expedited
1220 | data_set_size << 2
1221 | ((request->complete_access ? 1 : 0) << 4)
1222 | 0x1 << 5)); // Download request
1223 EC_WRITE_U16(data + 3, request->index);
1224 EC_WRITE_U8 (data + 5,
1225 request->complete_access ? 0x00 : request->subindex);
1226 memcpy(data + 6, request->data, request->data_size);
1227 memset(data + 6 + request->data_size, 0x00, 4 - request->data_size);
1228
1229 if (slave->master->debug_level) {
1230 EC_SLAVE_DBG(slave, 1, "Expedited download request:\n");
1232 }
1233 }
1234 else { // data_size < 1 or data_size > 4, use normal transfer type
1235 size_t data_size,
1236 max_data_size =
1238 required_data_size =
1240
1241 if (max_data_size < required_data_size) {
1242 // segmenting needed
1243 data_size = max_data_size;
1244 } else {
1245 data_size = required_data_size;
1246 }
1247
1248 data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1249 data_size);
1250 if (IS_ERR(data)) {
1251 request->errno = PTR_ERR(data);
1252 return PTR_ERR(data);
1253 }
1254
1255 fsm->offset = 0;
1256 fsm->remaining = request->data_size;
1257
1258 EC_WRITE_U16(data, 0x2 << 12); // SDO request
1259 EC_WRITE_U8(data + 2,
1260 0x1 // size indicator, normal
1261 | ((request->complete_access ? 1 : 0) << 4)
1262 | 0x1 << 5); // Download request
1263 EC_WRITE_U16(data + 3, request->index);
1264 EC_WRITE_U8 (data + 5,
1265 request->complete_access ? 0x00 : request->subindex);
1266 EC_WRITE_U32(data + 6, request->data_size);
1267
1268 if (data_size > EC_COE_DOWN_REQ_HEADER_SIZE) {
1269 size_t segment_size = data_size - EC_COE_DOWN_REQ_HEADER_SIZE;
1270 memcpy(data + EC_COE_DOWN_REQ_HEADER_SIZE,
1271 request->data, segment_size);
1272 fsm->offset += segment_size;
1273 fsm->remaining -= segment_size;
1274 }
1275
1276 if (slave->master->debug_level) {
1277 EC_SLAVE_DBG(slave, 1, "Normal download request:\n");
1278 ec_print_data(data, data_size);
1279 }
1280 }
1281
1283 return 0;
1284}
1285
1286/****************************************************************************/
1287
1291 ec_fsm_coe_t *fsm,
1292 ec_datagram_t *datagram
1293 )
1294{
1295 ec_slave_t *slave = fsm->slave;
1296 ec_sdo_request_t *request = fsm->request;
1297
1298 if (fsm->slave->master->debug_level) {
1299 char subidxstr[10];
1300 if (request->complete_access) {
1301 subidxstr[0] = 0x00;
1302 } else {
1303 sprintf(subidxstr, ":%02X", request->subindex);
1304 }
1305 EC_SLAVE_DBG(slave, 1, "Downloading SDO 0x%04X%s.\n",
1306 request->index, subidxstr);
1307 ec_print_data(request->data, request->data_size);
1308 }
1309
1310 if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
1311 EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
1312 request->errno = EPROTONOSUPPORT;
1313 fsm->state = ec_fsm_coe_error;
1314 return;
1315 }
1316
1317 if (slave->configured_rx_mailbox_size <
1319 EC_SLAVE_ERR(slave, "Mailbox too small!\n");
1320 request->errno = EOVERFLOW;
1321 fsm->state = ec_fsm_coe_error;
1322 return;
1323 }
1324
1325
1326 fsm->request->jiffies_sent = jiffies;
1327 fsm->retries = EC_FSM_RETRIES;
1328
1329 if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1330 fsm->state = ec_fsm_coe_error;
1331 }
1332}
1333
1334/*****************************************************************************/
1335
1342 ec_fsm_coe_t *fsm,
1343 ec_datagram_t *datagram
1344 )
1345{
1346 ec_slave_t *slave = fsm->slave;
1347 unsigned long diff_ms;
1348
1349 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1350 if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1351 fsm->state = ec_fsm_coe_error;
1352 }
1353 return;
1354 }
1355
1356 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1357 fsm->request->errno = EIO;
1358 fsm->state = ec_fsm_coe_error;
1359 EC_SLAVE_ERR(slave, "Failed to receive CoE download"
1360 " request datagram: ");
1362 return;
1363 }
1364
1365 diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
1366
1367 if (fsm->datagram->working_counter != 1) {
1368 if (!fsm->datagram->working_counter) {
1369 if (diff_ms < fsm->request->response_timeout) {
1370#if DEBUG_RETRIES
1371 EC_SLAVE_DBG(slave, 1, "Slave did not respond to SDO"
1372 " download request. Retrying after %lu ms...\n",
1373 diff_ms);
1374#endif
1375 // no response; send request datagram again
1376 if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1377 fsm->state = ec_fsm_coe_error;
1378 }
1379 return;
1380 }
1381 }
1382 fsm->request->errno = EIO;
1383 fsm->state = ec_fsm_coe_error;
1384 EC_SLAVE_ERR(slave, "Reception of CoE download request"
1385 " for SDO 0x%04x:%x failed with timeout after %lu ms: ",
1386 fsm->request->index, fsm->request->subindex, diff_ms);
1388 return;
1389 }
1390
1391#if DEBUG_LONG
1392 if (diff_ms > 200) {
1393 EC_SLAVE_WARN(slave, "SDO 0x%04x:%x download took %lu ms.\n",
1394 fsm->request->index, fsm->request->subindex, diff_ms);
1395 }
1396#endif
1397
1398 fsm->jiffies_start = fsm->datagram->jiffies_sent;
1399
1400 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1401 fsm->retries = EC_FSM_RETRIES;
1403}
1404
1405/*****************************************************************************/
1406
1410 ec_fsm_coe_t *fsm,
1411 ec_datagram_t *datagram
1412 )
1413{
1414 ec_slave_t *slave = fsm->slave;
1415
1416 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1417 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1418 return;
1419 }
1420
1421 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1422 fsm->request->errno = EIO;
1423 fsm->state = ec_fsm_coe_error;
1424 EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
1425 " datagram: ");
1427 return;
1428 }
1429
1430 if (fsm->datagram->working_counter != 1) {
1431 fsm->request->errno = EIO;
1432 fsm->state = ec_fsm_coe_error;
1433 EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
1434 " datagram failed: ");
1436 return;
1437 }
1438
1439 if (!ec_slave_mbox_check(fsm->datagram)) {
1440 unsigned long diff_ms =
1441 (fsm->datagram->jiffies_received - fsm->jiffies_start) *
1442 1000 / HZ;
1443 if (diff_ms >= fsm->request->response_timeout) {
1444 fsm->request->errno = EIO;
1445 fsm->state = ec_fsm_coe_error;
1446 EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting"
1447 " for SDO 0x%04x:%x download response.\n", diff_ms,
1448 fsm->request->index, fsm->request->subindex);
1449 return;
1450 }
1451
1452 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1453 fsm->retries = EC_FSM_RETRIES;
1454 return;
1455 }
1456
1457 // Fetch response
1458 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1459 fsm->retries = EC_FSM_RETRIES;
1461}
1462
1463/*****************************************************************************/
1464
1468 ec_fsm_coe_t *fsm,
1469 ec_datagram_t *datagram
1470 )
1471{
1472 ec_slave_t *slave = fsm->slave;
1473 ec_sdo_request_t *request = fsm->request;
1474 size_t max_segment_size =
1478 size_t data_size;
1479 uint8_t last_segment, seg_data_size, *data;
1480
1481 if (fsm->remaining > max_segment_size) {
1482 fsm->segment_size = max_segment_size;
1483 last_segment = 0;
1484 } else {
1485 fsm->segment_size = fsm->remaining;
1486 last_segment = 1;
1487 }
1488
1490 seg_data_size = 0x00;
1492 } else {
1493 seg_data_size = EC_COE_DOWN_SEG_MIN_DATA_SIZE - fsm->segment_size;
1496 }
1497
1498 data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1499 data_size);
1500 if (IS_ERR(data)) {
1501 request->errno = PTR_ERR(data);
1502 fsm->state = ec_fsm_coe_error;
1503 return;
1504 }
1505
1506 EC_WRITE_U16(data, 0x2 << 12); // SDO request
1507 EC_WRITE_U8(data + 2, (last_segment ? 1 : 0)
1508 | (seg_data_size << 1)
1509 | (fsm->toggle << 4)
1510 | (0x00 << 5)); // Download segment request
1511 memcpy(data + EC_COE_DOWN_SEG_REQ_HEADER_SIZE,
1512 request->data + fsm->offset, fsm->segment_size);
1514 memset(data + EC_COE_DOWN_SEG_REQ_HEADER_SIZE + fsm->segment_size,
1516 }
1517
1518 if (slave->master->debug_level) {
1519 EC_SLAVE_DBG(slave, 1, "Download segment request:\n");
1520 ec_print_data(data, data_size);
1521 }
1522
1524}
1525
1526/*****************************************************************************/
1527
1534 ec_fsm_coe_t *fsm,
1535 ec_datagram_t *datagram
1536 )
1537{
1538 ec_slave_t *slave = fsm->slave;
1539 uint8_t *data, mbox_prot;
1540 size_t rec_size;
1541 ec_sdo_request_t *request = fsm->request;
1542
1543 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1544 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1545 return;
1546 }
1547
1548 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1549 request->errno = EIO;
1550 fsm->state = ec_fsm_coe_error;
1551 EC_SLAVE_ERR(slave, "Failed to receive CoE download"
1552 " response datagram: ");
1554 return;
1555 }
1556
1557 if (fsm->datagram->working_counter != 1) {
1558 request->errno = EIO;
1559 fsm->state = ec_fsm_coe_error;
1560 EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
1562 return;
1563 }
1564
1565 data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
1566 if (IS_ERR(data)) {
1567 request->errno = PTR_ERR(data);
1568 fsm->state = ec_fsm_coe_error;
1569 return;
1570 }
1571
1572 if (mbox_prot != EC_MBOX_TYPE_COE) {
1573 request->errno = EIO;
1574 fsm->state = ec_fsm_coe_error;
1575 EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
1576 mbox_prot);
1577 return;
1578 }
1579
1580 if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
1581 // check for CoE response again
1582 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1583 fsm->retries = EC_FSM_RETRIES;
1585 return;
1586 }
1587
1588 if (slave->master->debug_level) {
1589 EC_SLAVE_DBG(slave, 1, "Download response:\n");
1590 ec_print_data(data, rec_size);
1591 }
1592
1593 if (rec_size < 6) {
1594 request->errno = EIO;
1595 fsm->state = ec_fsm_coe_error;
1596 EC_SLAVE_ERR(slave, "Received data are too small (%zu bytes):\n",
1597 rec_size);
1598 ec_print_data(data, rec_size);
1599 return;
1600 }
1601
1602 if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
1603 EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
1604 char subidxstr[10];
1605 request->errno = EIO;
1606 fsm->state = ec_fsm_coe_error;
1607 if (request->complete_access) {
1608 subidxstr[0] = 0x00;
1609 } else {
1610 sprintf(subidxstr, ":%02X", request->subindex);
1611 }
1612 EC_SLAVE_ERR(slave, "SDO download 0x%04X%s (%zu bytes) aborted.\n",
1613 request->index, subidxstr, request->data_size);
1614 if (rec_size < 10) {
1615 EC_SLAVE_ERR(slave, "Incomplete abort command:\n");
1616 ec_print_data(data, rec_size);
1617 } else {
1618 fsm->request->abort_code = EC_READ_U32(data + 6);
1620 }
1621 return;
1622 }
1623
1624 if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
1625 EC_READ_U8 (data + 2) >> 5 != 0x3 || // Download response
1626 EC_READ_U16(data + 3) != request->index || // index
1627 EC_READ_U8 (data + 5) != request->subindex) { // subindex
1628 if (slave->master->debug_level) {
1629 EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!"
1630 " Retrying...\n");
1631 ec_print_data(data, rec_size);
1632 }
1633 // check for CoE response again
1634 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1635 fsm->retries = EC_FSM_RETRIES;
1637 return;
1638 }
1639
1640 if (fsm->remaining) { // more segments to download
1641 fsm->toggle = 0;
1643 } else {
1644 fsm->state = ec_fsm_coe_end; // success
1645 }
1646}
1647
1648/*****************************************************************************/
1649
1655 ec_fsm_coe_t *fsm,
1656 ec_datagram_t *datagram
1657 )
1658{
1659 ec_slave_t *slave = fsm->slave;
1660
1661 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
1662 return;
1663
1664 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1665 fsm->request->errno = EIO;
1666 fsm->state = ec_fsm_coe_error;
1667 EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
1669 return;
1670 }
1671
1672 if (fsm->datagram->working_counter != 1) {
1673 fsm->request->errno = EIO;
1674 fsm->state = ec_fsm_coe_error;
1675 EC_SLAVE_ERR(slave, "Reception of CoE mailbox segment check"
1676 " datagram failed: ");
1678 return;
1679 }
1680
1681 if (!ec_slave_mbox_check(fsm->datagram)) {
1682 unsigned long diff_ms =
1683 (fsm->datagram->jiffies_received - fsm->jiffies_start) *
1684 1000 / HZ;
1685 if (diff_ms >= fsm->request->response_timeout) {
1686 fsm->request->errno = EIO;
1687 fsm->state = ec_fsm_coe_error;
1688 EC_SLAVE_ERR(slave, "Timeout while waiting for SDO download"
1689 " segment response.\n");
1690 return;
1691 }
1692
1693 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1694 fsm->retries = EC_FSM_RETRIES;
1695 return;
1696 }
1697
1698 // Fetch response
1699 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1700 fsm->retries = EC_FSM_RETRIES;
1702}
1703
1704/*****************************************************************************/
1705
1712 ec_fsm_coe_t *fsm,
1713 ec_datagram_t *datagram
1714 )
1715{
1716 ec_slave_t *slave = fsm->slave;
1717 uint8_t *data, mbox_prot;
1718 size_t rec_size;
1719 ec_sdo_request_t *request = fsm->request;
1720
1721 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1722 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1723 return;
1724 }
1725
1726 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1727 request->errno = EIO;
1728 fsm->state = ec_fsm_coe_error;
1729 EC_SLAVE_ERR(slave, "Failed to receive CoE download response"
1730 " datagram: ");
1732 return;
1733 }
1734
1735 if (fsm->datagram->working_counter != 1) {
1736 request->errno = EIO;
1737 fsm->state = ec_fsm_coe_error;
1738 EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
1740 return;
1741 }
1742
1743 data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
1744 if (IS_ERR(data)) {
1745 request->errno = PTR_ERR(data);
1746 fsm->state = ec_fsm_coe_error;
1747 return;
1748 }
1749
1750 if (mbox_prot != EC_MBOX_TYPE_COE) {
1751 request->errno = EIO;
1752 fsm->state = ec_fsm_coe_error;
1753 EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
1754 mbox_prot);
1755 return;
1756 }
1757
1758 if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
1759 // check for CoE response again
1760 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1761 fsm->retries = EC_FSM_RETRIES;
1763 return;
1764 }
1765
1766 if (slave->master->debug_level) {
1767 EC_SLAVE_DBG(slave, 1, "Download response:\n");
1768 ec_print_data(data, rec_size);
1769 }
1770
1771 if (rec_size < 6) {
1772 request->errno = EIO;
1773 fsm->state = ec_fsm_coe_error;
1774 EC_SLAVE_ERR(slave, "Received data are too small (%zu bytes):\n",
1775 rec_size);
1776 ec_print_data(data, rec_size);
1777 return;
1778 }
1779
1780 if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
1781 EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
1782 char subidxstr[10];
1783 request->errno = EIO;
1784 fsm->state = ec_fsm_coe_error;
1785 if (request->complete_access) {
1786 subidxstr[0] = 0x00;
1787 } else {
1788 sprintf(subidxstr, ":%02X", request->subindex);
1789 }
1790 EC_SLAVE_ERR(slave, "SDO download 0x%04X%s (%zu bytes) aborted.\n",
1791 request->index, subidxstr, request->data_size);
1792 if (rec_size < 10) {
1793 EC_SLAVE_ERR(slave, "Incomplete abort command:\n");
1794 ec_print_data(data, rec_size);
1795 } else {
1796 fsm->request->abort_code = EC_READ_U32(data + 6);
1798 }
1799 return;
1800 }
1801
1802 if (EC_READ_U16(data) >> 12 != 0x3 ||
1803 ((EC_READ_U8(data + 2) >> 5) != 0x01)) { // segment response
1804 if (slave->master->debug_level) {
1805 EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!"
1806 " Retrying...\n");
1807 ec_print_data(data, rec_size);
1808 }
1809 // check for CoE response again
1810 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1811 fsm->retries = EC_FSM_RETRIES;
1813 return;
1814 }
1815
1816 if (((EC_READ_U8(data + 2) >> 4) & 0x01) != fsm->toggle) {
1817 EC_SLAVE_ERR(slave, "Invalid toggle received during"
1818 " segmented download:\n");
1819 ec_print_data(data, rec_size);
1820 request->errno = EIO;
1821 fsm->state = ec_fsm_coe_error;
1822 return;
1823 }
1824
1825 fsm->offset += fsm->segment_size;
1826 fsm->remaining -= fsm->segment_size;
1827
1828 if (fsm->remaining) { // more segments to download
1829 fsm->toggle = !fsm->toggle;
1831 } else {
1832 fsm->state = ec_fsm_coe_end; // success
1833 }
1834}
1835
1836/*****************************************************************************/
1837
1843 ec_fsm_coe_t *fsm,
1844 ec_datagram_t *datagram
1845 )
1846{
1847 ec_slave_t *slave = fsm->slave;
1848 ec_sdo_request_t *request = fsm->request;
1849 ec_master_t *master = slave->master;
1850
1851 u8 *data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1852 10);
1853 if (IS_ERR(data)) {
1854 request->errno = PTR_ERR(data);
1855 return PTR_ERR(data);
1856 }
1857
1858 EC_WRITE_U16(data, 0x2 << 12); // SDO request
1859 EC_WRITE_U8 (data + 2, 0x2 << 5); // initiate upload request
1860 EC_WRITE_U16(data + 3, request->index);
1861 EC_WRITE_U8 (data + 5, request->subindex);
1862 memset(data + 6, 0x00, 4);
1863
1864 if (master->debug_level) {
1865 EC_SLAVE_DBG(slave, 1, "Upload request:\n");
1866 ec_print_data(data, 10);
1867 }
1868
1870 return 0;
1871}
1872
1873/*****************************************************************************/
1874
1880 ec_fsm_coe_t *fsm,
1881 ec_datagram_t *datagram
1882 )
1883{
1884 ec_slave_t *slave = fsm->slave;
1885 ec_sdo_request_t *request = fsm->request;
1886
1887 EC_SLAVE_DBG(slave, 1, "Uploading SDO 0x%04X:%02X.\n",
1888 request->index, request->subindex);
1889
1890 if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
1891 EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
1892 request->errno = EPROTONOSUPPORT;
1893 fsm->state = ec_fsm_coe_error;
1894 return;
1895 }
1896
1897 fsm->retries = EC_FSM_RETRIES;
1898 fsm->request->jiffies_sent = jiffies;
1899
1900 if (ec_fsm_coe_prepare_up(fsm, datagram)) {
1901 fsm->state = ec_fsm_coe_error;
1902 }
1903}
1904
1905/*****************************************************************************/
1912 ec_fsm_coe_t *fsm,
1913 ec_datagram_t *datagram
1914 )
1915{
1916 ec_slave_t *slave = fsm->slave;
1917 unsigned long diff_ms;
1918
1919 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1920 if (ec_fsm_coe_prepare_up(fsm, datagram)) {
1921 fsm->state = ec_fsm_coe_error;
1922 }
1923 return;
1924 }
1925
1926 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1927 fsm->request->errno = EIO;
1928 fsm->state = ec_fsm_coe_error;
1929 EC_SLAVE_ERR(slave, "Failed to receive CoE upload request: ");
1931 return;
1932 }
1933
1934 diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
1935
1936 if (fsm->datagram->working_counter != 1) {
1937 if (!fsm->datagram->working_counter) {
1938 if (diff_ms < fsm->request->response_timeout) {
1939#if DEBUG_RETRIES
1940 EC_SLAVE_DBG(slave, 1, "Slave did not respond to"
1941 " SDO upload request. Retrying after %lu ms...\n",
1942 diff_ms);
1943#endif
1944 // no response; send request datagram again
1945 if (ec_fsm_coe_prepare_up(fsm, datagram)) {
1946 fsm->state = ec_fsm_coe_error;
1947 }
1948 return;
1949 }
1950 }
1951 fsm->request->errno = EIO;
1952 fsm->state = ec_fsm_coe_error;
1953 EC_SLAVE_ERR(slave, "Reception of CoE upload request for"
1954 " SDO 0x%04x:%x failed with timeout after %lu ms: ",
1955 fsm->request->index, fsm->request->subindex, diff_ms);
1957 return;
1958 }
1959
1960#if DEBUG_LONG
1961 if (diff_ms > 200) {
1962 EC_SLAVE_WARN(slave, "SDO 0x%04x:%x upload took %lu ms.\n",
1963 fsm->request->index, fsm->request->subindex, diff_ms);
1964 }
1965#endif
1966
1967 fsm->jiffies_start = fsm->datagram->jiffies_sent;
1968
1969 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1970 fsm->retries = EC_FSM_RETRIES;
1972}
1973
1974/*****************************************************************************/
1975
1981 ec_fsm_coe_t *fsm,
1982 ec_datagram_t *datagram
1983 )
1984{
1985 ec_slave_t *slave = fsm->slave;
1986
1987 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1988 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1989 return;
1990 }
1991
1992 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1993 fsm->request->errno = EIO;
1994 fsm->state = ec_fsm_coe_error;
1995 EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
1997 return;
1998 }
1999
2000 if (fsm->datagram->working_counter != 1) {
2001 fsm->request->errno = EIO;
2002 fsm->state = ec_fsm_coe_error;
2003 EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
2004 " datagram failed: ");
2006 return;
2007 }
2008
2009 if (!ec_slave_mbox_check(fsm->datagram)) {
2010 unsigned long diff_ms =
2011 (fsm->datagram->jiffies_received - fsm->jiffies_start) *
2012 1000 / HZ;
2013 if (diff_ms >= fsm->request->response_timeout) {
2014 fsm->request->errno = EIO;
2015 fsm->state = ec_fsm_coe_error;
2016 EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting for"
2017 " SDO 0x%04x:%x upload response.\n", diff_ms,
2018 fsm->request->index, fsm->request->subindex);
2019 return;
2020 }
2021
2022 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2023 fsm->retries = EC_FSM_RETRIES;
2024 return;
2025 }
2026
2027 // Fetch response
2028 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2029 fsm->retries = EC_FSM_RETRIES;
2031}
2032
2033/*****************************************************************************/
2034
2038 ec_fsm_coe_t *fsm,
2039 ec_datagram_t *datagram
2040 )
2041{
2042 uint8_t *data =
2043 ec_slave_mbox_prepare_send(fsm->slave, datagram, EC_MBOX_TYPE_COE,
2044 10);
2045 if (IS_ERR(data)) {
2046 fsm->request->errno = PTR_ERR(data);
2047 fsm->state = ec_fsm_coe_error;
2048 return;
2049 }
2050
2051 EC_WRITE_U16(data, 0x2 << 12); // SDO request
2052 EC_WRITE_U8 (data + 2, (fsm->toggle << 4 // toggle
2053 | 0x3 << 5)); // upload segment request
2054 memset(data + 3, 0x00, 7);
2055
2056 if (fsm->slave->master->debug_level) {
2057 EC_SLAVE_DBG(fsm->slave, 1, "Upload segment request:\n");
2058 ec_print_data(data, 10);
2059 }
2060}
2061
2062/*****************************************************************************/
2063
2070 ec_fsm_coe_t *fsm,
2071 ec_datagram_t *datagram
2072 )
2073{
2074 ec_slave_t *slave = fsm->slave;
2075 ec_master_t *master = slave->master;
2076 uint16_t rec_index;
2077 uint8_t *data, mbox_prot, rec_subindex;
2078 size_t rec_size, data_size;
2079 ec_sdo_request_t *request = fsm->request;
2080 unsigned int expedited, size_specified;
2081 int ret;
2082
2083 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2084 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2085 return;
2086 }
2087
2088 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2089 request->errno = EIO;
2090 fsm->state = ec_fsm_coe_error;
2091 EC_SLAVE_ERR(slave, "Failed to receive CoE upload response"
2092 " datagram: ");
2094 return;
2095 }
2096
2097 if (fsm->datagram->working_counter != 1) {
2098 request->errno = EIO;
2099 fsm->state = ec_fsm_coe_error;
2100 EC_SLAVE_ERR(slave, "Reception of CoE upload response failed: ");
2102 return;
2103 }
2104
2105 data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
2106 if (IS_ERR(data)) {
2107 request->errno = PTR_ERR(data);
2108 fsm->state = ec_fsm_coe_error;
2109 return;
2110 }
2111
2112 if (master->debug_level) {
2113 EC_SLAVE_DBG(slave, 1, "Upload response:\n");
2114 ec_print_data(data, rec_size);
2115 }
2116
2117 if (mbox_prot != EC_MBOX_TYPE_COE) {
2118 request->errno = EIO;
2119 fsm->state = ec_fsm_coe_error;
2120 EC_SLAVE_WARN(slave, "Received mailbox protocol 0x%02X"
2121 " as response.\n", mbox_prot);
2122 return;
2123 }
2124
2125 if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
2126 // check for CoE response again
2127 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2128 fsm->retries = EC_FSM_RETRIES;
2130 return;
2131 }
2132
2133 if (rec_size < 6) {
2134 request->errno = EIO;
2135 fsm->state = ec_fsm_coe_error;
2136 EC_SLAVE_ERR(slave, "Received currupted SDO upload response"
2137 " (%zu bytes)!\n", rec_size);
2138 ec_print_data(data, rec_size);
2139 return;
2140 }
2141
2142 if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
2143 EC_READ_U8(data + 2) >> 5 == 0x4) { // abort SDO transfer request
2144 EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X aborted.\n",
2145 request->index, request->subindex);
2146 if (rec_size >= 10) {
2147 request->abort_code = EC_READ_U32(data + 6);
2148 ec_canopen_abort_msg(slave, request->abort_code);
2149 } else {
2150 EC_SLAVE_ERR(slave, "No abort message.\n");
2151 }
2152 request->errno = EIO;
2153 fsm->state = ec_fsm_coe_error;
2154 return;
2155 }
2156
2157 if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
2158 EC_READ_U8(data + 2) >> 5 != 0x2) { // upload response
2159 EC_SLAVE_ERR(slave, "Received unknown response while"
2160 " uploading SDO 0x%04X:%02X.\n",
2161 request->index, request->subindex);
2162 ec_print_data(data, rec_size);
2163 request->errno = EIO;
2164 fsm->state = ec_fsm_coe_error;
2165 return;
2166 }
2167
2168 rec_index = EC_READ_U16(data + 3);
2169 rec_subindex = EC_READ_U8(data + 5);
2170
2171 if (rec_index != request->index || rec_subindex != request->subindex) {
2172 EC_SLAVE_ERR(slave, "Received upload response for wrong SDO"
2173 " (0x%04X:%02X, requested: 0x%04X:%02X).\n",
2174 rec_index, rec_subindex, request->index, request->subindex);
2175 ec_print_data(data, rec_size);
2176
2177 // check for CoE response again
2178 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2179 fsm->retries = EC_FSM_RETRIES;
2181 return;
2182 }
2183
2184 // normal or expedited?
2185 expedited = EC_READ_U8(data + 2) & 0x02;
2186
2187 if (expedited) {
2188 size_specified = EC_READ_U8(data + 2) & 0x01;
2189 if (size_specified) {
2190 fsm->complete_size = 4 - ((EC_READ_U8(data + 2) & 0x0C) >> 2);
2191 } else {
2192 fsm->complete_size = 4;
2193 }
2194
2195 if (rec_size < 6 + fsm->complete_size) {
2196 request->errno = EIO;
2197 fsm->state = ec_fsm_coe_error;
2198 EC_SLAVE_ERR(slave, "Received corrupted SDO expedited upload"
2199 " response (only %zu bytes)!\n", rec_size);
2200 ec_print_data(data, rec_size);
2201 return;
2202 }
2203
2204 ret = ec_sdo_request_copy_data(request, data + 6, fsm->complete_size);
2205 if (ret) {
2206 request->errno = -ret;
2207 fsm->state = ec_fsm_coe_error;
2208 return;
2209 }
2210 } else { // normal
2211 if (rec_size < 10) {
2212 request->errno = EIO;
2213 fsm->state = ec_fsm_coe_error;
2214 EC_SLAVE_ERR(slave, "Received currupted SDO normal upload"
2215 " response (only %zu bytes)!\n", rec_size);
2216 ec_print_data(data, rec_size);
2217 return;
2218 }
2219
2220 data_size = rec_size - 10;
2221 fsm->complete_size = EC_READ_U32(data + 6);
2222
2223 ret = ec_sdo_request_alloc(request, fsm->complete_size);
2224 if (ret) {
2225 request->errno = -ret;
2226 fsm->state = ec_fsm_coe_error;
2227 return;
2228 }
2229
2230 ret = ec_sdo_request_copy_data(request, data + 10, data_size);
2231 if (ret) {
2232 request->errno = -ret;
2233 fsm->state = ec_fsm_coe_error;
2234 return;
2235 }
2236
2237 fsm->toggle = 0;
2238
2239 if (data_size < fsm->complete_size) {
2240 EC_SLAVE_DBG(slave, 1, "SDO data incomplete (%zu / %u)."
2241 " Segmenting...\n", data_size, fsm->complete_size);
2243 fsm->retries = EC_FSM_RETRIES;
2245 return;
2246 }
2247 }
2248
2249 if (master->debug_level) {
2250 EC_SLAVE_DBG(slave, 1, "Uploaded data:\n");
2251 ec_print_data(request->data, request->data_size);
2252 }
2253
2254 fsm->state = ec_fsm_coe_end; // success
2255}
2256
2257/*****************************************************************************/
2258
2265 ec_fsm_coe_t *fsm,
2266 ec_datagram_t *datagram
2267 )
2268{
2269 ec_slave_t *slave = fsm->slave;
2270
2271 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2273 return;
2274 }
2275
2276 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2277 fsm->request->errno = EIO;
2278 fsm->state = ec_fsm_coe_error;
2279 EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
2280 " request datagram: ");
2282 return;
2283 }
2284
2285 if (fsm->datagram->working_counter != 1) {
2286 fsm->request->errno = EIO;
2287 fsm->state = ec_fsm_coe_error;
2288 EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
2289 " request failed: ");
2291 return;
2292 }
2293
2294 fsm->jiffies_start = fsm->datagram->jiffies_sent;
2295
2296 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2297 fsm->retries = EC_FSM_RETRIES;
2299}
2300
2301/*****************************************************************************/
2302
2308 ec_fsm_coe_t *fsm,
2309 ec_datagram_t *datagram
2310 )
2311{
2312 ec_slave_t *slave = fsm->slave;
2313
2314 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2315 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2316 return;
2317 }
2318
2319 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2320 fsm->request->errno = EIO;
2321 fsm->state = ec_fsm_coe_error;
2322 EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
2323 " datagram: ");
2325 return;
2326 }
2327
2328 if (fsm->datagram->working_counter != 1) {
2329 fsm->request->errno = EIO;
2330 fsm->state = ec_fsm_coe_error;
2331 EC_SLAVE_ERR(slave, "Reception of CoE mailbox check datagram"
2332 " failed: ");
2334 return;
2335 }
2336
2337 if (!ec_slave_mbox_check(fsm->datagram)) {
2338 unsigned long diff_ms =
2339 (fsm->datagram->jiffies_received - fsm->jiffies_start) *
2340 1000 / HZ;
2341 if (diff_ms >= fsm->request->response_timeout) {
2342 fsm->request->errno = EIO;
2343 fsm->state = ec_fsm_coe_error;
2344 EC_SLAVE_ERR(slave, "Timeout while waiting for SDO upload"
2345 " segment response.\n");
2346 return;
2347 }
2348
2349 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2350 fsm->retries = EC_FSM_RETRIES;
2351 return;
2352 }
2353
2354 // Fetch response
2355 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2356 fsm->retries = EC_FSM_RETRIES;
2358}
2359
2360/*****************************************************************************/
2361
2368 ec_fsm_coe_t *fsm,
2369 ec_datagram_t *datagram
2370 )
2371{
2372 ec_slave_t *slave = fsm->slave;
2373 ec_master_t *master = slave->master;
2374 uint8_t *data, mbox_prot;
2375 size_t rec_size, data_size;
2376 ec_sdo_request_t *request = fsm->request;
2377 unsigned int last_segment;
2378
2379 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2380 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2381 return;
2382 }
2383
2384 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2385 request->errno = EIO;
2386 fsm->state = ec_fsm_coe_error;
2387 EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
2388 " response datagram: ");
2390 return;
2391 }
2392
2393 if (fsm->datagram->working_counter != 1) {
2394 request->errno = EIO;
2395 fsm->state = ec_fsm_coe_error;
2396 EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
2397 " response failed: ");
2399 return;
2400 }
2401
2402 data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
2403 if (IS_ERR(data)) {
2404 request->errno = PTR_ERR(data);
2405 fsm->state = ec_fsm_coe_error;
2406 return;
2407 }
2408
2409 if (master->debug_level) {
2410 EC_SLAVE_DBG(slave, 1, "Upload segment response:\n");
2411 ec_print_data(data, rec_size);
2412 }
2413
2414 if (mbox_prot != EC_MBOX_TYPE_COE) {
2415 EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
2416 mbox_prot);
2417 request->errno = EIO;
2418 fsm->state = ec_fsm_coe_error;
2419 return;
2420 }
2421
2422 if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
2423 // check for CoE response again
2424 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2425 fsm->retries = EC_FSM_RETRIES;
2427 return;
2428 }
2429
2430 if (rec_size < 10) {
2431 EC_SLAVE_ERR(slave, "Received currupted SDO upload"
2432 " segment response!\n");
2433 ec_print_data(data, rec_size);
2434 request->errno = EIO;
2435 fsm->state = ec_fsm_coe_error;
2436 return;
2437 }
2438
2439 if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
2440 EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
2441 EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X aborted.\n",
2442 request->index, request->subindex);
2443 request->abort_code = EC_READ_U32(data + 6);
2444 ec_canopen_abort_msg(slave, request->abort_code);
2445 request->errno = EIO;
2446 fsm->state = ec_fsm_coe_error;
2447 return;
2448 }
2449
2450 if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
2451 EC_READ_U8 (data + 2) >> 5 != 0x0) { // upload segment response
2452 if (fsm->slave->master->debug_level) {
2453 EC_SLAVE_DBG(slave, 1, "Invalid SDO upload segment response!\n");
2454 ec_print_data(data, rec_size);
2455 }
2456 // check for CoE response again
2457 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2458 fsm->retries = EC_FSM_RETRIES;
2460 return;
2461 }
2462
2463 data_size = rec_size - 3; /* Header of segment upload is smaller than
2464 normal upload */
2465 if (rec_size == 10) {
2466 uint8_t seg_size = (EC_READ_U8(data + 2) & 0xE) >> 1;
2467 data_size -= seg_size;
2468 }
2469
2470 if (request->data_size + data_size > fsm->complete_size) {
2471 EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X failed: Fragment"
2472 " exceeding complete size!\n",
2473 request->index, request->subindex);
2474 request->errno = EOVERFLOW;
2475 fsm->state = ec_fsm_coe_error;
2476 return;
2477 }
2478
2479 memcpy(request->data + request->data_size, data + 3, data_size);
2480 request->data_size += data_size;
2481
2482 last_segment = EC_READ_U8(data + 2) & 0x01;
2483 if (!last_segment) {
2484 fsm->toggle = !fsm->toggle;
2486 fsm->retries = EC_FSM_RETRIES;
2488 return;
2489 }
2490
2491 if (request->data_size != fsm->complete_size) {
2492 EC_SLAVE_WARN(slave, "SDO upload 0x%04X:%02X: Assembled data"
2493 " size (%zu) does not match complete size (%u)!\n",
2494 request->index, request->subindex,
2495 request->data_size, fsm->complete_size);
2496 }
2497
2498 if (master->debug_level) {
2499 EC_SLAVE_DBG(slave, 1, "Uploaded data:\n");
2500 ec_print_data(request->data, request->data_size);
2501 }
2502
2503 fsm->state = ec_fsm_coe_end; // success
2504}
2505
2506/*****************************************************************************/
2507
2513 ec_fsm_coe_t *fsm,
2514 ec_datagram_t *datagram
2515 )
2516{
2517}
2518
2519/*****************************************************************************/
2520
2526 ec_fsm_coe_t *fsm,
2527 ec_datagram_t *datagram
2528 )
2529{
2530}
2531
2532/*****************************************************************************/
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:1842
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:1879
#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:2307
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:1467
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:2037
void ec_fsm_coe_down_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN RESPONSE.
Definition: fsm_coe.c:1533
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:1290
void ec_fsm_coe_down_seg_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN SEG RESPONSE.
Definition: fsm_coe.c:1711
void ec_fsm_coe_error(ec_fsm_coe_t *, ec_datagram_t *)
State: ERROR.
Definition: fsm_coe.c:2512
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:1654
void ec_fsm_coe_down_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN REQUEST.
Definition: fsm_coe.c:1341
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:2525
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:1980
#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:1409
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:2264
void ec_fsm_coe_up_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP REQUEST.
Definition: fsm_coe.c:1911
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:2367
void ec_fsm_coe_up_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP RESPONSE.
Definition: fsm_coe.c:2069
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:348
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2266
#define EC_WRITE_U32(DATA, VAL)
Write a 32-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2300
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2178
#define EC_READ_U8(DATA)
Read an 8-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2162
#define EC_READ_U32(DATA)
Read a 32-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2194
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2283
@ 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