IgH EtherCAT Master  1.5.2
fsm_foe.c
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * $Id$
4 *
5 * Copyright (C) 2008 Olav Zarges, imc Messsysteme GmbH
6 * 2013 Florian Pose <fp@igh-essen.com>
7 *
8 * This file is part of the IgH EtherCAT Master.
9 *
10 * The IgH EtherCAT Master is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License version 2, as
12 * published by the Free Software Foundation.
13 *
14 * The IgH EtherCAT Master is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17 * Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with the IgH EtherCAT Master; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 *
23 * ---
24 *
25 * The license mentioned above concerns the source code only. Using the
26 * EtherCAT technology and brand is only permitted in compliance with the
27 * industrial property and similar rights of Beckhoff Automation GmbH.
28 *
29 *****************************************************************************/
30
35/*****************************************************************************/
36
37#include "globals.h"
38#include "master.h"
39#include "mailbox.h"
40#include "fsm_foe.h"
41#include "foe.h"
42
43/*****************************************************************************/
44
47#define EC_FSM_FOE_TIMEOUT 3000
48
51#define EC_FOE_HEADER_SIZE 6
52// uint8_t OpCode
53// uint8_t reserved
54// uint32_t PacketNo, Password, ErrorCode
55
56//#define DEBUG_FOE
57
58/*****************************************************************************/
59
62enum {
70
71/*****************************************************************************/
72
77
78void ec_foe_set_tx_error(ec_fsm_foe_t *, uint32_t);
79void ec_foe_set_rx_error(ec_fsm_foe_t *, uint32_t);
80
83
86
89
91
95
98
99/*****************************************************************************/
100
104 ec_fsm_foe_t *fsm
105 )
106{
107 fsm->state = NULL;
108 fsm->datagram = NULL;
109}
110
111/*****************************************************************************/
112
116{
117}
118
119/*****************************************************************************/
120
126 ec_fsm_foe_t *fsm,
127 ec_datagram_t *datagram
128 )
129{
130 int datagram_used = 0;
131
132 if (fsm->datagram &&
133 (fsm->datagram->state == EC_DATAGRAM_INIT ||
135 fsm->datagram->state == EC_DATAGRAM_SENT)) {
136 // datagram not received yet
137 return datagram_used;
138 }
139
140 fsm->state(fsm, datagram);
141
142 datagram_used =
143 fsm->state != ec_fsm_foe_end && fsm->state != ec_fsm_foe_error;
144
145 if (datagram_used) {
146 fsm->datagram = datagram;
147 } else {
148 fsm->datagram = NULL;
149 }
150
151 return datagram_used;
152}
153
154/*****************************************************************************/
155
160{
161 return fsm->state == ec_fsm_foe_end;
162}
163
164/*****************************************************************************/
165
169 ec_fsm_foe_t *fsm,
170 ec_slave_t *slave,
171 ec_foe_request_t *request
172 )
173{
174 fsm->slave = slave;
175 fsm->request = request;
176
177 if (request->dir == EC_DIR_OUTPUT) {
178 fsm->tx_buffer = fsm->request->buffer;
179 fsm->tx_buffer_size = fsm->request->data_size;
180 fsm->tx_buffer_offset = 0;
181
182 fsm->tx_filename = fsm->request->file_name;
183 fsm->tx_filename_len = strlen(fsm->tx_filename);
184
186 }
187 else {
188 fsm->rx_buffer = fsm->request->buffer;
190
191 fsm->rx_filename = fsm->request->file_name;
192 fsm->rx_filename_len = strlen(fsm->rx_filename);
193
195 }
196}
197
198/*****************************************************************************/
199
203 ec_fsm_foe_t *fsm,
204 ec_datagram_t *datagram
205 )
206{
207#ifdef DEBUG_FOE
208 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
209#endif
210}
211
212/*****************************************************************************/
213
217 ec_fsm_foe_t *fsm,
218 ec_datagram_t *datagram
219 )
220{
221#ifdef DEBUG_FOE
222 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
223#endif
224}
225
226/*****************************************************************************/
227
233 ec_fsm_foe_t *fsm,
234 ec_datagram_t *datagram
235 )
236{
237 size_t remaining_size, current_size;
238 uint8_t *data;
239
240 remaining_size = fsm->tx_buffer_size - fsm->tx_buffer_offset;
241
242 if (remaining_size < fsm->slave->configured_tx_mailbox_size
244 current_size = remaining_size;
245 fsm->tx_last_packet = 1;
246 } else {
247 current_size = fsm->slave->configured_tx_mailbox_size
249 }
250
252 datagram, EC_MBOX_TYPE_FOE, current_size + EC_FOE_HEADER_SIZE);
253 if (IS_ERR(data)) {
254 return -1;
255 }
256
257 EC_WRITE_U16(data, EC_FOE_OPCODE_DATA); // OpCode = DataBlock req.
258 EC_WRITE_U32(data + 2, fsm->tx_packet_no); // PacketNo, Password
259
260 memcpy(data + EC_FOE_HEADER_SIZE,
261 fsm->tx_buffer + fsm->tx_buffer_offset, current_size);
262 fsm->tx_current_size = current_size;
263
264 return 0;
265}
266
267/*****************************************************************************/
268
274 ec_fsm_foe_t *fsm,
275 ec_datagram_t *datagram
276 )
277{
278 size_t current_size;
279 uint8_t *data;
280
281 fsm->tx_buffer_offset = 0;
282 fsm->tx_current_size = 0;
283 fsm->tx_packet_no = 0;
284 fsm->tx_last_packet = 0;
285
286 current_size = fsm->tx_filename_len;
287
288 data = ec_slave_mbox_prepare_send(fsm->slave, datagram,
289 EC_MBOX_TYPE_FOE, current_size + EC_FOE_HEADER_SIZE);
290 if (IS_ERR(data)) {
291 return -1;
292 }
293
294 EC_WRITE_U16( data, EC_FOE_OPCODE_WRQ); // fsm write request
295 EC_WRITE_U32( data + 2, fsm->tx_packet_no );
296
297 memcpy(data + EC_FOE_HEADER_SIZE, fsm->tx_filename, current_size);
298
299 return 0;
300}
301
302/*****************************************************************************/
303
307 ec_fsm_foe_t *fsm,
308 ec_datagram_t *datagram
309 )
310{
311 ec_slave_t *slave = fsm->slave;
312
313 fsm->tx_buffer_offset = 0;
314 fsm->tx_current_size = 0;
315 fsm->tx_packet_no = 0;
316 fsm->tx_last_packet = 0;
317
318#ifdef DEBUG_FOE
319 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
320#endif
321
322 if (!(slave->sii.mailbox_protocols & EC_MBOX_FOE)) {
324 EC_SLAVE_ERR(slave, "Slave does not support FoE!\n");
325 return;
326 }
327
328 if (ec_foe_prepare_wrq_send(fsm, datagram)) {
330 return;
331 }
332
334}
335
336/*****************************************************************************/
337
341 ec_fsm_foe_t *fsm,
342 ec_datagram_t *datagram
343 )
344{
345 ec_slave_t *slave = fsm->slave;
346
347#ifdef DEBUG_FOE
348 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
349#endif
350
351 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
353 EC_SLAVE_ERR(slave, "Failed to receive FoE mailbox check datagram: ");
355 return;
356 }
357
358 if (fsm->datagram->working_counter != 1) {
360 EC_SLAVE_ERR(slave, "Reception of FoE mailbox check datagram"
361 " failed: ");
363 return;
364 }
365
366 if (!ec_slave_mbox_check(fsm->datagram)) {
367 // slave did not put anything in the mailbox yet
368 unsigned long diff_ms = (fsm->datagram->jiffies_received -
369 fsm->jiffies_start) * 1000 / HZ;
370 if (diff_ms >= EC_FSM_FOE_TIMEOUT) {
372 EC_SLAVE_ERR(slave, "Timeout while waiting for ack response.\n");
373 return;
374 }
375
376 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
377 fsm->retries = EC_FSM_RETRIES;
378 return;
379 }
380
381 // Fetch response
382 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
383
384 fsm->retries = EC_FSM_RETRIES;
386}
387
388/*****************************************************************************/
389
393 ec_fsm_foe_t *fsm,
394 ec_datagram_t *datagram
395 )
396{
397 ec_slave_t *slave = fsm->slave;
398 uint8_t *data, mbox_prot;
399 uint8_t opCode;
400 size_t rec_size;
401
402#ifdef DEBUG_FOE
403 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
404#endif
405
406 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
408 EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: ");
410 return;
411 }
412
413 if (fsm->datagram->working_counter != 1) {
415 EC_SLAVE_ERR(slave, "Reception of FoE ack response failed: ");
417 return;
418 }
419
420 data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
421 if (IS_ERR(data)) {
423 return;
424 }
425
426 if (mbox_prot != EC_MBOX_TYPE_FOE) {
428 EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
429 mbox_prot);
430 return;
431 }
432
433 opCode = EC_READ_U8(data);
434
435 if (opCode == EC_FOE_OPCODE_BUSY) {
436 // slave not ready
437 if (ec_foe_prepare_data_send(fsm, datagram)) {
439 EC_SLAVE_ERR(slave, "Slave is busy.\n");
440 return;
441 }
443 return;
444 }
445
446 if (opCode == EC_FOE_OPCODE_ACK) {
447 fsm->tx_packet_no++;
449
450 if (fsm->tx_last_packet) {
451 fsm->state = ec_fsm_foe_end;
452 return;
453 }
454
455 if (ec_foe_prepare_data_send(fsm, datagram)) {
457 return;
458 }
460 return;
461 }
463}
464
465/*****************************************************************************/
466
473 ec_fsm_foe_t *fsm,
474 ec_datagram_t *datagram
475 )
476{
477 ec_slave_t *slave = fsm->slave;
478
479#ifdef DEBUG_FOE
480 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
481#endif
482
483 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
485 EC_SLAVE_ERR(slave, "Failed to send FoE WRQ: ");
487 return;
488 }
489
490 if (fsm->datagram->working_counter != 1) {
491 // slave did not put anything in the mailbox yet
493 EC_SLAVE_ERR(slave, "Reception of FoE WRQ failed: ");
495 return;
496 }
497
499
500 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
501
502 fsm->retries = EC_FSM_RETRIES;
504}
505
506/*****************************************************************************/
507
514 ec_fsm_foe_t *fsm,
515 ec_datagram_t *datagram
516 )
517{
518 ec_slave_t *slave = fsm->slave;
519
520#ifdef DEBUG_FOE
521 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
522#endif
523
524 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
526 EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: ");
528 return;
529 }
530
531 if (fsm->datagram->working_counter != 1) {
533 EC_SLAVE_ERR(slave, "Reception of FoE data send failed: ");
535 return;
536 }
537
538 ec_slave_mbox_prepare_check(slave, datagram);
539 fsm->jiffies_start = jiffies;
540 fsm->retries = EC_FSM_RETRIES;
542}
543
544/*****************************************************************************/
545
551 ec_fsm_foe_t *fsm,
552 ec_datagram_t *datagram
553 )
554{
555 size_t current_size;
556 uint8_t *data;
557
558 current_size = fsm->rx_filename_len;
559
560 data = ec_slave_mbox_prepare_send(fsm->slave, datagram,
561 EC_MBOX_TYPE_FOE, current_size + EC_FOE_HEADER_SIZE);
562 if (IS_ERR(data)) {
563 return -1;
564 }
565
566 EC_WRITE_U16(data, EC_FOE_OPCODE_RRQ); // fsm read request
567 EC_WRITE_U32(data + 2, 0x00000000); // no passwd
568 memcpy(data + EC_FOE_HEADER_SIZE, fsm->rx_filename, current_size);
569
570 if (fsm->slave->master->debug_level) {
571 EC_SLAVE_DBG(fsm->slave, 1, "FoE Read Request:\n");
572 ec_print_data(data, current_size + EC_FOE_HEADER_SIZE);
573 }
574
575 return 0;
576}
577
578/*****************************************************************************/
579
585 ec_fsm_foe_t *fsm,
586 ec_datagram_t *datagram
587 )
588{
589 uint8_t *data;
590
591 data = ec_slave_mbox_prepare_send(fsm->slave, datagram,
592 EC_MBOX_TYPE_FOE, EC_FOE_HEADER_SIZE);
593 if (IS_ERR(data)) {
594 return -1;
595 }
596
598 EC_WRITE_U32(data + 2, fsm->rx_expected_packet_no);
599
600 return 0;
601}
602
603/*****************************************************************************/
604
611 ec_fsm_foe_t *fsm,
612 ec_datagram_t *datagram
613 )
614{
615 ec_slave_t *slave = fsm->slave;
616
617#ifdef DEBUG_FOE
618 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
619#endif
620
621 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
623 EC_SLAVE_ERR(slave, "Failed to send FoE RRQ: ");
625 return;
626 }
627
628 if (fsm->datagram->working_counter != 1) {
629 // slave did not put anything in the mailbox yet
631 EC_SLAVE_ERR(slave, "Reception of FoE RRQ failed: ");
633 return;
634 }
635
637
638 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
639
640 fsm->retries = EC_FSM_RETRIES;
642}
643
644/*****************************************************************************/
645
649 ec_fsm_foe_t *fsm,
650 ec_datagram_t *datagram
651 )
652{
653 ec_slave_t *slave = fsm->slave;
654
655 fsm->rx_buffer_offset = 0;
656 fsm->rx_expected_packet_no = 1;
657 fsm->rx_last_packet = 0;
658
659#ifdef DEBUG_FOE
660 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
661#endif
662
663 if (!(slave->sii.mailbox_protocols & EC_MBOX_FOE)) {
665 EC_SLAVE_ERR(slave, "Slave does not support FoE!\n");
666 return;
667 }
668
669 if (ec_foe_prepare_rrq_send(fsm, datagram)) {
671 return;
672 }
673
675}
676
677/*****************************************************************************/
678
682 ec_fsm_foe_t *fsm,
683 ec_datagram_t *datagram
684 )
685{
686 ec_slave_t *slave = fsm->slave;
687
688#ifdef DEBUG_FOE
689 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
690#endif
691
692 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
694 EC_SLAVE_ERR(slave, "Failed to send FoE DATA READ: ");
696 return;
697 }
698
699 if (fsm->datagram->working_counter != 1) {
701 EC_SLAVE_ERR(slave, "Reception of FoE DATA READ: ");
703 return;
704 }
705
706 if (!ec_slave_mbox_check(fsm->datagram)) {
707 unsigned long diff_ms = (fsm->datagram->jiffies_received -
708 fsm->jiffies_start) * 1000 / HZ;
709 if (diff_ms >= EC_FSM_FOE_TIMEOUT) {
711 EC_SLAVE_ERR(slave, "Timeout while waiting for ack response.\n");
712 return;
713 }
714
715 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
716 fsm->retries = EC_FSM_RETRIES;
717 return;
718 }
719
720 // Fetch response
721 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
722
723 fsm->retries = EC_FSM_RETRIES;
725}
726
727/*****************************************************************************/
728
732 ec_fsm_foe_t *fsm,
733 ec_datagram_t *datagram
734 )
735{
736 size_t rec_size;
737 uint8_t *data, opCode, packet_no, mbox_prot;
738
739 ec_slave_t *slave = fsm->slave;
740
741#ifdef DEBUG_FOE
742 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
743#endif
744
745 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
747 EC_SLAVE_ERR(slave, "Failed to receive FoE DATA READ datagram: ");
749 return;
750 }
751
752 if (fsm->datagram->working_counter != 1) {
754 EC_SLAVE_ERR(slave, "Reception of FoE DATA READ failed: ");
756 return;
757 }
758
759 data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
760 if (IS_ERR(data)) {
762 return;
763 }
764
765 if (mbox_prot != EC_MBOX_TYPE_FOE) {
766 EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
767 mbox_prot);
769 return;
770 }
771
772 opCode = EC_READ_U8(data);
773
774 if (opCode == EC_FOE_OPCODE_BUSY) {
775 if (ec_foe_prepare_send_ack(fsm, datagram)) {
777 }
778 return;
779 }
780
781 if (opCode == EC_FOE_OPCODE_ERR) {
782 fsm->request->error_code = EC_READ_U32(data + 2);
783 EC_SLAVE_ERR(slave, "Received FoE Error Request (code 0x%08x).\n",
784 fsm->request->error_code);
785 if (rec_size > 6) {
786 uint8_t text[256];
787 strncpy(text, data + 6, min(rec_size - 6, sizeof(text)));
788 EC_SLAVE_ERR(slave, "FoE Error Text: %s\n", text);
789 }
791 return;
792 }
793
794 if (opCode != EC_FOE_OPCODE_DATA) {
795 EC_SLAVE_ERR(slave, "Received OPCODE %x, expected %x.\n",
796 opCode, EC_FOE_OPCODE_DATA);
797 fsm->request->error_code = 0x00000000;
799 return;
800 }
801
802 packet_no = EC_READ_U16(data + 2);
803 if (packet_no != fsm->rx_expected_packet_no) {
804 EC_SLAVE_ERR(slave, "Received unexpected packet number.\n");
806 return;
807 }
808
809 rec_size -= EC_FOE_HEADER_SIZE;
810
811 if (fsm->rx_buffer_size >= fsm->rx_buffer_offset + rec_size) {
812 memcpy(fsm->rx_buffer + fsm->rx_buffer_offset,
813 data + EC_FOE_HEADER_SIZE, rec_size);
814 fsm->rx_buffer_offset += rec_size;
815 }
816
817 fsm->rx_last_packet =
820
821 if (fsm->rx_last_packet ||
824 <= fsm->rx_buffer_size) {
825 // either it was the last packet or a new packet will fit into the
826 // delivered buffer
827#ifdef DEBUG_FOE
828 EC_SLAVE_DBG(fsm->slave, 0, "last_packet=true\n");
829#endif
830 if (ec_foe_prepare_send_ack(fsm, datagram)) {
832 return;
833 }
834
836 }
837 else {
838 // no more data fits into the delivered buffer
839 // ... wait for new read request
840 EC_SLAVE_ERR(slave, "Data do not fit in receive buffer!\n");
841 printk(KERN_CONT " rx_buffer_size = %d\n", fsm->rx_buffer_size);
842 printk(KERN_CONT "rx_buffer_offset = %d\n", fsm->rx_buffer_offset);
843 printk(KERN_CONT " rec_size = %zd\n", rec_size);
844 printk(KERN_CONT " rx_mailbox_size = %d\n",
846 printk(KERN_CONT " rx_last_packet = %d\n", fsm->rx_last_packet);
847 fsm->request->result = FOE_READY;
848 }
849}
850
851/*****************************************************************************/
852
856 ec_fsm_foe_t *fsm,
857 ec_datagram_t *datagram
858 )
859{
860 ec_slave_t *slave = fsm->slave;
861
862#ifdef DEBUG_FOE
863 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
864#endif
865
866 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
868 EC_SLAVE_ERR(slave, "Failed to send FoE ACK: ");
870 return;
871 }
872
873 if (fsm->datagram->working_counter != 1) {
874 // slave did not put anything into the mailbox yet
876 EC_SLAVE_ERR(slave, "Reception of FoE ACK failed: ");
878 return;
879 }
880
882
883 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
884
885 if (fsm->rx_last_packet) {
886 fsm->rx_expected_packet_no = 0;
888 fsm->state = ec_fsm_foe_end;
889 }
890 else {
892 fsm->retries = EC_FSM_RETRIES;
894 }
895}
896
897/*****************************************************************************/
898
902 ec_fsm_foe_t *fsm,
903 uint32_t errorcode
904 )
905{
906 fsm->request->result = errorcode;
907 fsm->state = ec_fsm_foe_error;
908}
909
910/*****************************************************************************/
911
915 ec_fsm_foe_t *fsm,
916 uint32_t errorcode
917 )
918{
919 fsm->request->result = errorcode;
920 fsm->state = ec_fsm_foe_error;
921}
922
923/*****************************************************************************/
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_SENT
Sent (still in the queue).
Definition: datagram.h:77
@ EC_DATAGRAM_QUEUED
Queued for sending.
Definition: datagram.h:76
FoE defines.
@ FOE_RX_DATA_ACK_ERROR
Error acknowledging received data.
Definition: foe.h:53
@ FOE_WC_ERROR
Working counter error.
Definition: foe.h:45
@ FOE_MBOX_PROT_ERROR
Mailbox protocol error.
Definition: foe.h:57
@ FOE_RECEIVE_ERROR
Receive error.
Definition: foe.h:46
@ FOE_OPCODE_ERROR
OpCode error.
Definition: foe.h:50
@ FOE_PACKETNO_ERROR
Packet number error.
Definition: foe.h:49
@ FOE_ACK_ERROR
Acknowledge error.
Definition: foe.h:54
@ FOE_TIMEOUT_ERROR
Timeout error.
Definition: foe.h:51
@ FOE_MBOX_FETCH_ERROR
Error fetching data from mailbox.
Definition: foe.h:55
@ FOE_PROT_ERROR
Protocol error.
Definition: foe.h:47
@ FOE_READY
Ready.
Definition: foe.h:43
@ EC_FOE_OPCODE_RRQ
Read request.
Definition: fsm_foe.c:63
@ EC_FOE_OPCODE_ERR
Error.
Definition: fsm_foe.c:67
@ EC_FOE_OPCODE_WRQ
Write request.
Definition: fsm_foe.c:64
@ EC_FOE_OPCODE_BUSY
Busy.
Definition: fsm_foe.c:68
@ EC_FOE_OPCODE_DATA
Data.
Definition: fsm_foe.c:65
@ EC_FOE_OPCODE_ACK
Acknowledge.
Definition: fsm_foe.c:66
#define EC_FOE_HEADER_SIZE
Size of the FoE header.
Definition: fsm_foe.c:51
void ec_fsm_foe_state_wrq_sent(ec_fsm_foe_t *, ec_datagram_t *)
State: WRQ SENT.
Definition: fsm_foe.c:472
void ec_fsm_foe_state_rrq_sent(ec_fsm_foe_t *, ec_datagram_t *)
State: RRQ SENT.
Definition: fsm_foe.c:610
enum @0 ec_foe_opcode_t
FoE OpCodes.
void ec_fsm_foe_state_ack_check(ec_fsm_foe_t *, ec_datagram_t *)
Check for acknowledge.
Definition: fsm_foe.c:340
void ec_fsm_foe_write_start(ec_fsm_foe_t *, ec_datagram_t *)
Initializes the FoE write state machine.
Definition: fsm_foe.c:306
int ec_fsm_foe_exec(ec_fsm_foe_t *fsm, ec_datagram_t *datagram)
Executes the current state of the state machine.
Definition: fsm_foe.c:125
void ec_fsm_foe_read_start(ec_fsm_foe_t *, ec_datagram_t *)
Starting state for read operations.
Definition: fsm_foe.c:648
int ec_foe_prepare_data_send(ec_fsm_foe_t *, ec_datagram_t *)
Sends a file or the next fragment.
Definition: fsm_foe.c:232
int ec_foe_prepare_rrq_send(ec_fsm_foe_t *, ec_datagram_t *)
Prepare a read request (RRQ) with filename.
Definition: fsm_foe.c:550
#define EC_FSM_FOE_TIMEOUT
Maximum time in ms to wait for responses when reading out the dictionary.
Definition: fsm_foe.c:47
void ec_fsm_foe_clear(ec_fsm_foe_t *fsm)
Destructor.
Definition: fsm_foe.c:115
void ec_fsm_foe_state_data_sent(ec_fsm_foe_t *, ec_datagram_t *)
State: WRQ SENT.
Definition: fsm_foe.c:513
int ec_foe_prepare_send_ack(ec_fsm_foe_t *, ec_datagram_t *)
Prepare to send an acknowledge.
Definition: fsm_foe.c:584
void ec_foe_set_tx_error(ec_fsm_foe_t *, uint32_t)
Set an error code and go to the send error state.
Definition: fsm_foe.c:901
void ec_foe_set_rx_error(ec_fsm_foe_t *, uint32_t)
Set an error code and go to the receive error state.
Definition: fsm_foe.c:914
int ec_fsm_foe_success(const ec_fsm_foe_t *fsm)
Returns, if the state machine terminated with success.
Definition: fsm_foe.c:159
void ec_fsm_foe_state_sent_ack(ec_fsm_foe_t *, ec_datagram_t *)
Sent an acknowledge.
Definition: fsm_foe.c:855
void ec_fsm_foe_init(ec_fsm_foe_t *fsm)
Constructor.
Definition: fsm_foe.c:103
int ec_foe_prepare_wrq_send(ec_fsm_foe_t *, ec_datagram_t *)
Prepare a write request (WRQ) with filename.
Definition: fsm_foe.c:273
void ec_fsm_foe_state_data_read(ec_fsm_foe_t *, ec_datagram_t *)
Start reading data.
Definition: fsm_foe.c:731
void ec_fsm_foe_transfer(ec_fsm_foe_t *fsm, ec_slave_t *slave, ec_foe_request_t *request)
Prepares an FoE transfer.
Definition: fsm_foe.c:168
void ec_fsm_foe_state_ack_read(ec_fsm_foe_t *, ec_datagram_t *)
Acknowledge a read operation.
Definition: fsm_foe.c:392
void ec_fsm_foe_error(ec_fsm_foe_t *, ec_datagram_t *)
State: ERROR.
Definition: fsm_foe.c:202
void ec_fsm_foe_end(ec_fsm_foe_t *, ec_datagram_t *)
State: END.
Definition: fsm_foe.c:216
void ec_fsm_foe_state_data_check(ec_fsm_foe_t *, ec_datagram_t *)
Check for data.
Definition: fsm_foe.c:681
EtherCAT FoE state machines.
Global definitions and macros.
#define EC_MBOX_HEADER_SIZE
Mailbox header size.
Definition: globals.h:83
#define EC_FSM_RETRIES
Number of state machine retries on datagram timeout.
Definition: globals.h:47
@ EC_MBOX_FOE
File-Access over EtherCAT.
Definition: globals.h:138
void ec_print_data(const uint8_t *, size_t)
Outputs frame contents for debugging purposes.
Definition: module.c:348
#define EC_WRITE_U32(DATA, VAL)
Write a 32-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2300
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2178
#define EC_READ_U8(DATA)
Read an 8-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2162
#define EC_READ_U32(DATA)
Read a 32-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2194
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2283
@ EC_DIR_OUTPUT
Values written by the master.
Definition: ecrt.h:432
uint8_t * ec_slave_mbox_fetch(const ec_slave_t *slave, const ec_datagram_t *datagram, uint8_t *type, size_t *size)
Processes received mailbox data.
Definition: mailbox.c:165
int ec_slave_mbox_prepare_check(const ec_slave_t *slave, ec_datagram_t *datagram)
Prepares a datagram for checking the mailbox state.
Definition: mailbox.c:96
int ec_slave_mbox_prepare_fetch(const ec_slave_t *slave, ec_datagram_t *datagram)
Prepares a datagram to fetch mailbox data.
Definition: mailbox.c:127
uint8_t * ec_slave_mbox_prepare_send(const ec_slave_t *slave, ec_datagram_t *datagram, uint8_t type, size_t size)
Prepares a mailbox-send datagram.
Definition: mailbox.c:51
int ec_slave_mbox_check(const ec_datagram_t *datagram)
Processes a mailbox state checking datagram.
Definition: mailbox.c:115
Mailbox functionality.
EtherCAT master structure.
#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
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
FoE request.
Definition: foe_request.h:50
ec_direction_t dir
Direction.
Definition: foe_request.h:60
uint32_t result
FoE request abort code.
Definition: foe_request.h:68
size_t buffer_size
Size of FoE data memory.
Definition: foe_request.h:53
uint32_t error_code
Error code from an FoE Error Request.
Definition: foe_request.h:69
uint8_t * buffer
Pointer to FoE data.
Definition: foe_request.h:52
uint8_t * file_name
Pointer to the filename.
Definition: foe_request.h:67
size_t data_size
Size of FoE data.
Definition: foe_request.h:54
Finite state machines for the CANopen-over-EtherCAT protocol.
Definition: fsm_foe.h:53
ec_foe_request_t * request
FoE request.
Definition: fsm_foe.h:61
uint32_t rx_last_packet
Current packet is the last to receive.
Definition: fsm_foe.h:77
ec_datagram_t * datagram
Datagram used in previous step.
Definition: fsm_foe.h:58
uint8_t * rx_buffer
Buffer for received data.
Definition: fsm_foe.h:73
uint32_t tx_buffer_size
Size of data to transmit.
Definition: fsm_foe.h:65
unsigned int retries
Retries upon datagram timeout.
Definition: fsm_foe.h:55
unsigned long jiffies_start
FoE timestamp.
Definition: fsm_foe.h:59
uint32_t rx_expected_packet_no
Expected receive packet number.
Definition: fsm_foe.h:76
uint32_t tx_filename_len
Lenth of transmit file name.
Definition: fsm_foe.h:71
uint32_t tx_packet_no
FoE packet number.
Definition: fsm_foe.h:68
uint32_t rx_buffer_offset
Offset in receive buffer.
Definition: fsm_foe.h:75
uint8_t * tx_filename
Name of file to transmit.
Definition: fsm_foe.h:70
uint32_t tx_last_packet
Current packet is last one to send.
Definition: fsm_foe.h:67
uint32_t rx_filename_len
Length of the receive file name.
Definition: fsm_foe.h:79
uint32_t rx_buffer_size
Size of receive buffer.
Definition: fsm_foe.h:74
ec_slave_t * slave
Slave the FSM runs on.
Definition: fsm_foe.h:54
uint32_t tx_buffer_offset
Offset of data to tranmit next.
Definition: fsm_foe.h:66
uint8_t * rx_filename
Name of the file to receive.
Definition: fsm_foe.h:78
void(* state)(ec_fsm_foe_t *, ec_datagram_t *)
FoE state function.
Definition: fsm_foe.h:57
uint32_t tx_current_size
Size of current packet to send.
Definition: fsm_foe.h:69
uint8_t * tx_buffer
Buffer with data to transmit.
Definition: fsm_foe.h:64
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
uint16_t configured_tx_mailbox_size
Configured send mailbox size.
Definition: slave.h:201
ec_master_t * master
Master owning the slave.
Definition: slave.h:178