IgH EtherCAT Master  1.6.9
fsm_foe.c
Go to the documentation of this file.
1/*****************************************************************************
2 *
3 * Copyright (C) 2008 Olav Zarges, imc Messsysteme GmbH
4 * 2013 Florian Pose <fp@igh.de>
5 *
6 * This file is part of the IgH EtherCAT Master.
7 *
8 * The IgH EtherCAT Master is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version 2, as
10 * published by the Free Software Foundation.
11 *
12 * The IgH EtherCAT Master is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15 * Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with the IgH EtherCAT Master; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 ****************************************************************************/
22
26
27/****************************************************************************/
28
29#include "globals.h"
30#include "master.h"
31#include "mailbox.h"
32#include "fsm_foe.h"
33#include "foe.h"
34
35/****************************************************************************/
36
39#define EC_FSM_FOE_TIMEOUT 3000
40
43#define EC_FOE_HEADER_SIZE 6
44// uint8_t OpCode
45// uint8_t reserved
46// uint32_t PacketNo, Password, ErrorCode
47
48//#define DEBUG_FOE
49
50/****************************************************************************/
51
54enum {
61};
62
63/****************************************************************************/
64
69
70void ec_foe_set_tx_error(ec_fsm_foe_t *, uint32_t);
71void ec_foe_set_rx_error(ec_fsm_foe_t *, uint32_t);
72
75
78
81
83
87
90
91/****************************************************************************/
92
96 ec_fsm_foe_t *fsm
97 )
98{
99 fsm->state = NULL;
100 fsm->datagram = NULL;
101}
102
103/****************************************************************************/
104
108{
109}
110
111/****************************************************************************/
112
118 ec_fsm_foe_t *fsm,
119 ec_datagram_t *datagram
120 )
121{
122 int datagram_used = 0;
123
124 if (fsm->datagram &&
125 (fsm->datagram->state == EC_DATAGRAM_INIT ||
127 fsm->datagram->state == EC_DATAGRAM_SENT)) {
128 // datagram not received yet
129 return datagram_used;
130 }
131
132 fsm->state(fsm, datagram);
133
134 datagram_used =
135 fsm->state != ec_fsm_foe_end && fsm->state != ec_fsm_foe_error;
136
137 if (datagram_used) {
138 fsm->datagram = datagram;
139 } else {
140 fsm->datagram = NULL;
141 }
142
143 return datagram_used;
144}
145
146/****************************************************************************/
147
152{
153 return fsm->state == ec_fsm_foe_end;
154}
155
156/****************************************************************************/
157
161 ec_fsm_foe_t *fsm,
162 ec_slave_t *slave,
163 ec_foe_request_t *request
164 )
165{
166 fsm->slave = slave;
167 fsm->request = request;
168
169 if (request->dir == EC_DIR_OUTPUT) {
170 fsm->tx_buffer = fsm->request->buffer;
171 fsm->tx_buffer_size = fsm->request->data_size;
172 fsm->tx_buffer_offset = 0;
173
174 fsm->tx_filename = fsm->request->file_name;
175 fsm->tx_filename_len = strlen(fsm->tx_filename);
176
178 }
179 else {
180 fsm->rx_buffer = fsm->request->buffer;
182
183 fsm->rx_filename = fsm->request->file_name;
184 fsm->rx_filename_len = strlen(fsm->rx_filename);
185
187 }
188}
189
190/****************************************************************************/
191
195 ec_fsm_foe_t *fsm,
196 ec_datagram_t *datagram
197 )
198{
199#ifdef DEBUG_FOE
200 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
201#endif
202}
203
204/****************************************************************************/
205
209 ec_fsm_foe_t *fsm,
210 ec_datagram_t *datagram
211 )
212{
213#ifdef DEBUG_FOE
214 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
215#endif
216}
217
218/****************************************************************************/
219
225 ec_fsm_foe_t *fsm,
226 ec_datagram_t *datagram
227 )
228{
229 size_t remaining_size, current_size;
230 uint8_t *data;
231
232 remaining_size = fsm->tx_buffer_size - fsm->tx_buffer_offset;
233
234 if (remaining_size < fsm->slave->configured_tx_mailbox_size
236 current_size = remaining_size;
237 fsm->tx_last_packet = 1;
238 } else {
239 current_size = fsm->slave->configured_tx_mailbox_size
241 }
242
244 datagram, EC_MBOX_TYPE_FOE, current_size + EC_FOE_HEADER_SIZE);
245 if (IS_ERR(data)) {
246 return -1;
247 }
248
249 EC_WRITE_U16(data, EC_FOE_OPCODE_DATA); // OpCode = DataBlock req.
250 EC_WRITE_U32(data + 2, fsm->tx_packet_no); // PacketNo, Password
251
252 memcpy(data + EC_FOE_HEADER_SIZE,
253 fsm->tx_buffer + fsm->tx_buffer_offset, current_size);
254 fsm->tx_current_size = current_size;
255
256 return 0;
257}
258
259/****************************************************************************/
260
266 ec_fsm_foe_t *fsm,
267 ec_datagram_t *datagram
268 )
269{
270 size_t current_size;
271 uint8_t *data;
272
273 fsm->tx_buffer_offset = 0;
274 fsm->tx_current_size = 0;
275 fsm->tx_packet_no = 0;
276 fsm->tx_last_packet = 0;
277
278 current_size = fsm->tx_filename_len;
279
280 data = ec_slave_mbox_prepare_send(fsm->slave, datagram,
281 EC_MBOX_TYPE_FOE, current_size + EC_FOE_HEADER_SIZE);
282 if (IS_ERR(data)) {
283 return -1;
284 }
285
286 EC_WRITE_U16( data, EC_FOE_OPCODE_WRQ); // fsm write request
287 EC_WRITE_U32( data + 2, fsm->tx_packet_no );
288
289 memcpy(data + EC_FOE_HEADER_SIZE, fsm->tx_filename, current_size);
290
291 return 0;
292}
293
294/****************************************************************************/
295
299 ec_fsm_foe_t *fsm,
300 ec_datagram_t *datagram
301 )
302{
303 ec_slave_t *slave = fsm->slave;
304
305 fsm->tx_buffer_offset = 0;
306 fsm->tx_current_size = 0;
307 fsm->tx_packet_no = 0;
308 fsm->tx_last_packet = 0;
309
310#ifdef DEBUG_FOE
311 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
312#endif
313
314 if (!(slave->sii.mailbox_protocols & EC_MBOX_FOE)) {
316 EC_SLAVE_ERR(slave, "Slave does not support FoE!\n");
317 return;
318 }
319
320 if (ec_foe_prepare_wrq_send(fsm, datagram)) {
322 return;
323 }
324
326}
327
328/****************************************************************************/
329
333 ec_fsm_foe_t *fsm,
334 ec_datagram_t *datagram
335 )
336{
337 ec_slave_t *slave = fsm->slave;
338
339#ifdef DEBUG_FOE
340 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
341#endif
342
343 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
345 EC_SLAVE_ERR(slave, "Failed to receive FoE mailbox check datagram: ");
347 return;
348 }
349
350 if (fsm->datagram->working_counter != 1) {
352 EC_SLAVE_ERR(slave, "Reception of FoE mailbox check datagram"
353 " failed: ");
355 return;
356 }
357
358 if (!ec_slave_mbox_check(fsm->datagram)) {
359 // slave did not put anything in the mailbox yet
360 unsigned long diff_ms = (fsm->datagram->jiffies_received -
361 fsm->jiffies_start) * 1000 / HZ;
362 if (diff_ms >= EC_FSM_FOE_TIMEOUT) {
364 EC_SLAVE_ERR(slave, "Timeout while waiting for ack response.\n");
365 return;
366 }
367
368 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
369 fsm->retries = EC_FSM_RETRIES;
370 return;
371 }
372
373 // Fetch response
374 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
375
376 fsm->retries = EC_FSM_RETRIES;
378}
379
380/****************************************************************************/
381
385 ec_fsm_foe_t *fsm,
386 ec_datagram_t *datagram
387 )
388{
389 ec_slave_t *slave = fsm->slave;
390 uint8_t *data, mbox_prot;
391 uint8_t opCode;
392 size_t rec_size;
393
394#ifdef DEBUG_FOE
395 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
396#endif
397
398 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
400 EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: ");
402 return;
403 }
404
405 if (fsm->datagram->working_counter != 1) {
407 EC_SLAVE_ERR(slave, "Reception of FoE ack response failed: ");
409 return;
410 }
411
412 data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
413 if (IS_ERR(data)) {
415 return;
416 }
417
418 if (mbox_prot != EC_MBOX_TYPE_FOE) {
420 EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
421 mbox_prot);
422 return;
423 }
424
425 opCode = EC_READ_U8(data);
426
427 if (opCode == EC_FOE_OPCODE_BUSY) {
428 // slave not ready
429 if (ec_foe_prepare_data_send(fsm, datagram)) {
431 EC_SLAVE_ERR(slave, "Slave is busy.\n");
432 return;
433 }
435 return;
436 }
437
438 if (opCode == EC_FOE_OPCODE_ACK) {
439 fsm->tx_packet_no++;
441
442 if (fsm->tx_last_packet) {
443 fsm->state = ec_fsm_foe_end;
444 return;
445 }
446
447 if (ec_foe_prepare_data_send(fsm, datagram)) {
449 return;
450 }
452 return;
453 }
455}
456
457/****************************************************************************/
458
465 ec_fsm_foe_t *fsm,
466 ec_datagram_t *datagram
467 )
468{
469 ec_slave_t *slave = fsm->slave;
470
471#ifdef DEBUG_FOE
472 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
473#endif
474
475 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
477 EC_SLAVE_ERR(slave, "Failed to send FoE WRQ: ");
479 return;
480 }
481
482 if (fsm->datagram->working_counter != 1) {
483 // slave did not put anything in the mailbox yet
485 EC_SLAVE_ERR(slave, "Reception of FoE WRQ failed: ");
487 return;
488 }
489
491
492 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
493
494 fsm->retries = EC_FSM_RETRIES;
496}
497
498/****************************************************************************/
499
506 ec_fsm_foe_t *fsm,
507 ec_datagram_t *datagram
508 )
509{
510 ec_slave_t *slave = fsm->slave;
511
512#ifdef DEBUG_FOE
513 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
514#endif
515
516 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
518 EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: ");
520 return;
521 }
522
523 if (fsm->datagram->working_counter != 1) {
525 EC_SLAVE_ERR(slave, "Reception of FoE data send failed: ");
527 return;
528 }
529
530 ec_slave_mbox_prepare_check(slave, datagram);
531 fsm->jiffies_start = jiffies;
532 fsm->retries = EC_FSM_RETRIES;
534}
535
536/****************************************************************************/
537
543 ec_fsm_foe_t *fsm,
544 ec_datagram_t *datagram
545 )
546{
547 size_t current_size;
548 uint8_t *data;
549
550 current_size = fsm->rx_filename_len;
551
552 data = ec_slave_mbox_prepare_send(fsm->slave, datagram,
553 EC_MBOX_TYPE_FOE, current_size + EC_FOE_HEADER_SIZE);
554 if (IS_ERR(data)) {
555 return -1;
556 }
557
558 EC_WRITE_U16(data, EC_FOE_OPCODE_RRQ); // fsm read request
559 EC_WRITE_U32(data + 2, 0x00000000); // no passwd
560 memcpy(data + EC_FOE_HEADER_SIZE, fsm->rx_filename, current_size);
561
562 if (fsm->slave->master->debug_level) {
563 EC_SLAVE_DBG(fsm->slave, 1, "FoE Read Request:\n");
564 ec_print_data(data, current_size + EC_FOE_HEADER_SIZE);
565 }
566
567 return 0;
568}
569
570/****************************************************************************/
571
577 ec_fsm_foe_t *fsm,
578 ec_datagram_t *datagram
579 )
580{
581 uint8_t *data;
582
583 data = ec_slave_mbox_prepare_send(fsm->slave, datagram,
584 EC_MBOX_TYPE_FOE, EC_FOE_HEADER_SIZE);
585 if (IS_ERR(data)) {
586 return -1;
587 }
588
590 EC_WRITE_U32(data + 2, fsm->rx_expected_packet_no);
591
592 return 0;
593}
594
595/****************************************************************************/
596
603 ec_fsm_foe_t *fsm,
604 ec_datagram_t *datagram
605 )
606{
607 ec_slave_t *slave = fsm->slave;
608
609#ifdef DEBUG_FOE
610 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
611#endif
612
613 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
615 EC_SLAVE_ERR(slave, "Failed to send FoE RRQ: ");
617 return;
618 }
619
620 if (fsm->datagram->working_counter != 1) {
621 // slave did not put anything in the mailbox yet
623 EC_SLAVE_ERR(slave, "Reception of FoE RRQ failed: ");
625 return;
626 }
627
629
630 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
631
632 fsm->retries = EC_FSM_RETRIES;
634}
635
636/****************************************************************************/
637
641 ec_fsm_foe_t *fsm,
642 ec_datagram_t *datagram
643 )
644{
645 ec_slave_t *slave = fsm->slave;
646
647 fsm->rx_buffer_offset = 0;
648 fsm->rx_expected_packet_no = 1;
649 fsm->rx_last_packet = 0;
650
651#ifdef DEBUG_FOE
652 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
653#endif
654
655 if (!(slave->sii.mailbox_protocols & EC_MBOX_FOE)) {
657 EC_SLAVE_ERR(slave, "Slave does not support FoE!\n");
658 return;
659 }
660
661 if (ec_foe_prepare_rrq_send(fsm, datagram)) {
663 return;
664 }
665
667}
668
669/****************************************************************************/
670
674 ec_fsm_foe_t *fsm,
675 ec_datagram_t *datagram
676 )
677{
678 ec_slave_t *slave = fsm->slave;
679
680#ifdef DEBUG_FOE
681 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
682#endif
683
684 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
686 EC_SLAVE_ERR(slave, "Failed to send FoE DATA READ: ");
688 return;
689 }
690
691 if (fsm->datagram->working_counter != 1) {
693 EC_SLAVE_ERR(slave, "Reception of FoE DATA READ: ");
695 return;
696 }
697
698 if (!ec_slave_mbox_check(fsm->datagram)) {
699 unsigned long diff_ms = (fsm->datagram->jiffies_received -
700 fsm->jiffies_start) * 1000 / HZ;
701 if (diff_ms >= EC_FSM_FOE_TIMEOUT) {
703 EC_SLAVE_ERR(slave, "Timeout while waiting for ack response.\n");
704 return;
705 }
706
707 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
708 fsm->retries = EC_FSM_RETRIES;
709 return;
710 }
711
712 // Fetch response
713 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
714
715 fsm->retries = EC_FSM_RETRIES;
717}
718
719/****************************************************************************/
720
724 ec_fsm_foe_t *fsm,
725 ec_datagram_t *datagram
726 )
727{
728 size_t rec_size;
729 uint8_t *data, opCode, packet_no, mbox_prot;
730
731 ec_slave_t *slave = fsm->slave;
732
733#ifdef DEBUG_FOE
734 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
735#endif
736
737 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
739 EC_SLAVE_ERR(slave, "Failed to receive FoE DATA READ datagram: ");
741 return;
742 }
743
744 if (fsm->datagram->working_counter != 1) {
746 EC_SLAVE_ERR(slave, "Reception of FoE DATA READ failed: ");
748 return;
749 }
750
751 data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
752 if (IS_ERR(data)) {
754 return;
755 }
756
757 if (mbox_prot != EC_MBOX_TYPE_FOE) {
758 EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
759 mbox_prot);
761 return;
762 }
763
764 opCode = EC_READ_U8(data);
765
766 if (opCode == EC_FOE_OPCODE_BUSY) {
767 if (ec_foe_prepare_send_ack(fsm, datagram)) {
769 }
770 return;
771 }
772
773 if (opCode == EC_FOE_OPCODE_ERR) {
774 fsm->request->error_code = EC_READ_U32(data + 2);
775 EC_SLAVE_ERR(slave, "Received FoE Error Request (code 0x%08x).\n",
776 fsm->request->error_code);
777 if (rec_size > 6) {
778 uint8_t text[256];
779 strncpy(text, data + 6, min(rec_size - 6, sizeof(text)));
780 EC_SLAVE_ERR(slave, "FoE Error Text: %s\n", text);
781 }
783 return;
784 }
785
786 if (opCode != EC_FOE_OPCODE_DATA) {
787 EC_SLAVE_ERR(slave, "Received OPCODE %x, expected %x.\n",
788 opCode, EC_FOE_OPCODE_DATA);
789 fsm->request->error_code = 0x00000000;
791 return;
792 }
793
794 packet_no = EC_READ_U16(data + 2);
795 if (packet_no != fsm->rx_expected_packet_no) {
796 EC_SLAVE_ERR(slave, "Received unexpected packet number.\n");
798 return;
799 }
800
801 rec_size -= EC_FOE_HEADER_SIZE;
802
803 if (fsm->rx_buffer_size >= fsm->rx_buffer_offset + rec_size) {
804 memcpy(fsm->rx_buffer + fsm->rx_buffer_offset,
805 data + EC_FOE_HEADER_SIZE, rec_size);
806 fsm->rx_buffer_offset += rec_size;
807 }
808
809 fsm->rx_last_packet =
812
813 if (fsm->rx_last_packet ||
816 <= fsm->rx_buffer_size) {
817 // either it was the last packet or a new packet will fit into the
818 // delivered buffer
819#ifdef DEBUG_FOE
820 EC_SLAVE_DBG(fsm->slave, 0, "last_packet=true\n");
821#endif
822 if (ec_foe_prepare_send_ack(fsm, datagram)) {
824 return;
825 }
826
828 }
829 else {
830 // no more data fits into the delivered buffer
831 // ... wait for new read request
832 EC_SLAVE_ERR(slave, "Data do not fit in receive buffer!\n");
833 printk(KERN_CONT " rx_buffer_size = %d\n", fsm->rx_buffer_size);
834 printk(KERN_CONT "rx_buffer_offset = %d\n", fsm->rx_buffer_offset);
835 printk(KERN_CONT " rec_size = %zd\n", rec_size);
836 printk(KERN_CONT " rx_mailbox_size = %d\n",
838 printk(KERN_CONT " rx_last_packet = %d\n", fsm->rx_last_packet);
839 fsm->request->result = FOE_READY;
840 }
841}
842
843/****************************************************************************/
844
848 ec_fsm_foe_t *fsm,
849 ec_datagram_t *datagram
850 )
851{
852 ec_slave_t *slave = fsm->slave;
853
854#ifdef DEBUG_FOE
855 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
856#endif
857
858 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
860 EC_SLAVE_ERR(slave, "Failed to send FoE ACK: ");
862 return;
863 }
864
865 if (fsm->datagram->working_counter != 1) {
866 // slave did not put anything into the mailbox yet
868 EC_SLAVE_ERR(slave, "Reception of FoE ACK failed: ");
870 return;
871 }
872
874
875 ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
876
877 if (fsm->rx_last_packet) {
878 fsm->rx_expected_packet_no = 0;
880 fsm->state = ec_fsm_foe_end;
881 }
882 else {
884 fsm->retries = EC_FSM_RETRIES;
886 }
887}
888
889/****************************************************************************/
890
894 ec_fsm_foe_t *fsm,
895 uint32_t errorcode
896 )
897{
898 fsm->request->result = errorcode;
899 fsm->state = ec_fsm_foe_error;
900}
901
902/****************************************************************************/
903
907 ec_fsm_foe_t *fsm,
908 uint32_t errorcode
909 )
910{
911 fsm->request->result = errorcode;
912 fsm->state = ec_fsm_foe_error;
913}
914
915/****************************************************************************/
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_SENT
Sent (still in the queue).
Definition datagram.h:69
@ EC_DATAGRAM_QUEUED
Queued for sending.
Definition datagram.h:68
FoE defines.
@ FOE_RX_DATA_ACK_ERROR
Error acknowledging received data.
Definition foe.h:45
@ FOE_WC_ERROR
Working counter error.
Definition foe.h:37
@ FOE_MBOX_PROT_ERROR
Mailbox protocol error.
Definition foe.h:49
@ FOE_RECEIVE_ERROR
Receive error.
Definition foe.h:38
@ FOE_OPCODE_ERROR
OpCode error.
Definition foe.h:42
@ FOE_PACKETNO_ERROR
Packet number error.
Definition foe.h:41
@ FOE_ACK_ERROR
Acknowledge error.
Definition foe.h:46
@ FOE_TIMEOUT_ERROR
Timeout error.
Definition foe.h:43
@ FOE_MBOX_FETCH_ERROR
Error fetching data from mailbox.
Definition foe.h:47
@ FOE_PROT_ERROR
Protocol error.
Definition foe.h:39
@ FOE_READY
Ready.
Definition foe.h:35
#define EC_FOE_HEADER_SIZE
Size of the FoE header.
Definition fsm_foe.c:43
void ec_fsm_foe_state_wrq_sent(ec_fsm_foe_t *, ec_datagram_t *)
State: WRQ SENT.
Definition fsm_foe.c:464
void ec_fsm_foe_state_rrq_sent(ec_fsm_foe_t *, ec_datagram_t *)
State: RRQ SENT.
Definition fsm_foe.c:602
void ec_fsm_foe_state_ack_check(ec_fsm_foe_t *, ec_datagram_t *)
Check for acknowledge.
Definition fsm_foe.c:332
void ec_fsm_foe_write_start(ec_fsm_foe_t *, ec_datagram_t *)
Initializes the FoE write state machine.
Definition fsm_foe.c:298
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:117
void ec_fsm_foe_read_start(ec_fsm_foe_t *, ec_datagram_t *)
Starting state for read operations.
Definition fsm_foe.c:640
int ec_foe_prepare_data_send(ec_fsm_foe_t *, ec_datagram_t *)
Sends a file or the next fragment.
Definition fsm_foe.c:224
int ec_foe_prepare_rrq_send(ec_fsm_foe_t *, ec_datagram_t *)
Prepare a read request (RRQ) with filename.
Definition fsm_foe.c:542
#define EC_FSM_FOE_TIMEOUT
Maximum time in ms to wait for responses when reading out the dictionary.
Definition fsm_foe.c:39
void ec_fsm_foe_clear(ec_fsm_foe_t *fsm)
Destructor.
Definition fsm_foe.c:107
@ EC_FOE_OPCODE_RRQ
Read request.
Definition fsm_foe.c:55
@ EC_FOE_OPCODE_ERR
Error.
Definition fsm_foe.c:59
@ EC_FOE_OPCODE_WRQ
Write request.
Definition fsm_foe.c:56
@ EC_FOE_OPCODE_BUSY
Busy.
Definition fsm_foe.c:60
@ EC_FOE_OPCODE_DATA
Data.
Definition fsm_foe.c:57
@ EC_FOE_OPCODE_ACK
Acknowledge.
Definition fsm_foe.c:58
void ec_fsm_foe_state_data_sent(ec_fsm_foe_t *, ec_datagram_t *)
State: WRQ SENT.
Definition fsm_foe.c:505
int ec_foe_prepare_send_ack(ec_fsm_foe_t *, ec_datagram_t *)
Prepare to send an acknowledge.
Definition fsm_foe.c:576
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:893
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:906
int ec_fsm_foe_success(const ec_fsm_foe_t *fsm)
Returns, if the state machine terminated with success.
Definition fsm_foe.c:151
void ec_fsm_foe_state_sent_ack(ec_fsm_foe_t *, ec_datagram_t *)
Sent an acknowledge.
Definition fsm_foe.c:847
void ec_fsm_foe_init(ec_fsm_foe_t *fsm)
Constructor.
Definition fsm_foe.c:95
int ec_foe_prepare_wrq_send(ec_fsm_foe_t *, ec_datagram_t *)
Prepare a write request (WRQ) with filename.
Definition fsm_foe.c:265
void ec_fsm_foe_state_data_read(ec_fsm_foe_t *, ec_datagram_t *)
Start reading data.
Definition fsm_foe.c:723
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:160
void ec_fsm_foe_state_ack_read(ec_fsm_foe_t *, ec_datagram_t *)
Acknowledge a read operation.
Definition fsm_foe.c:384
void ec_fsm_foe_error(ec_fsm_foe_t *, ec_datagram_t *)
State: ERROR.
Definition fsm_foe.c:194
void ec_fsm_foe_end(ec_fsm_foe_t *, ec_datagram_t *)
State: END.
Definition fsm_foe.c:208
void ec_fsm_foe_state_data_check(ec_fsm_foe_t *, ec_datagram_t *)
Check for data.
Definition fsm_foe.c:673
EtherCAT FoE state machines.
struct ec_fsm_foe ec_fsm_foe_t
Definition fsm_foe.h:41
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:147
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_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.
#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
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
FoE request.
Definition foe_request.h:42
ec_direction_t dir
Direction.
Definition foe_request.h:52
uint32_t result
FoE request abort code.
Definition foe_request.h:60
size_t buffer_size
Size of FoE data memory.
Definition foe_request.h:45
uint32_t error_code
Error code from an FoE Error Request.
Definition foe_request.h:61
uint8_t * buffer
Pointer to FoE data.
Definition foe_request.h:44
uint8_t * file_name
Pointer to the filename.
Definition foe_request.h:59
size_t data_size
Size of FoE data.
Definition foe_request.h:46
ec_foe_request_t * request
FoE request.
Definition fsm_foe.h:54
uint32_t rx_last_packet
Current packet is the last to receive.
Definition fsm_foe.h:70
ec_datagram_t * datagram
Datagram used in previous step.
Definition fsm_foe.h:51
uint8_t * rx_buffer
Buffer for received data.
Definition fsm_foe.h:66
uint32_t tx_buffer_size
Size of data to transmit.
Definition fsm_foe.h:58
unsigned int retries
Retries upon datagram timeout.
Definition fsm_foe.h:47
unsigned long jiffies_start
FoE timestamp.
Definition fsm_foe.h:52
uint32_t rx_expected_packet_no
Expected receive packet number.
Definition fsm_foe.h:69
uint32_t tx_filename_len
Lenth of transmit file name.
Definition fsm_foe.h:64
uint32_t tx_packet_no
FoE packet number.
Definition fsm_foe.h:61
uint32_t rx_buffer_offset
Offset in receive buffer.
Definition fsm_foe.h:68
uint8_t * tx_filename
Name of file to transmit.
Definition fsm_foe.h:63
uint32_t tx_last_packet
Current packet is last one to send.
Definition fsm_foe.h:60
uint32_t rx_filename_len
Length of the receive file name.
Definition fsm_foe.h:72
uint32_t rx_buffer_size
Size of receive buffer.
Definition fsm_foe.h:67
ec_slave_t * slave
Slave the FSM runs on.
Definition fsm_foe.h:46
uint32_t tx_buffer_offset
Offset of data to tranmit next.
Definition fsm_foe.h:59
uint8_t * rx_filename
Name of the file to receive.
Definition fsm_foe.h:71
void(* state)(ec_fsm_foe_t *, ec_datagram_t *)
FoE state function.
Definition fsm_foe.h:49
uint32_t tx_current_size
Size of current packet to send.
Definition fsm_foe.h:62
uint8_t * tx_buffer
Buffer with data to transmit.
Definition fsm_foe.h:57
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
uint16_t configured_tx_mailbox_size
Configured send mailbox size.
Definition slave.h:193
ec_master_t * master
Master owning the slave.
Definition slave.h:170