IgH EtherCAT Master  1.5.3
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  *
22  * The license mentioned above concerns the source code only. Using the
23  * EtherCAT technology and brand is only permitted in compliance with the
24  * industrial property and similar rights of Beckhoff Automation GmbH.
25  *
26  *****************************************************************************/
27 
33 /*****************************************************************************/
34 
35 #include "globals.h"
36 #include "master.h"
37 #include "mailbox.h"
38 #include "fsm_soe.h"
39 
40 /*****************************************************************************/
41 
49 };
50 
53 #define EC_SOE_SIZE 0x04
54 
57 #define EC_SOE_HEADER_SIZE (EC_MBOX_HEADER_SIZE + EC_SOE_SIZE)
58 
61 #define EC_SOE_RESPONSE_TIMEOUT 1000
62 
63 /*****************************************************************************/
64 
69 
74 
77 
78 /*****************************************************************************/
79 
80 extern const ec_code_msg_t soe_error_codes[];
81 
82 /*****************************************************************************/
83 
86 void ec_print_soe_error(const ec_slave_t *slave, uint16_t error_code)
87 {
88  const ec_code_msg_t *error_msg;
89 
90  for (error_msg = soe_error_codes; error_msg->code; error_msg++) {
91  if (error_msg->code == error_code) {
92  EC_SLAVE_ERR(slave, "SoE error 0x%04X: \"%s\".\n",
93  error_msg->code, error_msg->message);
94  return;
95  }
96  }
97 
98  EC_SLAVE_ERR(slave, "Unknown SoE error 0x%04X.\n", error_code);
99 }
100 
101 /*****************************************************************************/
102 
106  ec_fsm_soe_t *fsm
107  )
108 {
109  fsm->state = NULL;
110  fsm->datagram = NULL;
111  fsm->fragment_size = 0;
112 }
113 
114 /*****************************************************************************/
115 
119  ec_fsm_soe_t *fsm
120  )
121 {
122 }
123 
124 /*****************************************************************************/
125 
129  ec_fsm_soe_t *fsm,
130  ec_slave_t *slave,
131  ec_soe_request_t *request
132  )
133 {
134  fsm->slave = slave;
135  fsm->request = request;
136 
137  if (request->dir == EC_DIR_OUTPUT) {
139  } else {
141  }
142 }
143 
144 /*****************************************************************************/
145 
151  ec_fsm_soe_t *fsm,
152  ec_datagram_t *datagram
153  )
154 {
155  int datagram_used = 0;
156 
157  if (fsm->datagram &&
158  (fsm->datagram->state == EC_DATAGRAM_INIT ||
159  fsm->datagram->state == EC_DATAGRAM_QUEUED ||
160  fsm->datagram->state == EC_DATAGRAM_SENT)) {
161  // datagram not received yet
162  return datagram_used;
163  }
164 
165  fsm->state(fsm, datagram);
166 
167  datagram_used =
168  fsm->state != ec_fsm_soe_end && fsm->state != ec_fsm_soe_error;
169 
170  if (datagram_used) {
171  fsm->datagram = datagram;
172  } else {
173  fsm->datagram = NULL;
174  }
175 
176  return datagram_used;
177 }
178 
179 /*****************************************************************************/
180 
186 {
187  return fsm->state == ec_fsm_soe_end;
188 }
189 
190 /*****************************************************************************/
191 
195 {
196  ec_soe_request_t *request = fsm->request;
197 
198  EC_SLAVE_ERR(fsm->slave, "");
199 
200  if (request->dir == EC_DIR_OUTPUT) {
201  printk(KERN_CONT "Writing");
202  } else {
203  printk(KERN_CONT "Reading");
204  }
205 
206  printk(KERN_CONT " IDN 0x%04X failed.\n", request->idn);
207 }
208 
209 /******************************************************************************
210  * SoE read state machine
211  *****************************************************************************/
212 
218  ec_fsm_soe_t *fsm,
219  ec_datagram_t *datagram
220  )
221 {
222  uint8_t *data;
223  ec_slave_t *slave = fsm->slave;
224  ec_master_t *master = slave->master;
225  ec_soe_request_t *request = fsm->request;
226 
227  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
228  EC_SOE_SIZE);
229  if (IS_ERR(data)) {
230  return PTR_ERR(data);
231  }
232 
233  EC_WRITE_U8(data, OPCODE_READ_REQUEST | (request->drive_no & 0x07) << 5);
234  EC_WRITE_U8(data + 1, 1 << 6); // request value
235  EC_WRITE_U16(data + 2, request->idn);
236 
237  if (master->debug_level) {
238  EC_SLAVE_DBG(slave, 0, "SSC read request:\n");
239  ec_print_data(data, EC_SOE_SIZE);
240  }
241 
242  fsm->request->jiffies_sent = jiffies;
244 
245  return 0;
246 }
247 
248 /*****************************************************************************/
249 
253  ec_fsm_soe_t *fsm,
254  ec_datagram_t *datagram
255  )
256 {
257  ec_slave_t *slave = fsm->slave;
258  ec_soe_request_t *request = fsm->request;
259 
260  EC_SLAVE_DBG(slave, 1, "Reading IDN 0x%04X of drive %u.\n", request->idn,
261  request->drive_no);
262 
263  if (!(slave->sii.mailbox_protocols & EC_MBOX_SOE)) {
264  EC_SLAVE_ERR(slave, "Slave does not support SoE!\n");
265  fsm->state = ec_fsm_soe_error;
267  return;
268  }
269 
270  request->data_size = 0;
271  fsm->retries = EC_FSM_RETRIES;
272 
273  if (ec_fsm_soe_prepare_read(fsm, datagram)) {
274  fsm->state = ec_fsm_soe_error;
276  }
277 }
278 
279 /*****************************************************************************/
280 
284  ec_fsm_soe_t *fsm,
285  ec_datagram_t *datagram
286  )
287 {
288  ec_slave_t *slave = fsm->slave;
289  unsigned long diff_ms;
290 
291  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
292  if (ec_fsm_soe_prepare_read(fsm, datagram)) {
293  fsm->state = ec_fsm_soe_error;
295  }
296  return;
297  }
298 
299  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
300  fsm->state = ec_fsm_soe_error;
301  EC_SLAVE_ERR(slave, "Failed to receive SoE read request: ");
304  return;
305  }
306 
307  diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
308 
309  if (fsm->datagram->working_counter != 1) {
310  if (!fsm->datagram->working_counter) {
311  if (diff_ms < EC_SOE_RESPONSE_TIMEOUT) {
312  // no response; send request datagram again
313  if (ec_fsm_soe_prepare_read(fsm, datagram)) {
314  fsm->state = ec_fsm_soe_error;
316  }
317  return;
318  }
319  }
320  fsm->state = ec_fsm_soe_error;
321  EC_SLAVE_ERR(slave, "Reception of SoE read request"
322  " failed after %lu ms: ", diff_ms);
325  return;
326  }
327 
328  fsm->jiffies_start = fsm->datagram->jiffies_sent;
329  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
330  fsm->retries = EC_FSM_RETRIES;
332 }
333 
334 /*****************************************************************************/
335 
339  ec_fsm_soe_t *fsm,
340  ec_datagram_t *datagram
341  )
342 {
343  ec_slave_t *slave = fsm->slave;
344 
345  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
346  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
347  return;
348  }
349 
350  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
351  fsm->state = ec_fsm_soe_error;
352  EC_SLAVE_ERR(slave, "Failed to receive SoE mailbox check datagram: ");
355  return;
356  }
357 
358  if (fsm->datagram->working_counter != 1) {
359  fsm->state = ec_fsm_soe_error;
360  EC_SLAVE_ERR(slave, "Reception of SoE mailbox check"
361  " datagram failed: ");
364  return;
365  }
366 
367  if (!ec_slave_mbox_check(fsm->datagram)) {
368  unsigned long diff_ms =
369  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
370  1000 / HZ;
371  if (diff_ms >= EC_SOE_RESPONSE_TIMEOUT) {
372  fsm->state = ec_fsm_soe_error;
373  EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting for"
374  " read response.\n", diff_ms);
376  return;
377  }
378 
379  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
380  fsm->retries = EC_FSM_RETRIES;
381  return;
382  }
383 
384  // Fetch response
385  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
386  fsm->retries = EC_FSM_RETRIES;
388 }
389 
390 /*****************************************************************************/
391 
395  ec_fsm_soe_t *fsm,
396  ec_datagram_t *datagram
397  )
398 {
399  ec_slave_t *slave = fsm->slave;
400  ec_master_t *master = slave->master;
401  uint8_t *data, mbox_prot, header, opcode, incomplete, error_flag,
402  value_included;
403  size_t rec_size, data_size;
404  ec_soe_request_t *req = fsm->request;
405 
406  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
407  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
408  return;
409  }
410 
411  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
412  fsm->state = ec_fsm_soe_error;
413  EC_SLAVE_ERR(slave, "Failed to receive SoE read response datagram: ");
416  return;
417  }
418 
419  if (fsm->datagram->working_counter != 1) {
420  fsm->state = ec_fsm_soe_error;
421  EC_SLAVE_ERR(slave, "Reception of SoE read response failed: ");
424  return;
425  }
426 
427  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
428  if (IS_ERR(data)) {
429  fsm->state = ec_fsm_soe_error;
431  return;
432  }
433 
434  if (master->debug_level) {
435  EC_SLAVE_DBG(slave, 0, "SSC read response:\n");
436  ec_print_data(data, rec_size);
437  }
438 
439  if (mbox_prot != EC_MBOX_TYPE_SOE) {
440  fsm->state = ec_fsm_soe_error;
441  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
442  mbox_prot);
444  return;
445  }
446 
447  if (rec_size < EC_SOE_SIZE) {
448  fsm->state = ec_fsm_soe_error;
449  EC_SLAVE_ERR(slave, "Received currupted SoE read response"
450  " (%zu bytes)!\n", rec_size);
451  ec_print_data(data, rec_size);
453  return;
454  }
455 
456  header = EC_READ_U8(data);
457  opcode = header & 0x7;
458  incomplete = (header >> 3) & 1;
459  error_flag = (header >> 4) & 1;
460 
461  if (opcode != OPCODE_READ_RESPONSE) {
462  EC_SLAVE_ERR(slave, "Received no read response (opcode %x).\n",
463  opcode);
464  ec_print_data(data, rec_size);
466  fsm->state = ec_fsm_soe_error;
467  return;
468  }
469 
470  if (error_flag) {
471  req->error_code = EC_READ_U16(data + rec_size - 2);
472  EC_SLAVE_ERR(slave, "Received error response:\n");
473  ec_print_soe_error(slave, req->error_code);
475  fsm->state = ec_fsm_soe_error;
476  return;
477  } else {
478  req->error_code = 0x0000;
479  }
480 
481  value_included = (EC_READ_U8(data + 1) >> 6) & 1;
482  if (!value_included) {
483  EC_SLAVE_ERR(slave, "No value included!\n");
485  fsm->state = ec_fsm_soe_error;
486  return;
487  }
488 
489  data_size = rec_size - EC_SOE_SIZE;
491  data + EC_SOE_SIZE, data_size)) {
492  fsm->state = ec_fsm_soe_error;
494  return;
495  }
496 
497  if (incomplete) {
498  EC_SLAVE_DBG(slave, 1, "SoE data incomplete. Waiting for fragment"
499  " at offset %zu.\n", req->data_size);
500  fsm->jiffies_start = fsm->datagram->jiffies_sent;
501  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
502  fsm->retries = EC_FSM_RETRIES;
504  } else {
505  if (master->debug_level) {
506  EC_SLAVE_DBG(slave, 0, "IDN data:\n");
507  ec_print_data(req->data, req->data_size);
508  }
509 
510  fsm->state = ec_fsm_soe_end; // success
511  }
512 }
513 
514 /******************************************************************************
515  * SoE write state machine
516  *****************************************************************************/
517 
521  ec_fsm_soe_t *fsm,
522  ec_datagram_t *datagram
523  )
524 {
525  ec_slave_t *slave = fsm->slave;
526  ec_master_t *master = slave->master;
527  ec_soe_request_t *req = fsm->request;
528  uint8_t incomplete, *data;
529  size_t max_fragment_size, remaining_size;
530  uint16_t fragments_left;
531 
532  remaining_size = req->data_size - fsm->offset;
533  max_fragment_size = slave->configured_rx_mailbox_size - EC_SOE_HEADER_SIZE;
534  incomplete = remaining_size > max_fragment_size;
535  fsm->fragment_size = incomplete ? max_fragment_size : remaining_size;
536  fragments_left = remaining_size / fsm->fragment_size - 1;
537  if (remaining_size % fsm->fragment_size) {
538  fragments_left++;
539  }
540 
541  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
542  EC_SOE_SIZE + fsm->fragment_size);
543  if (IS_ERR(data)) {
544  fsm->state = ec_fsm_soe_error;
546  return;
547  }
548 
549  EC_WRITE_U8(data, OPCODE_WRITE_REQUEST | incomplete << 3 |
550  (req->drive_no & 0x07) << 5);
551  EC_WRITE_U8(data + 1, 1 << 6); // only value included
552  EC_WRITE_U16(data + 2, incomplete ? fragments_left : req->idn);
553  memcpy(data + EC_SOE_SIZE, req->data + fsm->offset, fsm->fragment_size);
554 
555  if (master->debug_level) {
556  EC_SLAVE_DBG(slave, 0, "SSC write request:\n");
558  }
559 
561 }
562 
563 /*****************************************************************************/
564 
568  ec_fsm_soe_t *fsm,
569  ec_datagram_t *datagram
570  )
571 {
572  ec_slave_t *slave = fsm->slave;
573  ec_soe_request_t *req = fsm->request;
574 
575  EC_SLAVE_DBG(slave, 1, "Writing IDN 0x%04X of drive %u (%zu byte).\n",
576  req->idn, req->drive_no, req->data_size);
577 
578  if (!(slave->sii.mailbox_protocols & EC_MBOX_SOE)) {
579  EC_SLAVE_ERR(slave, "Slave does not support SoE!\n");
580  fsm->state = ec_fsm_soe_error;
582  return;
583  }
584 
586  EC_SLAVE_ERR(slave, "Mailbox size (%u) too small for SoE write.\n",
588  fsm->state = ec_fsm_soe_error;
590  return;
591  }
592 
593  fsm->offset = 0;
594  fsm->retries = EC_FSM_RETRIES;
595  ec_fsm_soe_write_next_fragment(fsm, datagram);
596  req->jiffies_sent = jiffies;
597 }
598 
599 /*****************************************************************************/
600 
604  ec_fsm_soe_t *fsm,
605  ec_datagram_t *datagram
606  )
607 {
608  ec_slave_t *slave = fsm->slave;
609  unsigned long diff_ms;
610 
611  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
612  ec_fsm_soe_write_next_fragment(fsm, datagram);
613  return;
614  }
615 
616  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
617  fsm->state = ec_fsm_soe_error;
618  EC_SLAVE_ERR(slave, "Failed to receive SoE write request: ");
621  return;
622  }
623 
624  diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
625 
626  if (fsm->datagram->working_counter != 1) {
627  if (!fsm->datagram->working_counter) {
628  if (diff_ms < EC_SOE_RESPONSE_TIMEOUT) {
629  // no response; send request datagram again
630  ec_fsm_soe_write_next_fragment(fsm, datagram);
631  return;
632  }
633  }
634  fsm->state = ec_fsm_soe_error;
635  EC_SLAVE_ERR(slave, "Reception of SoE write request"
636  " failed after %lu ms: ", diff_ms);
639  return;
640  }
641 
642  // fragment successfully sent
643  fsm->offset += fsm->fragment_size;
644 
645  if (fsm->offset < fsm->request->data_size) {
646  // next fragment
647  fsm->retries = EC_FSM_RETRIES;
648  ec_fsm_soe_write_next_fragment(fsm, datagram);
649  fsm->request->jiffies_sent = jiffies;
650  } else {
651  // all fragments sent; query response
652  fsm->jiffies_start = fsm->datagram->jiffies_sent;
653  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
654  fsm->retries = EC_FSM_RETRIES;
656  }
657 }
658 
659 /*****************************************************************************/
660 
664  ec_fsm_soe_t *fsm,
665  ec_datagram_t *datagram
666  )
667 {
668  ec_slave_t *slave = fsm->slave;
669 
670  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
671  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
672  return;
673  }
674 
675  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
676  fsm->state = ec_fsm_soe_error;
677  EC_SLAVE_ERR(slave, "Failed to receive SoE write request datagram: ");
680  return;
681  }
682 
683  if (fsm->datagram->working_counter != 1) {
684  fsm->state = ec_fsm_soe_error;
685  EC_SLAVE_ERR(slave, "Reception of SoE write request datagram: ");
688  return;
689  }
690 
691  if (!ec_slave_mbox_check(fsm->datagram)) {
692  unsigned long diff_ms =
693  (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
694  if (diff_ms >= EC_SOE_RESPONSE_TIMEOUT) {
695  fsm->state = ec_fsm_soe_error;
696  EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting"
697  " for write response.\n", diff_ms);
699  return;
700  }
701 
702  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
703  fsm->retries = EC_FSM_RETRIES;
704  return;
705  }
706 
707  // Fetch response
708  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
709  fsm->retries = EC_FSM_RETRIES;
711 }
712 
713 /*****************************************************************************/
714 
718  ec_fsm_soe_t *fsm,
719  ec_datagram_t *datagram
720  )
721 {
722  ec_slave_t *slave = fsm->slave;
723  ec_master_t *master = slave->master;
724  ec_soe_request_t *req = fsm->request;
725  uint8_t *data, mbox_prot, opcode, error_flag;
726  uint16_t idn;
727  size_t rec_size;
728 
729  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
730  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
731  return; // FIXME: request again?
732  }
733 
734  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
735  fsm->state = ec_fsm_soe_error;
736  EC_SLAVE_ERR(slave, "Failed to receive SoE write"
737  " response datagram: ");
740  return;
741  }
742 
743  if (fsm->datagram->working_counter != 1) {
744  fsm->state = ec_fsm_soe_error;
745  EC_SLAVE_ERR(slave, "Reception of SoE write response failed: ");
748  return;
749  }
750 
751  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
752  if (IS_ERR(data)) {
753  fsm->state = ec_fsm_soe_error;
755  return;
756  }
757 
758  if (master->debug_level) {
759  EC_SLAVE_DBG(slave, 0, "SSC write response:\n");
760  ec_print_data(data, rec_size);
761  }
762 
763  if (mbox_prot != EC_MBOX_TYPE_SOE) {
764  fsm->state = ec_fsm_soe_error;
765  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
766  mbox_prot);
768  return;
769  }
770 
771  if (rec_size < EC_SOE_SIZE) {
772  fsm->state = ec_fsm_soe_error;
773  EC_SLAVE_ERR(slave, "Received corrupted SoE write response"
774  " (%zu bytes)!\n", rec_size);
775  ec_print_data(data, rec_size);
777  return;
778  }
779 
780  opcode = EC_READ_U8(data) & 0x7;
781  if (opcode != OPCODE_WRITE_RESPONSE) {
782  EC_SLAVE_ERR(slave, "Received no write response"
783  " (opcode %x).\n", opcode);
784  ec_print_data(data, rec_size);
786  fsm->state = ec_fsm_soe_error;
787  return;
788  }
789 
790  idn = EC_READ_U16(data + 2);
791  if (idn != req->idn) {
792  EC_SLAVE_ERR(slave, "Received response for"
793  " wrong IDN 0x%04x.\n", idn);
794  ec_print_data(data, rec_size);
796  fsm->state = ec_fsm_soe_error;
797  return;
798  }
799 
800  error_flag = (EC_READ_U8(data) >> 4) & 1;
801  if (error_flag) {
802  if (rec_size < EC_SOE_SIZE + 2) {
803  EC_SLAVE_ERR(slave, "Received corrupted error response"
804  " - error flag set, but received size is %zu.\n",
805  rec_size);
806  } else {
807  req->error_code = EC_READ_U16(data + EC_SOE_SIZE);
808  EC_SLAVE_ERR(slave, "Received error response:\n");
809  ec_print_soe_error(slave, req->error_code);
810  }
811  ec_print_data(data, rec_size);
813  fsm->state = ec_fsm_soe_error;
814  } else {
815  req->error_code = 0x0000;
816  fsm->state = ec_fsm_soe_end; // success
817  }
818 }
819 
820 /*****************************************************************************/
821 
825  ec_fsm_soe_t *fsm,
826  ec_datagram_t *datagram
827  )
828 {
829 }
830 
831 /*****************************************************************************/
832 
836  ec_fsm_soe_t *fsm,
837  ec_datagram_t *datagram
838  )
839 {
840 }
841 
842 /*****************************************************************************/
ec_soe_opcodes
SoE operations.
Definition: fsm_soe.c:44
#define EC_FSM_RETRIES
Number of state machine retries on datagram timeout.
Definition: globals.h:47
Servo-Profile over EtherCAT.
Definition: globals.h:139
Finite state machines for the Sercos over EtherCAT protocol.
Definition: fsm_soe.h:51
uint16_t error_code
SoE error code.
Definition: soe_request.h:64
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
size_t fragment_size
Size of the current fragment.
Definition: fsm_soe.h:60
ec_sii_t sii
Extracted SII data.
Definition: slave.h:223
uint8_t * ec_slave_mbox_fetch(const ec_slave_t *slave, const ec_datagram_t *datagram, uint8_t *type, size_t *size)
Processes received mailbox data.
Definition: mailbox.c:165
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition: slave.h:106
void ec_fsm_soe_end(ec_fsm_soe_t *, ec_datagram_t *)
State: END.
Definition: fsm_soe.c:835
ec_soe_request_t * request
SoE request.
Definition: fsm_soe.h:58
void ec_fsm_soe_error(ec_fsm_soe_t *, ec_datagram_t *)
State: ERROR.
Definition: fsm_soe.c:824
ec_direction_t dir
Direction.
Definition: soe_request.h:58
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
uint32_t code
Code.
Definition: globals.h:267
int ec_fsm_soe_prepare_read(ec_fsm_soe_t *fsm, ec_datagram_t *datagram)
Prepare a read operation.
Definition: fsm_soe.c:217
EtherCAT datagram.
Definition: datagram.h:87
#define EC_SOE_HEADER_SIZE
SoE header size.
Definition: fsm_soe.c:57
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2401
void ec_fsm_soe_read_response(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ RESPONSE.
Definition: fsm_soe.c:394
uint16_t working_counter
Working counter.
Definition: datagram.h:99
Sent (still in the queue).
Definition: datagram.h:77
size_t data_size
Size of SDO data.
Definition: soe_request.h:55
const char * message
Message belonging to code.
Definition: globals.h:268
void ec_print_soe_error(const ec_slave_t *slave, uint16_t error_code)
Outputs an SoE error code.
Definition: fsm_soe.c:86
void ec_fsm_soe_write_check(ec_fsm_soe_t *, ec_datagram_t *)
CoE state: WRITE CHECK.
Definition: fsm_soe.c:663
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:338
EtherCAT master structure.
Initial state of a new datagram.
Definition: datagram.h:75
EtherCAT slave.
Definition: slave.h:176
Code/Message pair.
Definition: globals.h:266
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:128
int ec_fsm_soe_success(const ec_fsm_soe_t *fsm)
Returns, if the state machine terminated with success.
Definition: fsm_soe.c:185
ec_datagram_state_t state
State.
Definition: datagram.h:100
#define EC_SOE_RESPONSE_TIMEOUT
SoE response timeout [ms].
Definition: fsm_soe.c:61
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:147
unsigned int debug_level
Master debug level.
Definition: master.h:285
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition: slave.h:76
void ec_datagram_print_wc_error(const ec_datagram_t *datagram)
Evaluates the working counter of a single-cast datagram.
Definition: datagram.c:602
void(* state)(ec_fsm_soe_t *, ec_datagram_t *)
CoE state function.
Definition: fsm_soe.h:55
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2418
void ec_fsm_soe_write_response(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE RESPONSE.
Definition: fsm_soe.c:717
Read response.
Definition: fsm_soe.c:46
ec_master_t * master
Master owning the slave.
Definition: slave.h:178
off_t offset
IDN data offset during fragmented write.
Definition: fsm_soe.h:59
EtherCAT CoE state machines.
unsigned int retries
retries upon datagram timeout
Definition: fsm_soe.h:53
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:203
void ec_print_data(const uint8_t *, size_t)
Outputs frame contents for debugging purposes.
Definition: module.c:348
void ec_fsm_soe_read_start(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ START.
Definition: fsm_soe.c:252
int ec_slave_mbox_prepare_check(const ec_slave_t *slave, ec_datagram_t *datagram)
Prepares a datagram for checking the mailbox state.
Definition: mailbox.c:96
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2313
ec_datagram_t * datagram
Datagram used in the previous step.
Definition: fsm_soe.h:56
void ec_fsm_soe_read_request(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ REQUEST.
Definition: fsm_soe.c:283
void ec_datagram_print_state(const ec_datagram_t *datagram)
Prints the state of a datagram.
Definition: datagram.c:565
Mailbox functionality.
const ec_code_msg_t soe_error_codes[]
SoE error codes.
Definition: soe_errors.c:43
Read request.
Definition: fsm_soe.c:45
Queued for sending.
Definition: datagram.h:76
uint8_t drive_no
Drive number.
Definition: soe_request.h:50
Timed out (dequeued).
Definition: datagram.h:79
unsigned long jiffies_start
Timestamp.
Definition: fsm_soe.h:57
uint16_t configured_rx_mailbox_size
Configured receive mailbox size.
Definition: slave.h:197
void ec_fsm_soe_init(ec_fsm_soe_t *fsm)
Constructor.
Definition: fsm_soe.c:105
void ec_fsm_soe_clear(ec_fsm_soe_t *fsm)
Destructor.
Definition: fsm_soe.c:118
Write request.
Definition: fsm_soe.c:47
#define EC_READ_U8(DATA)
Read an 8-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2297
void ec_fsm_soe_write_next_fragment(ec_fsm_soe_t *fsm, ec_datagram_t *datagram)
Write next fragment.
Definition: fsm_soe.c:520
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:150
unsigned long jiffies_sent
Jiffies, when the upload/download request was sent.
Definition: soe_request.h:62
void ec_fsm_soe_print_error(ec_fsm_soe_t *fsm)
Output information about a failed SoE transfer.
Definition: fsm_soe.c:194
Values written by the master.
Definition: ecrt.h:448
Received (dequeued).
Definition: datagram.h:78
ec_slave_t * slave
slave the FSM runs on
Definition: fsm_soe.h:52
EtherCAT master.
Definition: master.h:194
#define EC_SOE_SIZE
Size of all SoE headers.
Definition: fsm_soe.c:53
uint16_t idn
Sercos ID-Number.
Definition: soe_request.h:51
Write response.
Definition: fsm_soe.c:48
Sercos-over-EtherCAT request.
Definition: soe_request.h:48
unsigned long jiffies_received
Jiffies, when the datagram was received.
Definition: datagram.h:108
uint8_t * data
Pointer to SDO data.
Definition: soe_request.h:53
int ec_slave_mbox_check(const ec_datagram_t *datagram)
Processes a mailbox state checking datagram.
Definition: mailbox.c:115
void ec_fsm_soe_write_start(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE START.
Definition: fsm_soe.c:567
void ec_fsm_soe_write_request(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE REQUEST.
Definition: fsm_soe.c:603