IgH EtherCAT Master  1.6.0-rc1
fsm_slave_scan.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 "slave_config.h"
41 
42 #include "fsm_slave_scan.h"
43 
44 /*****************************************************************************/
45 
53 #ifdef EC_SII_ASSIGN
55 #endif
59 #ifdef EC_REGALIAS
60 void ec_fsm_slave_scan_state_regalias(ec_fsm_slave_scan_t *);
61 #endif
65 
68 
70 #ifdef EC_REGALIAS
71 void ec_fsm_slave_scan_enter_regalias(ec_fsm_slave_scan_t *);
72 #endif
76 
77 /*****************************************************************************/
78 
82  ec_fsm_slave_scan_t *fsm,
83  ec_datagram_t *datagram,
84  ec_fsm_slave_config_t *fsm_slave_config,
86  ec_fsm_pdo_t *fsm_pdo
87  )
88 {
89  fsm->datagram = datagram;
90  fsm->fsm_slave_config = fsm_slave_config;
91  fsm->fsm_pdo = fsm_pdo;
92 
93  // init sub state machines
94  ec_fsm_sii_init(&fsm->fsm_sii, fsm->datagram);
95 }
96 
97 /*****************************************************************************/
98 
102 {
103  // clear sub state machines
104  ec_fsm_sii_clear(&fsm->fsm_sii);
105 }
106 
107 /*****************************************************************************/
108 
114  ec_fsm_slave_scan_t *fsm,
115  ec_slave_t *slave
116  )
117 {
118  fsm->slave = slave;
120 }
121 
122 /*****************************************************************************/
123 
129 {
130  return fsm->state != ec_fsm_slave_scan_state_end
132 }
133 
134 /*****************************************************************************/
135 
144 {
145  if (fsm->datagram->state == EC_DATAGRAM_SENT
146  || fsm->datagram->state == EC_DATAGRAM_QUEUED) {
147  // datagram was not sent or received yet.
148  return ec_fsm_slave_scan_running(fsm);
149  }
150 
151  fsm->state(fsm);
152  return ec_fsm_slave_scan_running(fsm);
153 }
154 
155 /*****************************************************************************/
156 
162 {
163  return fsm->state == ec_fsm_slave_scan_state_end;
164 }
165 
166 /******************************************************************************
167  * slave scan state machine
168  *****************************************************************************/
169 
177 {
178  // write station address
179  ec_datagram_apwr(fsm->datagram, fsm->slave->ring_position, 0x0010, 2);
181  fsm->retries = EC_FSM_RETRIES;
183 }
184 
185 /*****************************************************************************/
186 
192  ec_fsm_slave_scan_t *fsm
193  )
194 {
195  ec_datagram_t *datagram = fsm->datagram;
196 
197  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
198  return;
199 
200  if (datagram->state != EC_DATAGRAM_RECEIVED) {
202  EC_SLAVE_ERR(fsm->slave,
203  "Failed to receive station address datagram: ");
204  ec_datagram_print_state(datagram);
205  return;
206  }
207 
208  if (datagram->working_counter != 1) {
209  fsm->slave->error_flag = 1;
211  EC_SLAVE_ERR(fsm->slave, "Failed to write station address: ");
212  ec_datagram_print_wc_error(datagram);
213  return;
214  }
215 
216  // Read AL state
217  ec_datagram_fprd(datagram, fsm->slave->station_address, 0x0130, 2);
218  ec_datagram_zero(datagram);
219  fsm->retries = EC_FSM_RETRIES;
221 }
222 
223 /*****************************************************************************/
224 
230  ec_fsm_slave_scan_t *fsm
231  )
232 {
233  ec_datagram_t *datagram = fsm->datagram;
234  ec_slave_t *slave = fsm->slave;
235 
236  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
237  return;
238 
239  if (datagram->state != EC_DATAGRAM_RECEIVED) {
241  EC_SLAVE_ERR(slave, "Failed to receive AL state datagram: ");
242  ec_datagram_print_state(datagram);
243  return;
244  }
245 
246  if (datagram->working_counter != 1) {
247  fsm->slave->error_flag = 1;
249  EC_SLAVE_ERR(slave, "Failed to read AL state: ");
250  ec_datagram_print_wc_error(datagram);
251  return;
252  }
253 
254  slave->current_state = EC_READ_U8(datagram->data);
255  if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
256  char state_str[EC_STATE_STRING_SIZE];
257  ec_state_string(slave->current_state, state_str, 0);
258  EC_SLAVE_WARN(slave, "Slave has state error bit set (%s)!\n",
259  state_str);
260  }
261 
262  // read base data
263  ec_datagram_fprd(datagram, fsm->slave->station_address, 0x0000, 12);
264  ec_datagram_zero(datagram);
265  fsm->retries = EC_FSM_RETRIES;
267 }
268 
269 /*****************************************************************************/
270 
274  ec_fsm_slave_scan_t *fsm
275  )
276 {
277  ec_datagram_t *datagram = fsm->datagram;
278  ec_slave_t *slave = fsm->slave;
279  u8 octet;
280  int i;
281 
282  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
283  return;
284 
285  if (datagram->state != EC_DATAGRAM_RECEIVED) {
287  EC_SLAVE_ERR(slave, "Failed to receive base data datagram: ");
288  ec_datagram_print_state(datagram);
289  return;
290  }
291 
292  if (datagram->working_counter != 1) {
293  fsm->slave->error_flag = 1;
295  EC_SLAVE_ERR(slave, "Failed to read base data: ");
296  ec_datagram_print_wc_error(datagram);
297  return;
298  }
299 
300  slave->base_type = EC_READ_U8 (datagram->data);
301  slave->base_revision = EC_READ_U8 (datagram->data + 1);
302  slave->base_build = EC_READ_U16(datagram->data + 2);
303 
304  slave->base_fmmu_count = EC_READ_U8 (datagram->data + 4);
305  if (slave->base_fmmu_count > EC_MAX_FMMUS) {
306  EC_SLAVE_WARN(slave, "Slave has more FMMUs (%u) than the master can"
307  " handle (%u).\n", slave->base_fmmu_count, EC_MAX_FMMUS);
308  slave->base_fmmu_count = EC_MAX_FMMUS;
309  }
310 
311  slave->base_sync_count = EC_READ_U8(datagram->data + 5);
312  if (slave->base_sync_count > EC_MAX_SYNC_MANAGERS) {
313  EC_SLAVE_WARN(slave, "Slave provides more sync managers (%u)"
314  " than the master can handle (%u).\n",
317  }
318 
319  octet = EC_READ_U8(datagram->data + 7);
320  for (i = 0; i < EC_MAX_PORTS; i++) {
321  slave->ports[i].desc = (octet >> (2 * i)) & 0x03;
322  }
323 
324  octet = EC_READ_U8(datagram->data + 8);
325  slave->base_fmmu_bit_operation = octet & 0x01;
326  slave->base_dc_supported = (octet >> 2) & 0x01;
327  slave->base_dc_range = ((octet >> 3) & 0x01) ? EC_DC_64 : EC_DC_32;
328 
329  if (slave->base_dc_supported) {
330  // read DC capabilities
331  ec_datagram_fprd(datagram, slave->station_address, 0x0910,
332  slave->base_dc_range == EC_DC_64 ? 8 : 4);
333  ec_datagram_zero(datagram);
334  fsm->retries = EC_FSM_RETRIES;
336  } else {
338  }
339 }
340 
341 /*****************************************************************************/
342 
348  ec_fsm_slave_scan_t *fsm
349  )
350 {
351  ec_datagram_t *datagram = fsm->datagram;
352  ec_slave_t *slave = fsm->slave;
353 
354  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
355  return;
356 
357  if (datagram->state != EC_DATAGRAM_RECEIVED) {
359  EC_SLAVE_ERR(slave, "Failed to receive system time datagram: ");
360  ec_datagram_print_state(datagram);
361  return;
362  }
363 
364  if (datagram->working_counter == 1) {
365  slave->has_dc_system_time = 1;
366  EC_SLAVE_DBG(slave, 1, "Slave has the System Time register.\n");
367  } else if (datagram->working_counter == 0) {
368  EC_SLAVE_DBG(slave, 1, "Slave has no System Time register; delay "
369  "measurement only.\n");
370  } else {
371  fsm->slave->error_flag = 1;
373  EC_SLAVE_ERR(slave, "Failed to determine, if system time register is "
374  "supported: ");
375  ec_datagram_print_wc_error(datagram);
376  return;
377  }
378 
379  // read DC port receive times
380  ec_datagram_fprd(datagram, slave->station_address, 0x0900, 16);
381  ec_datagram_zero(datagram);
382  fsm->retries = EC_FSM_RETRIES;
384 }
385 
386 /*****************************************************************************/
387 
393  ec_fsm_slave_scan_t *fsm
394  )
395 {
396  ec_datagram_t *datagram = fsm->datagram;
397  ec_slave_t *slave = fsm->slave;
398  int i;
399 
400  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
401  return;
402 
403  if (datagram->state != EC_DATAGRAM_RECEIVED) {
405  EC_SLAVE_ERR(slave, "Failed to receive system time datagram: ");
406  ec_datagram_print_state(datagram);
407  return;
408  }
409 
410  if (datagram->working_counter != 1) {
411  fsm->slave->error_flag = 1;
413  EC_SLAVE_ERR(slave, "Failed to get DC receive times: ");
414  ec_datagram_print_wc_error(datagram);
415  return;
416  }
417 
418  for (i = 0; i < EC_MAX_PORTS; i++) {
419  slave->ports[i].receive_time = EC_READ_U32(datagram->data + 4 * i);
420  }
421 
423 }
424 
425 /*****************************************************************************/
426 
432  ec_fsm_slave_scan_t *fsm
433  )
434 {
435  ec_datagram_t *datagram = fsm->datagram;
436  ec_slave_t *slave = fsm->slave;
437 
438  // read data link status
439  ec_datagram_fprd(datagram, slave->station_address, 0x0110, 2);
440  ec_datagram_zero(datagram);
441  fsm->retries = EC_FSM_RETRIES;
443 }
444 
445 /*****************************************************************************/
446 
450  ec_fsm_slave_scan_t *fsm
451  )
452 {
453  // Start fetching SII size
454 
455  EC_SLAVE_DBG(fsm->slave, 1, "Determining SII size.\n");
456 
457  fsm->sii_offset = EC_FIRST_SII_CATEGORY_OFFSET; // first category header
458  ec_fsm_sii_read(&fsm->fsm_sii, fsm->slave, fsm->sii_offset,
461  fsm->state(fsm); // execute state immediately
462 }
463 
464 /*****************************************************************************/
465 
466 #ifdef EC_SII_ASSIGN
467 
471  ec_fsm_slave_scan_t *fsm
472  )
473 {
474  ec_datagram_t *datagram = fsm->datagram;
475  ec_slave_t *slave = fsm->slave;
476 
477  EC_SLAVE_DBG(slave, 1, "Assigning SII access to EtherCAT.\n");
478 
479  // assign SII to ECAT
480  ec_datagram_fpwr(datagram, slave->station_address, 0x0500, 1);
481  EC_WRITE_U8(datagram->data, 0x00); // EtherCAT
482  fsm->retries = EC_FSM_RETRIES;
484 }
485 
486 #endif
487 
488 /*****************************************************************************/
489 
495  ec_fsm_slave_scan_t *fsm
496  )
497 {
498  ec_datagram_t *datagram = fsm->datagram;
499  ec_slave_t *slave = fsm->slave;
500 
501  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
502  return;
503 
504  if (datagram->state != EC_DATAGRAM_RECEIVED) {
506  EC_SLAVE_ERR(slave, "Failed to receive DL status datagram: ");
507  ec_datagram_print_state(datagram);
508  return;
509  }
510 
511  if (datagram->working_counter != 1) {
512  fsm->slave->error_flag = 1;
514  EC_SLAVE_ERR(slave, "Failed to read DL status: ");
515  ec_datagram_print_wc_error(datagram);
516  return;
517  }
518 
519  ec_slave_set_dl_status(slave, EC_READ_U16(datagram->data));
520 
521 #ifdef EC_SII_ASSIGN
523 #else
525 #endif
526 }
527 
528 /*****************************************************************************/
529 
530 #ifdef EC_SII_ASSIGN
531 
537  ec_fsm_slave_scan_t *fsm
538  )
539 {
540  ec_datagram_t *datagram = fsm->datagram;
541  ec_slave_t *slave = fsm->slave;
542 
543  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
544  return;
545  }
546 
547  if (datagram->state != EC_DATAGRAM_RECEIVED) {
548  EC_SLAVE_WARN(slave, "Failed to receive SII assignment datagram: ");
549  ec_datagram_print_state(datagram);
550  // Try to go on, probably assignment is correct
551  goto continue_with_sii_size;
552  }
553 
554  if (datagram->working_counter != 1) {
555  EC_SLAVE_WARN(slave, "Failed to assign SII to EtherCAT: ");
556  ec_datagram_print_wc_error(datagram);
557  // Try to go on, probably assignment is correct
558  }
559 
560 continue_with_sii_size:
562 }
563 
564 #endif
565 
566 /*****************************************************************************/
567 
573  ec_fsm_slave_scan_t *fsm
574  )
575 {
576  ec_slave_t *slave = fsm->slave;
577  uint16_t cat_type, cat_size;
578 
579  if (ec_fsm_sii_exec(&fsm->fsm_sii))
580  return;
581 
582  if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
583  fsm->slave->error_flag = 1;
585  EC_SLAVE_ERR(slave, "Failed to determine SII content size:"
586  " Reading word offset 0x%04x failed. Assuming %u words.\n",
589  goto alloc_sii;
590  }
591 
592  cat_type = EC_READ_U16(fsm->fsm_sii.value);
593  cat_size = EC_READ_U16(fsm->fsm_sii.value + 2);
594 
595  if (cat_type != 0xFFFF) { // not the last category
596  off_t next_offset = 2UL + fsm->sii_offset + cat_size;
597 
598  EC_SLAVE_DBG(slave, 1, "Found category type %u with size %u."
599  " Proceeding to offset %zu.\n",
600  cat_type, cat_size, next_offset);
601 
602  if (next_offset >= EC_MAX_SII_SIZE) {
603  EC_SLAVE_WARN(slave, "SII size exceeds %u words"
604  " (0xffff limiter missing?).\n", EC_MAX_SII_SIZE);
605  // cut off category data...
607  goto alloc_sii;
608  }
609  fsm->sii_offset = next_offset;
610  ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset,
612  ec_fsm_sii_exec(&fsm->fsm_sii); // execute state immediately
613  return;
614  }
615 
616  slave->sii_nwords = fsm->sii_offset + 1;
617 
618 alloc_sii:
619  if (slave->sii_words) {
620  EC_SLAVE_WARN(slave, "Freeing old SII data...\n");
621  kfree(slave->sii_words);
622  }
623 
624  if (!(slave->sii_words =
625  (uint16_t *) kmalloc(slave->sii_nwords * 2, GFP_KERNEL))) {
626  EC_SLAVE_ERR(slave, "Failed to allocate %zu words of SII data.\n",
627  slave->sii_nwords);
628  slave->sii_nwords = 0;
629  slave->error_flag = 1;
631  return;
632  }
633 
634  // Start fetching SII contents
635 
637  fsm->sii_offset = 0x0000;
638  ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset,
640  ec_fsm_sii_exec(&fsm->fsm_sii); // execute state immediately
641 }
642 
643 /*****************************************************************************/
644 
651 {
652  ec_slave_t *slave = fsm->slave;
653  uint16_t *cat_word, cat_type, cat_size;
654 
655  if (ec_fsm_sii_exec(&fsm->fsm_sii)) return;
656 
657  if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
658  fsm->slave->error_flag = 1;
660  EC_SLAVE_ERR(slave, "Failed to fetch SII contents.\n");
661  return;
662  }
663 
664  // 2 words fetched
665 
666  if (fsm->sii_offset + 2 <= slave->sii_nwords) { // 2 words fit
667  memcpy(slave->sii_words + fsm->sii_offset, fsm->fsm_sii.value, 4);
668  } else { // copy the last word
669  memcpy(slave->sii_words + fsm->sii_offset, fsm->fsm_sii.value, 2);
670  }
671 
672  if (fsm->sii_offset + 2 < slave->sii_nwords) {
673  // fetch the next 2 words
674  fsm->sii_offset += 2;
675  ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset,
677  ec_fsm_sii_exec(&fsm->fsm_sii); // execute state immediately
678  return;
679  }
680 
681  // Evaluate SII contents
682 
684 
685  slave->sii.alias =
686  EC_READ_U16(slave->sii_words + 0x0004);
687  slave->effective_alias = slave->sii.alias;
688  slave->sii.vendor_id =
689  EC_READ_U32(slave->sii_words + 0x0008);
690  slave->sii.product_code =
691  EC_READ_U32(slave->sii_words + 0x000A);
692  slave->sii.revision_number =
693  EC_READ_U32(slave->sii_words + 0x000C);
694  slave->sii.serial_number =
695  EC_READ_U32(slave->sii_words + 0x000E);
696  slave->sii.boot_rx_mailbox_offset =
697  EC_READ_U16(slave->sii_words + 0x0014);
698  slave->sii.boot_rx_mailbox_size =
699  EC_READ_U16(slave->sii_words + 0x0015);
700  slave->sii.boot_tx_mailbox_offset =
701  EC_READ_U16(slave->sii_words + 0x0016);
702  slave->sii.boot_tx_mailbox_size =
703  EC_READ_U16(slave->sii_words + 0x0017);
704  slave->sii.std_rx_mailbox_offset =
705  EC_READ_U16(slave->sii_words + 0x0018);
706  slave->sii.std_rx_mailbox_size =
707  EC_READ_U16(slave->sii_words + 0x0019);
708  slave->sii.std_tx_mailbox_offset =
709  EC_READ_U16(slave->sii_words + 0x001A);
710  slave->sii.std_tx_mailbox_size =
711  EC_READ_U16(slave->sii_words + 0x001B);
712  slave->sii.mailbox_protocols =
713  EC_READ_U16(slave->sii_words + 0x001C);
714  if (slave->sii.mailbox_protocols) {
715  int need_delim = 0;
716  uint16_t all = EC_MBOX_AOE | EC_MBOX_COE | EC_MBOX_FOE |
718  if ((slave->sii.mailbox_protocols & all) &&
719  slave->master->debug_level >= 1) {
720  EC_SLAVE_DBG(slave, 1, "Slave announces to support ");
721  if (slave->sii.mailbox_protocols & EC_MBOX_AOE) {
722  printk(KERN_CONT "AoE");
723  need_delim = 1;
724  }
725  if (slave->sii.mailbox_protocols & EC_MBOX_COE) {
726  if (need_delim) {
727  printk(KERN_CONT ", ");
728  }
729  printk(KERN_CONT "CoE");
730  need_delim = 1;
731  }
732  if (slave->sii.mailbox_protocols & EC_MBOX_FOE) {
733  if (need_delim) {
734  printk(KERN_CONT ", ");
735  }
736  printk(KERN_CONT "FoE");
737  need_delim = 1;
738  }
739  if (slave->sii.mailbox_protocols & EC_MBOX_SOE) {
740  if (need_delim) {
741  printk(KERN_CONT ", ");
742  }
743  printk(KERN_CONT "SoE");
744  need_delim = 1;
745  }
746  if (slave->sii.mailbox_protocols & EC_MBOX_VOE) {
747  if (need_delim) {
748  printk(KERN_CONT ", ");
749  }
750  printk(KERN_CONT "VoE");
751  need_delim = 1;
752  }
753  printk(KERN_CONT ".\n");
754  }
755  if (slave->sii.mailbox_protocols & ~all) {
756  EC_SLAVE_DBG(slave, 1, "Slave announces to support unknown"
757  " mailbox protocols 0x%04X.",
758  slave->sii.mailbox_protocols & ~all);
759  }
760  }
761  else {
762  EC_SLAVE_DBG(slave, 1, "Slave announces to support no mailbox"
763  " protocols.");
764  }
765 
766  if (slave->sii.boot_rx_mailbox_offset == 0xffff ||
767  slave->sii.boot_rx_mailbox_size == 0xffff ||
768  slave->sii.boot_tx_mailbox_offset == 0xffff ||
769  slave->sii.boot_tx_mailbox_size == 0xffff ||
770  slave->sii.std_rx_mailbox_offset == 0xffff ||
771  slave->sii.std_rx_mailbox_size == 0xffff ||
772  slave->sii.std_tx_mailbox_offset == 0xffff ||
773  slave->sii.std_tx_mailbox_size == 0xffff) {
774  slave->sii.mailbox_protocols = 0x0000;
775  EC_SLAVE_ERR(slave, "Invalid mailbox settings in SII."
776  " Disabling mailbox communication.");
777  }
778 
779  // clear mailbox settings if invalid values due to invalid sii file
780  if ((slave->sii.boot_rx_mailbox_offset == 0xFFFF) ||
781  (slave->sii.boot_tx_mailbox_offset == 0xFFFF) ||
782  (slave->sii.std_rx_mailbox_offset == 0xFFFF) ||
783  (slave->sii.std_tx_mailbox_offset == 0xFFFF)) {
784  slave->sii.boot_rx_mailbox_offset = 0;
785  slave->sii.boot_tx_mailbox_offset = 0;
786  slave->sii.boot_rx_mailbox_size = 0;
787  slave->sii.boot_tx_mailbox_size = 0;
788  slave->sii.std_rx_mailbox_offset = 0;
789  slave->sii.std_tx_mailbox_offset = 0;
790  slave->sii.std_rx_mailbox_size = 0;
791  slave->sii.std_tx_mailbox_size = 0;
792  slave->sii.mailbox_protocols = 0;
793  EC_SLAVE_ERR(slave, "Unexpected mailbox offset in SII data.\n");
794  }
795 
797  // sii does not contain category data
799  return;
800  }
801 
802  if (slave->sii_nwords < EC_FIRST_SII_CATEGORY_OFFSET + 1) {
803  EC_SLAVE_ERR(slave, "Unexpected end of SII data:"
804  " First category header missing.\n");
805  goto end;
806  }
807 
808  // evaluate category data
809  cat_word = slave->sii_words + EC_FIRST_SII_CATEGORY_OFFSET;
810  while (EC_READ_U16(cat_word) != 0xFFFF) {
811 
812  // type and size words must fit
813  if (cat_word + 2 - slave->sii_words > slave->sii_nwords) {
814  EC_SLAVE_ERR(slave, "Unexpected end of SII data:"
815  " Category header incomplete.\n");
816  goto end;
817  }
818 
819  cat_type = EC_READ_U16(cat_word) & 0x7FFF;
820  cat_size = EC_READ_U16(cat_word + 1);
821  cat_word += 2;
822 
823  if (cat_word + cat_size - slave->sii_words > slave->sii_nwords) {
824  EC_SLAVE_WARN(slave, "Unexpected end of SII data:"
825  " Category data incomplete.\n");
826  goto end;
827  }
828 
829  switch (cat_type) {
830  case 0x000A:
831  if (ec_slave_fetch_sii_strings(slave, (uint8_t *) cat_word,
832  cat_size * 2))
833  goto end;
834  break;
835  case 0x001E:
836  if (ec_slave_fetch_sii_general(slave, (uint8_t *) cat_word,
837  cat_size * 2))
838  goto end;
839  break;
840  case 0x0028:
841  break;
842  case 0x0029:
843  if (ec_slave_fetch_sii_syncs(slave, (uint8_t *) cat_word,
844  cat_size * 2))
845  goto end;
846  break;
847  case 0x0032:
848  if (ec_slave_fetch_sii_pdos( slave, (uint8_t *) cat_word,
849  cat_size * 2, EC_DIR_INPUT)) // TxPDO
850  goto end;
851  break;
852  case 0x0033:
853  if (ec_slave_fetch_sii_pdos( slave, (uint8_t *) cat_word,
854  cat_size * 2, EC_DIR_OUTPUT)) // RxPDO
855  goto end;
856  break;
857  default:
858  EC_SLAVE_DBG(slave, 1, "Unknown category type 0x%04X.\n",
859  cat_type);
860  }
861 
862  cat_word += cat_size;
863  if (cat_word - slave->sii_words >= slave->sii_nwords) {
864  EC_SLAVE_WARN(slave, "Unexpected end of SII data:"
865  " Next category header missing.\n");
866  goto end;
867  }
868  }
869 
870 #ifdef EC_REGALIAS
871  ec_fsm_slave_scan_enter_regalias(fsm);
872 #else
873  if (slave->sii.mailbox_protocols & EC_MBOX_COE) {
875  } else {
877  }
878 #endif
879  return;
880 
881 end:
882  EC_SLAVE_ERR(slave, "Failed to analyze category data.\n");
883  fsm->slave->error_flag = 1;
885 }
886 
887 /*****************************************************************************/
888 
889 #ifdef EC_REGALIAS
890 
893 void ec_fsm_slave_scan_enter_regalias(
894  ec_fsm_slave_scan_t *fsm
895  )
896 {
897  ec_datagram_t *datagram = fsm->datagram;
898  ec_slave_t *slave = fsm->slave;
899 
900  // read alias from register
901  EC_SLAVE_DBG(slave, 1, "Reading alias from register.\n");
902  ec_datagram_fprd(datagram, slave->station_address, 0x0012, 2);
903  ec_datagram_zero(datagram);
904  fsm->retries = EC_FSM_RETRIES;
905  fsm->state = ec_fsm_slave_scan_state_regalias;
906 }
907 
908 /*****************************************************************************/
909 
912 void ec_fsm_slave_scan_state_regalias(
913  ec_fsm_slave_scan_t *fsm
914  )
915 {
916  ec_datagram_t *datagram = fsm->datagram;
917  ec_slave_t *slave = fsm->slave;
918 
919  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
920  return;
921 
922  if (datagram->state != EC_DATAGRAM_RECEIVED) {
924  EC_SLAVE_ERR(slave, "Failed to receive register alias datagram: ");
925  ec_datagram_print_state(datagram);
926  return;
927  }
928 
929  if (datagram->working_counter != 1) {
930  EC_SLAVE_DBG(slave, 1, "Failed to read register alias.\n");
931  } else {
932  slave->effective_alias = EC_READ_U16(datagram->data);
933  EC_SLAVE_DBG(slave, 1, "Read alias %u from register.\n",
934  slave->effective_alias);
935  }
936 
937  if (slave->sii.mailbox_protocols & EC_MBOX_COE) {
939  } else {
941  }
942 }
943 
944 #endif // defined EC_REGALIAS
945 
946 /*****************************************************************************/
947 
951  ec_fsm_slave_scan_t *fsm
952  )
953 {
954  ec_slave_t *slave = fsm->slave;
955  uint8_t current_state = slave->current_state & EC_SLAVE_STATE_MASK;
956 
957  if (current_state != EC_SLAVE_STATE_PREOP
958  && current_state != EC_SLAVE_STATE_SAFEOP
959  && current_state != EC_SLAVE_STATE_OP) {
960  if (slave->master->debug_level) {
961  char str[EC_STATE_STRING_SIZE];
962  ec_state_string(current_state, str, 0);
963  EC_SLAVE_DBG(slave, 0, "Slave is not in the state"
964  " to do mailbox com (%s), setting to PREOP.\n", str);
965  }
966 
971  } else {
972  EC_SLAVE_DBG(slave, 1, "Reading mailbox"
973  " sync manager configuration.\n");
974 
975  /* Scan current sync manager configuration to get configured mailbox
976  * sizes. */
977  ec_datagram_fprd(fsm->datagram, slave->station_address, 0x0800,
978  EC_SYNC_PAGE_SIZE * 2);
980  fsm->retries = EC_FSM_RETRIES;
982  }
983 }
984 
985 /*****************************************************************************/
986 
990  ec_fsm_slave_scan_t *fsm
991  )
992 {
994  return;
995 
998  return;
999  }
1000 
1002 }
1003 
1004 /*****************************************************************************/
1005 
1009  ec_fsm_slave_scan_t *fsm
1010  )
1011 {
1012  ec_datagram_t *datagram = fsm->datagram;
1013  ec_slave_t *slave = fsm->slave;
1014  uint16_t tx_offset, tx_size, rx_offset, rx_size;
1015 
1016  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
1017  return;
1018 
1019  if (datagram->state != EC_DATAGRAM_RECEIVED) {
1021  EC_SLAVE_ERR(slave, "Failed to receive sync manager"
1022  " configuration datagram: ");
1023  ec_datagram_print_state(datagram);
1024  return;
1025  }
1026 
1027  if (datagram->working_counter != 1) {
1028  fsm->slave->error_flag = 1;
1030  EC_SLAVE_ERR(slave, "Failed to read DL status: ");
1031  ec_datagram_print_wc_error(datagram);
1032  return;
1033  }
1034 
1035  rx_offset = EC_READ_U16(datagram->data);
1036  rx_size = EC_READ_U16(datagram->data + 2);
1037  tx_offset = EC_READ_U16(datagram->data + 8);
1038  tx_size = EC_READ_U16(datagram->data + 10);
1039 
1040  if (rx_size == 0xffff) {
1042  slave->sii.mailbox_protocols = 0x0000;
1043  EC_SLAVE_ERR(slave, "Invalid RX mailbox size (%u) configured."
1044  " Disabling mailbox communication.", rx_size);
1045  return;
1046  }
1047 
1048  if (tx_size == 0xffff) {
1050  slave->sii.mailbox_protocols = 0x0000;
1051  EC_SLAVE_ERR(slave, "Invalid TX mailbox size (%u) configured."
1052  " Disabling mailbox communication.", tx_size);
1053  return;
1054  }
1055 
1056  slave->configured_rx_mailbox_offset = rx_offset;
1057  slave->configured_rx_mailbox_size = rx_size;
1058  slave->configured_tx_mailbox_offset = tx_offset;
1059  slave->configured_tx_mailbox_size = tx_size;
1060 
1061  EC_SLAVE_DBG(slave, 1, "Mailbox configuration:\n");
1062  EC_SLAVE_DBG(slave, 1, " RX offset=0x%04x size=%u\n",
1065  EC_SLAVE_DBG(slave, 1, " TX offset=0x%04x size=%u\n",
1068 
1069  // allocate memory for mailbox response data for supported mailbox protocols
1071 
1073 }
1074 
1075 /*****************************************************************************/
1076 
1080  ec_fsm_slave_scan_t *fsm
1081  )
1082 {
1083  ec_slave_t *slave = fsm->slave;
1084 
1085  // If there is some old data in the slave's mailbox, read it out and
1086  // discard it. We don't need to check the mailbox first, we just ignore
1087  // an error or empty mailbox response.
1088  ec_datagram_t *datagram = fsm->datagram;
1089  ec_slave_mbox_prepare_fetch(fsm->slave, datagram);
1090  fsm->retries = EC_FSM_RETRIES;
1092 
1093  slave->valid_mbox_data = 0;
1094 }
1095 
1096 /*****************************************************************************/
1097 
1101 {
1102  ec_slave_t *slave = fsm->slave;
1103  ec_datagram_t *datagram = fsm->datagram;
1104 
1105  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1106  ec_slave_mbox_prepare_fetch(fsm->slave, datagram);
1107  return;
1108  }
1109 
1110  if (unlikely(slave->master->debug_level > 0)
1111  && datagram->state == EC_DATAGRAM_RECEIVED
1112  && datagram->working_counter == 1)
1113  EC_SLAVE_INFO(slave, "Cleared old data from the mailbox\n");
1114 
1115  slave->valid_mbox_data = 1;
1116 
1118 }
1119 
1120 /*****************************************************************************/
1121 
1125  ec_fsm_slave_scan_t *fsm
1126  )
1127 {
1128  ec_slave_t *slave = fsm->slave;
1129 
1130  EC_SLAVE_DBG(slave, 1, "Scanning PDO assignment and mapping.\n");
1132  ec_fsm_pdo_start_reading(fsm->fsm_pdo, slave);
1133  ec_fsm_pdo_exec(fsm->fsm_pdo, fsm->datagram); // execute immediately
1134 }
1135 
1136 /*****************************************************************************/
1137 
1141  ec_fsm_slave_scan_t *fsm
1142  )
1143 {
1144  if (ec_fsm_pdo_exec(fsm->fsm_pdo, fsm->datagram)) {
1145  return;
1146  }
1147 
1148  if (!ec_fsm_pdo_success(fsm->fsm_pdo)) {
1150  return;
1151  }
1152 
1153  // reading PDO configuration finished
1155 }
1156 
1157 /******************************************************************************
1158  * Common state functions
1159  *****************************************************************************/
1160 
1164  ec_fsm_slave_scan_t *fsm
1165  )
1166 {
1167 }
1168 
1169 /*****************************************************************************/
1170 
1174  ec_fsm_slave_scan_t *fsm
1175  )
1176 {
1177 }
1178 
1179 /*****************************************************************************/
void ec_fsm_slave_scan_state_sync(ec_fsm_slave_scan_t *)
Slave scan state: SYNC.
#define EC_FSM_RETRIES
Number of state machine retries on datagram timeout.
Definition: globals.h:47
ec_slave_t * slave
Slave the FSM runs on.
Vendor specific.
Definition: globals.h:155
void ec_fsm_slave_scan_state_pdos(ec_fsm_slave_scan_t *)
Slave scan state: PDOS.
void ec_mbox_prot_data_prealloc(ec_slave_t *slave, uint16_t protocols, size_t size)
Allocates internal memory for mailbox response data for all slave supported mailbox protocols ...
Definition: datagram.c:720
uint16_t ring_position
Ring position.
Definition: slave.h:206
uint32_t revision_number
Revision number.
Definition: slave.h:160
uint16_t boot_rx_mailbox_offset
Bootstrap receive mailbox address.
Definition: slave.h:162
#define EC_SYNC_PAGE_SIZE
Size of a sync manager configuration page.
Definition: globals.h:95
void ec_fsm_slave_scan_enter_assign_sii(ec_fsm_slave_scan_t *fsm)
Enter slave scan state ASSIGN_SII.
#define EC_SLAVE_STATE_MASK
Slave state mask.
Definition: globals.h:123
ec_sii_t sii
Extracted SII data.
Definition: slave.h:246
int ec_fsm_pdo_exec(ec_fsm_pdo_t *fsm, ec_datagram_t *datagram)
Executes the current state of the state machine.
Definition: fsm_pdo.c:164
void ec_fsm_slave_config_start(ec_fsm_slave_config_t *fsm, ec_slave_t *slave)
Start slave configuration state machine.
ec_datagram_t * datagram
Datagram used in the state machine.
uint16_t configured_tx_mailbox_size
Configured send mailbox size.
Definition: slave.h:224
uint16_t base_build
Build number.
Definition: slave.h:229
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition: slave.h:107
Servo-Profile over EtherCAT.
Definition: globals.h:154
OP (mailbox communication and input/output update)
Definition: globals.h:138
uint16_t configured_tx_mailbox_offset
Configured send mailbox offset.
Definition: slave.h:222
void ec_fsm_slave_scan_init(ec_fsm_slave_scan_t *fsm, ec_datagram_t *datagram, ec_fsm_slave_config_t *fsm_slave_config, ec_fsm_pdo_t *fsm_pdo)
Constructor.
size_t ec_state_string(uint8_t, char *, uint8_t)
Prints slave states in clear text.
Definition: module.c:402
ec_slave_port_t ports[EC_MAX_PORTS]
Ports.
Definition: slave.h:210
ec_slave_state_t current_state
Current application state.
Definition: slave.h:215
void ec_fsm_slave_scan_state_dc_times(ec_fsm_slave_scan_t *)
Slave scan state: DC TIMES.
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:128
#define EC_SLAVE_WARN(slave, fmt, args...)
Convenience macro for printing slave-specific warnings to syslog.
Definition: slave.h:91
void ec_fsm_slave_scan_state_end(ec_fsm_slave_scan_t *)
State: END.
void ec_fsm_slave_scan_state_base(ec_fsm_slave_scan_t *)
Slave scan state: BASE.
EtherCAT datagram.
Definition: datagram.h:88
uint32_t serial_number
Serial number.
Definition: slave.h:161
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2338
void ec_fsm_slave_scan_state_state(ec_fsm_slave_scan_t *)
Slave scan state: STATE.
uint16_t working_counter
Working counter.
Definition: datagram.h:100
void ec_fsm_slave_scan_state_error(ec_fsm_slave_scan_t *)
State: ERROR.
void ec_fsm_slave_scan_state_start(ec_fsm_slave_scan_t *)
Slave scan state: START.
Acknowledge/Error bit (no actual state)
Definition: globals.h:140
uint16_t boot_tx_mailbox_size
Bootstrap transmit mailbox size.
Definition: slave.h:165
int ec_slave_fetch_sii_strings(ec_slave_t *slave, const uint8_t *data, size_t data_size)
Fetches data from a STRING category.
Definition: slave.c:434
Sent (still in the queue).
Definition: datagram.h:77
void ec_slave_set_dl_status(ec_slave_t *slave, uint16_t new_state)
Sets the data-link state of a slave.
Definition: slave.c:356
void ec_fsm_sii_init(ec_fsm_sii_t *fsm, ec_datagram_t *datagram)
Constructor.
Definition: fsm_sii.c:74
EtherCAT slave scanning state machine.
uint16_t station_address
Configured station address.
Definition: slave.h:207
#define EC_MAX_SII_SIZE
Maximum SII size in words, to avoid infinite reading.
Definition: globals.h:57
uint16_t std_rx_mailbox_size
Standard receive mailbox size.
Definition: slave.h:167
#define EC_MAX_FMMUS
Maximum number of FMMUs per slave.
Definition: globals.h:98
uint8_t base_type
Slave type.
Definition: slave.h:227
int ec_fsm_slave_scan_exec(ec_fsm_slave_scan_t *fsm)
Executes the current state of the state machine.
Global definitions and macros.
uint16_t std_tx_mailbox_offset
Standard transmit mailbox address.
Definition: slave.h:168
EtherCAT master structure.
SAFEOP (mailbox communication and input update)
Definition: globals.h:136
uint16_t boot_tx_mailbox_offset
Bootstrap transmit mailbox address.
Definition: slave.h:164
void ec_fsm_slave_scan_enter_preop(ec_fsm_slave_scan_t *)
Enter slave scan state PREOP.
ec_fsm_slave_config_t * fsm_slave_config
Slave configuration state machine to use.
EtherCAT slave.
Definition: slave.h:199
void ec_fsm_slave_scan_state_datalink(ec_fsm_slave_scan_t *)
Slave scan state: DATALINK.
int ec_datagram_apwr(ec_datagram_t *datagram, uint16_t ring_position, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT APWR datagram.
Definition: datagram.c:211
void ec_datagram_zero(ec_datagram_t *datagram)
Fills the datagram payload memory with zeros.
Definition: datagram.c:179
ec_datagram_state_t state
State.
Definition: datagram.h:101
CANopen over EtherCAT.
Definition: globals.h:152
ec_fsm_pdo_t * fsm_pdo
PDO configuration state machine to use.
void ec_slave_clear_sync_managers(ec_slave_t *slave)
Clear the sync manager array.
Definition: slave.c:337
Use configured addresses.
Definition: fsm_sii.h:50
uint16_t * sii_words
Complete SII image.
Definition: slave.h:242
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:170
void ec_fsm_pdo_start_reading(ec_fsm_pdo_t *fsm, ec_slave_t *slave)
Start reading the PDO configuration.
Definition: fsm_pdo.c:119
void ec_fsm_slave_scan_state_sii_data(ec_fsm_slave_scan_t *)
Slave scan state: SII DATA.
ec_fsm_sii_t fsm_sii
SII state machine.
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:77
void ec_datagram_print_wc_error(const ec_datagram_t *datagram)
Evaluates the working counter of a single-cast datagram.
Definition: datagram.c:606
ec_slave_dc_range_t base_dc_range
DC range.
Definition: slave.h:234
uint16_t std_rx_mailbox_offset
Standard receive mailbox address.
Definition: slave.h:166
uint8_t base_fmmu_bit_operation
FMMU bit operation is supported.
Definition: slave.h:232
int ec_fsm_slave_scan_running(const ec_fsm_slave_scan_t *fsm)
uint16_t alias
Configured station alias.
Definition: slave.h:157
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2355
uint8_t base_fmmu_count
Number of supported FMMUs.
Definition: slave.h:230
uint16_t configured_rx_mailbox_offset
Configured receive mailbox offset.
Definition: slave.h:218
#define EC_READ_U32(DATA)
Read a 32-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2266
ec_slave_port_desc_t desc
Port descriptors.
Definition: slave.h:138
Finite state machine for scanning an EtherCAT slave.
ec_master_t * master
Master owning the slave.
Definition: slave.h:201
int ec_datagram_fpwr(ec_datagram_t *datagram, uint16_t configured_address, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT FPWR datagram.
Definition: datagram.c:299
uint8_t has_dc_system_time
The slave supports the DC system time register.
Definition: slave.h:235
void ec_fsm_slave_scan_state_sii_size(ec_fsm_slave_scan_t *)
Slave scan state: SII SIZE.
unsigned int retries
Retries on datagram timeout.
int ec_datagram_fprd(ec_datagram_t *datagram, uint16_t configured_address, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT FPRD datagram.
Definition: datagram.c:274
Values read by the master.
Definition: ecrt.h:438
PDO configuration state machine.
Definition: fsm_pdo.h:54
#define EC_FIRST_SII_CATEGORY_OFFSET
Word offset of first SII category.
Definition: globals.h:92
uint8_t base_revision
Revision.
Definition: slave.h:228
32 bit.
Definition: globals.h:179
void ec_fsm_sii_read(ec_fsm_sii_t *fsm, ec_slave_t *slave, uint16_t word_offset, ec_fsm_sii_addressing_t mode)
Initializes the SII read state machine.
Definition: fsm_sii.c:98
void ec_fsm_slave_scan_enter_datalink(ec_fsm_slave_scan_t *)
Slave scan entry function: DATALINK.
#define EC_SLAVE_INFO(slave, fmt, args...)
Convenience macro for printing slave-specific information to syslog.
Definition: slave.h:63
uint8_t valid_mbox_data
Received mailbox data is valid.
Definition: slave.h:273
void ec_fsm_sii_clear(ec_fsm_sii_t *fsm)
Destructor.
Definition: fsm_sii.c:88
int ec_fsm_pdo_success(const ec_fsm_pdo_t *fsm)
Get execution result.
Definition: fsm_pdo.c:180
uint16_t effective_alias
Effective alias address.
Definition: slave.h:208
int ec_fsm_sii_exec(ec_fsm_sii_t *fsm)
Executes the SII state machine.
Definition: fsm_sii.c:137
int ec_fsm_sii_success(ec_fsm_sii_t *fsm)
Returns, if the master startup state machine terminated with success.
Definition: fsm_sii.c:152
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2250
Finite state machine to configure an EtherCAT slave.
void ec_datagram_print_state(const ec_datagram_t *datagram)
Prints the state of a datagram.
Definition: datagram.c:566
Mailbox functionality.
int ec_slave_fetch_sii_syncs(ec_slave_t *slave, const uint8_t *data, size_t data_size)
Fetches data from a SYNC MANAGER category.
Definition: slave.c:541
#define EC_STATE_STRING_SIZE
Minimum size of a buffer used with ec_state_string().
Definition: globals.h:54
uint16_t boot_rx_mailbox_size
Bootstrap receive mailbox size.
Definition: slave.h:163
#define EC_MAX_PORTS
Maximum number of slave ports.
Definition: ecrt.h:227
int ec_fsm_slave_config_exec(ec_fsm_slave_config_t *fsm)
Executes the current state of the state machine.
void ec_fsm_slave_scan_state_dc_cap(ec_fsm_slave_scan_t *)
Slave scan state: DC CAPABILITIES.
void(* state)(ec_fsm_slave_scan_t *)
State function.
void ec_fsm_slave_scan_state_preop(ec_fsm_slave_scan_t *)
Slave scan state: PREOP.
Queued for sending.
Definition: datagram.h:76
uint32_t receive_time
Port receive times for delay measurement.
Definition: slave.h:141
Timed out (dequeued).
Definition: datagram.h:79
void ec_fsm_slave_scan_state_mailbox_cleared(ec_fsm_slave_scan_t *)
Slave scan state: Mailbox cleared.
uint16_t sii_offset
SII offset in words.
void ec_slave_request_state(ec_slave_t *slave, ec_slave_state_t state)
Request a slave state and resets the error flag.
Definition: slave.c:418
uint16_t configured_rx_mailbox_size
Configured receive mailbox size.
Definition: slave.h:220
uint8_t base_dc_supported
Distributed clocks are supported.
Definition: slave.h:233
void ec_fsm_slave_scan_start(ec_fsm_slave_scan_t *fsm, ec_slave_t *slave)
Start slave scan state machine.
size_t sii_nwords
Size of the SII contents in words.
Definition: slave.h:243
uint8_t * data
Datagram payload.
Definition: datagram.h:95
uint8_t base_sync_count
Number of supported sync managers.
Definition: slave.h:231
#define EC_READ_U8(DATA)
Read an 8-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2234
int ec_fsm_slave_config_success(const ec_fsm_slave_config_t *fsm)
void ec_fsm_slave_scan_clear(ec_fsm_slave_scan_t *fsm)
Destructor.
EtherCAT slave configuration structure.
void ec_fsm_slave_scan_enter_sii_size(ec_fsm_slave_scan_t *fsm)
Enter slave scan state SII_SIZE.
uint32_t product_code
Vendor-specific product code.
Definition: slave.h:159
PREOP state (mailbox communication, no IO)
Definition: globals.h:132
Values written by the master.
Definition: ecrt.h:437
Received (dequeued).
Definition: datagram.h:78
void ec_fsm_slave_scan_enter_clear_mailbox(ec_fsm_slave_scan_t *)
Enter slave scan state: Clear Mailbox.
unsigned int error_flag
Stop processing after an error.
Definition: slave.h:216
uint16_t std_tx_mailbox_size
Standard transmit mailbox size.
Definition: slave.h:169
void ec_fsm_slave_scan_enter_pdos(ec_fsm_slave_scan_t *)
Enter slave scan state PDOS.
ADS over EtherCAT.
Definition: globals.h:150
int ec_slave_fetch_sii_pdos(ec_slave_t *slave, const uint8_t *data, size_t data_size, ec_direction_t dir)
Fetches data from a [RT]xPDO category.
Definition: slave.c:607
#define EC_MAX_SYNC_MANAGERS
Maximum number of sync managers per slave.
Definition: ecrt.h:218
File-Access over EtherCAT.
Definition: globals.h:153
int ec_slave_fetch_sii_general(ec_slave_t *slave, const uint8_t *data, size_t data_size)
Fetches data from a GENERAL category.
Definition: slave.c:490
void ec_fsm_slave_scan_state_assign_sii(ec_fsm_slave_scan_t *)
Slave scan state: ASSIGN_SII.
void ec_fsm_slave_scan_state_address(ec_fsm_slave_scan_t *)
Slave scan state: ADDRESS.
uint32_t vendor_id
Vendor ID.
Definition: slave.h:158
int ec_fsm_slave_scan_success(const ec_fsm_slave_scan_t *fsm)
uint8_t value[4]
raw SII value (32bit)
Definition: fsm_sii.h:70