IgH EtherCAT Master  1.7.0
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 
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 
54 enum {
61 };
62 
63 /****************************************************************************/
64 
69 
70 void ec_foe_set_tx_error(ec_fsm_foe_t *, uint32_t);
71 void ec_foe_set_rx_error(ec_fsm_foe_t *, uint32_t);
72 
75 
78 
80 
82 
85 
88 
89 /****************************************************************************/
90 
94  ec_fsm_foe_t *fsm
95  )
96 {
97  fsm->state = NULL;
98  fsm->datagram = NULL;
100 }
101 
102 /****************************************************************************/
103 
107 {
109 }
110 
111 /****************************************************************************/
112 
118  ec_fsm_foe_t *fsm,
119  ec_datagram_t *datagram
120  )
121 {
122  if (fsm->state == ec_fsm_foe_end || fsm->state == ec_fsm_foe_error)
123  return 0;
124 
125  if (fsm->datagram &&
126  (fsm->datagram->state == EC_DATAGRAM_INIT ||
127  fsm->datagram->state == EC_DATAGRAM_QUEUED ||
128  fsm->datagram->state == EC_DATAGRAM_SENT)) {
129  // datagram not received yet
130  if (datagram != fsm->datagram)
131  datagram->state = EC_DATAGRAM_UNUSED;
132  return 1;
133  }
134 
135  fsm->state(fsm, datagram);
136 
137  if (fsm->state == ec_fsm_foe_end || fsm->state == ec_fsm_foe_error) {
138  fsm->datagram = NULL;
139  return 0;
140  }
141 
142  fsm->datagram = datagram;
143  return 1;
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;
181  fsm->rx_buffer_size = fsm->request->buffer_size;
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 
243  data = ec_slave_mbox_prepare_send(fsm->slave,
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 
335 static void ec_fsm_foe_wait(
336  ec_fsm_foe_t *fsm,
337  void (*state)(ec_fsm_foe_t *, ec_datagram_t *)
339  )
340 {
341  ec_fsm_mbox_receive(&fsm->fsm_mbox, fsm->slave,
342  &fsm->slave->mbox_foe_data, fsm->jiffies_start,
344  fsm->state = state;
345 }
346 
347 /****************************************************************************/
348 
355 static void ec_fsm_foe_receive(
356  ec_fsm_foe_t *fsm,
357  ec_datagram_t *datagram,
358  void (*state)(ec_fsm_foe_t *, ec_datagram_t *)
360  )
361 {
362  ec_fsm_foe_wait(fsm, state);
363  fsm->state(fsm, datagram);
364 }
365 
366 /****************************************************************************/
367 
373  ec_fsm_foe_t *fsm,
374  ec_datagram_t *datagram
375  )
376 {
377  ec_slave_t *slave = fsm->slave;
378  uint8_t *data, mbox_prot;
379  uint8_t opCode;
380  size_t rec_size;
381 
382  if (ec_fsm_mbox_exec(&fsm->fsm_mbox, datagram)) {
383  return;
384  }
385 
386 #ifdef DEBUG_FOE
387  EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
388 #endif
389 
390  if (ec_fsm_mbox_result(&fsm->fsm_mbox) == -ETIMEDOUT) {
392  EC_SLAVE_ERR(slave, "Timeout while waiting for ack response.\n");
393  return;
394  } else if (ec_fsm_mbox_result(&fsm->fsm_mbox)) {
396  return;
397  }
398 
399  data = ec_slave_mbox_fetch(slave, &slave->mbox_foe_data,
400  &mbox_prot, &rec_size);
401  if (IS_ERR(data)) {
403  return;
404  }
405 
406  if (mbox_prot != EC_MBOX_TYPE_FOE) {
408  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
409  mbox_prot);
410  return;
411  }
412 
413  opCode = EC_READ_U8(data);
414 
415  if (opCode == EC_FOE_OPCODE_BUSY) {
416  // slave not ready
417  if (ec_foe_prepare_data_send(fsm, datagram)) {
419  EC_SLAVE_ERR(slave, "Slave is busy.\n");
420  return;
421  }
423  return;
424  }
425 
426  if (opCode == EC_FOE_OPCODE_ACK) {
427  fsm->tx_packet_no++;
428  fsm->tx_buffer_offset += fsm->tx_current_size;
429 
430  if (fsm->tx_last_packet) {
431  fsm->state = ec_fsm_foe_end;
432  return;
433  }
434 
435  if (ec_foe_prepare_data_send(fsm, datagram)) {
437  return;
438  }
440  return;
441  }
443 }
444 
445 /****************************************************************************/
446 
453  ec_fsm_foe_t *fsm,
454  ec_datagram_t *datagram
455  )
456 {
457  ec_slave_t *slave = fsm->slave;
458 
459 #ifdef DEBUG_FOE
460  EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
461 #endif
462 
463  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
465  EC_SLAVE_ERR(slave, "Failed to send FoE WRQ: ");
467  return;
468  }
469 
470  if (fsm->datagram->working_counter != 1) {
471  // slave did not put anything in the mailbox yet
473  EC_SLAVE_ERR(slave, "Reception of FoE WRQ failed: ");
475  return;
476  }
477 
478  fsm->jiffies_start = fsm->datagram->jiffies_sent;
479 
481 }
482 
483 /****************************************************************************/
484 
491  ec_fsm_foe_t *fsm,
492  ec_datagram_t *datagram
493  )
494 {
495  ec_slave_t *slave = fsm->slave;
496 
497 #ifdef DEBUG_FOE
498  EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
499 #endif
500 
501  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
503  EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: ");
505  return;
506  }
507 
508  if (fsm->datagram->working_counter != 1) {
510  EC_SLAVE_ERR(slave, "Reception of FoE data send failed: ");
512  return;
513  }
514 
515  fsm->jiffies_start = jiffies;
516 
518 }
519 
520 /****************************************************************************/
521 
527  ec_fsm_foe_t *fsm,
528  ec_datagram_t *datagram
529  )
530 {
531  size_t current_size;
532  uint8_t *data;
533 
534  current_size = fsm->rx_filename_len;
535 
536  data = ec_slave_mbox_prepare_send(fsm->slave, datagram,
537  EC_MBOX_TYPE_FOE, current_size + EC_FOE_HEADER_SIZE);
538  if (IS_ERR(data)) {
539  return -1;
540  }
541 
542  EC_WRITE_U16(data, EC_FOE_OPCODE_RRQ); // fsm read request
543  EC_WRITE_U32(data + 2, 0x00000000); // no passwd
544  memcpy(data + EC_FOE_HEADER_SIZE, fsm->rx_filename, current_size);
545 
546  if (fsm->slave->master->debug_level) {
547  EC_SLAVE_DBG(fsm->slave, 1, "FoE Read Request:\n");
548  ec_print_data(data, current_size + EC_FOE_HEADER_SIZE);
549  }
550 
551  return 0;
552 }
553 
554 /****************************************************************************/
555 
561  ec_fsm_foe_t *fsm,
562  ec_datagram_t *datagram
563  )
564 {
565  uint8_t *data;
566 
567  data = ec_slave_mbox_prepare_send(fsm->slave, datagram,
568  EC_MBOX_TYPE_FOE, EC_FOE_HEADER_SIZE);
569  if (IS_ERR(data)) {
570  return -1;
571  }
572 
574  EC_WRITE_U32(data + 2, fsm->rx_expected_packet_no);
575 
576  return 0;
577 }
578 
579 /****************************************************************************/
580 
587  ec_fsm_foe_t *fsm,
588  ec_datagram_t *datagram
589  )
590 {
591  ec_slave_t *slave = fsm->slave;
592 
593 #ifdef DEBUG_FOE
594  EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
595 #endif
596 
597  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
599  EC_SLAVE_ERR(slave, "Failed to send FoE RRQ: ");
601  return;
602  }
603 
604  if (fsm->datagram->working_counter != 1) {
605  // slave did not put anything in the mailbox yet
607  EC_SLAVE_ERR(slave, "Reception of FoE RRQ failed: ");
609  return;
610  }
611 
612  fsm->jiffies_start = fsm->datagram->jiffies_sent;
613 
615 }
616 
617 /****************************************************************************/
618 
622  ec_fsm_foe_t *fsm,
623  ec_datagram_t *datagram
624  )
625 {
626  ec_slave_t *slave = fsm->slave;
627 
628  fsm->rx_buffer_offset = 0;
629  fsm->rx_expected_packet_no = 1;
630  fsm->rx_last_packet = 0;
631 
632 #ifdef DEBUG_FOE
633  EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
634 #endif
635 
636  if (!(slave->sii.mailbox_protocols & EC_MBOX_FOE)) {
638  EC_SLAVE_ERR(slave, "Slave does not support FoE!\n");
639  return;
640  }
641 
642  if (ec_foe_prepare_rrq_send(fsm, datagram)) {
644  return;
645  }
646 
648 }
649 
650 /****************************************************************************/
651 
657  ec_fsm_foe_t *fsm,
658  ec_datagram_t *datagram
659  )
660 {
661  ec_slave_t *slave = fsm->slave;
662  size_t rec_size;
663  uint8_t *data, opCode, packet_no, mbox_prot;
664 
665  if (ec_fsm_mbox_exec(&fsm->fsm_mbox, datagram)) {
666  return;
667  }
668 
669 #ifdef DEBUG_FOE
670  EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
671 #endif
672 
673  if (ec_fsm_mbox_result(&fsm->fsm_mbox) == -ETIMEDOUT) {
675  EC_SLAVE_ERR(slave, "Timeout while waiting for data.\n");
676  return;
677  } else if (ec_fsm_mbox_result(&fsm->fsm_mbox)) {
679  return;
680  }
681 
682  data = ec_slave_mbox_fetch(slave, &slave->mbox_foe_data,
683  &mbox_prot, &rec_size);
684  if (IS_ERR(data)) {
686  return;
687  }
688 
689  if (mbox_prot != EC_MBOX_TYPE_FOE) {
690  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
691  mbox_prot);
693  return;
694  }
695 
696  opCode = EC_READ_U8(data);
697 
698  if (opCode == EC_FOE_OPCODE_BUSY) {
699  if (ec_foe_prepare_send_ack(fsm, datagram)) {
701  return;
702  }
703  // wait for the data again, after the acknowledge was sent
705  return;
706  }
707 
708  if (opCode == EC_FOE_OPCODE_ERR) {
709  fsm->request->error_code = EC_READ_U32(data + 2);
710  EC_SLAVE_ERR(slave, "Received FoE Error Request (code 0x%08x).\n",
711  fsm->request->error_code);
712  if (rec_size > 6) {
713  uint8_t text[256];
714  strscpy(text, data + 6, min(rec_size - 6, sizeof(text)));
715  EC_SLAVE_ERR(slave, "FoE Error Text: %s\n", text);
716  }
718  return;
719  }
720 
721  if (opCode != EC_FOE_OPCODE_DATA) {
722  EC_SLAVE_ERR(slave, "Received OPCODE %x, expected %x.\n",
723  opCode, EC_FOE_OPCODE_DATA);
724  fsm->request->error_code = 0x00000000;
726  return;
727  }
728 
729  packet_no = EC_READ_U16(data + 2);
730  if (packet_no != fsm->rx_expected_packet_no) {
731  EC_SLAVE_ERR(slave, "Received unexpected packet number.\n");
733  return;
734  }
735 
736  if (rec_size < EC_FOE_HEADER_SIZE) {
737  EC_SLAVE_ERR(slave, "Received corrupted FoE size (%zu bytes)!\n",
738  rec_size);
740  return;
741  }
742 
743  rec_size -= EC_FOE_HEADER_SIZE;
744 
745  if (fsm->rx_buffer_size >= fsm->rx_buffer_offset + rec_size) {
746  memcpy(fsm->rx_buffer + fsm->rx_buffer_offset,
747  data + EC_FOE_HEADER_SIZE, rec_size);
748  fsm->rx_buffer_offset += rec_size;
749  }
750 
751  fsm->rx_last_packet =
753  != slave->configured_rx_mailbox_size);
754 
755  if (fsm->rx_last_packet ||
758  <= fsm->rx_buffer_size) {
759  // either it was the last packet or a new packet will fit into the
760  // delivered buffer
761 #ifdef DEBUG_FOE
762  EC_SLAVE_DBG(fsm->slave, 0, "last_packet=true\n");
763 #endif
764  if (ec_foe_prepare_send_ack(fsm, datagram)) {
766  return;
767  }
768 
770  }
771  else {
772  // no more data fits into the delivered buffer
773  // ... wait for new read request
774  EC_SLAVE_ERR(slave, "Data do not fit in receive buffer!\n");
775  printk(KERN_CONT " rx_buffer_size = %d\n", fsm->rx_buffer_size);
776  printk(KERN_CONT "rx_buffer_offset = %d\n", fsm->rx_buffer_offset);
777  printk(KERN_CONT " rec_size = %zd\n", rec_size);
778  printk(KERN_CONT " rx_mailbox_size = %d\n",
780  printk(KERN_CONT " rx_last_packet = %d\n", fsm->rx_last_packet);
781  fsm->request->result = FOE_READY;
783  }
784 }
785 
786 /****************************************************************************/
787 
791  ec_fsm_foe_t *fsm,
792  ec_datagram_t *datagram
793  )
794 {
795  ec_slave_t *slave = fsm->slave;
796 
797 #ifdef DEBUG_FOE
798  EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
799 #endif
800 
801  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
803  EC_SLAVE_ERR(slave, "Failed to send FoE ACK: ");
805  return;
806  }
807 
808  if (fsm->datagram->working_counter != 1) {
809  // slave did not put anything into the mailbox yet
811  EC_SLAVE_ERR(slave, "Reception of FoE ACK failed: ");
813  return;
814  }
815 
816  fsm->jiffies_start = fsm->datagram->jiffies_sent;
817 
818  if (fsm->rx_last_packet) {
819  fsm->rx_expected_packet_no = 0;
820  fsm->request->data_size = fsm->rx_buffer_offset;
821  fsm->state = ec_fsm_foe_end;
822  }
823  else {
824  fsm->rx_expected_packet_no++;
825 
827  }
828 }
829 
830 /****************************************************************************/
831 
835  ec_fsm_foe_t *fsm,
836  uint32_t errorcode
837  )
838 {
839  fsm->request->result = errorcode;
840  fsm->state = ec_fsm_foe_error;
841 }
842 
843 /****************************************************************************/
844 
848  ec_fsm_foe_t *fsm,
849  uint32_t errorcode
850  )
851 {
852  fsm->request->result = errorcode;
853  fsm->state = ec_fsm_foe_error;
854 }
855 
856 /****************************************************************************/
uint8_t * tx_filename
Name of file to transmit.
Definition: fsm_foe.h:64
static void ec_fsm_foe_receive(ec_fsm_foe_t *fsm, ec_datagram_t *datagram, void(*state)(ec_fsm_foe_t *, ec_datagram_t *))
Waits for an FoE response.
Definition: fsm_foe.c:355
Receive error.
Definition: foe.h:38
ec_slave_t * slave
Slave the FSM runs on.
Definition: fsm_foe.h:47
uint8_t * rx_buffer
Buffer for received data.
Definition: fsm_foe.h:67
void ec_fsm_foe_read_start(ec_fsm_foe_t *, ec_datagram_t *)
Starting state for read operations.
Definition: fsm_foe.c:621
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:143
unsigned long jiffies_sent
Jiffies, when the datagram was sent.
Definition: datagram.h:101
ec_sii_t sii
Extracted SII data.
Definition: slave.h:218
Error fetching data from mailbox.
Definition: foe.h:47
int ec_fsm_foe_success(const ec_fsm_foe_t *fsm)
Returns, if the state machine terminated with success.
Definition: fsm_foe.c:151
ec_direction_t dir
Direction.
Definition: foe_request.h:52
uint16_t configured_tx_mailbox_size
Configured send mailbox size.
Definition: slave.h:195
void ec_fsm_foe_error(ec_fsm_foe_t *, ec_datagram_t *)
State: ERROR.
Definition: fsm_foe.c:194
void ec_fsm_foe_clear(ec_fsm_foe_t *fsm)
Destructor.
Definition: fsm_foe.c:106
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition: slave.h:100
Working counter error.
Definition: foe.h:37
uint32_t tx_packet_no
FoE packet number.
Definition: fsm_foe.h:62
int ec_fsm_mbox_exec(ec_fsm_mbox_t *fsm, ec_datagram_t *datagram)
Executes the current state of the state machine.
Definition: fsm_mbox.c:161
unsigned long jiffies_start
FoE timestamp.
Definition: fsm_foe.h:52
ec_mbox_data_t mbox_foe_data
Received mailbox data for FoE.
Definition: slave.h:239
Packet number error.
Definition: foe.h:41
void ec_fsm_mbox_receive(ec_fsm_mbox_t *fsm, ec_slave_t *slave, ec_mbox_data_t *mbox_data, unsigned long jiffies_start, unsigned long timeout_ms)
Starts waiting for a mailbox response.
Definition: fsm_mbox.c:102
Not used by its state machine in this cycle and not to be queued.
Definition: datagram.h:73
EtherCAT datagram.
Definition: datagram.h:81
void ec_fsm_foe_state_rrq_sent(ec_fsm_foe_t *, ec_datagram_t *)
State: RRQ SENT.
Definition: fsm_foe.c:586
uint8_t * tx_buffer
Buffer with data to transmit.
Definition: fsm_foe.h:58
static void ec_fsm_foe_wait(ec_fsm_foe_t *fsm, void(*state)(ec_fsm_foe_t *, ec_datagram_t *))
Starts waiting for an FoE response.
Definition: fsm_foe.c:335
uint32_t tx_buffer_offset
Offset of data to tranmit next.
Definition: fsm_foe.h:60
#define EC_FOE_HEADER_SIZE
Size of the FoE header.
Definition: fsm_foe.c:43
uint8_t * ec_slave_mbox_fetch(const ec_slave_t *slave, ec_mbox_data_t *response_data, uint8_t *type, size_t *size)
Processes received mailbox data.
Definition: mailbox.c:290
uint16_t working_counter
Working counter.
Definition: datagram.h:96
ec_fsm_mbox_t fsm_mbox
Mailbox receive state machine.
Definition: fsm_foe.h:53
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_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:834
uint32_t tx_filename_len
Lenth of transmit file name.
Definition: fsm_foe.h:65
uint32_t rx_filename_len
Length of the receive file name.
Definition: fsm_foe.h:73
Sent (still in the queue).
Definition: datagram.h:69
uint32_t result
FoE request abort code.
Definition: foe_request.h:60
void ec_fsm_foe_end(ec_fsm_foe_t *, ec_datagram_t *)
State: END.
Definition: fsm_foe.c:208
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
Global definitions and macros.
EtherCAT master structure.
Initial state of a new datagram.
Definition: datagram.h:67
Read request.
Definition: fsm_foe.c:55
EtherCAT slave.
Definition: slave.h:170
size_t buffer_size
Size of FoE data memory.
Definition: foe_request.h:45
uint32_t tx_last_packet
Current packet is last one to send.
Definition: fsm_foe.h:61
int ec_fsm_mbox_result(const ec_fsm_mbox_t *fsm)
Returns the result of the terminated state machine.
Definition: fsm_mbox.c:195
OpCode error.
Definition: foe.h:42
void ec_fsm_foe_state_wrq_sent(ec_fsm_foe_t *, ec_datagram_t *)
State: WRQ SENT.
Definition: fsm_foe.c:452
void ec_fsm_foe_init(ec_fsm_foe_t *fsm)
Constructor.
Definition: fsm_foe.c:93
ec_datagram_state_t state
State.
Definition: datagram.h:97
#define EC_WRITE_U32(DATA, VAL)
Write a 32-bit unsigned value to EtherCAT data.
Definition: ecrt.h:3387
uint8_t * buffer
Pointer to FoE data.
Definition: foe_request.h:44
Write request.
Definition: fsm_foe.c:56
uint32_t rx_expected_packet_no
Expected receive packet number.
Definition: fsm_foe.h:70
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:141
Error acknowledging received data.
Definition: foe.h:45
unsigned int debug_level
Master debug level.
Definition: master.h:284
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition: slave.h:70
void ec_datagram_print_wc_error(const ec_datagram_t *datagram)
Evaluates the working counter of a single-cast datagram.
Definition: datagram.c:605
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:847
Acknowledge.
Definition: fsm_foe.c:58
uint32_t rx_buffer_size
Size of receive buffer.
Definition: fsm_foe.h:68
void ec_fsm_foe_write_start(ec_fsm_foe_t *, ec_datagram_t *)
Initializes the FoE write state machine.
Definition: fsm_foe.c:298
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition: ecrt.h:3370
File-Access over EtherCAT.
Definition: globals.h:153
#define EC_READ_U32(DATA)
Read a 32-bit unsigned value from EtherCAT data.
Definition: ecrt.h:3277
Timeout error.
Definition: foe.h:43
ec_master_t * master
Master owning the slave.
Definition: slave.h:172
#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_state_sent_ack(ec_fsm_foe_t *, ec_datagram_t *)
Sent an acknowledge.
Definition: fsm_foe.c:790
uint32_t tx_buffer_size
Size of data to transmit.
Definition: fsm_foe.h:59
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
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:46
void ec_fsm_foe_state_data_read(ec_fsm_foe_t *, ec_datagram_t *)
State: DATA READ.
Definition: fsm_foe.c:656
uint32_t rx_last_packet
Current packet is the last to receive.
Definition: fsm_foe.h:71
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:59
FoE request.
Definition: foe_request.h:42
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
Definition: ecrt.h:3261
Protocol error.
Definition: foe.h:39
ec_datagram_t * datagram
Datagram used in previous step.
Definition: fsm_foe.h:51
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_datagram_print_state(const ec_datagram_t *datagram)
Prints the state of a datagram.
Definition: datagram.c:565
Mailbox functionality.
int ec_foe_prepare_rrq_send(ec_fsm_foe_t *, ec_datagram_t *)
Prepare a read request (RRQ) with filename.
Definition: fsm_foe.c:526
ec_foe_request_t * request
FoE request.
Definition: fsm_foe.h:55
void ec_fsm_foe_state_ack_read(ec_fsm_foe_t *, ec_datagram_t *)
State: ACK READ.
Definition: fsm_foe.c:372
Queued for sending.
Definition: datagram.h:68
Ready.
Definition: foe.h:35
void ec_fsm_mbox_init(ec_fsm_mbox_t *fsm)
Constructor.
Definition: fsm_mbox.c:45
uint16_t configured_rx_mailbox_size
Configured receive mailbox size.
Definition: slave.h:191
void(* state)(ec_fsm_foe_t *, ec_datagram_t *)
FoE state function.
Definition: fsm_foe.h:49
Mailbox protocol error.
Definition: foe.h:49
#define EC_READ_U8(DATA)
Read an 8-bit unsigned value from EtherCAT data.
Definition: ecrt.h:3245
uint8_t * rx_filename
Name of the file to receive.
Definition: fsm_foe.h:72
uint32_t error_code
Error code from an FoE Error Request.
Definition: foe_request.h:61
void ec_fsm_foe_state_data_sent(ec_fsm_foe_t *, ec_datagram_t *)
State: WRQ SENT.
Definition: fsm_foe.c:490
Acknowledge error.
Definition: foe.h:46
Values written by the master.
Definition: ecrt.h:524
Received (dequeued).
Definition: datagram.h:70
uint32_t tx_current_size
Size of current packet to send.
Definition: fsm_foe.h:63
int ec_foe_prepare_send_ack(ec_fsm_foe_t *, ec_datagram_t *)
Prepare to send an acknowledge.
Definition: fsm_foe.c:560
EtherCAT FoE state machines.
void ec_fsm_mbox_clear(ec_fsm_mbox_t *fsm)
Destructor.
Definition: fsm_mbox.c:64
Finite state machines for the CANopen-over-EtherCAT protocol.
Definition: fsm_foe.h:46
uint32_t rx_buffer_offset
Offset in receive buffer.
Definition: fsm_foe.h:69