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_HEADER_SIZE (EC_MBOX_HEADER_SIZE + EC_SOE_SIZE)
64 
67 #define EC_SOE_RESPONSE_TIMEOUT 1000
68 
69 /*****************************************************************************/
70 
75 
80 
83 
84 /*****************************************************************************/
85 
86 extern const ec_code_msg_t soe_error_codes[];
87 
88 /*****************************************************************************/
89 
92 void ec_print_soe_error(const ec_slave_t *slave, uint16_t error_code)
93 {
94  const ec_code_msg_t *error_msg;
95 
96  for (error_msg = soe_error_codes; error_msg->code; error_msg++) {
97  if (error_msg->code == error_code) {
98  EC_SLAVE_ERR(slave, "SoE error 0x%04X: \"%s\".\n",
99  error_msg->code, error_msg->message);
100  return;
101  }
102  }
103 
104  EC_SLAVE_ERR(slave, "Unknown SoE error 0x%04X.\n", error_code);
105 }
106 
107 /*****************************************************************************/
108 
112  ec_fsm_soe_t *fsm
113  )
114 {
115  fsm->state = NULL;
116  fsm->datagram = NULL;
117  fsm->fragment_size = 0;
118 }
119 
120 /*****************************************************************************/
121 
125  ec_fsm_soe_t *fsm
126  )
127 {
128 }
129 
130 /*****************************************************************************/
131 
135  ec_fsm_soe_t *fsm,
136  ec_slave_t *slave,
137  ec_soe_request_t *request
138  )
139 {
140  fsm->slave = slave;
141  fsm->request = request;
142 
143  if (request->dir == EC_DIR_OUTPUT) {
145  } else {
147  }
148 }
149 
150 /*****************************************************************************/
151 
157  ec_fsm_soe_t *fsm,
158  ec_datagram_t *datagram
159  )
160 {
161  int datagram_used = 0;
162 
163  if (fsm->datagram &&
164  (fsm->datagram->state == EC_DATAGRAM_INIT ||
165  fsm->datagram->state == EC_DATAGRAM_QUEUED ||
166  fsm->datagram->state == EC_DATAGRAM_SENT)) {
167  // datagram not received yet
168  return datagram_used;
169  }
170 
171  fsm->state(fsm, datagram);
172 
173  datagram_used =
174  fsm->state != ec_fsm_soe_end && fsm->state != ec_fsm_soe_error;
175 
176  if (datagram_used) {
177  fsm->datagram = datagram;
178  } else {
179  fsm->datagram = NULL;
180  }
181 
182  return datagram_used;
183 }
184 
185 /*****************************************************************************/
186 
192 {
193  return fsm->state == ec_fsm_soe_end;
194 }
195 
196 /*****************************************************************************/
197 
201 {
202  ec_soe_request_t *request = fsm->request;
203 
204  EC_SLAVE_ERR(fsm->slave, "");
205 
206  if (request->dir == EC_DIR_OUTPUT) {
207  printk("Writing");
208  } else {
209  printk("Reading");
210  }
211 
212  printk(" IDN 0x%04X failed.\n", request->idn);
213 }
214 
215 /******************************************************************************
216  * SoE read state machine
217  *****************************************************************************/
218 
224  ec_fsm_soe_t *fsm,
225  ec_datagram_t *datagram
226  )
227 {
228  uint8_t *data;
229  ec_slave_t *slave = fsm->slave;
230  ec_master_t *master = slave->master;
231  ec_soe_request_t *request = fsm->request;
232 
233  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
234  EC_SOE_SIZE);
235  if (IS_ERR(data)) {
236  return PTR_ERR(data);
237  }
238 
239  EC_WRITE_U8(data, OPCODE_READ_REQUEST | (request->drive_no & 0x07) << 5);
240  EC_WRITE_U8(data + 1, 1 << 6); // request value
241  EC_WRITE_U16(data + 2, request->idn);
242 
243  if (master->debug_level) {
244  EC_SLAVE_DBG(slave, 0, "SSC read request:\n");
245  ec_print_data(data, EC_SOE_SIZE);
246  }
247 
248  fsm->request->jiffies_sent = jiffies;
250 
251  return 0;
252 }
253 
254 /*****************************************************************************/
255 
259  ec_fsm_soe_t *fsm,
260  ec_datagram_t *datagram
261  )
262 {
263  ec_slave_t *slave = fsm->slave;
264  ec_soe_request_t *request = fsm->request;
265 
266  EC_SLAVE_DBG(slave, 1, "Reading IDN 0x%04X of drive %u.\n", request->idn,
267  request->drive_no);
268 
269  if (!(slave->sii.mailbox_protocols & EC_MBOX_SOE)) {
270  EC_SLAVE_ERR(slave, "Slave does not support SoE!\n");
271  fsm->state = ec_fsm_soe_error;
273  return;
274  }
275 
276  request->data_size = 0;
277  fsm->retries = EC_FSM_RETRIES;
278 
279  if (ec_fsm_soe_prepare_read(fsm, datagram)) {
280  fsm->state = ec_fsm_soe_error;
282  }
283 }
284 
285 /*****************************************************************************/
286 
290  ec_fsm_soe_t *fsm,
291  ec_datagram_t *datagram
292  )
293 {
294  ec_slave_t *slave = fsm->slave;
295  unsigned long diff_ms;
296 
297  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
298  if (ec_fsm_soe_prepare_read(fsm, datagram)) {
299  fsm->state = ec_fsm_soe_error;
301  }
302  return;
303  }
304 
305  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
306  fsm->state = ec_fsm_soe_error;
307  EC_SLAVE_ERR(slave, "Failed to receive SoE read request: ");
310  return;
311  }
312 
313  diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
314 
315  if (fsm->datagram->working_counter != 1) {
316  if (!fsm->datagram->working_counter) {
317  if (diff_ms < EC_SOE_RESPONSE_TIMEOUT) {
318  // no response; send request datagram again
319  if (ec_fsm_soe_prepare_read(fsm, datagram)) {
320  fsm->state = ec_fsm_soe_error;
322  }
323  return;
324  }
325  }
326  fsm->state = ec_fsm_soe_error;
327  EC_SLAVE_ERR(slave, "Reception of SoE read request"
328  " failed after %lu ms: ", diff_ms);
331  return;
332  }
333 
334  fsm->jiffies_start = fsm->datagram->jiffies_sent;
335  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
336  fsm->retries = EC_FSM_RETRIES;
338 }
339 
340 /*****************************************************************************/
341 
345  ec_fsm_soe_t *fsm,
346  ec_datagram_t *datagram
347  )
348 {
349  ec_slave_t *slave = fsm->slave;
350 
351  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
352  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
353  return;
354  }
355 
356  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
357  fsm->state = ec_fsm_soe_error;
358  EC_SLAVE_ERR(slave, "Failed to receive SoE mailbox check datagram: ");
361  return;
362  }
363 
364  if (fsm->datagram->working_counter != 1) {
365  fsm->state = ec_fsm_soe_error;
366  EC_SLAVE_ERR(slave, "Reception of SoE mailbox check"
367  " datagram failed: ");
370  return;
371  }
372 
373  if (!ec_slave_mbox_check(fsm->datagram)) {
374  unsigned long diff_ms =
375  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
376  1000 / HZ;
377  if (diff_ms >= EC_SOE_RESPONSE_TIMEOUT) {
378  fsm->state = ec_fsm_soe_error;
379  EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting for"
380  " read response.\n", diff_ms);
382  return;
383  }
384 
385  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
386  fsm->retries = EC_FSM_RETRIES;
387  return;
388  }
389 
390  // Fetch response
391  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
392  fsm->retries = EC_FSM_RETRIES;
394 }
395 
396 /*****************************************************************************/
397 
401  ec_fsm_soe_t *fsm,
402  ec_datagram_t *datagram
403  )
404 {
405  ec_slave_t *slave = fsm->slave;
406  ec_master_t *master = slave->master;
407  uint8_t *data, mbox_prot, header, opcode, incomplete, error_flag,
408  value_included;
409  size_t rec_size, data_size;
410  ec_soe_request_t *req = fsm->request;
411 
412  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
413  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
414  return;
415  }
416 
417  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
418  fsm->state = ec_fsm_soe_error;
419  EC_SLAVE_ERR(slave, "Failed to receive SoE read response datagram: ");
422  return;
423  }
424 
425  if (fsm->datagram->working_counter != 1) {
426  fsm->state = ec_fsm_soe_error;
427  EC_SLAVE_ERR(slave, "Reception of SoE read response failed: ");
430  return;
431  }
432 
433  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
434  if (IS_ERR(data)) {
435  fsm->state = ec_fsm_soe_error;
437  return;
438  }
439 
440  if (master->debug_level) {
441  EC_SLAVE_DBG(slave, 0, "SSC read response:\n");
442  ec_print_data(data, rec_size);
443  }
444 
445  if (mbox_prot != EC_MBOX_TYPE_SOE) {
446  fsm->state = ec_fsm_soe_error;
447  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
448  mbox_prot);
450  return;
451  }
452 
453  if (rec_size < EC_SOE_SIZE) {
454  fsm->state = ec_fsm_soe_error;
455  EC_SLAVE_ERR(slave, "Received currupted SoE read response"
456  " (%zu bytes)!\n", rec_size);
457  ec_print_data(data, rec_size);
459  return;
460  }
461 
462  header = EC_READ_U8(data);
463  opcode = header & 0x7;
464  incomplete = (header >> 3) & 1;
465  error_flag = (header >> 4) & 1;
466 
467  if (opcode != OPCODE_READ_RESPONSE) {
468  EC_SLAVE_ERR(slave, "Received no read response (opcode %x).\n",
469  opcode);
470  ec_print_data(data, rec_size);
472  fsm->state = ec_fsm_soe_error;
473  return;
474  }
475 
476  if (error_flag) {
477  req->error_code = EC_READ_U16(data + rec_size - 2);
478  EC_SLAVE_ERR(slave, "Received error response:\n");
479  ec_print_soe_error(slave, req->error_code);
481  fsm->state = ec_fsm_soe_error;
482  return;
483  } else {
484  req->error_code = 0x0000;
485  }
486 
487  value_included = (EC_READ_U8(data + 1) >> 6) & 1;
488  if (!value_included) {
489  EC_SLAVE_ERR(slave, "No value included!\n");
491  fsm->state = ec_fsm_soe_error;
492  return;
493  }
494 
495  data_size = rec_size - EC_SOE_SIZE;
497  data + EC_SOE_SIZE, data_size)) {
498  fsm->state = ec_fsm_soe_error;
500  return;
501  }
502 
503  if (incomplete) {
504  EC_SLAVE_DBG(slave, 1, "SoE data incomplete. Waiting for fragment"
505  " at offset %zu.\n", req->data_size);
506  fsm->jiffies_start = fsm->datagram->jiffies_sent;
507  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
508  fsm->retries = EC_FSM_RETRIES;
510  } else {
511  if (master->debug_level) {
512  EC_SLAVE_DBG(slave, 0, "IDN data:\n");
513  ec_print_data(req->data, req->data_size);
514  }
515 
516  fsm->state = ec_fsm_soe_end; // success
517  }
518 }
519 
520 /******************************************************************************
521  * SoE write state machine
522  *****************************************************************************/
523 
527  ec_fsm_soe_t *fsm,
528  ec_datagram_t *datagram
529  )
530 {
531  ec_slave_t *slave = fsm->slave;
532  ec_master_t *master = slave->master;
533  ec_soe_request_t *req = fsm->request;
534  uint8_t incomplete, *data;
535  size_t max_fragment_size, remaining_size;
536  uint16_t fragments_left;
537 
538  remaining_size = req->data_size - fsm->offset;
539  max_fragment_size = slave->configured_rx_mailbox_size - EC_SOE_HEADER_SIZE;
540  incomplete = remaining_size > max_fragment_size;
541  fsm->fragment_size = incomplete ? max_fragment_size : remaining_size;
542  fragments_left = remaining_size / fsm->fragment_size - 1;
543  if (remaining_size % fsm->fragment_size) {
544  fragments_left++;
545  }
546 
547  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
548  EC_SOE_SIZE + fsm->fragment_size);
549  if (IS_ERR(data)) {
550  fsm->state = ec_fsm_soe_error;
552  return;
553  }
554 
555  EC_WRITE_U8(data, OPCODE_WRITE_REQUEST | incomplete << 3 |
556  (req->drive_no & 0x07) << 5);
557  EC_WRITE_U8(data + 1, 1 << 6); // only value included
558  EC_WRITE_U16(data + 2, incomplete ? fragments_left : req->idn);
559  memcpy(data + EC_SOE_SIZE, req->data + fsm->offset, fsm->fragment_size);
560 
561  if (master->debug_level) {
562  EC_SLAVE_DBG(slave, 0, "SSC write request:\n");
564  }
565 
566  req->jiffies_sent = jiffies;
568 }
569 
570 /*****************************************************************************/
571 
575  ec_fsm_soe_t *fsm,
576  ec_datagram_t *datagram
577  )
578 {
579  ec_slave_t *slave = fsm->slave;
580  ec_soe_request_t *req = fsm->request;
581 
582  EC_SLAVE_DBG(slave, 1, "Writing IDN 0x%04X of drive %u (%zu byte).\n",
583  req->idn, req->drive_no, req->data_size);
584 
585  if (!(slave->sii.mailbox_protocols & EC_MBOX_SOE)) {
586  EC_SLAVE_ERR(slave, "Slave does not support SoE!\n");
587  fsm->state = ec_fsm_soe_error;
589  return;
590  }
591 
593  EC_SLAVE_ERR(slave, "Mailbox size (%u) too small for SoE write.\n",
595  fsm->state = ec_fsm_soe_error;
597  return;
598  }
599 
600  fsm->offset = 0;
601  fsm->retries = EC_FSM_RETRIES;
602  ec_fsm_soe_write_next_fragment(fsm, datagram);
603 }
604 
605 /*****************************************************************************/
606 
610  ec_fsm_soe_t *fsm,
611  ec_datagram_t *datagram
612  )
613 {
614  ec_slave_t *slave = fsm->slave;
615  unsigned long diff_ms;
616 
617  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
618  ec_fsm_soe_write_next_fragment(fsm, datagram);
619  return;
620  }
621 
622  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
623  fsm->state = ec_fsm_soe_error;
624  EC_SLAVE_ERR(slave, "Failed to receive SoE write request: ");
627  return;
628  }
629 
630  diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
631 
632  if (fsm->datagram->working_counter != 1) {
633  if (!fsm->datagram->working_counter) {
634  if (diff_ms < EC_SOE_RESPONSE_TIMEOUT) {
635  // no response; send request datagram again
636  ec_fsm_soe_write_next_fragment(fsm, datagram);
637  return;
638  }
639  }
640  fsm->state = ec_fsm_soe_error;
641  EC_SLAVE_ERR(slave, "Reception of SoE write request"
642  " failed after %lu ms: ", diff_ms);
645  return;
646  }
647 
648  // fragment successfully sent
649  fsm->offset += fsm->fragment_size;
650 
651  if (fsm->offset < fsm->request->data_size) {
652  // next fragment
653  fsm->retries = EC_FSM_RETRIES;
654  ec_fsm_soe_write_next_fragment(fsm, datagram);
655  } else {
656  // all fragments sent; query response
657  fsm->jiffies_start = fsm->datagram->jiffies_sent;
658  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
659  fsm->retries = EC_FSM_RETRIES;
661  }
662 }
663 
664 /*****************************************************************************/
665 
669  ec_fsm_soe_t *fsm,
670  ec_datagram_t *datagram
671  )
672 {
673  ec_slave_t *slave = fsm->slave;
674 
675  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
676  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
677  return;
678  }
679 
680  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
681  fsm->state = ec_fsm_soe_error;
682  EC_SLAVE_ERR(slave, "Failed to receive SoE write request datagram: ");
685  return;
686  }
687 
688  if (fsm->datagram->working_counter != 1) {
689  fsm->state = ec_fsm_soe_error;
690  EC_SLAVE_ERR(slave, "Reception of SoE write request datagram: ");
693  return;
694  }
695 
696  if (!ec_slave_mbox_check(fsm->datagram)) {
697  unsigned long diff_ms =
698  (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
699  if (diff_ms >= EC_SOE_RESPONSE_TIMEOUT) {
700  fsm->state = ec_fsm_soe_error;
701  EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting"
702  " for write response.\n", diff_ms);
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  fsm->retries = EC_FSM_RETRIES;
716 }
717 
718 /*****************************************************************************/
719 
723  ec_fsm_soe_t *fsm,
724  ec_datagram_t *datagram
725  )
726 {
727  ec_slave_t *slave = fsm->slave;
728  ec_master_t *master = slave->master;
729  ec_soe_request_t *req = fsm->request;
730  uint8_t *data, mbox_prot, opcode, error_flag;
731  uint16_t idn;
732  size_t rec_size;
733 
734  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
735  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
736  return; // FIXME: request again?
737  }
738 
739  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
740  fsm->state = ec_fsm_soe_error;
741  EC_SLAVE_ERR(slave, "Failed to receive SoE write"
742  " response datagram: ");
745  return;
746  }
747 
748  if (fsm->datagram->working_counter != 1) {
749  fsm->state = ec_fsm_soe_error;
750  EC_SLAVE_ERR(slave, "Reception of SoE write response failed: ");
753  return;
754  }
755 
756  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
757  if (IS_ERR(data)) {
758  fsm->state = ec_fsm_soe_error;
760  return;
761  }
762 
763  if (master->debug_level) {
764  EC_SLAVE_DBG(slave, 0, "SSC write response:\n");
765  ec_print_data(data, rec_size);
766  }
767 
768  if (mbox_prot != EC_MBOX_TYPE_SOE) {
769  fsm->state = ec_fsm_soe_error;
770  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
771  mbox_prot);
773  return;
774  }
775 
776  if (rec_size < EC_SOE_SIZE) {
777  fsm->state = ec_fsm_soe_error;
778  EC_SLAVE_ERR(slave, "Received corrupted SoE write response"
779  " (%zu bytes)!\n", rec_size);
780  ec_print_data(data, rec_size);
782  return;
783  }
784 
785  opcode = EC_READ_U8(data) & 0x7;
786  if (opcode != OPCODE_WRITE_RESPONSE) {
787  EC_SLAVE_ERR(slave, "Received no write response"
788  " (opcode %x).\n", opcode);
789  ec_print_data(data, rec_size);
791  fsm->state = ec_fsm_soe_error;
792  return;
793  }
794 
795  idn = EC_READ_U16(data + 2);
796  if (idn != req->idn) {
797  EC_SLAVE_ERR(slave, "Received response for"
798  " wrong IDN 0x%04x.\n", idn);
799  ec_print_data(data, rec_size);
801  fsm->state = ec_fsm_soe_error;
802  return;
803  }
804 
805  error_flag = (EC_READ_U8(data) >> 4) & 1;
806  if (error_flag) {
807  if (rec_size < EC_SOE_SIZE + 2) {
808  EC_SLAVE_ERR(slave, "Received corrupted error response"
809  " - error flag set, but received size is %zu.\n",
810  rec_size);
811  } else {
812  req->error_code = EC_READ_U16(data + EC_SOE_SIZE);
813  EC_SLAVE_ERR(slave, "Received error response:\n");
814  ec_print_soe_error(slave, req->error_code);
815  }
816  ec_print_data(data, rec_size);
818  fsm->state = ec_fsm_soe_error;
819  } else {
820  req->error_code = 0x0000;
821  fsm->state = ec_fsm_soe_end; // success
822  }
823 }
824 
825 /*****************************************************************************/
826 
830  ec_fsm_soe_t *fsm,
831  ec_datagram_t *datagram
832  )
833 {
834 }
835 
836 /*****************************************************************************/
837 
841  ec_fsm_soe_t *fsm,
842  ec_datagram_t *datagram
843  )
844 {
845 }
846 
847 /*****************************************************************************/
void ec_fsm_soe_read_start(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ START.
Definition: fsm_soe.c:258
void ec_fsm_soe_end(ec_fsm_soe_t *, ec_datagram_t *)
State: END.
Definition: fsm_soe.c:840
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:574
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:223
void ec_fsm_soe_read_request(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ REQUEST.
Definition: fsm_soe.c:289
EtherCAT datagram.
Definition: datagram.h:87
#define EC_SOE_HEADER_SIZE
SoE header size.
Definition: fsm_soe.c:63
#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:92
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:722
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:134
int ec_fsm_soe_success(const ec_fsm_soe_t *fsm)
Returns, if the state machine terminated with success.
Definition: fsm_soe.c:191
ec_datagram_state_t state
State.
Definition: datagram.h:100
#define EC_SOE_RESPONSE_TIMEOUT
SoE response timeout [ms].
Definition: fsm_soe.c:67
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:609
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: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:344
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:111
void ec_fsm_soe_clear(ec_fsm_soe_t *fsm)
Destructor.
Definition: fsm_soe.c:124
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:526
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:156
void ec_fsm_soe_print_error(ec_fsm_soe_t *fsm)
Output information about a failed SoE transfer.
Definition: fsm_soe.c:200
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:400
void ec_fsm_soe_error(ec_fsm_soe_t *, ec_datagram_t *)
State: ERROR.
Definition: fsm_soe.c:829
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:668