IgH EtherCAT Master  1.6.1
fsm_soe.c
Go to the documentation of this file.
1 /*****************************************************************************
2  *
3  * Copyright (C) 2006-2020 Florian Pose, Ingenieurgemeinschaft IgH
4  *
5  * This file is part of the IgH EtherCAT Master.
6  *
7  * The IgH EtherCAT Master is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License version 2, as
9  * published by the Free Software Foundation.
10  *
11  * The IgH EtherCAT Master is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
14  * Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with the IgH EtherCAT Master; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  *
20  ****************************************************************************/
21 
27 /****************************************************************************/
28 
29 #include "globals.h"
30 #include "master.h"
31 #include "mailbox.h"
32 #include "fsm_soe.h"
33 
34 /****************************************************************************/
35 
38 enum {
43 };
44 
47 #define EC_SOE_SIZE 0x04
48 
51 #define EC_SOE_HEADER_SIZE (EC_MBOX_HEADER_SIZE + EC_SOE_SIZE)
52 
55 #define EC_SOE_RESPONSE_TIMEOUT 1000
56 
57 /****************************************************************************/
58 
59 // prototypes for private methods
60 void ec_print_soe_error(const ec_slave_t *, uint16_t);
64 
65 /****************************************************************************/
66 
71 
76 
79 
80 /****************************************************************************/
81 
82 extern const ec_code_msg_t soe_error_codes[];
83 
84 /****************************************************************************/
85 
88 void ec_print_soe_error(const ec_slave_t *slave, uint16_t error_code)
89 {
90  const ec_code_msg_t *error_msg;
91 
92  for (error_msg = soe_error_codes; error_msg->code; error_msg++) {
93  if (error_msg->code == error_code) {
94  EC_SLAVE_ERR(slave, "SoE error 0x%04X: \"%s\".\n",
95  error_msg->code, error_msg->message);
96  return;
97  }
98  }
99 
100  EC_SLAVE_ERR(slave, "Unknown SoE error 0x%04X.\n", error_code);
101 }
102 
103 /****************************************************************************/
104 
108  ec_fsm_soe_t *fsm
109  )
110 {
111  fsm->state = NULL;
112  fsm->datagram = NULL;
113  fsm->fragment_size = 0;
114 }
115 
116 /****************************************************************************/
117 
121  ec_fsm_soe_t *fsm
122  )
123 {
124 }
125 
126 /****************************************************************************/
127 
131  ec_fsm_soe_t *fsm,
132  ec_slave_t *slave,
133  ec_soe_request_t *request
134  )
135 {
136  fsm->slave = slave;
137  fsm->request = request;
138 
139  if (request->dir == EC_DIR_OUTPUT) {
141  } else {
143  }
144 }
145 
146 /****************************************************************************/
147 
153  ec_fsm_soe_t *fsm,
154  ec_datagram_t *datagram
155  )
156 {
157  int datagram_used = 0;
158 
159  if (fsm->datagram &&
160  (fsm->datagram->state == EC_DATAGRAM_INIT ||
161  fsm->datagram->state == EC_DATAGRAM_QUEUED ||
162  fsm->datagram->state == EC_DATAGRAM_SENT)) {
163  // datagram not received yet
164  return datagram_used;
165  }
166 
167  fsm->state(fsm, datagram);
168 
169  datagram_used =
170  fsm->state != ec_fsm_soe_end && fsm->state != ec_fsm_soe_error;
171 
172  if (datagram_used) {
173  fsm->datagram = datagram;
174  } else {
175  fsm->datagram = NULL;
176  }
177 
178  return datagram_used;
179 }
180 
181 /****************************************************************************/
182 
188 {
189  return fsm->state == ec_fsm_soe_end;
190 }
191 
192 /****************************************************************************/
193 
197 {
198  ec_soe_request_t *request = fsm->request;
199 
200  EC_SLAVE_ERR(fsm->slave, "");
201 
202  if (request->dir == EC_DIR_OUTPUT) {
203  printk(KERN_CONT "Writing");
204  } else {
205  printk(KERN_CONT "Reading");
206  }
207 
208  printk(KERN_CONT " IDN 0x%04X failed.\n", request->idn);
209 }
210 
211 /*****************************************************************************
212  * SoE read state machine
213  ****************************************************************************/
214 
220  ec_fsm_soe_t *fsm,
221  ec_datagram_t *datagram
222  )
223 {
224  uint8_t *data;
225  ec_slave_t *slave = fsm->slave;
226  ec_master_t *master = slave->master;
227  ec_soe_request_t *request = fsm->request;
228 
229  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
230  EC_SOE_SIZE);
231  if (IS_ERR(data)) {
232  return PTR_ERR(data);
233  }
234 
235  EC_WRITE_U8(data, OPCODE_READ_REQUEST | (request->drive_no & 0x07) << 5);
236  EC_WRITE_U8(data + 1, 1 << 6); // request value
237  EC_WRITE_U16(data + 2, request->idn);
238 
239  if (master->debug_level) {
240  EC_SLAVE_DBG(slave, 0, "SSC read request:\n");
241  ec_print_data(data, EC_SOE_SIZE);
242  }
243 
244  fsm->request->jiffies_sent = jiffies;
246 
247  return 0;
248 }
249 
250 /****************************************************************************/
251 
255  ec_fsm_soe_t *fsm,
256  ec_datagram_t *datagram
257  )
258 {
259  ec_slave_t *slave = fsm->slave;
260  ec_soe_request_t *request = fsm->request;
261 
262  EC_SLAVE_DBG(slave, 1, "Reading IDN 0x%04X of drive %u.\n", request->idn,
263  request->drive_no);
264 
265  if (!(slave->sii.mailbox_protocols & EC_MBOX_SOE)) {
266  EC_SLAVE_ERR(slave, "Slave does not support SoE!\n");
267  fsm->state = ec_fsm_soe_error;
269  return;
270  }
271 
272  request->data_size = 0;
273  fsm->retries = EC_FSM_RETRIES;
274 
275  if (ec_fsm_soe_prepare_read(fsm, datagram)) {
276  fsm->state = ec_fsm_soe_error;
278  }
279 }
280 
281 /****************************************************************************/
282 
286  ec_fsm_soe_t *fsm,
287  ec_datagram_t *datagram
288  )
289 {
290  ec_slave_t *slave = fsm->slave;
291  unsigned long diff_ms;
292 
293  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
294  if (ec_fsm_soe_prepare_read(fsm, datagram)) {
295  fsm->state = ec_fsm_soe_error;
297  }
298  return;
299  }
300 
301  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
302  fsm->state = ec_fsm_soe_error;
303  EC_SLAVE_ERR(slave, "Failed to receive SoE read request: ");
306  return;
307  }
308 
309  diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
310 
311  if (fsm->datagram->working_counter != 1) {
312  if (!fsm->datagram->working_counter) {
313  if (diff_ms < EC_SOE_RESPONSE_TIMEOUT) {
314  // no response; send request datagram again
315  if (ec_fsm_soe_prepare_read(fsm, datagram)) {
316  fsm->state = ec_fsm_soe_error;
318  }
319  return;
320  }
321  }
322  fsm->state = ec_fsm_soe_error;
323  EC_SLAVE_ERR(slave, "Reception of SoE read request"
324  " failed after %lu ms: ", diff_ms);
327  return;
328  }
329 
330  fsm->jiffies_start = fsm->datagram->jiffies_sent;
331  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
332  fsm->retries = EC_FSM_RETRIES;
334 }
335 
336 /****************************************************************************/
337 
341  ec_fsm_soe_t *fsm,
342  ec_datagram_t *datagram
343  )
344 {
345  ec_slave_t *slave = fsm->slave;
346 
347  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
348  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
349  return;
350  }
351 
352  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
353  fsm->state = ec_fsm_soe_error;
354  EC_SLAVE_ERR(slave, "Failed to receive SoE mailbox check datagram: ");
357  return;
358  }
359 
360  if (fsm->datagram->working_counter != 1) {
361  fsm->state = ec_fsm_soe_error;
362  EC_SLAVE_ERR(slave, "Reception of SoE mailbox check"
363  " datagram failed: ");
366  return;
367  }
368 
369  if (!ec_slave_mbox_check(fsm->datagram)) {
370  unsigned long diff_ms =
371  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
372  1000 / HZ;
373  if (diff_ms >= EC_SOE_RESPONSE_TIMEOUT) {
374  fsm->state = ec_fsm_soe_error;
375  EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting for"
376  " read response.\n", diff_ms);
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  fsm->retries = EC_FSM_RETRIES;
390 }
391 
392 /****************************************************************************/
393 
397  ec_fsm_soe_t *fsm,
398  ec_datagram_t *datagram
399  )
400 {
401  ec_slave_t *slave = fsm->slave;
402  ec_master_t *master = slave->master;
403  uint8_t *data, mbox_prot, header, opcode, incomplete, error_flag,
404  value_included;
405  size_t rec_size, data_size;
406  ec_soe_request_t *req = fsm->request;
407 
408  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
409  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
410  return;
411  }
412 
413  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
414  fsm->state = ec_fsm_soe_error;
415  EC_SLAVE_ERR(slave, "Failed to receive SoE read response datagram: ");
418  return;
419  }
420 
421  if (fsm->datagram->working_counter != 1) {
422  fsm->state = ec_fsm_soe_error;
423  EC_SLAVE_ERR(slave, "Reception of SoE read response failed: ");
426  return;
427  }
428 
429  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
430  if (IS_ERR(data)) {
431  fsm->state = ec_fsm_soe_error;
433  return;
434  }
435 
436  if (master->debug_level) {
437  EC_SLAVE_DBG(slave, 0, "SSC read response:\n");
438  ec_print_data(data, rec_size);
439  }
440 
441  if (mbox_prot != EC_MBOX_TYPE_SOE) {
442  fsm->state = ec_fsm_soe_error;
443  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
444  mbox_prot);
446  return;
447  }
448 
449  if (rec_size < EC_SOE_SIZE) {
450  fsm->state = ec_fsm_soe_error;
451  EC_SLAVE_ERR(slave, "Received currupted SoE read response"
452  " (%zu bytes)!\n", rec_size);
453  ec_print_data(data, rec_size);
455  return;
456  }
457 
458  header = EC_READ_U8(data);
459  opcode = header & 0x7;
460  incomplete = (header >> 3) & 1;
461  error_flag = (header >> 4) & 1;
462 
463  if (opcode != OPCODE_READ_RESPONSE) {
464  EC_SLAVE_ERR(slave, "Received no read response (opcode %x).\n",
465  opcode);
466  ec_print_data(data, rec_size);
468  fsm->state = ec_fsm_soe_error;
469  return;
470  }
471 
472  if (error_flag) {
473  req->error_code = EC_READ_U16(data + rec_size - 2);
474  EC_SLAVE_ERR(slave, "Received error response:\n");
475  ec_print_soe_error(slave, req->error_code);
477  fsm->state = ec_fsm_soe_error;
478  return;
479  } else {
480  req->error_code = 0x0000;
481  }
482 
483  value_included = (EC_READ_U8(data + 1) >> 6) & 1;
484  if (!value_included) {
485  EC_SLAVE_ERR(slave, "No value included!\n");
487  fsm->state = ec_fsm_soe_error;
488  return;
489  }
490 
491  data_size = rec_size - EC_SOE_SIZE;
493  data + EC_SOE_SIZE, data_size)) {
494  fsm->state = ec_fsm_soe_error;
496  return;
497  }
498 
499  if (incomplete) {
500  EC_SLAVE_DBG(slave, 1, "SoE data incomplete. Waiting for fragment"
501  " at offset %zu.\n", req->data_size);
502  fsm->jiffies_start = fsm->datagram->jiffies_sent;
503  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
504  fsm->retries = EC_FSM_RETRIES;
506  } else {
507  if (master->debug_level) {
508  EC_SLAVE_DBG(slave, 0, "IDN data:\n");
509  ec_print_data(req->data, req->data_size);
510  }
511 
512  fsm->state = ec_fsm_soe_end; // success
513  }
514 }
515 
516 /*****************************************************************************
517  * SoE write state machine
518  ****************************************************************************/
519 
523  ec_fsm_soe_t *fsm,
524  ec_datagram_t *datagram
525  )
526 {
527  ec_slave_t *slave = fsm->slave;
528  ec_master_t *master = slave->master;
529  ec_soe_request_t *req = fsm->request;
530  uint8_t incomplete, *data;
531  size_t max_fragment_size, remaining_size;
532  uint16_t fragments_left;
533 
534  remaining_size = req->data_size - fsm->offset;
535  max_fragment_size = slave->configured_rx_mailbox_size - EC_SOE_HEADER_SIZE;
536  incomplete = remaining_size > max_fragment_size;
537  fsm->fragment_size = incomplete ? max_fragment_size : remaining_size;
538  fragments_left = remaining_size / fsm->fragment_size - 1;
539  if (remaining_size % fsm->fragment_size) {
540  fragments_left++;
541  }
542 
543  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
544  EC_SOE_SIZE + fsm->fragment_size);
545  if (IS_ERR(data)) {
546  fsm->state = ec_fsm_soe_error;
548  return;
549  }
550 
551  EC_WRITE_U8(data, OPCODE_WRITE_REQUEST | incomplete << 3 |
552  (req->drive_no & 0x07) << 5);
553  EC_WRITE_U8(data + 1, 1 << 6); // only value included
554  EC_WRITE_U16(data + 2, incomplete ? fragments_left : req->idn);
555  memcpy(data + EC_SOE_SIZE, req->data + fsm->offset, fsm->fragment_size);
556 
557  if (master->debug_level) {
558  EC_SLAVE_DBG(slave, 0, "SSC write request:\n");
560  }
561 
563 }
564 
565 /****************************************************************************/
566 
570  ec_fsm_soe_t *fsm,
571  ec_datagram_t *datagram
572  )
573 {
574  ec_slave_t *slave = fsm->slave;
575  ec_soe_request_t *req = fsm->request;
576 
577  EC_SLAVE_DBG(slave, 1, "Writing IDN 0x%04X of drive %u (%zu byte).\n",
578  req->idn, req->drive_no, req->data_size);
579 
580  if (!(slave->sii.mailbox_protocols & EC_MBOX_SOE)) {
581  EC_SLAVE_ERR(slave, "Slave does not support SoE!\n");
582  fsm->state = ec_fsm_soe_error;
584  return;
585  }
586 
588  EC_SLAVE_ERR(slave, "Mailbox size (%u) too small for SoE write.\n",
590  fsm->state = ec_fsm_soe_error;
592  return;
593  }
594 
595  fsm->offset = 0;
596  fsm->retries = EC_FSM_RETRIES;
597  ec_fsm_soe_write_next_fragment(fsm, datagram);
598  req->jiffies_sent = jiffies;
599 }
600 
601 /****************************************************************************/
602 
606  ec_fsm_soe_t *fsm,
607  ec_datagram_t *datagram
608  )
609 {
610  ec_slave_t *slave = fsm->slave;
611  unsigned long diff_ms;
612 
613  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
614  ec_fsm_soe_write_next_fragment(fsm, datagram);
615  return;
616  }
617 
618  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
619  fsm->state = ec_fsm_soe_error;
620  EC_SLAVE_ERR(slave, "Failed to receive SoE write request: ");
623  return;
624  }
625 
626  diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
627 
628  if (fsm->datagram->working_counter != 1) {
629  if (!fsm->datagram->working_counter) {
630  if (diff_ms < EC_SOE_RESPONSE_TIMEOUT) {
631  // no response; send request datagram again
632  ec_fsm_soe_write_next_fragment(fsm, datagram);
633  return;
634  }
635  }
636  fsm->state = ec_fsm_soe_error;
637  EC_SLAVE_ERR(slave, "Reception of SoE write request"
638  " failed after %lu ms: ", diff_ms);
641  return;
642  }
643 
644  // fragment successfully sent
645  fsm->offset += fsm->fragment_size;
646 
647  if (fsm->offset < fsm->request->data_size) {
648  // next fragment
649  fsm->retries = EC_FSM_RETRIES;
650  ec_fsm_soe_write_next_fragment(fsm, datagram);
651  fsm->request->jiffies_sent = jiffies;
652  } else {
653  // all fragments sent; query response
654  fsm->jiffies_start = fsm->datagram->jiffies_sent;
655  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
656  fsm->retries = EC_FSM_RETRIES;
658  }
659 }
660 
661 /****************************************************************************/
662 
666  ec_fsm_soe_t *fsm,
667  ec_datagram_t *datagram
668  )
669 {
670  ec_slave_t *slave = fsm->slave;
671 
672  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
673  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
674  return;
675  }
676 
677  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
678  fsm->state = ec_fsm_soe_error;
679  EC_SLAVE_ERR(slave, "Failed to receive SoE write request datagram: ");
682  return;
683  }
684 
685  if (fsm->datagram->working_counter != 1) {
686  fsm->state = ec_fsm_soe_error;
687  EC_SLAVE_ERR(slave, "Reception of SoE write request datagram: ");
690  return;
691  }
692 
693  if (!ec_slave_mbox_check(fsm->datagram)) {
694  unsigned long diff_ms =
695  (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
696  if (diff_ms >= EC_SOE_RESPONSE_TIMEOUT) {
697  fsm->state = ec_fsm_soe_error;
698  EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting"
699  " for write response.\n", diff_ms);
701  return;
702  }
703 
704  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
705  fsm->retries = EC_FSM_RETRIES;
706  return;
707  }
708 
709  // Fetch response
710  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
711  fsm->retries = EC_FSM_RETRIES;
713 }
714 
715 /****************************************************************************/
716 
720  ec_fsm_soe_t *fsm,
721  ec_datagram_t *datagram
722  )
723 {
724  ec_slave_t *slave = fsm->slave;
725  ec_master_t *master = slave->master;
726  ec_soe_request_t *req = fsm->request;
727  uint8_t *data, mbox_prot, opcode, error_flag;
728  uint16_t idn;
729  size_t rec_size;
730 
731  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
732  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
733  return; // FIXME: request again?
734  }
735 
736  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
737  fsm->state = ec_fsm_soe_error;
738  EC_SLAVE_ERR(slave, "Failed to receive SoE write"
739  " response datagram: ");
742  return;
743  }
744 
745  if (fsm->datagram->working_counter != 1) {
746  fsm->state = ec_fsm_soe_error;
747  EC_SLAVE_ERR(slave, "Reception of SoE write response failed: ");
750  return;
751  }
752 
753  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
754  if (IS_ERR(data)) {
755  fsm->state = ec_fsm_soe_error;
757  return;
758  }
759 
760  if (master->debug_level) {
761  EC_SLAVE_DBG(slave, 0, "SSC write response:\n");
762  ec_print_data(data, rec_size);
763  }
764 
765  if (mbox_prot != EC_MBOX_TYPE_SOE) {
766  fsm->state = ec_fsm_soe_error;
767  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
768  mbox_prot);
770  return;
771  }
772 
773  if (rec_size < EC_SOE_SIZE) {
774  fsm->state = ec_fsm_soe_error;
775  EC_SLAVE_ERR(slave, "Received corrupted SoE write response"
776  " (%zu bytes)!\n", rec_size);
777  ec_print_data(data, rec_size);
779  return;
780  }
781 
782  opcode = EC_READ_U8(data) & 0x7;
783  if (opcode != OPCODE_WRITE_RESPONSE) {
784  EC_SLAVE_ERR(slave, "Received no write response"
785  " (opcode %x).\n", opcode);
786  ec_print_data(data, rec_size);
788  fsm->state = ec_fsm_soe_error;
789  return;
790  }
791 
792  idn = EC_READ_U16(data + 2);
793  if (idn != req->idn) {
794  EC_SLAVE_ERR(slave, "Received response for"
795  " wrong IDN 0x%04x.\n", idn);
796  ec_print_data(data, rec_size);
798  fsm->state = ec_fsm_soe_error;
799  return;
800  }
801 
802  error_flag = (EC_READ_U8(data) >> 4) & 1;
803  if (error_flag) {
804  if (rec_size < EC_SOE_SIZE + 2) {
805  EC_SLAVE_ERR(slave, "Received corrupted error response"
806  " - error flag set, but received size is %zu.\n",
807  rec_size);
808  } else {
809  req->error_code = EC_READ_U16(data + EC_SOE_SIZE);
810  EC_SLAVE_ERR(slave, "Received error response:\n");
811  ec_print_soe_error(slave, req->error_code);
812  }
813  ec_print_data(data, rec_size);
815  fsm->state = ec_fsm_soe_error;
816  } else {
817  req->error_code = 0x0000;
818  fsm->state = ec_fsm_soe_end; // success
819  }
820 }
821 
822 /****************************************************************************/
823 
827  ec_fsm_soe_t *fsm,
828  ec_datagram_t *datagram
829  )
830 {
831 }
832 
833 /****************************************************************************/
834 
838  ec_fsm_soe_t *fsm,
839  ec_datagram_t *datagram
840  )
841 {
842 }
843 
844 /****************************************************************************/
#define EC_FSM_RETRIES
Number of state machine retries on datagram timeout.
Definition: globals.h:47
Finite state machines for the Sercos over EtherCAT protocol.
Definition: fsm_soe.h:43
uint16_t error_code
SoE error code.
Definition: soe_request.h:56
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
size_t fragment_size
Size of the current fragment.
Definition: fsm_soe.h:52
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
Read request.
Definition: fsm_soe.c:39
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition: slave.h:98
Write response.
Definition: fsm_soe.c:42
void ec_fsm_soe_end(ec_fsm_soe_t *, ec_datagram_t *)
State: END.
Definition: fsm_soe.c:837
ec_soe_request_t * request
SoE request.
Definition: fsm_soe.h:50
void ec_fsm_soe_error(ec_fsm_soe_t *, ec_datagram_t *)
State: ERROR.
Definition: fsm_soe.c:826
ec_direction_t dir
Direction.
Definition: soe_request.h:50
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
uint32_t code
Code.
Definition: globals.h:276
Servo-Profile over EtherCAT.
Definition: globals.h:148
int ec_fsm_soe_prepare_read(ec_fsm_soe_t *, ec_datagram_t *)
Prepare a read operation.
Definition: fsm_soe.c:219
EtherCAT datagram.
Definition: datagram.h:79
#define EC_SOE_HEADER_SIZE
SoE header size.
Definition: fsm_soe.c:51
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition: ecrt.h:3137
void ec_fsm_soe_read_response(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ RESPONSE.
Definition: fsm_soe.c:396
uint16_t working_counter
Working counter.
Definition: datagram.h:93
Sent (still in the queue).
Definition: datagram.h:69
size_t data_size
Size of SDO data.
Definition: soe_request.h:47
const char * message
Message belonging to code.
Definition: globals.h:277
void ec_print_soe_error(const ec_slave_t *, uint16_t)
Outputs an SoE error code.
Definition: fsm_soe.c:88
void ec_fsm_soe_write_check(ec_fsm_soe_t *, ec_datagram_t *)
CoE state: WRITE CHECK.
Definition: fsm_soe.c:665
Global definitions and macros.
void ec_fsm_soe_read_check(ec_fsm_soe_t *, ec_datagram_t *)
CoE state: READ CHECK.
Definition: fsm_soe.c:340
EtherCAT master structure.
Initial state of a new datagram.
Definition: datagram.h:67
EtherCAT slave.
Definition: slave.h:168
Code/Message pair.
Definition: globals.h:275
void ec_fsm_soe_transfer(ec_fsm_soe_t *fsm, ec_slave_t *slave, ec_soe_request_t *request)
Starts to transfer an IDN to/from a slave.
Definition: fsm_soe.c:130
int ec_fsm_soe_success(const ec_fsm_soe_t *fsm)
Returns, if the state machine terminated with success.
Definition: fsm_soe.c:187
ec_datagram_state_t state
State.
Definition: datagram.h:94
#define EC_SOE_RESPONSE_TIMEOUT
SoE response timeout [ms].
Definition: fsm_soe.c:55
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:139
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
Read response.
Definition: fsm_soe.c:40
void(* state)(ec_fsm_soe_t *, ec_datagram_t *)
CoE state function.
Definition: fsm_soe.h:47
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition: ecrt.h:3154
void ec_fsm_soe_write_response(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE RESPONSE.
Definition: fsm_soe.c:719
ec_master_t * master
Master owning the slave.
Definition: slave.h:170
off_t offset
IDN data offset during fragmented write.
Definition: fsm_soe.h:51
EtherCAT CoE state machines.
unsigned int retries
retries upon datagram timeout
Definition: fsm_soe.h:45
int ec_soe_request_append_data(ec_soe_request_t *req, const uint8_t *source, size_t size)
Copies SoE data from an external source.
Definition: soe_request.c:197
void ec_print_data(const uint8_t *, size_t)
Outputs frame contents for debugging purposes.
Definition: module.c:344
void ec_fsm_soe_read_start(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ START.
Definition: fsm_soe.c:254
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
ec_datagram_t * datagram
Datagram used in the previous step.
Definition: fsm_soe.h:48
void ec_fsm_soe_read_request(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ REQUEST.
Definition: fsm_soe.c:285
void ec_datagram_print_state(const ec_datagram_t *datagram)
Prints the state of a datagram.
Definition: datagram.c:557
Mailbox functionality.
const ec_code_msg_t soe_error_codes[]
SoE error codes.
Definition: soe_errors.c:35
Queued for sending.
Definition: datagram.h:68
Write request.
Definition: fsm_soe.c:41
uint8_t drive_no
Drive number.
Definition: soe_request.h:42
Timed out (dequeued).
Definition: datagram.h:71
unsigned long jiffies_start
Timestamp.
Definition: fsm_soe.h:49
uint16_t configured_rx_mailbox_size
Configured receive mailbox size.
Definition: slave.h:189
void ec_fsm_soe_init(ec_fsm_soe_t *fsm)
Constructor.
Definition: fsm_soe.c:107
void ec_fsm_soe_clear(ec_fsm_soe_t *fsm)
Destructor.
Definition: fsm_soe.c:120
#define EC_READ_U8(DATA)
Read an 8-bit unsigned value from EtherCAT data.
Definition: ecrt.h:3029
void ec_fsm_soe_write_next_fragment(ec_fsm_soe_t *, ec_datagram_t *)
Write next fragment.
Definition: fsm_soe.c:522
int ec_fsm_soe_exec(ec_fsm_soe_t *fsm, ec_datagram_t *datagram)
Executes the current state of the state machine.
Definition: fsm_soe.c:152
unsigned long jiffies_sent
Jiffies, when the upload/download request was sent.
Definition: soe_request.h:54
void ec_fsm_soe_print_error(ec_fsm_soe_t *)
Output information about a failed SoE transfer.
Definition: fsm_soe.c:196
Values written by the master.
Definition: ecrt.h:506
Received (dequeued).
Definition: datagram.h:70
ec_slave_t * slave
slave the FSM runs on
Definition: fsm_soe.h:44
EtherCAT master.
Definition: master.h:187
#define EC_SOE_SIZE
Size of all SoE headers.
Definition: fsm_soe.c:47
uint16_t idn
Sercos ID-Number.
Definition: soe_request.h:43
Sercos-over-EtherCAT request.
Definition: soe_request.h:40
unsigned long jiffies_received
Jiffies, when the datagram was received.
Definition: datagram.h:102
uint8_t * data
Pointer to SDO data.
Definition: soe_request.h:45
int ec_slave_mbox_check(const ec_datagram_t *datagram)
Processes a mailbox state checking datagram.
Definition: mailbox.c:107
void ec_fsm_soe_write_start(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE START.
Definition: fsm_soe.c:569
void ec_fsm_soe_write_request(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE REQUEST.
Definition: fsm_soe.c:605