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