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