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_MBOX_TYPE_FILEACCESS 0x04
52 
55 #define EC_FOE_HEADER_SIZE 6
56 // uint8_t OpCode
57 // uint8_t reserved
58 // uint32_t PacketNo, Password, ErrorCode
59 
60 //#define DEBUG_FOE
61 
62 /*****************************************************************************/
63 
66 enum {
74 
75 /*****************************************************************************/
76 
81 
82 void ec_foe_set_tx_error(ec_fsm_foe_t *, uint32_t);
83 void ec_foe_set_rx_error(ec_fsm_foe_t *, uint32_t);
84 
87 
90 
93 
95 
99 
102 
103 /*****************************************************************************/
104 
108  ec_fsm_foe_t *fsm
109  )
110 {
111  fsm->state = NULL;
112  fsm->datagram = NULL;
113 }
114 
115 /*****************************************************************************/
116 
120 {
121 }
122 
123 /*****************************************************************************/
124 
130  ec_fsm_foe_t *fsm,
131  ec_datagram_t *datagram
132  )
133 {
134  int datagram_used = 0;
135 
136  if (fsm->datagram &&
137  (fsm->datagram->state == EC_DATAGRAM_INIT ||
138  fsm->datagram->state == EC_DATAGRAM_QUEUED ||
139  fsm->datagram->state == EC_DATAGRAM_SENT)) {
140  // datagram not received yet
141  return datagram_used;
142  }
143 
144  fsm->state(fsm, datagram);
145 
146  datagram_used =
147  fsm->state != ec_fsm_foe_end && fsm->state != ec_fsm_foe_error;
148 
149  if (datagram_used) {
150  fsm->datagram = datagram;
151  } else {
152  fsm->datagram = NULL;
153  }
154 
155  return datagram_used;
156 }
157 
158 /*****************************************************************************/
159 
164 {
165  return fsm->state == ec_fsm_foe_end;
166 }
167 
168 /*****************************************************************************/
169 
173  ec_fsm_foe_t *fsm,
174  ec_slave_t *slave,
175  ec_foe_request_t *request
176  )
177 {
178  fsm->slave = slave;
179  fsm->request = request;
180 
181  if (request->dir == EC_DIR_OUTPUT) {
182  fsm->tx_buffer = fsm->request->buffer;
183  fsm->tx_buffer_size = fsm->request->data_size;
184  fsm->tx_buffer_offset = 0;
185 
186  fsm->tx_filename = fsm->request->file_name;
187  fsm->tx_filename_len = strlen(fsm->tx_filename);
188 
190  }
191  else {
192  fsm->rx_buffer = fsm->request->buffer;
193  fsm->rx_buffer_size = fsm->request->buffer_size;
194 
195  fsm->rx_filename = fsm->request->file_name;
196  fsm->rx_filename_len = strlen(fsm->rx_filename);
197 
199  }
200 }
201 
202 /*****************************************************************************/
203 
207  ec_fsm_foe_t *fsm,
208  ec_datagram_t *datagram
209  )
210 {
211 #ifdef DEBUG_FOE
212  EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
213 #endif
214 }
215 
216 /*****************************************************************************/
217 
221  ec_fsm_foe_t *fsm,
222  ec_datagram_t *datagram
223  )
224 {
225 #ifdef DEBUG_FOE
226  EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
227 #endif
228 }
229 
230 /*****************************************************************************/
231 
237  ec_fsm_foe_t *fsm,
238  ec_datagram_t *datagram
239  )
240 {
241  size_t remaining_size, current_size;
242  uint8_t *data;
243 
244  remaining_size = fsm->tx_buffer_size - fsm->tx_buffer_offset;
245 
246  if (remaining_size < fsm->slave->configured_tx_mailbox_size
248  current_size = remaining_size;
249  fsm->tx_last_packet = 1;
250  } else {
251  current_size = fsm->slave->configured_tx_mailbox_size
253  }
254 
255  data = ec_slave_mbox_prepare_send(fsm->slave,
256  datagram, EC_MBOX_TYPE_FILEACCESS,
257  current_size + EC_FOE_HEADER_SIZE);
258  if (IS_ERR(data)) {
259  return -1;
260  }
261 
262  EC_WRITE_U16(data, EC_FOE_OPCODE_DATA); // OpCode = DataBlock req.
263  EC_WRITE_U32(data + 2, fsm->tx_packet_no); // PacketNo, Password
264 
265  memcpy(data + EC_FOE_HEADER_SIZE,
266  fsm->tx_buffer + fsm->tx_buffer_offset, current_size);
267  fsm->tx_current_size = current_size;
268 
269  return 0;
270 }
271 
272 /*****************************************************************************/
273 
279  ec_fsm_foe_t *fsm,
280  ec_datagram_t *datagram
281  )
282 {
283  size_t current_size;
284  uint8_t *data;
285 
286  fsm->tx_buffer_offset = 0;
287  fsm->tx_current_size = 0;
288  fsm->tx_packet_no = 0;
289  fsm->tx_last_packet = 0;
290 
291  current_size = fsm->tx_filename_len;
292 
293  data = ec_slave_mbox_prepare_send(fsm->slave, datagram,
295  if (IS_ERR(data)) {
296  return -1;
297  }
298 
299  EC_WRITE_U16( data, EC_FOE_OPCODE_WRQ); // fsm write request
300  EC_WRITE_U32( data + 2, fsm->tx_packet_no );
301 
302  memcpy(data + EC_FOE_HEADER_SIZE, fsm->tx_filename, current_size);
303 
304  return 0;
305 }
306 
307 /*****************************************************************************/
308 
312  ec_fsm_foe_t *fsm,
313  ec_datagram_t *datagram
314  )
315 {
316  ec_slave_t *slave = fsm->slave;
317 
318  fsm->tx_buffer_offset = 0;
319  fsm->tx_current_size = 0;
320  fsm->tx_packet_no = 0;
321  fsm->tx_last_packet = 0;
322 
323 #ifdef DEBUG_FOE
324  EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
325 #endif
326 
327  if (!(slave->sii.mailbox_protocols & EC_MBOX_FOE)) {
329  EC_SLAVE_ERR(slave, "Slave does not support FoE!\n");
330  return;
331  }
332 
333  if (ec_foe_prepare_wrq_send(fsm, datagram)) {
335  return;
336  }
337 
339 }
340 
341 /*****************************************************************************/
342 
346  ec_fsm_foe_t *fsm,
347  ec_datagram_t *datagram
348  )
349 {
350  ec_slave_t *slave = fsm->slave;
351 
352 #ifdef DEBUG_FOE
353  EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
354 #endif
355 
356  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
358  EC_SLAVE_ERR(slave, "Failed to receive FoE mailbox check datagram: ");
360  return;
361  }
362 
363  if (fsm->datagram->working_counter != 1) {
365  EC_SLAVE_ERR(slave, "Reception of FoE mailbox check datagram"
366  " failed: ");
368  return;
369  }
370 
371  if (!ec_slave_mbox_check(fsm->datagram)) {
372  // slave did not put anything in the mailbox yet
373  unsigned long diff_ms = (fsm->datagram->jiffies_received -
374  fsm->jiffies_start) * 1000 / HZ;
375  if (diff_ms >= EC_FSM_FOE_TIMEOUT) {
377  EC_SLAVE_ERR(slave, "Timeout while waiting for ack response.\n");
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 
389  fsm->retries = EC_FSM_RETRIES;
391 }
392 
393 /*****************************************************************************/
394 
398  ec_fsm_foe_t *fsm,
399  ec_datagram_t *datagram
400  )
401 {
402  ec_slave_t *slave = fsm->slave;
403  uint8_t *data, mbox_prot;
404  uint8_t opCode;
405  size_t rec_size;
406 
407 #ifdef DEBUG_FOE
408  EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
409 #endif
410 
411  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
413  EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: ");
415  return;
416  }
417 
418  if (fsm->datagram->working_counter != 1) {
420  EC_SLAVE_ERR(slave, "Reception of FoE ack response failed: ");
422  return;
423  }
424 
425  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
426  if (IS_ERR(data)) {
428  return;
429  }
430 
431  if (mbox_prot != EC_MBOX_TYPE_FILEACCESS) { // FoE
433  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
434  mbox_prot);
435  return;
436  }
437 
438  opCode = EC_READ_U8(data);
439 
440  if (opCode == EC_FOE_OPCODE_BUSY) {
441  // slave not ready
442  if (ec_foe_prepare_data_send(fsm, datagram)) {
444  EC_SLAVE_ERR(slave, "Slave is busy.\n");
445  return;
446  }
448  return;
449  }
450 
451  if (opCode == EC_FOE_OPCODE_ACK) {
452  fsm->tx_packet_no++;
453  fsm->tx_buffer_offset += fsm->tx_current_size;
454 
455  if (fsm->tx_last_packet) {
456  fsm->state = ec_fsm_foe_end;
457  return;
458  }
459 
460  if (ec_foe_prepare_data_send(fsm, datagram)) {
462  return;
463  }
465  return;
466  }
468 }
469 
470 /*****************************************************************************/
471 
478  ec_fsm_foe_t *fsm,
479  ec_datagram_t *datagram
480  )
481 {
482  ec_slave_t *slave = fsm->slave;
483 
484 #ifdef DEBUG_FOE
485  EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
486 #endif
487 
488  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
490  EC_SLAVE_ERR(slave, "Failed to send FoE WRQ: ");
492  return;
493  }
494 
495  if (fsm->datagram->working_counter != 1) {
496  // slave did not put anything in the mailbox yet
498  EC_SLAVE_ERR(slave, "Reception of FoE WRQ failed: ");
500  return;
501  }
502 
503  fsm->jiffies_start = fsm->datagram->jiffies_sent;
504 
505  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
506 
507  fsm->retries = EC_FSM_RETRIES;
509 }
510 
511 /*****************************************************************************/
512 
519  ec_fsm_foe_t *fsm,
520  ec_datagram_t *datagram
521  )
522 {
523  ec_slave_t *slave = fsm->slave;
524 
525 #ifdef DEBUG_FOE
526  EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
527 #endif
528 
529  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
531  EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: ");
533  return;
534  }
535 
536  if (fsm->datagram->working_counter != 1) {
538  EC_SLAVE_ERR(slave, "Reception of FoE data send failed: ");
540  return;
541  }
542 
543  ec_slave_mbox_prepare_check(slave, datagram);
544  fsm->jiffies_start = jiffies;
545  fsm->retries = EC_FSM_RETRIES;
547 }
548 
549 /*****************************************************************************/
550 
556  ec_fsm_foe_t *fsm,
557  ec_datagram_t *datagram
558  )
559 {
560  size_t current_size;
561  uint8_t *data;
562 
563  current_size = fsm->rx_filename_len;
564 
565  data = ec_slave_mbox_prepare_send(fsm->slave, datagram,
567  if (IS_ERR(data)) {
568  return -1;
569  }
570 
571  EC_WRITE_U16(data, EC_FOE_OPCODE_RRQ); // fsm read request
572  EC_WRITE_U32(data + 2, 0x00000000); // no passwd
573  memcpy(data + EC_FOE_HEADER_SIZE, fsm->rx_filename, current_size);
574 
575  if (fsm->slave->master->debug_level) {
576  EC_SLAVE_DBG(fsm->slave, 1, "FoE Read Request:\n");
577  ec_print_data(data, current_size + EC_FOE_HEADER_SIZE);
578  }
579 
580  return 0;
581 }
582 
583 /*****************************************************************************/
584 
590  ec_fsm_foe_t *fsm,
591  ec_datagram_t *datagram
592  )
593 {
594  uint8_t *data;
595 
596  data = ec_slave_mbox_prepare_send(fsm->slave, datagram,
598  if (IS_ERR(data)) {
599  return -1;
600  }
601 
603  EC_WRITE_U32(data + 2, fsm->rx_expected_packet_no);
604 
605  return 0;
606 }
607 
608 /*****************************************************************************/
609 
616  ec_fsm_foe_t *fsm,
617  ec_datagram_t *datagram
618  )
619 {
620  ec_slave_t *slave = fsm->slave;
621 
622 #ifdef DEBUG_FOE
623  EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
624 #endif
625 
626  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
628  EC_SLAVE_ERR(slave, "Failed to send FoE RRQ: ");
630  return;
631  }
632 
633  if (fsm->datagram->working_counter != 1) {
634  // slave did not put anything in the mailbox yet
636  EC_SLAVE_ERR(slave, "Reception of FoE RRQ failed: ");
638  return;
639  }
640 
641  fsm->jiffies_start = fsm->datagram->jiffies_sent;
642 
643  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
644 
645  fsm->retries = EC_FSM_RETRIES;
647 }
648 
649 /*****************************************************************************/
650 
654  ec_fsm_foe_t *fsm,
655  ec_datagram_t *datagram
656  )
657 {
658  ec_slave_t *slave = fsm->slave;
659 
660  fsm->rx_buffer_offset = 0;
661  fsm->rx_expected_packet_no = 1;
662  fsm->rx_last_packet = 0;
663 
664 #ifdef DEBUG_FOE
665  EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
666 #endif
667 
668  if (!(slave->sii.mailbox_protocols & EC_MBOX_FOE)) {
670  EC_SLAVE_ERR(slave, "Slave does not support FoE!\n");
671  return;
672  }
673 
674  if (ec_foe_prepare_rrq_send(fsm, datagram)) {
676  return;
677  }
678 
680 }
681 
682 /*****************************************************************************/
683 
687  ec_fsm_foe_t *fsm,
688  ec_datagram_t *datagram
689  )
690 {
691  ec_slave_t *slave = fsm->slave;
692 
693 #ifdef DEBUG_FOE
694  EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
695 #endif
696 
697  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
699  EC_SLAVE_ERR(slave, "Failed to send FoE DATA READ: ");
701  return;
702  }
703 
704  if (fsm->datagram->working_counter != 1) {
706  EC_SLAVE_ERR(slave, "Reception of FoE DATA READ: ");
708  return;
709  }
710 
711  if (!ec_slave_mbox_check(fsm->datagram)) {
712  unsigned long diff_ms = (fsm->datagram->jiffies_received -
713  fsm->jiffies_start) * 1000 / HZ;
714  if (diff_ms >= EC_FSM_FOE_TIMEOUT) {
716  EC_SLAVE_ERR(slave, "Timeout while waiting for ack response.\n");
717  return;
718  }
719 
720  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
721  fsm->retries = EC_FSM_RETRIES;
722  return;
723  }
724 
725  // Fetch response
726  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
727 
728  fsm->retries = EC_FSM_RETRIES;
730 }
731 
732 /*****************************************************************************/
733 
737  ec_fsm_foe_t *fsm,
738  ec_datagram_t *datagram
739  )
740 {
741  size_t rec_size;
742  uint8_t *data, opCode, packet_no, mbox_prot;
743 
744  ec_slave_t *slave = fsm->slave;
745 
746 #ifdef DEBUG_FOE
747  EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
748 #endif
749 
750  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
752  EC_SLAVE_ERR(slave, "Failed to receive FoE DATA READ datagram: ");
754  return;
755  }
756 
757  if (fsm->datagram->working_counter != 1) {
759  EC_SLAVE_ERR(slave, "Reception of FoE DATA READ failed: ");
761  return;
762  }
763 
764  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
765  if (IS_ERR(data)) {
767  return;
768  }
769 
770  if (mbox_prot != EC_MBOX_TYPE_FILEACCESS) { // FoE
771  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
772  mbox_prot);
774  return;
775  }
776 
777  opCode = EC_READ_U8(data);
778 
779  if (opCode == EC_FOE_OPCODE_BUSY) {
780  if (ec_foe_prepare_send_ack(fsm, datagram)) {
782  }
783  return;
784  }
785 
786  if (opCode == EC_FOE_OPCODE_ERR) {
787  fsm->request->error_code = EC_READ_U32(data + 2);
788  EC_SLAVE_ERR(slave, "Received FoE Error Request (code 0x%08x).\n",
789  fsm->request->error_code);
790  if (rec_size > 6) {
791  uint8_t text[256];
792  strncpy(text, data + 6, min(rec_size - 6, sizeof(text)));
793  EC_SLAVE_ERR(slave, "FoE Error Text: %s\n", text);
794  }
796  return;
797  }
798 
799  if (opCode != EC_FOE_OPCODE_DATA) {
800  EC_SLAVE_ERR(slave, "Received OPCODE %x, expected %x.\n",
801  opCode, EC_FOE_OPCODE_DATA);
802  fsm->request->error_code = 0x00000000;
804  return;
805  }
806 
807  packet_no = EC_READ_U16(data + 2);
808  if (packet_no != fsm->rx_expected_packet_no) {
809  EC_SLAVE_ERR(slave, "Received unexpected packet number.\n");
811  return;
812  }
813 
814  rec_size -= EC_FOE_HEADER_SIZE;
815 
816  if (fsm->rx_buffer_size >= fsm->rx_buffer_offset + rec_size) {
817  memcpy(fsm->rx_buffer + fsm->rx_buffer_offset,
818  data + EC_FOE_HEADER_SIZE, rec_size);
819  fsm->rx_buffer_offset += rec_size;
820  }
821 
822  fsm->rx_last_packet =
824  != slave->configured_rx_mailbox_size);
825 
826  if (fsm->rx_last_packet ||
829  <= fsm->rx_buffer_size) {
830  // either it was the last packet or a new packet will fit into the
831  // delivered buffer
832 #ifdef DEBUG_FOE
833  EC_SLAVE_DBG(fsm->slave, 0, "last_packet=true\n");
834 #endif
835  if (ec_foe_prepare_send_ack(fsm, datagram)) {
837  return;
838  }
839 
841  }
842  else {
843  // no more data fits into the delivered buffer
844  // ... wait for new read request
845  EC_SLAVE_ERR(slave, "Data do not fit in receive buffer!\n");
846  printk(" rx_buffer_size = %d\n", fsm->rx_buffer_size);
847  printk("rx_buffer_offset = %d\n", fsm->rx_buffer_offset);
848  printk(" rec_size = %zd\n", rec_size);
849  printk(" rx_mailbox_size = %d\n", slave->configured_rx_mailbox_size);
850  printk(" rx_last_packet = %d\n", fsm->rx_last_packet);
851  fsm->request->result = FOE_READY;
852  }
853 }
854 
855 /*****************************************************************************/
856 
860  ec_fsm_foe_t *fsm,
861  ec_datagram_t *datagram
862  )
863 {
864  ec_slave_t *slave = fsm->slave;
865 
866 #ifdef DEBUG_FOE
867  EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
868 #endif
869 
870  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
872  EC_SLAVE_ERR(slave, "Failed to send FoE ACK: ");
874  return;
875  }
876 
877  if (fsm->datagram->working_counter != 1) {
878  // slave did not put anything into the mailbox yet
880  EC_SLAVE_ERR(slave, "Reception of FoE ACK failed: ");
882  return;
883  }
884 
885  fsm->jiffies_start = fsm->datagram->jiffies_sent;
886 
887  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
888 
889  if (fsm->rx_last_packet) {
890  fsm->rx_expected_packet_no = 0;
891  fsm->request->data_size = fsm->rx_buffer_offset;
892  fsm->state = ec_fsm_foe_end;
893  }
894  else {
895  fsm->rx_expected_packet_no++;
896  fsm->retries = EC_FSM_RETRIES;
898  }
899 }
900 
901 /*****************************************************************************/
902 
906  ec_fsm_foe_t *fsm,
907  uint32_t errorcode
908  )
909 {
910  fsm->request->result = errorcode;
911  fsm->state = ec_fsm_foe_error;
912 }
913 
914 /*****************************************************************************/
915 
919  ec_fsm_foe_t *fsm,
920  uint32_t errorcode
921  )
922 {
923  fsm->request->result = errorcode;
924  fsm->state = ec_fsm_foe_error;
925 }
926 
927 /*****************************************************************************/
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:59
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:918
Receive error.
Definition: foe.h:46
#define EC_MBOX_TYPE_FILEACCESS
Mailbox type FoE.
Definition: fsm_foe.c:51
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
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
File-Access over EtherCAT.
Definition: globals.h:150
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:163
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_clear(ec_fsm_foe_t *fsm)
Destructor.
Definition: fsm_foe.c:119
#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
void ec_fsm_foe_read_start(ec_fsm_foe_t *, ec_datagram_t *)
Starting state for read operations.
Definition: fsm_foe.c:653
unsigned long jiffies_start
FoE timestamp.
Definition: fsm_foe.h:59
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
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:55
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:172
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
void ec_fsm_foe_state_rrq_sent(ec_fsm_foe_t *, ec_datagram_t *)
State: RRQ SENT.
Definition: fsm_foe.c:615
Sent (still in the queue).
Definition: datagram.h:77
uint32_t result
FoE request abort code.
Definition: foe_request.h:68
enum @0 ec_foe_opcode_t
FoE OpCodes.
Global definitions and macros.
EtherCAT master structure.
Initial state of a new datagram.
Definition: datagram.h:75
EtherCAT slave.
Definition: slave.h:176
void ec_fsm_foe_state_data_sent(ec_fsm_foe_t *, ec_datagram_t *)
State: WRQ SENT.
Definition: fsm_foe.c:518
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_init(ec_fsm_foe_t *fsm)
Constructor.
Definition: fsm_foe.c:107
ec_datagram_state_t state
State.
Definition: datagram.h:100
void ec_fsm_foe_error(ec_fsm_foe_t *, ec_datagram_t *)
State: ERROR.
Definition: fsm_foe.c:206
#define EC_WRITE_U32(DATA, VAL)
Write a 32-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2221
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:286
#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
uint32_t rx_buffer_size
Size of receive buffer.
Definition: fsm_foe.h:74
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2204
Acknowledge.
Definition: fsm_foe.c:70
void(* state)(ec_fsm_foe_t *, ec_datagram_t *)
FoE state function.
Definition: fsm_foe.h:57
#define EC_READ_U32(DATA)
Read a 32-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2151
Timeout error.
Definition: foe.h:51
ec_master_t * master
Master owning the slave.
Definition: slave.h:178
void ec_fsm_foe_state_ack_check(ec_fsm_foe_t *, ec_datagram_t *)
Check for acknowledge.
Definition: fsm_foe.c:345
#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_wrq_sent(ec_fsm_foe_t *, ec_datagram_t *)
State: WRQ SENT.
Definition: fsm_foe.c:477
uint32_t tx_buffer_size
Size of data to transmit.
Definition: fsm_foe.h:65
FoE defines.
int ec_foe_prepare_wrq_send(ec_fsm_foe_t *, ec_datagram_t *)
Prepare a write request (WRQ) with filename.
Definition: fsm_foe.c:278
#define EC_MBOX_HEADER_SIZE
Mailbox header size.
Definition: globals.h:95
size_t data_size
Size of FoE data.
Definition: foe_request.h:54
uint32_t rx_last_packet
Current packet is the last to receive.
Definition: fsm_foe.h:77
void ec_fsm_foe_state_sent_ack(ec_fsm_foe_t *, ec_datagram_t *)
Sent an acknowledge.
Definition: fsm_foe.c:859
void ec_print_data(const uint8_t *, size_t)
Outputs frame contents for debugging purposes.
Definition: module.c:341
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:2135
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:129
void ec_datagram_print_state(const ec_datagram_t *datagram)
Prints the state of a datagram.
Definition: datagram.c:565
Mailbox functionality.
ec_foe_request_t * request
FoE request.
Definition: fsm_foe.h:61
void ec_fsm_foe_end(ec_fsm_foe_t *, ec_datagram_t *)
State: END.
Definition: fsm_foe.c:220
int ec_foe_prepare_data_send(ec_fsm_foe_t *, ec_datagram_t *)
Sends a file or the next fragment.
Definition: fsm_foe.c:236
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:905
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 ec_fsm_foe_state_ack_read(ec_fsm_foe_t *, ec_datagram_t *)
Acknowledge a read operation.
Definition: fsm_foe.c:397
Mailbox protocol error.
Definition: foe.h:57
#define EC_READ_U8(DATA)
Read an 8-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2119
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
int ec_foe_prepare_send_ack(ec_fsm_foe_t *, ec_datagram_t *)
Prepare to send an acknowledge.
Definition: fsm_foe.c:589
Acknowledge error.
Definition: foe.h:54
Values written by the master.
Definition: ecrt.h:419
Received (dequeued).
Definition: datagram.h:78
int ec_foe_prepare_rrq_send(ec_fsm_foe_t *, ec_datagram_t *)
Prepare a read request (RRQ) with filename.
Definition: fsm_foe.c:555
uint32_t tx_current_size
Size of current packet to send.
Definition: fsm_foe.h:69
Write request.
Definition: fsm_foe.c:68
Read request.
Definition: fsm_foe.c:67
void ec_fsm_foe_state_data_read(ec_fsm_foe_t *, ec_datagram_t *)
Start reading data.
Definition: fsm_foe.c:736
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
void ec_fsm_foe_state_data_check(ec_fsm_foe_t *, ec_datagram_t *)
Check for data.
Definition: fsm_foe.c:686
Finite state machines for the CANopen-over-EtherCAT protocol.
Definition: fsm_foe.h:53
void ec_fsm_foe_write_start(ec_fsm_foe_t *, ec_datagram_t *)
Initializes the FoE write state machine.
Definition: fsm_foe.c:311
uint32_t rx_buffer_offset
Offset in receive buffer.
Definition: fsm_foe.h:75