IgH EtherCAT Master  1.5.2
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 
44 #define EC_MBOX_TYPE_SOE 0x05
45 
53 };
54 
57 #define EC_SOE_SIZE 0x04
58 
61 #define EC_SOE_HEADER_SIZE (EC_MBOX_HEADER_SIZE + EC_SOE_SIZE)
62 
65 #define EC_SOE_RESPONSE_TIMEOUT 1000
66 
67 /*****************************************************************************/
68 
73 
78 
81 
82 /*****************************************************************************/
83 
84 extern const ec_code_msg_t soe_error_codes[];
85 
86 /*****************************************************************************/
87 
90 void ec_print_soe_error(const ec_slave_t *slave, uint16_t error_code)
91 {
92  const ec_code_msg_t *error_msg;
93 
94  for (error_msg = soe_error_codes; error_msg->code; error_msg++) {
95  if (error_msg->code == error_code) {
96  EC_SLAVE_ERR(slave, "SoE error 0x%04X: \"%s\".\n",
97  error_msg->code, error_msg->message);
98  return;
99  }
100  }
101 
102  EC_SLAVE_ERR(slave, "Unknown SoE error 0x%04X.\n", error_code);
103 }
104 
105 /*****************************************************************************/
106 
110  ec_fsm_soe_t *fsm
111  )
112 {
113  fsm->state = NULL;
114  fsm->datagram = NULL;
115  fsm->fragment_size = 0;
116 }
117 
118 /*****************************************************************************/
119 
123  ec_fsm_soe_t *fsm
124  )
125 {
126 }
127 
128 /*****************************************************************************/
129 
133  ec_fsm_soe_t *fsm,
134  ec_slave_t *slave,
135  ec_soe_request_t *request
136  )
137 {
138  fsm->slave = slave;
139  fsm->request = request;
140 
141  if (request->dir == EC_DIR_OUTPUT) {
143  } else {
145  }
146 }
147 
148 /*****************************************************************************/
149 
155  ec_fsm_soe_t *fsm,
156  ec_datagram_t *datagram
157  )
158 {
159  int datagram_used = 0;
160 
161  if (fsm->datagram &&
162  (fsm->datagram->state == EC_DATAGRAM_INIT ||
163  fsm->datagram->state == EC_DATAGRAM_QUEUED ||
164  fsm->datagram->state == EC_DATAGRAM_SENT)) {
165  // datagram not received yet
166  return datagram_used;
167  }
168 
169  fsm->state(fsm, datagram);
170 
171  datagram_used =
172  fsm->state != ec_fsm_soe_end && fsm->state != ec_fsm_soe_error;
173 
174  if (datagram_used) {
175  fsm->datagram = datagram;
176  } else {
177  fsm->datagram = NULL;
178  }
179 
180  return datagram_used;
181 }
182 
183 /*****************************************************************************/
184 
190 {
191  return fsm->state == ec_fsm_soe_end;
192 }
193 
194 /*****************************************************************************/
195 
199 {
200  ec_soe_request_t *request = fsm->request;
201 
202  EC_SLAVE_ERR(fsm->slave, "");
203 
204  if (request->dir == EC_DIR_OUTPUT) {
205  printk("Writing");
206  } else {
207  printk("Reading");
208  }
209 
210  printk(" IDN 0x%04X failed.\n", request->idn);
211 }
212 
213 /******************************************************************************
214  * SoE read state machine
215  *****************************************************************************/
216 
222  ec_fsm_soe_t *fsm,
223  ec_datagram_t *datagram
224  )
225 {
226  uint8_t *data;
227  ec_slave_t *slave = fsm->slave;
228  ec_master_t *master = slave->master;
229  ec_soe_request_t *request = fsm->request;
230 
231  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
232  EC_SOE_SIZE);
233  if (IS_ERR(data)) {
234  return PTR_ERR(data);
235  }
236 
237  EC_WRITE_U8(data, OPCODE_READ_REQUEST | (request->drive_no & 0x07) << 5);
238  EC_WRITE_U8(data + 1, 1 << 6); // request value
239  EC_WRITE_U16(data + 2, request->idn);
240 
241  if (master->debug_level) {
242  EC_SLAVE_DBG(slave, 0, "SSC read request:\n");
243  ec_print_data(data, EC_SOE_SIZE);
244  }
245 
246  fsm->request->jiffies_sent = jiffies;
248 
249  return 0;
250 }
251 
252 /*****************************************************************************/
253 
257  ec_fsm_soe_t *fsm,
258  ec_datagram_t *datagram
259  )
260 {
261  ec_slave_t *slave = fsm->slave;
262  ec_soe_request_t *request = fsm->request;
263 
264  EC_SLAVE_DBG(slave, 1, "Reading IDN 0x%04X of drive %u.\n", request->idn,
265  request->drive_no);
266 
267  if (!(slave->sii.mailbox_protocols & EC_MBOX_SOE)) {
268  EC_SLAVE_ERR(slave, "Slave does not support SoE!\n");
269  fsm->state = ec_fsm_soe_error;
271  return;
272  }
273 
274  request->data_size = 0;
275  fsm->retries = EC_FSM_RETRIES;
276 
277  if (ec_fsm_soe_prepare_read(fsm, datagram)) {
278  fsm->state = ec_fsm_soe_error;
280  }
281 }
282 
283 /*****************************************************************************/
284 
288  ec_fsm_soe_t *fsm,
289  ec_datagram_t *datagram
290  )
291 {
292  ec_slave_t *slave = fsm->slave;
293  unsigned long diff_ms;
294 
295  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
296  if (ec_fsm_soe_prepare_read(fsm, datagram)) {
297  fsm->state = ec_fsm_soe_error;
299  }
300  return;
301  }
302 
303  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
304  fsm->state = ec_fsm_soe_error;
305  EC_SLAVE_ERR(slave, "Failed to receive SoE read request: ");
308  return;
309  }
310 
311  diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
312 
313  if (fsm->datagram->working_counter != 1) {
314  if (!fsm->datagram->working_counter) {
315  if (diff_ms < EC_SOE_RESPONSE_TIMEOUT) {
316  // no response; send request datagram again
317  if (ec_fsm_soe_prepare_read(fsm, datagram)) {
318  fsm->state = ec_fsm_soe_error;
320  }
321  return;
322  }
323  }
324  fsm->state = ec_fsm_soe_error;
325  EC_SLAVE_ERR(slave, "Reception of SoE read request"
326  " failed after %lu ms: ", diff_ms);
329  return;
330  }
331 
332  fsm->jiffies_start = fsm->datagram->jiffies_sent;
333  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
334  fsm->retries = EC_FSM_RETRIES;
336 }
337 
338 /*****************************************************************************/
339 
343  ec_fsm_soe_t *fsm,
344  ec_datagram_t *datagram
345  )
346 {
347  ec_slave_t *slave = fsm->slave;
348 
349  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
350  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
351  return;
352  }
353 
354  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
355  fsm->state = ec_fsm_soe_error;
356  EC_SLAVE_ERR(slave, "Failed to receive SoE mailbox check datagram: ");
359  return;
360  }
361 
362  if (fsm->datagram->working_counter != 1) {
363  fsm->state = ec_fsm_soe_error;
364  EC_SLAVE_ERR(slave, "Reception of SoE mailbox check"
365  " datagram failed: ");
368  return;
369  }
370 
371  if (!ec_slave_mbox_check(fsm->datagram)) {
372  unsigned long diff_ms =
373  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
374  1000 / HZ;
375  if (diff_ms >= EC_SOE_RESPONSE_TIMEOUT) {
376  fsm->state = ec_fsm_soe_error;
377  EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting for"
378  " read response.\n", diff_ms);
380  return;
381  }
382 
383  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
384  fsm->retries = EC_FSM_RETRIES;
385  return;
386  }
387 
388  // Fetch response
389  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
390  fsm->retries = EC_FSM_RETRIES;
392 }
393 
394 /*****************************************************************************/
395 
399  ec_fsm_soe_t *fsm,
400  ec_datagram_t *datagram
401  )
402 {
403  ec_slave_t *slave = fsm->slave;
404  ec_master_t *master = slave->master;
405  uint8_t *data, mbox_prot, header, opcode, incomplete, error_flag,
406  value_included;
407  size_t rec_size, data_size;
408  ec_soe_request_t *req = fsm->request;
409 
410  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
411  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
412  return;
413  }
414 
415  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
416  fsm->state = ec_fsm_soe_error;
417  EC_SLAVE_ERR(slave, "Failed to receive SoE read response datagram: ");
420  return;
421  }
422 
423  if (fsm->datagram->working_counter != 1) {
424  fsm->state = ec_fsm_soe_error;
425  EC_SLAVE_ERR(slave, "Reception of SoE read response failed: ");
428  return;
429  }
430 
431  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
432  if (IS_ERR(data)) {
433  fsm->state = ec_fsm_soe_error;
435  return;
436  }
437 
438  if (master->debug_level) {
439  EC_SLAVE_DBG(slave, 0, "SSC read response:\n");
440  ec_print_data(data, rec_size);
441  }
442 
443  if (mbox_prot != EC_MBOX_TYPE_SOE) {
444  fsm->state = ec_fsm_soe_error;
445  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
446  mbox_prot);
448  return;
449  }
450 
451  if (rec_size < EC_SOE_SIZE) {
452  fsm->state = ec_fsm_soe_error;
453  EC_SLAVE_ERR(slave, "Received currupted SoE read response"
454  " (%zu bytes)!\n", rec_size);
455  ec_print_data(data, rec_size);
457  return;
458  }
459 
460  header = EC_READ_U8(data);
461  opcode = header & 0x7;
462  incomplete = (header >> 3) & 1;
463  error_flag = (header >> 4) & 1;
464 
465  if (opcode != OPCODE_READ_RESPONSE) {
466  EC_SLAVE_ERR(slave, "Received no read response (opcode %x).\n",
467  opcode);
468  ec_print_data(data, rec_size);
470  fsm->state = ec_fsm_soe_error;
471  return;
472  }
473 
474  if (error_flag) {
475  req->error_code = EC_READ_U16(data + rec_size - 2);
476  EC_SLAVE_ERR(slave, "Received error response:\n");
477  ec_print_soe_error(slave, req->error_code);
479  fsm->state = ec_fsm_soe_error;
480  return;
481  } else {
482  req->error_code = 0x0000;
483  }
484 
485  value_included = (EC_READ_U8(data + 1) >> 6) & 1;
486  if (!value_included) {
487  EC_SLAVE_ERR(slave, "No value included!\n");
489  fsm->state = ec_fsm_soe_error;
490  return;
491  }
492 
493  data_size = rec_size - EC_SOE_SIZE;
495  data + EC_SOE_SIZE, data_size)) {
496  fsm->state = ec_fsm_soe_error;
498  return;
499  }
500 
501  if (incomplete) {
502  EC_SLAVE_DBG(slave, 1, "SoE data incomplete. Waiting for fragment"
503  " at offset %zu.\n", req->data_size);
504  fsm->jiffies_start = fsm->datagram->jiffies_sent;
505  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
506  fsm->retries = EC_FSM_RETRIES;
508  } else {
509  if (master->debug_level) {
510  EC_SLAVE_DBG(slave, 0, "IDN data:\n");
511  ec_print_data(req->data, req->data_size);
512  }
513 
514  fsm->state = ec_fsm_soe_end; // success
515  }
516 }
517 
518 /******************************************************************************
519  * SoE write state machine
520  *****************************************************************************/
521 
525  ec_fsm_soe_t *fsm,
526  ec_datagram_t *datagram
527  )
528 {
529  ec_slave_t *slave = fsm->slave;
530  ec_master_t *master = slave->master;
531  ec_soe_request_t *req = fsm->request;
532  uint8_t incomplete, *data;
533  size_t max_fragment_size, remaining_size;
534  uint16_t fragments_left;
535 
536  remaining_size = req->data_size - fsm->offset;
537  max_fragment_size = slave->configured_rx_mailbox_size - EC_SOE_HEADER_SIZE;
538  incomplete = remaining_size > max_fragment_size;
539  fsm->fragment_size = incomplete ? max_fragment_size : remaining_size;
540  fragments_left = remaining_size / fsm->fragment_size - 1;
541  if (remaining_size % fsm->fragment_size) {
542  fragments_left++;
543  }
544 
545  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
546  EC_SOE_SIZE + fsm->fragment_size);
547  if (IS_ERR(data)) {
548  fsm->state = ec_fsm_soe_error;
550  return;
551  }
552 
553  EC_WRITE_U8(data, OPCODE_WRITE_REQUEST | incomplete << 3 |
554  (req->drive_no & 0x07) << 5);
555  EC_WRITE_U8(data + 1, 1 << 6); // only value included
556  EC_WRITE_U16(data + 2, incomplete ? fragments_left : req->idn);
557  memcpy(data + EC_SOE_SIZE, req->data + fsm->offset, fsm->fragment_size);
558 
559  if (master->debug_level) {
560  EC_SLAVE_DBG(slave, 0, "SSC write request:\n");
562  }
563 
565 }
566 
567 /*****************************************************************************/
568 
572  ec_fsm_soe_t *fsm,
573  ec_datagram_t *datagram
574  )
575 {
576  ec_slave_t *slave = fsm->slave;
577  ec_soe_request_t *req = fsm->request;
578 
579  EC_SLAVE_DBG(slave, 1, "Writing IDN 0x%04X of drive %u (%zu byte).\n",
580  req->idn, req->drive_no, req->data_size);
581 
582  if (!(slave->sii.mailbox_protocols & EC_MBOX_SOE)) {
583  EC_SLAVE_ERR(slave, "Slave does not support SoE!\n");
584  fsm->state = ec_fsm_soe_error;
586  return;
587  }
588 
590  EC_SLAVE_ERR(slave, "Mailbox size (%u) too small for SoE write.\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  req->jiffies_sent = jiffies;
601 }
602 
603 /*****************************************************************************/
604 
608  ec_fsm_soe_t *fsm,
609  ec_datagram_t *datagram
610  )
611 {
612  ec_slave_t *slave = fsm->slave;
613  unsigned long diff_ms;
614 
615  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
616  ec_fsm_soe_write_next_fragment(fsm, datagram);
617  return;
618  }
619 
620  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
621  fsm->state = ec_fsm_soe_error;
622  EC_SLAVE_ERR(slave, "Failed to receive SoE write request: ");
625  return;
626  }
627 
628  diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
629 
630  if (fsm->datagram->working_counter != 1) {
631  if (!fsm->datagram->working_counter) {
632  if (diff_ms < EC_SOE_RESPONSE_TIMEOUT) {
633  // no response; send request datagram again
634  ec_fsm_soe_write_next_fragment(fsm, datagram);
635  return;
636  }
637  }
638  fsm->state = ec_fsm_soe_error;
639  EC_SLAVE_ERR(slave, "Reception of SoE write request"
640  " failed after %lu ms: ", diff_ms);
643  return;
644  }
645 
646  // fragment successfully sent
647  fsm->offset += fsm->fragment_size;
648 
649  if (fsm->offset < fsm->request->data_size) {
650  // next fragment
651  fsm->retries = EC_FSM_RETRIES;
652  ec_fsm_soe_write_next_fragment(fsm, datagram);
653  fsm->request->jiffies_sent = jiffies;
654  } else {
655  // all fragments sent; query response
656  fsm->jiffies_start = fsm->datagram->jiffies_sent;
657  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
658  fsm->retries = EC_FSM_RETRIES;
660  }
661 }
662 
663 /*****************************************************************************/
664 
668  ec_fsm_soe_t *fsm,
669  ec_datagram_t *datagram
670  )
671 {
672  ec_slave_t *slave = fsm->slave;
673 
674  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
675  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
676  return;
677  }
678 
679  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
680  fsm->state = ec_fsm_soe_error;
681  EC_SLAVE_ERR(slave, "Failed to receive SoE write request datagram: ");
684  return;
685  }
686 
687  if (fsm->datagram->working_counter != 1) {
688  fsm->state = ec_fsm_soe_error;
689  EC_SLAVE_ERR(slave, "Reception of SoE write request datagram: ");
692  return;
693  }
694 
695  if (!ec_slave_mbox_check(fsm->datagram)) {
696  unsigned long diff_ms =
697  (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
698  if (diff_ms >= EC_SOE_RESPONSE_TIMEOUT) {
699  fsm->state = ec_fsm_soe_error;
700  EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting"
701  " for write response.\n", diff_ms);
703  return;
704  }
705 
706  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
707  fsm->retries = EC_FSM_RETRIES;
708  return;
709  }
710 
711  // Fetch response
712  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
713  fsm->retries = EC_FSM_RETRIES;
715 }
716 
717 /*****************************************************************************/
718 
722  ec_fsm_soe_t *fsm,
723  ec_datagram_t *datagram
724  )
725 {
726  ec_slave_t *slave = fsm->slave;
727  ec_master_t *master = slave->master;
728  ec_soe_request_t *req = fsm->request;
729  uint8_t *data, mbox_prot, opcode, error_flag;
730  uint16_t idn;
731  size_t rec_size;
732 
733  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
734  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
735  return; // FIXME: request again?
736  }
737 
738  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
739  fsm->state = ec_fsm_soe_error;
740  EC_SLAVE_ERR(slave, "Failed to receive SoE write"
741  " response datagram: ");
744  return;
745  }
746 
747  if (fsm->datagram->working_counter != 1) {
748  fsm->state = ec_fsm_soe_error;
749  EC_SLAVE_ERR(slave, "Reception of SoE write response failed: ");
752  return;
753  }
754 
755  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
756  if (IS_ERR(data)) {
757  fsm->state = ec_fsm_soe_error;
759  return;
760  }
761 
762  if (master->debug_level) {
763  EC_SLAVE_DBG(slave, 0, "SSC write response:\n");
764  ec_print_data(data, rec_size);
765  }
766 
767  if (mbox_prot != EC_MBOX_TYPE_SOE) {
768  fsm->state = ec_fsm_soe_error;
769  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
770  mbox_prot);
772  return;
773  }
774 
775  if (rec_size < EC_SOE_SIZE) {
776  fsm->state = ec_fsm_soe_error;
777  EC_SLAVE_ERR(slave, "Received corrupted SoE write response"
778  " (%zu bytes)!\n", rec_size);
779  ec_print_data(data, rec_size);
781  return;
782  }
783 
784  opcode = EC_READ_U8(data) & 0x7;
785  if (opcode != OPCODE_WRITE_RESPONSE) {
786  EC_SLAVE_ERR(slave, "Received no write response"
787  " (opcode %x).\n", opcode);
788  ec_print_data(data, rec_size);
790  fsm->state = ec_fsm_soe_error;
791  return;
792  }
793 
794  idn = EC_READ_U16(data + 2);
795  if (idn != req->idn) {
796  EC_SLAVE_ERR(slave, "Received response for"
797  " wrong IDN 0x%04x.\n", idn);
798  ec_print_data(data, rec_size);
800  fsm->state = ec_fsm_soe_error;
801  return;
802  }
803 
804  error_flag = (EC_READ_U8(data) >> 4) & 1;
805  if (error_flag) {
806  if (rec_size < EC_SOE_SIZE + 2) {
807  EC_SLAVE_ERR(slave, "Received corrupted error response"
808  " - error flag set, but received size is %zu.\n",
809  rec_size);
810  } else {
811  req->error_code = EC_READ_U16(data + EC_SOE_SIZE);
812  EC_SLAVE_ERR(slave, "Received error response:\n");
813  ec_print_soe_error(slave, req->error_code);
814  }
815  ec_print_data(data, rec_size);
817  fsm->state = ec_fsm_soe_error;
818  } else {
819  req->error_code = 0x0000;
820  fsm->state = ec_fsm_soe_end; // success
821  }
822 }
823 
824 /*****************************************************************************/
825 
829  ec_fsm_soe_t *fsm,
830  ec_datagram_t *datagram
831  )
832 {
833 }
834 
835 /*****************************************************************************/
836 
840  ec_fsm_soe_t *fsm,
841  ec_datagram_t *datagram
842  )
843 {
844 }
845 
846 /*****************************************************************************/
ec_soe_opcodes
SoE operations.
Definition: fsm_soe.c:48
#define EC_FSM_RETRIES
Number of state machine retries on datagram timeout.
Definition: globals.h:59
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
void ec_fsm_soe_end(ec_fsm_soe_t *, ec_datagram_t *)
State: END.
Definition: fsm_soe.c:839
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:828
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:221
EtherCAT datagram.
Definition: datagram.h:87
#define EC_SOE_HEADER_SIZE
SoE header size.
Definition: fsm_soe.c:61
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2231
uint16_t error_code
SoE error code.
Definition: soe_request.h:61
void ec_fsm_soe_read_response(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ RESPONSE.
Definition: fsm_soe.c:398
uint16_t working_counter
Working counter.
Definition: datagram.h:99
#define EC_MBOX_TYPE_SOE
Mailbox type for SoE.
Definition: fsm_soe.c:44
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:90
void ec_fsm_soe_write_check(ec_fsm_soe_t *, ec_datagram_t *)
CoE state: WRITE CHECK.
Definition: fsm_soe.c:667
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:342
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: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:132
int ec_fsm_soe_success(const ec_fsm_soe_t *fsm)
Returns, if the state machine terminated with success.
Definition: fsm_soe.c:189
ec_datagram_state_t state
State.
Definition: datagram.h:100
#define EC_SOE_RESPONSE_TIMEOUT
SoE response timeout [ms].
Definition: fsm_soe.c:65
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: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:2248
void ec_fsm_soe_write_response(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE RESPONSE.
Definition: fsm_soe.c:721
Read response.
Definition: fsm_soe.c:50
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.
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
void ec_fsm_soe_read_start(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ START.
Definition: fsm_soe.c:256
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:2143
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:287
void ec_datagram_print_state(const ec_datagram_t *datagram)
Prints the state of a datagram.
Definition: datagram.c:565
Mailbox functionality.
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:49
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:109
void ec_fsm_soe_clear(ec_fsm_soe_t *fsm)
Destructor.
Definition: fsm_soe.c:122
Write request.
Definition: fsm_soe.c:51
#define EC_READ_U8(DATA)
Read an 8-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2127
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:524
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:154
void ec_fsm_soe_print_error(ec_fsm_soe_t *fsm)
Output information about a failed SoE transfer.
Definition: fsm_soe.c:198
Values written by the master.
Definition: ecrt.h:423
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:57
Write response.
Definition: fsm_soe.c:52
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_write_start(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE START.
Definition: fsm_soe.c:571
Sercos-over-EtherCAT request.
Definition: soe_request.h:48
void ec_fsm_soe_write_request(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE REQUEST.
Definition: fsm_soe.c:607