IgH EtherCAT Master  1.5.3
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 
62 enum {
70 
71 /*****************************************************************************/
72 
77 
78 void ec_foe_set_tx_error(ec_fsm_foe_t *, uint32_t);
79 void 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 ||
134  fsm->datagram->state == EC_DATAGRAM_QUEUED ||
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;
189  fsm->rx_buffer_size = fsm->request->buffer_size;
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 
251  data = ec_slave_mbox_prepare_send(fsm->slave,
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++;
448  fsm->tx_buffer_offset += fsm->tx_current_size;
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 
498  fsm->jiffies_start = fsm->datagram->jiffies_sent;
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 
636  fsm->jiffies_start = fsm->datagram->jiffies_sent;
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 =
819  != slave->configured_rx_mailbox_size);
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 
881  fsm->jiffies_start = fsm->datagram->jiffies_sent;
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;
887  fsm->request->data_size = fsm->rx_buffer_offset;
888  fsm->state = ec_fsm_foe_end;
889  }
890  else {
891  fsm->rx_expected_packet_no++;
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 /*****************************************************************************/
uint8_t * tx_filename
Name of file to transmit.
Definition: fsm_foe.h:70
#define EC_FSM_RETRIES
Number of state machine retries on datagram timeout.
Definition: globals.h:47
Receive error.
Definition: foe.h:46
ec_slave_t * slave
Slave the FSM runs on.
Definition: fsm_foe.h:54
uint8_t * rx_buffer
Buffer for received data.
Definition: fsm_foe.h:73
void ec_fsm_foe_read_start(ec_fsm_foe_t *, ec_datagram_t *)
Starting state for read operations.
Definition: fsm_foe.c:648
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
unsigned long jiffies_sent
Jiffies, when the datagram was sent.
Definition: datagram.h:104
ec_sii_t sii
Extracted SII data.
Definition: slave.h:223
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
Error fetching data from mailbox.
Definition: foe.h:55
int ec_fsm_foe_success(const ec_fsm_foe_t *fsm)
Returns, if the state machine terminated with success.
Definition: fsm_foe.c:159
ec_direction_t dir
Direction.
Definition: foe_request.h:60
uint16_t configured_tx_mailbox_size
Configured send mailbox size.
Definition: slave.h:201
void ec_fsm_foe_error(ec_fsm_foe_t *, ec_datagram_t *)
State: ERROR.
Definition: fsm_foe.c:202
void ec_fsm_foe_clear(ec_fsm_foe_t *fsm)
Destructor.
Definition: fsm_foe.c:115
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition: slave.h:106
Working counter error.
Definition: foe.h:45
uint32_t tx_packet_no
FoE packet number.
Definition: fsm_foe.h:68
unsigned long jiffies_start
FoE timestamp.
Definition: fsm_foe.h:59
Read request.
Definition: fsm_foe.c:63
Packet number error.
Definition: foe.h:49
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
EtherCAT datagram.
Definition: datagram.h:87
void ec_fsm_foe_state_rrq_sent(ec_fsm_foe_t *, ec_datagram_t *)
State: RRQ SENT.
Definition: fsm_foe.c:610
uint8_t * tx_buffer
Buffer with data to transmit.
Definition: fsm_foe.h:64
uint32_t tx_buffer_offset
Offset of data to tranmit next.
Definition: fsm_foe.h:66
#define EC_FOE_HEADER_SIZE
Size of the FoE header.
Definition: fsm_foe.c:51
enum @1 ec_foe_opcode_t
FoE OpCodes.
uint16_t working_counter
Working counter.
Definition: datagram.h:99
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_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
uint32_t tx_filename_len
Lenth of transmit file name.
Definition: fsm_foe.h:71
uint32_t rx_filename_len
Length of the receive file name.
Definition: fsm_foe.h:79
Sent (still in the queue).
Definition: datagram.h:77
uint32_t result
FoE request abort code.
Definition: foe_request.h:68
void ec_fsm_foe_end(ec_fsm_foe_t *, ec_datagram_t *)
State: END.
Definition: fsm_foe.c:216
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
Global definitions and macros.
EtherCAT master structure.
Initial state of a new datagram.
Definition: datagram.h:75
EtherCAT slave.
Definition: slave.h:176
File-Access over EtherCAT.
Definition: globals.h:138
size_t buffer_size
Size of FoE data memory.
Definition: foe_request.h:53
uint32_t tx_last_packet
Current packet is last one to send.
Definition: fsm_foe.h:67
OpCode error.
Definition: foe.h:50
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_init(ec_fsm_foe_t *fsm)
Constructor.
Definition: fsm_foe.c:103
ec_datagram_state_t state
State.
Definition: datagram.h:100
#define EC_WRITE_U32(DATA, VAL)
Write a 32-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2435
uint8_t * buffer
Pointer to FoE data.
Definition: foe_request.h:52
uint32_t rx_expected_packet_no
Expected receive packet number.
Definition: fsm_foe.h:76
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:147
Error acknowledging received data.
Definition: foe.h:53
unsigned int debug_level
Master debug level.
Definition: master.h:285
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition: slave.h:76
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_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
uint32_t rx_buffer_size
Size of receive buffer.
Definition: fsm_foe.h:74
void ec_fsm_foe_write_start(ec_fsm_foe_t *, ec_datagram_t *)
Initializes the FoE write state machine.
Definition: fsm_foe.c:306
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2418
#define EC_READ_U32(DATA)
Read a 32-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2329
Timeout error.
Definition: foe.h:51
ec_master_t * master
Master owning the slave.
Definition: slave.h:178
#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_state_sent_ack(ec_fsm_foe_t *, ec_datagram_t *)
Sent an acknowledge.
Definition: fsm_foe.c:855
uint32_t tx_buffer_size
Size of data to transmit.
Definition: fsm_foe.h:65
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
FoE defines.
#define EC_MBOX_HEADER_SIZE
Mailbox header size.
Definition: globals.h:83
size_t data_size
Size of FoE data.
Definition: foe_request.h:54
void ec_fsm_foe_state_data_read(ec_fsm_foe_t *, ec_datagram_t *)
Start reading data.
Definition: fsm_foe.c:731
uint32_t rx_last_packet
Current packet is the last to receive.
Definition: fsm_foe.h:77
void ec_print_data(const uint8_t *, size_t)
Outputs frame contents for debugging purposes.
Definition: module.c:348
uint8_t * file_name
Pointer to the filename.
Definition: foe_request.h:67
unsigned int retries
Retries upon datagram timeout.
Definition: fsm_foe.h:55
FoE request.
Definition: foe_request.h:50
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
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2313
Protocol error.
Definition: foe.h:47
ec_datagram_t * datagram
Datagram used in previous step.
Definition: fsm_foe.h:58
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_datagram_print_state(const ec_datagram_t *datagram)
Prints the state of a datagram.
Definition: datagram.c:565
Mailbox functionality.
Acknowledge.
Definition: fsm_foe.c:66
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
ec_foe_request_t * request
FoE request.
Definition: fsm_foe.h:61
void ec_fsm_foe_state_ack_read(ec_fsm_foe_t *, ec_datagram_t *)
Acknowledge a read operation.
Definition: fsm_foe.c:392
Queued for sending.
Definition: datagram.h:76
Ready.
Definition: foe.h:43
uint16_t configured_rx_mailbox_size
Configured receive mailbox size.
Definition: slave.h:197
void(* state)(ec_fsm_foe_t *, ec_datagram_t *)
FoE state function.
Definition: fsm_foe.h:57
Mailbox protocol error.
Definition: foe.h:57
#define EC_READ_U8(DATA)
Read an 8-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2297
uint8_t * rx_filename
Name of the file to receive.
Definition: fsm_foe.h:78
uint32_t error_code
Error code from an FoE Error Request.
Definition: foe_request.h:69
void ec_fsm_foe_state_data_sent(ec_fsm_foe_t *, ec_datagram_t *)
State: WRQ SENT.
Definition: fsm_foe.c:513
Acknowledge error.
Definition: foe.h:54
Values written by the master.
Definition: ecrt.h:448
Received (dequeued).
Definition: datagram.h:78
uint32_t tx_current_size
Size of current packet to send.
Definition: fsm_foe.h:69
int ec_foe_prepare_send_ack(ec_fsm_foe_t *, ec_datagram_t *)
Prepare to send an acknowledge.
Definition: fsm_foe.c:584
Write request.
Definition: fsm_foe.c:64
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.
unsigned long jiffies_received
Jiffies, when the datagram was received.
Definition: datagram.h:108
int ec_slave_mbox_check(const ec_datagram_t *datagram)
Processes a mailbox state checking datagram.
Definition: mailbox.c:115
Finite state machines for the CANopen-over-EtherCAT protocol.
Definition: fsm_foe.h:53
uint32_t rx_buffer_offset
Offset in receive buffer.
Definition: fsm_foe.h:75
void ec_fsm_foe_state_ack_check(ec_fsm_foe_t *, ec_datagram_t *)
Check for acknowledge.
Definition: fsm_foe.c:340