IgH EtherCAT Master  1.6.1
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 
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 ||
126  fsm->datagram->state == EC_DATAGRAM_QUEUED ||
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;
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 
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++;
440  fsm->tx_buffer_offset += fsm->tx_current_size;
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 
490  fsm->jiffies_start = fsm->datagram->jiffies_sent;
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 
628  fsm->jiffies_start = fsm->datagram->jiffies_sent;
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 =
811  != slave->configured_rx_mailbox_size);
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 
873  fsm->jiffies_start = fsm->datagram->jiffies_sent;
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;
879  fsm->request->data_size = fsm->rx_buffer_offset;
880  fsm->state = ec_fsm_foe_end;
881  }
882  else {
883  fsm->rx_expected_packet_no++;
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 /****************************************************************************/
uint8_t * tx_filename
Name of file to transmit.
Definition: fsm_foe.h:63
#define EC_FSM_RETRIES
Number of state machine retries on datagram timeout.
Definition: globals.h:47
Receive error.
Definition: foe.h:38
ec_slave_t * slave
Slave the FSM runs on.
Definition: fsm_foe.h:46
uint8_t * rx_buffer
Buffer for received data.
Definition: fsm_foe.h:66
void ec_fsm_foe_read_start(ec_fsm_foe_t *, ec_datagram_t *)
Starting state for read operations.
Definition: fsm_foe.c:640
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
unsigned long jiffies_sent
Jiffies, when the datagram was sent.
Definition: datagram.h:98
ec_sii_t sii
Extracted SII data.
Definition: slave.h:215
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
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:193
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:107
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition: slave.h:98
Working counter error.
Definition: foe.h:37
uint32_t tx_packet_no
FoE packet number.
Definition: fsm_foe.h:61
unsigned long jiffies_start
FoE timestamp.
Definition: fsm_foe.h:52
Packet number error.
Definition: foe.h:41
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
EtherCAT datagram.
Definition: datagram.h:79
void ec_fsm_foe_state_rrq_sent(ec_fsm_foe_t *, ec_datagram_t *)
State: RRQ SENT.
Definition: fsm_foe.c:602
uint8_t * tx_buffer
Buffer with data to transmit.
Definition: fsm_foe.h:57
uint32_t tx_buffer_offset
Offset of data to tranmit next.
Definition: fsm_foe.h:59
#define EC_FOE_HEADER_SIZE
Size of the FoE header.
Definition: fsm_foe.c:43
uint16_t working_counter
Working counter.
Definition: datagram.h:93
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:893
uint32_t tx_filename_len
Lenth of transmit file name.
Definition: fsm_foe.h:64
uint32_t rx_filename_len
Length of the receive file name.
Definition: fsm_foe.h:72
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:168
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:60
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:464
void ec_fsm_foe_init(ec_fsm_foe_t *fsm)
Constructor.
Definition: fsm_foe.c:95
ec_datagram_state_t state
State.
Definition: datagram.h:94
#define EC_WRITE_U32(DATA, VAL)
Write a 32-bit unsigned value to EtherCAT data.
Definition: ecrt.h:3171
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:69
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:139
Error acknowledging received data.
Definition: foe.h:45
unsigned int debug_level
Master debug level.
Definition: master.h:275
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition: slave.h:68
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_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
Acknowledge.
Definition: fsm_foe.c:58
uint32_t rx_buffer_size
Size of receive buffer.
Definition: fsm_foe.h:67
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:3154
File-Access over EtherCAT.
Definition: globals.h:147
#define EC_READ_U32(DATA)
Read a 32-bit unsigned value from EtherCAT data.
Definition: ecrt.h:3061
Timeout error.
Definition: foe.h:43
ec_master_t * master
Master owning the slave.
Definition: slave.h:170
#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:847
uint32_t tx_buffer_size
Size of data to transmit.
Definition: fsm_foe.h:58
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 *)
Start reading data.
Definition: fsm_foe.c:723
uint32_t rx_last_packet
Current packet is the last to receive.
Definition: fsm_foe.h:70
void ec_print_data(const uint8_t *, size_t)
Outputs frame contents for debugging purposes.
Definition: module.c:344
uint8_t * file_name
Pointer to the filename.
Definition: foe_request.h:59
unsigned int retries
Retries upon datagram timeout.
Definition: fsm_foe.h:47
FoE request.
Definition: foe_request.h:42
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
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
Definition: ecrt.h:3045
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:557
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:542
ec_foe_request_t * request
FoE request.
Definition: fsm_foe.h:54
void ec_fsm_foe_state_ack_read(ec_fsm_foe_t *, ec_datagram_t *)
Acknowledge a read operation.
Definition: fsm_foe.c:384
Queued for sending.
Definition: datagram.h:68
Ready.
Definition: foe.h:35
uint16_t configured_rx_mailbox_size
Configured receive mailbox size.
Definition: slave.h:189
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:3029
uint8_t * rx_filename
Name of the file to receive.
Definition: fsm_foe.h:71
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:505
Acknowledge error.
Definition: foe.h:46
Values written by the master.
Definition: ecrt.h:506
Received (dequeued).
Definition: datagram.h:70
uint32_t tx_current_size
Size of current packet to send.
Definition: fsm_foe.h:62
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_fsm_foe_state_data_check(ec_fsm_foe_t *, ec_datagram_t *)
Check for data.
Definition: fsm_foe.c:673
EtherCAT FoE state machines.
unsigned long jiffies_received
Jiffies, when the datagram was received.
Definition: datagram.h:102
int ec_slave_mbox_check(const ec_datagram_t *datagram)
Processes a mailbox state checking datagram.
Definition: mailbox.c:107
Finite state machines for the CANopen-over-EtherCAT protocol.
Definition: fsm_foe.h:45
uint32_t rx_buffer_offset
Offset in receive buffer.
Definition: fsm_foe.h:68
void ec_fsm_foe_state_ack_check(ec_fsm_foe_t *, ec_datagram_t *)
Check for acknowledge.
Definition: fsm_foe.c:332