IgH EtherCAT Master  1.5.2
fsm_soe.c
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * $Id$
4  *
5  * Copyright (C) 2006-2008 Florian Pose, Ingenieurgemeinschaft IgH
6  *
7  * This file is part of the IgH EtherCAT Master.
8  *
9  * The IgH EtherCAT Master is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License version 2, as
11  * published by the Free Software Foundation.
12  *
13  * The IgH EtherCAT Master is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16  * Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with the IgH EtherCAT Master; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21  *
22  * ---
23  *
24  * The license mentioned above concerns the source code only. Using the
25  * EtherCAT technology and brand is only permitted in compliance with the
26  * industrial property and similar rights of Beckhoff Automation GmbH.
27  *
28  *****************************************************************************/
29 
35 /*****************************************************************************/
36 
37 #include "globals.h"
38 #include "master.h"
39 #include "mailbox.h"
40 #include "fsm_soe.h"
41 
42 /*****************************************************************************/
43 
46 #define EC_MBOX_TYPE_SOE 0x05
47 
55 };
56 
59 #define EC_SOE_SIZE 0x04
60 
63 #define EC_SOE_RESPONSE_TIMEOUT 1000
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("Writing");
204  } else {
205  printk("Reading");
206  }
207 
208  printk(" 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, "SCC 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, "SCC 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 header_size, max_fragment_size, remaining_size;
532  uint16_t fragments_left;
533 
534  header_size = EC_MBOX_HEADER_SIZE + EC_SOE_SIZE;
535  if (slave->configured_rx_mailbox_size <= header_size) {
536  EC_SLAVE_ERR(slave, "Mailbox size (%u) too small for SoE write.\n",
538  fsm->state = ec_fsm_soe_error;
540  return;
541  }
542 
543  remaining_size = req->data_size - fsm->offset;
544  max_fragment_size = slave->configured_rx_mailbox_size - header_size;
545  incomplete = remaining_size > max_fragment_size;
546  fsm->fragment_size = incomplete ? max_fragment_size : remaining_size;
547  fragments_left = remaining_size / fsm->fragment_size - 1;
548  if (remaining_size % fsm->fragment_size) {
549  fragments_left++;
550  }
551 
552  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
553  EC_SOE_SIZE + fsm->fragment_size);
554  if (IS_ERR(data)) {
555  fsm->state = ec_fsm_soe_error;
557  return;
558  }
559 
560  EC_WRITE_U8(data, OPCODE_WRITE_REQUEST | incomplete << 3 |
561  (req->drive_no & 0x07) << 5);
562  EC_WRITE_U8(data + 1, 1 << 6); // only value included
563  EC_WRITE_U16(data + 2, incomplete ? fragments_left : req->idn);
564  memcpy(data + 4, req->data + fsm->offset, fsm->fragment_size);
565 
566  if (master->debug_level) {
567  EC_SLAVE_DBG(slave, 0, "SCC write request:\n");
568  ec_print_data(data, EC_SOE_SIZE + fsm->fragment_size);
569  }
570 
571  req->jiffies_sent = jiffies;
573 }
574 
575 /*****************************************************************************/
576 
580  ec_fsm_soe_t *fsm,
581  ec_datagram_t *datagram
582  )
583 {
584  ec_slave_t *slave = fsm->slave;
585  ec_soe_request_t *req = fsm->request;
586 
587  EC_SLAVE_DBG(slave, 1, "Writing IDN 0x%04X of drive %u (%zu byte).\n",
588  req->idn, req->drive_no, req->data_size);
589 
590  if (!(slave->sii.mailbox_protocols & EC_MBOX_SOE)) {
591  EC_SLAVE_ERR(slave, "Slave does not support SoE!\n");
592  fsm->state = ec_fsm_soe_error;
594  return;
595  }
596 
597  fsm->offset = 0;
598  fsm->retries = EC_FSM_RETRIES;
599  ec_fsm_soe_write_next_fragment(fsm, datagram);
600 }
601 
602 /*****************************************************************************/
603 
607  ec_fsm_soe_t *fsm,
608  ec_datagram_t *datagram
609  )
610 {
611  ec_slave_t *slave = fsm->slave;
612  unsigned long diff_ms;
613 
614  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
615  ec_fsm_soe_write_next_fragment(fsm, datagram);
616  return;
617  }
618 
619  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
620  fsm->state = ec_fsm_soe_error;
621  EC_SLAVE_ERR(slave, "Failed to receive SoE write request: ");
624  return;
625  }
626 
627  diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
628 
629  if (fsm->datagram->working_counter != 1) {
630  if (!fsm->datagram->working_counter) {
631  if (diff_ms < EC_SOE_RESPONSE_TIMEOUT) {
632  // no response; send request datagram again
633  ec_fsm_soe_write_next_fragment(fsm, datagram);
634  return;
635  }
636  }
637  fsm->state = ec_fsm_soe_error;
638  EC_SLAVE_ERR(slave, "Reception of SoE write request"
639  " failed after %lu ms: ", diff_ms);
642  return;
643  }
644 
645  fsm->jiffies_start = fsm->datagram->jiffies_sent;
646 
647  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
648  fsm->retries = EC_FSM_RETRIES;
650 }
651 
652 /*****************************************************************************/
653 
657  ec_fsm_soe_t *fsm,
658  ec_datagram_t *datagram
659  )
660 {
661  ec_slave_t *slave = fsm->slave;
662 
663  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
664  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
665  return;
666  }
667 
668  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
669  fsm->state = ec_fsm_soe_error;
670  EC_SLAVE_ERR(slave, "Failed to receive SoE write request datagram: ");
673  return;
674  }
675 
676  if (fsm->datagram->working_counter != 1) {
677  fsm->state = ec_fsm_soe_error;
678  EC_SLAVE_ERR(slave, "Reception of SoE write request datagram: ");
681  return;
682  }
683 
684  if (!ec_slave_mbox_check(fsm->datagram)) {
685  unsigned long diff_ms =
686  (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
687  if (diff_ms >= EC_SOE_RESPONSE_TIMEOUT) {
688  fsm->state = ec_fsm_soe_error;
689  EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting"
690  " for write response.\n", diff_ms);
692  return;
693  }
694 
695  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
696  fsm->retries = EC_FSM_RETRIES;
697  return;
698  }
699 
700  // Fetch response
701  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
702  fsm->retries = EC_FSM_RETRIES;
704 }
705 
706 /*****************************************************************************/
707 
711  ec_fsm_soe_t *fsm,
712  ec_datagram_t *datagram
713  )
714 {
715  ec_slave_t *slave = fsm->slave;
716  ec_master_t *master = slave->master;
717  ec_soe_request_t *req = fsm->request;
718  uint8_t *data, mbox_prot, opcode, error_flag;
719  uint16_t idn;
720  size_t rec_size;
721 
722  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
723  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
724  return; // FIXME: request again?
725  }
726 
727  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
728  fsm->state = ec_fsm_soe_error;
729  EC_SLAVE_ERR(slave, "Failed to receive SoE write"
730  " response datagram: ");
733  return;
734  }
735 
736  if (fsm->datagram->working_counter != 1) {
737  fsm->state = ec_fsm_soe_error;
738  EC_SLAVE_ERR(slave, "Reception of SoE write response failed: ");
741  return;
742  }
743 
744  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
745  if (IS_ERR(data)) {
746  fsm->state = ec_fsm_soe_error;
748  return;
749  }
750 
751  if (master->debug_level) {
752  EC_SLAVE_DBG(slave, 0, "SCC write response:\n");
753  ec_print_data(data, rec_size);
754  }
755 
756  if (mbox_prot != EC_MBOX_TYPE_SOE) {
757  fsm->state = ec_fsm_soe_error;
758  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
759  mbox_prot);
761  return;
762  }
763 
764  if (rec_size < EC_SOE_SIZE) {
765  fsm->state = ec_fsm_soe_error;
766  EC_SLAVE_ERR(slave, "Received corrupted SoE write response"
767  " (%zu bytes)!\n", rec_size);
768  ec_print_data(data, rec_size);
770  return;
771  }
772 
773  opcode = EC_READ_U8(data) & 0x7;
774  if (opcode != OPCODE_WRITE_RESPONSE) {
775  EC_SLAVE_ERR(slave, "Received no write response"
776  " (opcode %x).\n", opcode);
777  ec_print_data(data, rec_size);
779  fsm->state = ec_fsm_soe_error;
780  return;
781  }
782 
783  idn = EC_READ_U16(data + 2);
784  if (idn != req->idn) {
785  EC_SLAVE_ERR(slave, "Received response for"
786  " wrong IDN 0x%04x.\n", idn);
787  ec_print_data(data, rec_size);
789  fsm->state = ec_fsm_soe_error;
790  return;
791  }
792 
793  error_flag = (EC_READ_U8(data) >> 4) & 1;
794  if (error_flag) {
795  if (rec_size < EC_SOE_SIZE + 2) {
796  EC_SLAVE_ERR(slave, "Received corrupted error response"
797  " - error flag set, but received size is %zu.\n",
798  rec_size);
799  } else {
800  req->error_code = EC_READ_U16(data + EC_SOE_SIZE);
801  EC_SLAVE_ERR(slave, "Received error response:\n");
802  ec_print_soe_error(slave, req->error_code);
803  }
804  ec_print_data(data, rec_size);
806  fsm->state = ec_fsm_soe_error;
807  return;
808  } else {
809  req->error_code = 0x0000;
810  }
811 
812  fsm->offset += fsm->fragment_size;
813 
814  if (fsm->offset < req->data_size) {
815  fsm->retries = EC_FSM_RETRIES;
816  ec_fsm_soe_write_next_fragment(fsm, datagram);
817  } else {
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 /*****************************************************************************/
void ec_fsm_soe_read_start(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ START.
Definition: fsm_soe.c:254
void ec_fsm_soe_end(ec_fsm_soe_t *, ec_datagram_t *)
State: END.
Definition: fsm_soe.c:837
ec_soe_opcodes
SoE operations.
Definition: fsm_soe.c:50
#define EC_FSM_RETRIES
Number of state machine retries on datagram timeout.
Definition: globals.h:59
void(* state)(ec_fsm_soe_t *, ec_datagram_t *)
CoE state function.
Definition: fsm_soe.h:55
void ec_fsm_soe_write_start(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE START.
Definition: fsm_soe.c:579
Finite state machines for the Sercos over EtherCAT protocol.
Definition: fsm_soe.h:51
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
unsigned long jiffies_sent
Jiffies, when the upload/download request was sent.
Definition: soe_request.h:59
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
uint8_t * data
Pointer to SDO data.
Definition: soe_request.h:53
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition: slave.h:106
ec_soe_request_t * request
SoE request.
Definition: fsm_soe.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:279
int ec_fsm_soe_prepare_read(ec_fsm_soe_t *fsm, ec_datagram_t *datagram)
Prepare a read operation.
Definition: fsm_soe.c:219
void ec_fsm_soe_read_request(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ REQUEST.
Definition: fsm_soe.c:285
EtherCAT datagram.
Definition: datagram.h:87
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2187
uint16_t error_code
SoE error code.
Definition: soe_request.h:61
uint16_t working_counter
Working counter.
Definition: datagram.h:99
#define EC_MBOX_TYPE_SOE
Mailbox type for SoE.
Definition: fsm_soe.c:46
uint8_t drive_no
Drive number.
Definition: soe_request.h:50
Sent (still in the queue).
Definition: datagram.h:77
const char * message
Message belonging to code.
Definition: globals.h:280
void ec_print_soe_error(const ec_slave_t *slave, uint16_t error_code)
Outputs an SoE error code.
Definition: fsm_soe.c:88
Global definitions and macros.
EtherCAT master structure.
Initial state of a new datagram.
Definition: datagram.h:75
void ec_fsm_soe_write_response(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE RESPONSE.
Definition: fsm_soe.c:710
EtherCAT slave.
Definition: slave.h:176
Code/Message pair.
Definition: globals.h:278
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:100
#define EC_SOE_RESPONSE_TIMEOUT
SoE response timeout [ms].
Definition: fsm_soe.c:63
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:147
size_t data_size
Size of SDO data.
Definition: soe_request.h:55
unsigned int debug_level
Master debug level.
Definition: master.h:286
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition: slave.h:76
void ec_datagram_print_wc_error(const ec_datagram_t *datagram)
Evaluates the working counter of a single-cast datagram.
Definition: datagram.c:602
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2204
Read response.
Definition: fsm_soe.c:52
ec_direction_t dir
Direction.
Definition: soe_request.h:56
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.
void ec_fsm_soe_write_request(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE REQUEST.
Definition: fsm_soe.c:606
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
#define EC_MBOX_HEADER_SIZE
Mailbox header size.
Definition: globals.h:95
void ec_print_data(const uint8_t *, size_t)
Outputs frame contents for debugging purposes.
Definition: module.c:341
int ec_slave_mbox_prepare_check(const ec_slave_t *slave, ec_datagram_t *datagram)
Prepares a datagram for checking the mailbox state.
Definition: mailbox.c:96
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2135
ec_datagram_t * datagram
Datagram used in the previous step.
Definition: fsm_soe.h:56
void ec_datagram_print_state(const ec_datagram_t *datagram)
Prints the state of a datagram.
Definition: datagram.c:565
Mailbox functionality.
void ec_fsm_soe_read_check(ec_fsm_soe_t *, ec_datagram_t *)
CoE state: READ CHECK.
Definition: fsm_soe.c:340
Servo-Profile over EtherCAT.
Definition: globals.h:151
const ec_code_msg_t soe_error_codes[]
SoE error codes.
Definition: soe_errors.c:43
Read request.
Definition: fsm_soe.c:51
Queued for sending.
Definition: datagram.h:76
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:107
void ec_fsm_soe_clear(ec_fsm_soe_t *fsm)
Destructor.
Definition: fsm_soe.c:120
Write request.
Definition: fsm_soe.c:53
#define EC_READ_U8(DATA)
Read an 8-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2119
uint16_t idn
Sercos ID-Number.
Definition: soe_request.h:51
void ec_fsm_soe_write_next_fragment(ec_fsm_soe_t *fsm, ec_datagram_t *datagram)
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
void ec_fsm_soe_print_error(ec_fsm_soe_t *fsm)
Output information about a failed SoE transfer.
Definition: fsm_soe.c:196
Values written by the master.
Definition: ecrt.h:419
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:59
Write response.
Definition: fsm_soe.c:54
unsigned long jiffies_received
Jiffies, when the datagram was received.
Definition: datagram.h:108
int ec_slave_mbox_check(const ec_datagram_t *datagram)
Processes a mailbox state checking datagram.
Definition: mailbox.c:115
void ec_fsm_soe_read_response(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ RESPONSE.
Definition: fsm_soe.c:396
void ec_fsm_soe_error(ec_fsm_soe_t *, ec_datagram_t *)
State: ERROR.
Definition: fsm_soe.c:826
Sercos-over-EtherCAT request.
Definition: soe_request.h:48
void ec_fsm_soe_write_check(ec_fsm_soe_t *, ec_datagram_t *)
CoE state: WRITE CHECK.
Definition: fsm_soe.c:656