IgH EtherCAT Master  1.5.2
fsm_soe.c
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Copyright (C) 2006-2020 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 *
22 * The license mentioned above concerns the source code only. Using the
23 * EtherCAT technology and brand is only permitted in compliance with the
24 * industrial property and similar rights of Beckhoff Automation GmbH.
25 *
26 *****************************************************************************/
27
33/*****************************************************************************/
34
35#include "globals.h"
36#include "master.h"
37#include "mailbox.h"
38#include "fsm_soe.h"
39
40/*****************************************************************************/
41
49};
50
53#define EC_SOE_SIZE 0x04
54
57#define EC_SOE_HEADER_SIZE (EC_MBOX_HEADER_SIZE + EC_SOE_SIZE)
58
61#define EC_SOE_RESPONSE_TIMEOUT 1000
62
63/*****************************************************************************/
64
69
74
77
78/*****************************************************************************/
79
80extern const ec_code_msg_t soe_error_codes[];
81
82/*****************************************************************************/
83
86void ec_print_soe_error(const ec_slave_t *slave, uint16_t error_code)
87{
88 const ec_code_msg_t *error_msg;
89
90 for (error_msg = soe_error_codes; error_msg->code; error_msg++) {
91 if (error_msg->code == error_code) {
92 EC_SLAVE_ERR(slave, "SoE error 0x%04X: \"%s\".\n",
93 error_msg->code, error_msg->message);
94 return;
95 }
96 }
97
98 EC_SLAVE_ERR(slave, "Unknown SoE error 0x%04X.\n", error_code);
99}
100
101/*****************************************************************************/
102
106 ec_fsm_soe_t *fsm
107 )
108{
109 fsm->state = NULL;
110 fsm->datagram = NULL;
111 fsm->fragment_size = 0;
112}
113
114/*****************************************************************************/
115
119 ec_fsm_soe_t *fsm
120 )
121{
122}
123
124/*****************************************************************************/
125
129 ec_fsm_soe_t *fsm,
130 ec_slave_t *slave,
131 ec_soe_request_t *request
132 )
133{
134 fsm->slave = slave;
135 fsm->request = request;
136
137 if (request->dir == EC_DIR_OUTPUT) {
139 } else {
141 }
142}
143
144/*****************************************************************************/
145
151 ec_fsm_soe_t *fsm,
152 ec_datagram_t *datagram
153 )
154{
155 int datagram_used = 0;
156
157 if (fsm->datagram &&
158 (fsm->datagram->state == EC_DATAGRAM_INIT ||
160 fsm->datagram->state == EC_DATAGRAM_SENT)) {
161 // datagram not received yet
162 return datagram_used;
163 }
164
165 fsm->state(fsm, datagram);
166
167 datagram_used =
168 fsm->state != ec_fsm_soe_end && fsm->state != ec_fsm_soe_error;
169
170 if (datagram_used) {
171 fsm->datagram = datagram;
172 } else {
173 fsm->datagram = NULL;
174 }
175
176 return datagram_used;
177}
178
179/*****************************************************************************/
180
186{
187 return fsm->state == ec_fsm_soe_end;
188}
189
190/*****************************************************************************/
191
195{
196 ec_soe_request_t *request = fsm->request;
197
198 EC_SLAVE_ERR(fsm->slave, "");
199
200 if (request->dir == EC_DIR_OUTPUT) {
201 printk(KERN_CONT "Writing");
202 } else {
203 printk(KERN_CONT "Reading");
204 }
205
206 printk(KERN_CONT " IDN 0x%04X failed.\n", request->idn);
207}
208
209/******************************************************************************
210 * SoE read state machine
211 *****************************************************************************/
212
218 ec_fsm_soe_t *fsm,
219 ec_datagram_t *datagram
220 )
221{
222 uint8_t *data;
223 ec_slave_t *slave = fsm->slave;
224 ec_master_t *master = slave->master;
225 ec_soe_request_t *request = fsm->request;
226
227 data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
229 if (IS_ERR(data)) {
230 return PTR_ERR(data);
231 }
232
233 EC_WRITE_U8(data, OPCODE_READ_REQUEST | (request->drive_no & 0x07) << 5);
234 EC_WRITE_U8(data + 1, 1 << 6); // request value
235 EC_WRITE_U16(data + 2, request->idn);
236
237 if (master->debug_level) {
238 EC_SLAVE_DBG(slave, 0, "SSC read request:\n");
240 }
241
242 fsm->request->jiffies_sent = jiffies;
244
245 return 0;
246}
247
248/*****************************************************************************/
249
253 ec_fsm_soe_t *fsm,
254 ec_datagram_t *datagram
255 )
256{
257 ec_slave_t *slave = fsm->slave;
258 ec_soe_request_t *request = fsm->request;
259
260 EC_SLAVE_DBG(slave, 1, "Reading IDN 0x%04X of drive %u.\n", request->idn,
261 request->drive_no);
262
263 if (!(slave->sii.mailbox_protocols & EC_MBOX_SOE)) {
264 EC_SLAVE_ERR(slave, "Slave does not support SoE!\n");
265 fsm->state = ec_fsm_soe_error;
267 return;
268 }
269
270 request->data_size = 0;
271 fsm->retries = EC_FSM_RETRIES;
272
273 if (ec_fsm_soe_prepare_read(fsm, datagram)) {
274 fsm->state = ec_fsm_soe_error;
276 }
277}
278
279/*****************************************************************************/
280
284 ec_fsm_soe_t *fsm,
285 ec_datagram_t *datagram
286 )
287{
288 ec_slave_t *slave = fsm->slave;
289 unsigned long diff_ms;
290
291 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
292 if (ec_fsm_soe_prepare_read(fsm, datagram)) {
293 fsm->state = ec_fsm_soe_error;
295 }
296 return;
297 }
298
299 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
300 fsm->state = ec_fsm_soe_error;
301 EC_SLAVE_ERR(slave, "Failed to receive SoE read request: ");
304 return;
305 }
306
307 diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
308
309 if (fsm->datagram->working_counter != 1) {
310 if (!fsm->datagram->working_counter) {
311 if (diff_ms < EC_SOE_RESPONSE_TIMEOUT) {
312 // no response; send request datagram again
313 if (ec_fsm_soe_prepare_read(fsm, datagram)) {
314 fsm->state = ec_fsm_soe_error;
316 }
317 return;
318 }
319 }
320 fsm->state = ec_fsm_soe_error;
321 EC_SLAVE_ERR(slave, "Reception of SoE read request"
322 " failed after %lu ms: ", diff_ms);
325 return;
326 }
327
329 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
330 fsm->retries = EC_FSM_RETRIES;
332}
333
334/*****************************************************************************/
335
339 ec_fsm_soe_t *fsm,
340 ec_datagram_t *datagram
341 )
342{
343 ec_slave_t *slave = fsm->slave;
344
345 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
346 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
347 return;
348 }
349
350 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
351 fsm->state = ec_fsm_soe_error;
352 EC_SLAVE_ERR(slave, "Failed to receive SoE mailbox check datagram: ");
355 return;
356 }
357
358 if (fsm->datagram->working_counter != 1) {
359 fsm->state = ec_fsm_soe_error;
360 EC_SLAVE_ERR(slave, "Reception of SoE mailbox check"
361 " datagram failed: ");
364 return;
365 }
366
367 if (!ec_slave_mbox_check(fsm->datagram)) {
368 unsigned long diff_ms =
370 1000 / HZ;
371 if (diff_ms >= EC_SOE_RESPONSE_TIMEOUT) {
372 fsm->state = ec_fsm_soe_error;
373 EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting for"
374 " read response.\n", diff_ms);
376 return;
377 }
378
379 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
380 fsm->retries = EC_FSM_RETRIES;
381 return;
382 }
383
384 // Fetch response
385 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
386 fsm->retries = EC_FSM_RETRIES;
388}
389
390/*****************************************************************************/
391
395 ec_fsm_soe_t *fsm,
396 ec_datagram_t *datagram
397 )
398{
399 ec_slave_t *slave = fsm->slave;
400 ec_master_t *master = slave->master;
401 uint8_t *data, mbox_prot, header, opcode, incomplete, error_flag,
402 value_included;
403 size_t rec_size, data_size;
404 ec_soe_request_t *req = fsm->request;
405
406 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
407 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
408 return;
409 }
410
411 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
412 fsm->state = ec_fsm_soe_error;
413 EC_SLAVE_ERR(slave, "Failed to receive SoE read response datagram: ");
416 return;
417 }
418
419 if (fsm->datagram->working_counter != 1) {
420 fsm->state = ec_fsm_soe_error;
421 EC_SLAVE_ERR(slave, "Reception of SoE read response failed: ");
424 return;
425 }
426
427 data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
428 if (IS_ERR(data)) {
429 fsm->state = ec_fsm_soe_error;
431 return;
432 }
433
434 if (master->debug_level) {
435 EC_SLAVE_DBG(slave, 0, "SSC read response:\n");
436 ec_print_data(data, rec_size);
437 }
438
439 if (mbox_prot != EC_MBOX_TYPE_SOE) {
440 fsm->state = ec_fsm_soe_error;
441 EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
442 mbox_prot);
444 return;
445 }
446
447 if (rec_size < EC_SOE_SIZE) {
448 fsm->state = ec_fsm_soe_error;
449 EC_SLAVE_ERR(slave, "Received currupted SoE read response"
450 " (%zu bytes)!\n", rec_size);
451 ec_print_data(data, rec_size);
453 return;
454 }
455
456 header = EC_READ_U8(data);
457 opcode = header & 0x7;
458 incomplete = (header >> 3) & 1;
459 error_flag = (header >> 4) & 1;
460
461 if (opcode != OPCODE_READ_RESPONSE) {
462 EC_SLAVE_ERR(slave, "Received no read response (opcode %x).\n",
463 opcode);
464 ec_print_data(data, rec_size);
466 fsm->state = ec_fsm_soe_error;
467 return;
468 }
469
470 if (error_flag) {
471 req->error_code = EC_READ_U16(data + rec_size - 2);
472 EC_SLAVE_ERR(slave, "Received error response:\n");
473 ec_print_soe_error(slave, req->error_code);
475 fsm->state = ec_fsm_soe_error;
476 return;
477 } else {
478 req->error_code = 0x0000;
479 }
480
481 value_included = (EC_READ_U8(data + 1) >> 6) & 1;
482 if (!value_included) {
483 EC_SLAVE_ERR(slave, "No value included!\n");
485 fsm->state = ec_fsm_soe_error;
486 return;
487 }
488
489 data_size = rec_size - EC_SOE_SIZE;
491 data + EC_SOE_SIZE, data_size)) {
492 fsm->state = ec_fsm_soe_error;
494 return;
495 }
496
497 if (incomplete) {
498 EC_SLAVE_DBG(slave, 1, "SoE data incomplete. Waiting for fragment"
499 " at offset %zu.\n", req->data_size);
501 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
502 fsm->retries = EC_FSM_RETRIES;
504 } else {
505 if (master->debug_level) {
506 EC_SLAVE_DBG(slave, 0, "IDN data:\n");
507 ec_print_data(req->data, req->data_size);
508 }
509
510 fsm->state = ec_fsm_soe_end; // success
511 }
512}
513
514/******************************************************************************
515 * SoE write state machine
516 *****************************************************************************/
517
521 ec_fsm_soe_t *fsm,
522 ec_datagram_t *datagram
523 )
524{
525 ec_slave_t *slave = fsm->slave;
526 ec_master_t *master = slave->master;
527 ec_soe_request_t *req = fsm->request;
528 uint8_t incomplete, *data;
529 size_t max_fragment_size, remaining_size;
530 uint16_t fragments_left;
531
532 remaining_size = req->data_size - fsm->offset;
533 max_fragment_size = slave->configured_rx_mailbox_size - EC_SOE_HEADER_SIZE;
534 incomplete = remaining_size > max_fragment_size;
535 fsm->fragment_size = incomplete ? max_fragment_size : remaining_size;
536 fragments_left = remaining_size / fsm->fragment_size - 1;
537 if (remaining_size % fsm->fragment_size) {
538 fragments_left++;
539 }
540
541 data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
543 if (IS_ERR(data)) {
544 fsm->state = ec_fsm_soe_error;
546 return;
547 }
548
549 EC_WRITE_U8(data, OPCODE_WRITE_REQUEST | incomplete << 3 |
550 (req->drive_no & 0x07) << 5);
551 EC_WRITE_U8(data + 1, 1 << 6); // only value included
552 EC_WRITE_U16(data + 2, incomplete ? fragments_left : req->idn);
553 memcpy(data + EC_SOE_SIZE, req->data + fsm->offset, fsm->fragment_size);
554
555 if (master->debug_level) {
556 EC_SLAVE_DBG(slave, 0, "SSC write request:\n");
558 }
559
561}
562
563/*****************************************************************************/
564
568 ec_fsm_soe_t *fsm,
569 ec_datagram_t *datagram
570 )
571{
572 ec_slave_t *slave = fsm->slave;
573 ec_soe_request_t *req = fsm->request;
574
575 EC_SLAVE_DBG(slave, 1, "Writing IDN 0x%04X of drive %u (%zu byte).\n",
576 req->idn, req->drive_no, req->data_size);
577
578 if (!(slave->sii.mailbox_protocols & EC_MBOX_SOE)) {
579 EC_SLAVE_ERR(slave, "Slave does not support SoE!\n");
580 fsm->state = ec_fsm_soe_error;
582 return;
583 }
584
586 EC_SLAVE_ERR(slave, "Mailbox size (%u) too small for SoE write.\n",
588 fsm->state = ec_fsm_soe_error;
590 return;
591 }
592
593 fsm->offset = 0;
594 fsm->retries = EC_FSM_RETRIES;
595 ec_fsm_soe_write_next_fragment(fsm, datagram);
596 req->jiffies_sent = jiffies;
597}
598
599/*****************************************************************************/
600
604 ec_fsm_soe_t *fsm,
605 ec_datagram_t *datagram
606 )
607{
608 ec_slave_t *slave = fsm->slave;
609 unsigned long diff_ms;
610
611 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
612 ec_fsm_soe_write_next_fragment(fsm, datagram);
613 return;
614 }
615
616 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
617 fsm->state = ec_fsm_soe_error;
618 EC_SLAVE_ERR(slave, "Failed to receive SoE write request: ");
621 return;
622 }
623
624 diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
625
626 if (fsm->datagram->working_counter != 1) {
627 if (!fsm->datagram->working_counter) {
628 if (diff_ms < EC_SOE_RESPONSE_TIMEOUT) {
629 // no response; send request datagram again
630 ec_fsm_soe_write_next_fragment(fsm, datagram);
631 return;
632 }
633 }
634 fsm->state = ec_fsm_soe_error;
635 EC_SLAVE_ERR(slave, "Reception of SoE write request"
636 " failed after %lu ms: ", diff_ms);
639 return;
640 }
641
642 // fragment successfully sent
643 fsm->offset += fsm->fragment_size;
644
645 if (fsm->offset < fsm->request->data_size) {
646 // next fragment
647 fsm->retries = EC_FSM_RETRIES;
648 ec_fsm_soe_write_next_fragment(fsm, datagram);
649 fsm->request->jiffies_sent = jiffies;
650 } else {
651 // all fragments sent; query response
653 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
654 fsm->retries = EC_FSM_RETRIES;
656 }
657}
658
659/*****************************************************************************/
660
664 ec_fsm_soe_t *fsm,
665 ec_datagram_t *datagram
666 )
667{
668 ec_slave_t *slave = fsm->slave;
669
670 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
671 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
672 return;
673 }
674
675 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
676 fsm->state = ec_fsm_soe_error;
677 EC_SLAVE_ERR(slave, "Failed to receive SoE write request datagram: ");
680 return;
681 }
682
683 if (fsm->datagram->working_counter != 1) {
684 fsm->state = ec_fsm_soe_error;
685 EC_SLAVE_ERR(slave, "Reception of SoE write request datagram: ");
688 return;
689 }
690
691 if (!ec_slave_mbox_check(fsm->datagram)) {
692 unsigned long diff_ms =
693 (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
694 if (diff_ms >= EC_SOE_RESPONSE_TIMEOUT) {
695 fsm->state = ec_fsm_soe_error;
696 EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting"
697 " for write response.\n", diff_ms);
699 return;
700 }
701
702 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
703 fsm->retries = EC_FSM_RETRIES;
704 return;
705 }
706
707 // Fetch response
708 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
709 fsm->retries = EC_FSM_RETRIES;
711}
712
713/*****************************************************************************/
714
718 ec_fsm_soe_t *fsm,
719 ec_datagram_t *datagram
720 )
721{
722 ec_slave_t *slave = fsm->slave;
723 ec_master_t *master = slave->master;
724 ec_soe_request_t *req = fsm->request;
725 uint8_t *data, mbox_prot, opcode, error_flag;
726 uint16_t idn;
727 size_t rec_size;
728
729 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
730 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
731 return; // FIXME: request again?
732 }
733
734 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
735 fsm->state = ec_fsm_soe_error;
736 EC_SLAVE_ERR(slave, "Failed to receive SoE write"
737 " response datagram: ");
740 return;
741 }
742
743 if (fsm->datagram->working_counter != 1) {
744 fsm->state = ec_fsm_soe_error;
745 EC_SLAVE_ERR(slave, "Reception of SoE write response failed: ");
748 return;
749 }
750
751 data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
752 if (IS_ERR(data)) {
753 fsm->state = ec_fsm_soe_error;
755 return;
756 }
757
758 if (master->debug_level) {
759 EC_SLAVE_DBG(slave, 0, "SSC write response:\n");
760 ec_print_data(data, rec_size);
761 }
762
763 if (mbox_prot != EC_MBOX_TYPE_SOE) {
764 fsm->state = ec_fsm_soe_error;
765 EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
766 mbox_prot);
768 return;
769 }
770
771 if (rec_size < EC_SOE_SIZE) {
772 fsm->state = ec_fsm_soe_error;
773 EC_SLAVE_ERR(slave, "Received corrupted SoE write response"
774 " (%zu bytes)!\n", rec_size);
775 ec_print_data(data, rec_size);
777 return;
778 }
779
780 opcode = EC_READ_U8(data) & 0x7;
781 if (opcode != OPCODE_WRITE_RESPONSE) {
782 EC_SLAVE_ERR(slave, "Received no write response"
783 " (opcode %x).\n", opcode);
784 ec_print_data(data, rec_size);
786 fsm->state = ec_fsm_soe_error;
787 return;
788 }
789
790 idn = EC_READ_U16(data + 2);
791 if (idn != req->idn) {
792 EC_SLAVE_ERR(slave, "Received response for"
793 " wrong IDN 0x%04x.\n", idn);
794 ec_print_data(data, rec_size);
796 fsm->state = ec_fsm_soe_error;
797 return;
798 }
799
800 error_flag = (EC_READ_U8(data) >> 4) & 1;
801 if (error_flag) {
802 if (rec_size < EC_SOE_SIZE + 2) {
803 EC_SLAVE_ERR(slave, "Received corrupted error response"
804 " - error flag set, but received size is %zu.\n",
805 rec_size);
806 } else {
807 req->error_code = EC_READ_U16(data + EC_SOE_SIZE);
808 EC_SLAVE_ERR(slave, "Received error response:\n");
809 ec_print_soe_error(slave, req->error_code);
810 }
811 ec_print_data(data, rec_size);
813 fsm->state = ec_fsm_soe_error;
814 } else {
815 req->error_code = 0x0000;
816 fsm->state = ec_fsm_soe_end; // success
817 }
818}
819
820/*****************************************************************************/
821
825 ec_fsm_soe_t *fsm,
826 ec_datagram_t *datagram
827 )
828{
829}
830
831/*****************************************************************************/
832
836 ec_fsm_soe_t *fsm,
837 ec_datagram_t *datagram
838 )
839{
840}
841
842/*****************************************************************************/
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
void ec_fsm_soe_write_start(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE START.
Definition: fsm_soe.c:567
void ec_fsm_soe_init(ec_fsm_soe_t *fsm)
Constructor.
Definition: fsm_soe.c:105
int ec_fsm_soe_exec(ec_fsm_soe_t *fsm, ec_datagram_t *datagram)
Executes the current state of the state machine.
Definition: fsm_soe.c:150
void ec_fsm_soe_write_request(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE REQUEST.
Definition: fsm_soe.c:603
#define EC_SOE_RESPONSE_TIMEOUT
SoE response timeout [ms].
Definition: fsm_soe.c:61
void ec_fsm_soe_transfer(ec_fsm_soe_t *fsm, ec_slave_t *slave, ec_soe_request_t *request)
Starts to transfer an IDN to/from a slave.
Definition: fsm_soe.c:128
void ec_fsm_soe_end(ec_fsm_soe_t *, ec_datagram_t *)
State: END.
Definition: fsm_soe.c:835
const ec_code_msg_t soe_error_codes[]
SoE error codes.
Definition: soe_errors.c:43
void ec_fsm_soe_clear(ec_fsm_soe_t *fsm)
Destructor.
Definition: fsm_soe.c:118
void ec_fsm_soe_read_check(ec_fsm_soe_t *, ec_datagram_t *)
CoE state: READ CHECK.
Definition: fsm_soe.c:338
void ec_fsm_soe_read_start(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ START.
Definition: fsm_soe.c:252
void ec_fsm_soe_print_error(ec_fsm_soe_t *fsm)
Output information about a failed SoE transfer.
Definition: fsm_soe.c:194
int ec_fsm_soe_prepare_read(ec_fsm_soe_t *fsm, ec_datagram_t *datagram)
Prepare a read operation.
Definition: fsm_soe.c:217
void ec_fsm_soe_write_check(ec_fsm_soe_t *, ec_datagram_t *)
CoE state: WRITE CHECK.
Definition: fsm_soe.c:663
void ec_fsm_soe_write_response(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE RESPONSE.
Definition: fsm_soe.c:717
void ec_fsm_soe_error(ec_fsm_soe_t *, ec_datagram_t *)
State: ERROR.
Definition: fsm_soe.c:824
ec_soe_opcodes
SoE operations.
Definition: fsm_soe.c:44
@ OPCODE_WRITE_REQUEST
Write request.
Definition: fsm_soe.c:47
@ OPCODE_READ_RESPONSE
Read response.
Definition: fsm_soe.c:46
@ OPCODE_READ_REQUEST
Read request.
Definition: fsm_soe.c:45
@ OPCODE_WRITE_RESPONSE
Write response.
Definition: fsm_soe.c:48
void ec_fsm_soe_write_next_fragment(ec_fsm_soe_t *fsm, ec_datagram_t *datagram)
Write next fragment.
Definition: fsm_soe.c:520
void ec_print_soe_error(const ec_slave_t *slave, uint16_t error_code)
Outputs an SoE error code.
Definition: fsm_soe.c:86
void ec_fsm_soe_read_request(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ REQUEST.
Definition: fsm_soe.c:283
#define EC_SOE_HEADER_SIZE
SoE header size.
Definition: fsm_soe.c:57
int ec_fsm_soe_success(const ec_fsm_soe_t *fsm)
Returns, if the state machine terminated with success.
Definition: fsm_soe.c:185
#define EC_SOE_SIZE
Size of all SoE headers.
Definition: fsm_soe.c:53
void ec_fsm_soe_read_response(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ RESPONSE.
Definition: fsm_soe.c:394
EtherCAT CoE state machines.
Global definitions and macros.
#define EC_FSM_RETRIES
Number of state machine retries on datagram timeout.
Definition: globals.h:47
@ EC_MBOX_SOE
Servo-Profile over EtherCAT.
Definition: globals.h:139
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_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_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.
#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
int ec_soe_request_append_data(ec_soe_request_t *req, const uint8_t *source, size_t size)
Copies SoE data from an external source.
Definition: soe_request.c:203
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 Sercos over EtherCAT protocol.
Definition: fsm_soe.h:51
void(* state)(ec_fsm_soe_t *, ec_datagram_t *)
CoE state function.
Definition: fsm_soe.h:55
off_t offset
IDN data offset during fragmented write.
Definition: fsm_soe.h:59
unsigned int retries
retries upon datagram timeout
Definition: fsm_soe.h:53
ec_slave_t * slave
slave the FSM runs on
Definition: fsm_soe.h:52
ec_datagram_t * datagram
Datagram used in the previous step.
Definition: fsm_soe.h:56
unsigned long jiffies_start
Timestamp.
Definition: fsm_soe.h:57
ec_soe_request_t * request
SoE request.
Definition: fsm_soe.h:58
size_t fragment_size
Size of the current fragment.
Definition: fsm_soe.h:60
EtherCAT master.
Definition: master.h:194
unsigned int debug_level
Master debug level.
Definition: master.h:285
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:147
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
ec_master_t * master
Master owning the slave.
Definition: slave.h:178
Sercos-over-EtherCAT request.
Definition: soe_request.h:48
uint8_t drive_no
Drive number.
Definition: soe_request.h:50
uint16_t idn
Sercos ID-Number.
Definition: soe_request.h:51
uint8_t * data
Pointer to SDO data.
Definition: soe_request.h:53
uint16_t error_code
SoE error code.
Definition: soe_request.h:61
unsigned long jiffies_sent
Jiffies, when the upload/download request was sent.
Definition: soe_request.h:59
ec_direction_t dir
Direction.
Definition: soe_request.h:56
size_t data_size
Size of SDO data.
Definition: soe_request.h:55