IgH EtherCAT Master  1.6.9
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
26
27/****************************************************************************/
28
29#include "globals.h"
30#include "master.h"
31#include "mailbox.h"
32#include "fsm_soe.h"
33
34/****************************************************************************/
35
38enum {
43};
44
47#define EC_SOE_SIZE 0x04
48
51#define EC_SOE_HEADER_SIZE (EC_MBOX_HEADER_SIZE + EC_SOE_SIZE)
52
55#define EC_SOE_RESPONSE_TIMEOUT 1000
56
57/****************************************************************************/
58
59// prototypes for private methods
60void ec_print_soe_error(const ec_slave_t *, uint16_t);
64
65/****************************************************************************/
66
71
76
79
80/****************************************************************************/
81
82extern const ec_code_msg_t soe_error_codes[];
83
84/****************************************************************************/
85
88void ec_print_soe_error(const ec_slave_t *slave, uint16_t error_code)
89{
90 const ec_code_msg_t *error_msg;
91
92 for (error_msg = soe_error_codes; error_msg->code; error_msg++) {
93 if (error_msg->code == error_code) {
94 EC_SLAVE_ERR(slave, "SoE error 0x%04X: \"%s\".\n",
95 error_msg->code, error_msg->message);
96 return;
97 }
98 }
99
100 EC_SLAVE_ERR(slave, "Unknown SoE error 0x%04X.\n", error_code);
101}
102
103/****************************************************************************/
104
108 ec_fsm_soe_t *fsm
109 )
110{
111 fsm->state = NULL;
112 fsm->datagram = NULL;
113 fsm->fragment_size = 0;
114}
115
116/****************************************************************************/
117
121 ec_fsm_soe_t *fsm
122 )
123{
124}
125
126/****************************************************************************/
127
131 ec_fsm_soe_t *fsm,
132 ec_slave_t *slave,
133 ec_soe_request_t *request
134 )
135{
136 fsm->slave = slave;
137 fsm->request = request;
138
139 if (request->dir == EC_DIR_OUTPUT) {
141 } else {
143 }
144}
145
146/****************************************************************************/
147
153 ec_fsm_soe_t *fsm,
154 ec_datagram_t *datagram
155 )
156{
157 int datagram_used = 0;
158
159 if (fsm->datagram &&
160 (fsm->datagram->state == EC_DATAGRAM_INIT ||
162 fsm->datagram->state == EC_DATAGRAM_SENT)) {
163 // datagram not received yet
164 return datagram_used;
165 }
166
167 fsm->state(fsm, datagram);
168
169 datagram_used =
170 fsm->state != ec_fsm_soe_end && fsm->state != ec_fsm_soe_error;
171
172 if (datagram_used) {
173 fsm->datagram = datagram;
174 } else {
175 fsm->datagram = NULL;
176 }
177
178 return datagram_used;
179}
180
181/****************************************************************************/
182
188{
189 return fsm->state == ec_fsm_soe_end;
190}
191
192/****************************************************************************/
193
197{
198 ec_soe_request_t *request = fsm->request;
199
200 EC_SLAVE_ERR(fsm->slave, "");
201
202 if (request->dir == EC_DIR_OUTPUT) {
203 printk(KERN_CONT "Writing");
204 } else {
205 printk(KERN_CONT "Reading");
206 }
207
208 printk(KERN_CONT " IDN 0x%04X failed.\n", request->idn);
209}
210
211/*****************************************************************************
212 * SoE read state machine
213 ****************************************************************************/
214
220 ec_fsm_soe_t *fsm,
221 ec_datagram_t *datagram
222 )
223{
224 uint8_t *data;
225 ec_slave_t *slave = fsm->slave;
226 ec_master_t *master = slave->master;
227 ec_soe_request_t *request = fsm->request;
228
229 data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
231 if (IS_ERR(data)) {
232 return PTR_ERR(data);
233 }
234
235 EC_WRITE_U8(data, OPCODE_READ_REQUEST | (request->drive_no & 0x07) << 5);
236 EC_WRITE_U8(data + 1, 1 << 6); // request value
237 EC_WRITE_U16(data + 2, request->idn);
238
239 if (master->debug_level) {
240 EC_SLAVE_DBG(slave, 0, "SSC read request:\n");
242 }
243
244 fsm->request->jiffies_sent = jiffies;
246
247 return 0;
248}
249
250/****************************************************************************/
251
255 ec_fsm_soe_t *fsm,
256 ec_datagram_t *datagram
257 )
258{
259 ec_slave_t *slave = fsm->slave;
260 ec_soe_request_t *request = fsm->request;
261
262 EC_SLAVE_DBG(slave, 1, "Reading IDN 0x%04X of drive %u.\n", request->idn,
263 request->drive_no);
264
265 if (!(slave->sii.mailbox_protocols & EC_MBOX_SOE)) {
266 EC_SLAVE_ERR(slave, "Slave does not support SoE!\n");
267 fsm->state = ec_fsm_soe_error;
269 return;
270 }
271
272 request->data_size = 0;
273 fsm->retries = EC_FSM_RETRIES;
274
275 if (ec_fsm_soe_prepare_read(fsm, datagram)) {
276 fsm->state = ec_fsm_soe_error;
278 }
279}
280
281/****************************************************************************/
282
286 ec_fsm_soe_t *fsm,
287 ec_datagram_t *datagram
288 )
289{
290 ec_slave_t *slave = fsm->slave;
291 unsigned long diff_ms;
292
293 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
294 if (ec_fsm_soe_prepare_read(fsm, datagram)) {
295 fsm->state = ec_fsm_soe_error;
297 }
298 return;
299 }
300
301 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
302 fsm->state = ec_fsm_soe_error;
303 EC_SLAVE_ERR(slave, "Failed to receive SoE read request: ");
306 return;
307 }
308
309 diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
310
311 if (fsm->datagram->working_counter != 1) {
312 if (!fsm->datagram->working_counter) {
313 if (diff_ms < EC_SOE_RESPONSE_TIMEOUT) {
314 // no response; send request datagram again
315 if (ec_fsm_soe_prepare_read(fsm, datagram)) {
316 fsm->state = ec_fsm_soe_error;
318 }
319 return;
320 }
321 }
322 fsm->state = ec_fsm_soe_error;
323 EC_SLAVE_ERR(slave, "Reception of SoE read request"
324 " failed after %lu ms: ", diff_ms);
327 return;
328 }
329
331 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
332 fsm->retries = EC_FSM_RETRIES;
334}
335
336/****************************************************************************/
337
341 ec_fsm_soe_t *fsm,
342 ec_datagram_t *datagram
343 )
344{
345 ec_slave_t *slave = fsm->slave;
346
347 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
348 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
349 return;
350 }
351
352 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
353 fsm->state = ec_fsm_soe_error;
354 EC_SLAVE_ERR(slave, "Failed to receive SoE mailbox check datagram: ");
357 return;
358 }
359
360 if (fsm->datagram->working_counter != 1) {
361 fsm->state = ec_fsm_soe_error;
362 EC_SLAVE_ERR(slave, "Reception of SoE mailbox check"
363 " datagram failed: ");
366 return;
367 }
368
369 if (!ec_slave_mbox_check(fsm->datagram)) {
370 unsigned long diff_ms =
372 1000 / HZ;
373 if (diff_ms >= EC_SOE_RESPONSE_TIMEOUT) {
374 fsm->state = ec_fsm_soe_error;
375 EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting for"
376 " read response.\n", diff_ms);
378 return;
379 }
380
381 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
382 fsm->retries = EC_FSM_RETRIES;
383 return;
384 }
385
386 // Fetch response
387 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
388 fsm->retries = EC_FSM_RETRIES;
390}
391
392/****************************************************************************/
393
397 ec_fsm_soe_t *fsm,
398 ec_datagram_t *datagram
399 )
400{
401 ec_slave_t *slave = fsm->slave;
402 ec_master_t *master = slave->master;
403 uint8_t *data, mbox_prot, header, opcode, incomplete, error_flag,
404 value_included;
405 size_t rec_size, data_size;
406 ec_soe_request_t *req = fsm->request;
407
408 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
409 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
410 return;
411 }
412
413 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
414 fsm->state = ec_fsm_soe_error;
415 EC_SLAVE_ERR(slave, "Failed to receive SoE read response datagram: ");
418 return;
419 }
420
421 if (fsm->datagram->working_counter != 1) {
422 fsm->state = ec_fsm_soe_error;
423 EC_SLAVE_ERR(slave, "Reception of SoE read response failed: ");
426 return;
427 }
428
429 data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
430 if (IS_ERR(data)) {
431 fsm->state = ec_fsm_soe_error;
433 return;
434 }
435
436 if (master->debug_level) {
437 EC_SLAVE_DBG(slave, 0, "SSC read response:\n");
438 ec_print_data(data, rec_size);
439 }
440
441 if (mbox_prot != EC_MBOX_TYPE_SOE) {
442 fsm->state = ec_fsm_soe_error;
443 EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
444 mbox_prot);
446 return;
447 }
448
449 if (rec_size < EC_SOE_SIZE) {
450 fsm->state = ec_fsm_soe_error;
451 EC_SLAVE_ERR(slave, "Received currupted SoE read response"
452 " (%zu bytes)!\n", rec_size);
453 ec_print_data(data, rec_size);
455 return;
456 }
457
458 header = EC_READ_U8(data);
459 opcode = header & 0x7;
460 incomplete = (header >> 3) & 1;
461 error_flag = (header >> 4) & 1;
462
463 if (opcode != OPCODE_READ_RESPONSE) {
464 EC_SLAVE_ERR(slave, "Received no read response (opcode %x).\n",
465 opcode);
466 ec_print_data(data, rec_size);
468 fsm->state = ec_fsm_soe_error;
469 return;
470 }
471
472 if (error_flag) {
473 req->error_code = EC_READ_U16(data + rec_size - 2);
474 EC_SLAVE_ERR(slave, "Received error response:\n");
475 ec_print_soe_error(slave, req->error_code);
477 fsm->state = ec_fsm_soe_error;
478 return;
479 } else {
480 req->error_code = 0x0000;
481 }
482
483 value_included = (EC_READ_U8(data + 1) >> 6) & 1;
484 if (!value_included) {
485 EC_SLAVE_ERR(slave, "No value included!\n");
487 fsm->state = ec_fsm_soe_error;
488 return;
489 }
490
491 data_size = rec_size - EC_SOE_SIZE;
493 data + EC_SOE_SIZE, data_size)) {
494 fsm->state = ec_fsm_soe_error;
496 return;
497 }
498
499 if (incomplete) {
500 EC_SLAVE_DBG(slave, 1, "SoE data incomplete. Waiting for fragment"
501 " at offset %zu.\n", req->data_size);
503 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
504 fsm->retries = EC_FSM_RETRIES;
506 } else {
507 if (master->debug_level) {
508 EC_SLAVE_DBG(slave, 0, "IDN data:\n");
509 ec_print_data(req->data, req->data_size);
510 }
511
512 fsm->state = ec_fsm_soe_end; // success
513 }
514}
515
516/*****************************************************************************
517 * SoE write state machine
518 ****************************************************************************/
519
523 ec_fsm_soe_t *fsm,
524 ec_datagram_t *datagram
525 )
526{
527 ec_slave_t *slave = fsm->slave;
528 ec_master_t *master = slave->master;
529 ec_soe_request_t *req = fsm->request;
530 uint8_t incomplete, *data;
531 size_t max_fragment_size, remaining_size;
532 uint16_t fragments_left;
533
534 remaining_size = req->data_size - fsm->offset;
535 max_fragment_size = slave->configured_rx_mailbox_size - EC_SOE_HEADER_SIZE;
536 incomplete = remaining_size > max_fragment_size;
537 fsm->fragment_size = incomplete ? max_fragment_size : remaining_size;
538 fragments_left = remaining_size / fsm->fragment_size - 1;
539 if (remaining_size % fsm->fragment_size) {
540 fragments_left++;
541 }
542
543 data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
545 if (IS_ERR(data)) {
546 fsm->state = ec_fsm_soe_error;
548 return;
549 }
550
551 EC_WRITE_U8(data, OPCODE_WRITE_REQUEST | incomplete << 3 |
552 (req->drive_no & 0x07) << 5);
553 EC_WRITE_U8(data + 1, 1 << 6); // only value included
554 EC_WRITE_U16(data + 2, incomplete ? fragments_left : req->idn);
555 memcpy(data + EC_SOE_SIZE, req->data + fsm->offset, fsm->fragment_size);
556
557 if (master->debug_level) {
558 EC_SLAVE_DBG(slave, 0, "SSC write request:\n");
560 }
561
563}
564
565/****************************************************************************/
566
570 ec_fsm_soe_t *fsm,
571 ec_datagram_t *datagram
572 )
573{
574 ec_slave_t *slave = fsm->slave;
575 ec_soe_request_t *req = fsm->request;
576
577 EC_SLAVE_DBG(slave, 1, "Writing IDN 0x%04X of drive %u (%zu byte).\n",
578 req->idn, req->drive_no, req->data_size);
579
580 if (!(slave->sii.mailbox_protocols & EC_MBOX_SOE)) {
581 EC_SLAVE_ERR(slave, "Slave does not support SoE!\n");
582 fsm->state = ec_fsm_soe_error;
584 return;
585 }
586
588 EC_SLAVE_ERR(slave, "Mailbox size (%u) too small for SoE write.\n",
590 fsm->state = ec_fsm_soe_error;
592 return;
593 }
594
595 fsm->offset = 0;
596 fsm->retries = EC_FSM_RETRIES;
597 ec_fsm_soe_write_next_fragment(fsm, datagram);
598 req->jiffies_sent = jiffies;
599}
600
601/****************************************************************************/
602
606 ec_fsm_soe_t *fsm,
607 ec_datagram_t *datagram
608 )
609{
610 ec_slave_t *slave = fsm->slave;
611 unsigned long diff_ms;
612
613 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
614 ec_fsm_soe_write_next_fragment(fsm, datagram);
615 return;
616 }
617
618 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
619 fsm->state = ec_fsm_soe_error;
620 EC_SLAVE_ERR(slave, "Failed to receive SoE write request: ");
623 return;
624 }
625
626 diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
627
628 if (fsm->datagram->working_counter != 1) {
629 if (!fsm->datagram->working_counter) {
630 if (diff_ms < EC_SOE_RESPONSE_TIMEOUT) {
631 // no response; send request datagram again
632 ec_fsm_soe_write_next_fragment(fsm, datagram);
633 return;
634 }
635 }
636 fsm->state = ec_fsm_soe_error;
637 EC_SLAVE_ERR(slave, "Reception of SoE write request"
638 " failed after %lu ms: ", diff_ms);
641 return;
642 }
643
644 // fragment successfully sent
645 fsm->offset += fsm->fragment_size;
646
647 if (fsm->offset < fsm->request->data_size) {
648 // next fragment
649 fsm->retries = EC_FSM_RETRIES;
650 ec_fsm_soe_write_next_fragment(fsm, datagram);
651 fsm->request->jiffies_sent = jiffies;
652 } else {
653 // all fragments sent; query response
655 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
656 fsm->retries = EC_FSM_RETRIES;
658 }
659}
660
661/****************************************************************************/
662
666 ec_fsm_soe_t *fsm,
667 ec_datagram_t *datagram
668 )
669{
670 ec_slave_t *slave = fsm->slave;
671
672 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
673 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
674 return;
675 }
676
677 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
678 fsm->state = ec_fsm_soe_error;
679 EC_SLAVE_ERR(slave, "Failed to receive SoE write request datagram: ");
682 return;
683 }
684
685 if (fsm->datagram->working_counter != 1) {
686 fsm->state = ec_fsm_soe_error;
687 EC_SLAVE_ERR(slave, "Reception of SoE write request datagram: ");
690 return;
691 }
692
693 if (!ec_slave_mbox_check(fsm->datagram)) {
694 unsigned long diff_ms =
695 (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
696 if (diff_ms >= EC_SOE_RESPONSE_TIMEOUT) {
697 fsm->state = ec_fsm_soe_error;
698 EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting"
699 " for write response.\n", diff_ms);
701 return;
702 }
703
704 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
705 fsm->retries = EC_FSM_RETRIES;
706 return;
707 }
708
709 // Fetch response
710 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
711 fsm->retries = EC_FSM_RETRIES;
713}
714
715/****************************************************************************/
716
720 ec_fsm_soe_t *fsm,
721 ec_datagram_t *datagram
722 )
723{
724 ec_slave_t *slave = fsm->slave;
725 ec_master_t *master = slave->master;
726 ec_soe_request_t *req = fsm->request;
727 uint8_t *data, mbox_prot, opcode, error_flag;
728 uint16_t idn;
729 size_t rec_size;
730
731 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
732 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
733 return; // FIXME: request again?
734 }
735
736 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
737 fsm->state = ec_fsm_soe_error;
738 EC_SLAVE_ERR(slave, "Failed to receive SoE write"
739 " response datagram: ");
742 return;
743 }
744
745 if (fsm->datagram->working_counter != 1) {
746 fsm->state = ec_fsm_soe_error;
747 EC_SLAVE_ERR(slave, "Reception of SoE write response failed: ");
750 return;
751 }
752
753 data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
754 if (IS_ERR(data)) {
755 fsm->state = ec_fsm_soe_error;
757 return;
758 }
759
760 if (master->debug_level) {
761 EC_SLAVE_DBG(slave, 0, "SSC write response:\n");
762 ec_print_data(data, rec_size);
763 }
764
765 if (mbox_prot != EC_MBOX_TYPE_SOE) {
766 fsm->state = ec_fsm_soe_error;
767 EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
768 mbox_prot);
770 return;
771 }
772
773 if (rec_size < EC_SOE_SIZE) {
774 fsm->state = ec_fsm_soe_error;
775 EC_SLAVE_ERR(slave, "Received corrupted SoE write response"
776 " (%zu bytes)!\n", rec_size);
777 ec_print_data(data, rec_size);
779 return;
780 }
781
782 opcode = EC_READ_U8(data) & 0x7;
783 if (opcode != OPCODE_WRITE_RESPONSE) {
784 EC_SLAVE_ERR(slave, "Received no write response"
785 " (opcode %x).\n", opcode);
786 ec_print_data(data, rec_size);
788 fsm->state = ec_fsm_soe_error;
789 return;
790 }
791
792 idn = EC_READ_U16(data + 2);
793 if (idn != req->idn) {
794 EC_SLAVE_ERR(slave, "Received response for"
795 " wrong IDN 0x%04x.\n", idn);
796 ec_print_data(data, rec_size);
798 fsm->state = ec_fsm_soe_error;
799 return;
800 }
801
802 error_flag = (EC_READ_U8(data) >> 4) & 1;
803 if (error_flag) {
804 if (rec_size < EC_SOE_SIZE + 2) {
805 EC_SLAVE_ERR(slave, "Received corrupted error response"
806 " - error flag set, but received size is %zu.\n",
807 rec_size);
808 } else {
809 req->error_code = EC_READ_U16(data + EC_SOE_SIZE);
810 EC_SLAVE_ERR(slave, "Received error response:\n");
811 ec_print_soe_error(slave, req->error_code);
812 }
813 ec_print_data(data, rec_size);
815 fsm->state = ec_fsm_soe_error;
816 } else {
817 req->error_code = 0x0000;
818 fsm->state = ec_fsm_soe_end; // success
819 }
820}
821
822/****************************************************************************/
823
827 ec_fsm_soe_t *fsm,
828 ec_datagram_t *datagram
829 )
830{
831}
832
833/****************************************************************************/
834
838 ec_fsm_soe_t *fsm,
839 ec_datagram_t *datagram
840 )
841{
842}
843
844/****************************************************************************/
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
void ec_fsm_soe_write_start(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE START.
Definition fsm_soe.c:569
@ OPCODE_WRITE_REQUEST
Write request.
Definition fsm_soe.c:41
@ OPCODE_READ_RESPONSE
Read response.
Definition fsm_soe.c:40
@ OPCODE_READ_REQUEST
Read request.
Definition fsm_soe.c:39
@ OPCODE_WRITE_RESPONSE
Write response.
Definition fsm_soe.c:42
void ec_fsm_soe_init(ec_fsm_soe_t *fsm)
Constructor.
Definition fsm_soe.c:107
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:152
void ec_fsm_soe_write_request(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE REQUEST.
Definition fsm_soe.c:605
#define EC_SOE_RESPONSE_TIMEOUT
SoE response timeout [ms].
Definition fsm_soe.c:55
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:130
void ec_fsm_soe_end(ec_fsm_soe_t *, ec_datagram_t *)
State: END.
Definition fsm_soe.c:837
const ec_code_msg_t soe_error_codes[]
SoE error codes.
Definition soe_errors.c:35
void ec_fsm_soe_clear(ec_fsm_soe_t *fsm)
Destructor.
Definition fsm_soe.c:120
void ec_fsm_soe_read_check(ec_fsm_soe_t *, ec_datagram_t *)
CoE state: READ CHECK.
Definition fsm_soe.c:340
void ec_fsm_soe_read_start(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ START.
Definition fsm_soe.c:254
void ec_fsm_soe_print_error(ec_fsm_soe_t *)
Output information about a failed SoE transfer.
Definition fsm_soe.c:196
int ec_fsm_soe_prepare_read(ec_fsm_soe_t *, ec_datagram_t *)
Prepare a read operation.
Definition fsm_soe.c:219
void ec_fsm_soe_write_check(ec_fsm_soe_t *, ec_datagram_t *)
CoE state: WRITE CHECK.
Definition fsm_soe.c:665
void ec_fsm_soe_write_response(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE RESPONSE.
Definition fsm_soe.c:719
void ec_fsm_soe_error(ec_fsm_soe_t *, ec_datagram_t *)
State: ERROR.
Definition fsm_soe.c:826
void ec_fsm_soe_write_next_fragment(ec_fsm_soe_t *, ec_datagram_t *)
Write next fragment.
Definition fsm_soe.c:522
void ec_print_soe_error(const ec_slave_t *, uint16_t)
Outputs an SoE error code.
Definition fsm_soe.c:88
void ec_fsm_soe_read_request(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ REQUEST.
Definition fsm_soe.c:285
#define EC_SOE_HEADER_SIZE
SoE header size.
Definition fsm_soe.c:51
int ec_fsm_soe_success(const ec_fsm_soe_t *fsm)
Returns, if the state machine terminated with success.
Definition fsm_soe.c:187
#define EC_SOE_SIZE
Size of all SoE headers.
Definition fsm_soe.c:47
void ec_fsm_soe_read_response(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ RESPONSE.
Definition fsm_soe.c:396
EtherCAT CoE state machines.
struct ec_fsm_soe ec_fsm_soe_t
Definition fsm_soe.h:39
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:148
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
struct ec_soe_request ec_soe_request_t
Definition ecrt.h:312
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition ecrt.h:3040
struct ec_master ec_master_t
Definition ecrt.h:300
#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_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.
#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
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.
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
void(* state)(ec_fsm_soe_t *, ec_datagram_t *)
CoE state function.
Definition fsm_soe.h:47
off_t offset
IDN data offset during fragmented write.
Definition fsm_soe.h:51
unsigned int retries
retries upon datagram timeout
Definition fsm_soe.h:45
ec_slave_t * slave
slave the FSM runs on
Definition fsm_soe.h:44
ec_datagram_t * datagram
Datagram used in the previous step.
Definition fsm_soe.h:48
unsigned long jiffies_start
Timestamp.
Definition fsm_soe.h:49
ec_soe_request_t * request
SoE request.
Definition fsm_soe.h:50
size_t fragment_size
Size of the current fragment.
Definition fsm_soe.h:52
unsigned int debug_level
Master debug level.
Definition master.h:275
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition slave.h:139
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
ec_master_t * master
Master owning the slave.
Definition slave.h:170
uint16_t idn
Sercos ID-Number.
Definition soe_request.h:43
uint8_t drive_no
Drive number.
Definition soe_request.h:42
ec_direction_t dir
Direction.
Definition soe_request.h:50
size_t data_size
Size of SDO data.
Definition soe_request.h:47
uint16_t error_code
SoE error code.
Definition soe_request.h:56
uint8_t * data
Pointer to SDO data.
Definition soe_request.h:45
unsigned long jiffies_sent
Jiffies, when the upload/download request was sent.
Definition soe_request.h:54