IgH EtherCAT Master  1.6.2
slave_config.c
Go to the documentation of this file.
1 /*****************************************************************************
2  *
3  * Copyright (C) 2006-2024 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  * vim: expandtab
21  *
22  ****************************************************************************/
23 
29 /****************************************************************************/
30 
31 #include "slave_config.h"
32 
33 #include "globals.h"
34 #include "master.h"
35 #include "voe_handler.h"
36 #include "flag.h"
37 #include "ioctl.h"
38 
39 #ifdef EC_EOE
40 #include "eoe_request.h"
41 #endif
42 
43 #include <linux/module.h>
44 #include <linux/slab.h>
45 
46 /****************************************************************************/
47 
48 // prototypes for private methods
52  ec_pdo_t *);
53 
54 /****************************************************************************/
55 
58 typedef struct {
59  struct list_head list;
60  ec_slave_state_t from;
62  unsigned int timeout_ms;
64 
65 /****************************************************************************/
66 
73  ec_slave_config_t *sc,
74  ec_master_t *master,
75  uint16_t alias,
76  uint16_t position,
77  uint32_t vendor_id,
78  uint32_t product_code
79  )
80 {
81  unsigned int i;
82 
83  sc->master = master;
84 
85  sc->alias = alias;
86  sc->position = position;
87  sc->vendor_id = vendor_id;
88  sc->product_code = product_code;
89  sc->watchdog_divider = 0; // use default
90  sc->watchdog_intervals = 0; // use default
91 
92  sc->slave = NULL;
93 
94  for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++)
96 
97  sc->used_fmmus = 0;
98  sc->dc_assign_activate = 0x0000;
99  sc->dc_sync[0].cycle_time = 0U;
100  sc->dc_sync[1].cycle_time = 0;
101  sc->dc_sync[0].shift_time = 0U;
102  sc->dc_sync[1].shift_time = 0;
103 
104  INIT_LIST_HEAD(&sc->sdo_configs);
105  INIT_LIST_HEAD(&sc->sdo_requests);
106  INIT_LIST_HEAD(&sc->soe_requests);
107  INIT_LIST_HEAD(&sc->reg_requests);
108  INIT_LIST_HEAD(&sc->voe_handlers);
109  INIT_LIST_HEAD(&sc->soe_configs);
110  INIT_LIST_HEAD(&sc->flags);
111  INIT_LIST_HEAD(&sc->al_timeouts);
112 
113 #ifdef EC_EOE
115 #endif
116 
118 }
119 
120 /****************************************************************************/
121 
127  ec_slave_config_t *sc
128  )
129 {
130  unsigned int i;
131  ec_sdo_request_t *req, *next_req;
132  ec_voe_handler_t *voe, *next_voe;
133  ec_reg_request_t *reg, *next_reg;
134  ec_soe_request_t *soe, *next_soe;
135  ec_flag_t *flag, *next_flag;
136  ec_al_timeout_t *timeout, *next_timeout;
137 
139 
140  // Free sync managers
141  for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++)
143 
144  // free all SDO configurations
145  list_for_each_entry_safe(req, next_req, &sc->sdo_configs, list) {
146  list_del(&req->list);
148  kfree(req);
149  }
150 
151  // free all SDO requests
152  list_for_each_entry_safe(req, next_req, &sc->sdo_requests, list) {
153  list_del(&req->list);
155  kfree(req);
156  }
157 
158  // free all SoE requests
159  list_for_each_entry_safe(soe, next_soe, &sc->soe_requests, list) {
160  list_del(&soe->list);
162  kfree(soe);
163  }
164 
165  // free all register requests
166  list_for_each_entry_safe(reg, next_reg, &sc->reg_requests, list) {
167  list_del(&reg->list);
169  kfree(reg);
170  }
171 
172  // free all VoE handlers
173  list_for_each_entry_safe(voe, next_voe, &sc->voe_handlers, list) {
174  list_del(&voe->list);
176  kfree(voe);
177  }
178 
179  // free all SoE configurations
180  list_for_each_entry_safe(soe, next_soe, &sc->soe_configs, list) {
181  list_del(&soe->list);
183  kfree(soe);
184  }
185 
186  // free all flags
187  list_for_each_entry_safe(flag, next_flag, &sc->flags, list) {
188  list_del(&flag->list);
189  ec_flag_clear(flag);
190  kfree(flag);
191  }
192 
193  // free all AL timeouts
194  list_for_each_entry_safe(timeout, next_timeout, &sc->al_timeouts, list) {
195  list_del(&timeout->list);
196  kfree(timeout);
197  }
198 
200 }
201 
202 /****************************************************************************/
203 
217  ec_slave_config_t *sc,
218  ec_domain_t *domain,
219  uint8_t sync_index,
220  ec_direction_t dir
221  )
222 {
223  unsigned int i;
224  ec_fmmu_config_t *fmmu;
225 
226  // FMMU configuration already prepared?
227  for (i = 0; i < sc->used_fmmus; i++) {
228  fmmu = &sc->fmmu_configs[i];
229  if (fmmu->domain == domain && fmmu->sync_index == sync_index)
230  return fmmu->logical_start_address;
231  }
232 
233  if (sc->used_fmmus == EC_MAX_FMMUS) {
234  EC_CONFIG_ERR(sc, "FMMU limit reached!\n");
235  return -EOVERFLOW;
236  }
237 
238  fmmu = &sc->fmmu_configs[sc->used_fmmus++];
239 
240  down(&sc->master->master_sem);
241  ec_fmmu_config_init(fmmu, sc, domain, sync_index, dir);
242  up(&sc->master->master_sem);
243 
244  return fmmu->logical_start_address;
245 }
246 
247 /****************************************************************************/
248 
255  ec_slave_config_t *sc
256  )
257 {
258  ec_slave_t *slave;
259 
260  if (sc->slave)
261  return 0; // already attached
262 
263  if (!(slave = ec_master_find_slave(
264  sc->master, sc->alias, sc->position))) {
265  EC_CONFIG_DBG(sc, 1, "Failed to find slave for configuration.\n");
266  return -ENOENT;
267  }
268 
269  if (slave->config) {
270  EC_CONFIG_DBG(sc, 1, "Failed to attach configuration. Slave %u"
271  " already has a configuration!\n", slave->ring_position);
272  return -EEXIST;
273  }
274 
275  if (
276 #ifdef EC_IDENT_WILDCARDS
277  sc->vendor_id != 0xffffffff &&
278 #endif
279  slave->sii.vendor_id != sc->vendor_id
280  ) {
281  EC_CONFIG_DBG(sc, 1, "Slave %u has no matching vendor ID (0x%08X)"
282  " for configuration (0x%08X).\n",
283  slave->ring_position, slave->sii.vendor_id, sc->vendor_id);
284  return -EINVAL;
285  }
286 
287  if (
288 #ifdef EC_IDENT_WILDCARDS
289  sc->product_code != 0xffffffff &&
290 #endif
291  slave->sii.product_code != sc->product_code
292  ) {
293  EC_CONFIG_DBG(sc, 1, "Slave %u has no matching product code (0x%08X)"
294  " for configuration (0x%08X).\n",
295  slave->ring_position, slave->sii.product_code,
296  sc->product_code);
297  return -EINVAL;
298  }
299 
300  // attach slave
301  slave->config = sc;
302  sc->slave = slave;
303 
304  EC_CONFIG_DBG(sc, 1, "Attached slave %u.\n", slave->ring_position);
305  return 0;
306 }
307 
308 /****************************************************************************/
309 
313  ec_slave_config_t *sc
314  )
315 {
316  if (sc->slave) {
317  ec_reg_request_t *reg;
318 
319  sc->slave->config = NULL;
320 
321  // invalidate processing register request
322  list_for_each_entry(reg, &sc->reg_requests, list) {
323  if (sc->slave->fsm.reg_request == reg) {
324  sc->slave->fsm.reg_request = NULL;
325  break;
326  }
327  }
328 
329  sc->slave = NULL;
330  }
331 }
332 
333 /****************************************************************************/
334 
338 {
339  uint8_t sync_index;
340  ec_sync_config_t *sync_config;
341  const ec_sync_t *sync;
342 
343  if (!sc->slave)
344  return;
345 
346  for (sync_index = 0; sync_index < EC_MAX_SYNC_MANAGERS; sync_index++) {
347  sync_config = &sc->sync_configs[sync_index];
348  if ((sync = ec_slave_get_sync(sc->slave, sync_index))) {
349  sync_config->dir = ec_sync_default_direction(sync);
350  if (sync_config->dir == EC_DIR_INVALID)
351  EC_SLAVE_WARN(sc->slave,
352  "SM%u has an invalid direction field!\n", sync_index);
353  ec_pdo_list_copy(&sync_config->pdos, &sync->pdos);
354  }
355  }
356 }
357 
358 /****************************************************************************/
359 
363  const ec_slave_config_t *sc,
364  ec_pdo_t *pdo
365  )
366 {
367  unsigned int i;
368  const ec_sync_t *sync;
369  const ec_pdo_t *default_pdo;
370 
371  if (!sc->slave)
372  return;
373 
374  EC_CONFIG_DBG(sc, 1, "Loading default mapping for PDO 0x%04X.\n",
375  pdo->index);
376 
377  // find PDO in any sync manager (it could be reassigned later)
378  for (i = 0; i < sc->slave->sii.sync_count; i++) {
379  sync = &sc->slave->sii.syncs[i];
380 
381  list_for_each_entry(default_pdo, &sync->pdos.list, list) {
382  if (default_pdo->index != pdo->index)
383  continue;
384 
385  if (default_pdo->name) {
386  EC_CONFIG_DBG(sc, 1, "Found PDO name \"%s\".\n",
387  default_pdo->name);
388 
389  // take PDO name from assigned one
390  ec_pdo_set_name(pdo, default_pdo->name);
391  }
392 
393  // copy entries (= default PDO mapping)
394  if (ec_pdo_copy_entries(pdo, default_pdo))
395  return;
396 
397  if (sc->master->debug_level) {
398  const ec_pdo_entry_t *entry;
399  list_for_each_entry(entry, &pdo->entries, list) {
400  EC_CONFIG_DBG(sc, 1, "Entry 0x%04X:%02X.\n",
401  entry->index, entry->subindex);
402  }
403  }
404 
405  return;
406  }
407  }
408 
409  EC_CONFIG_DBG(sc, 1, "No default mapping found.\n");
410 }
411 
412 /****************************************************************************/
413 
419  const ec_slave_config_t *sc
420  )
421 {
422  const ec_sdo_request_t *req;
423  unsigned int count = 0;
424 
425  list_for_each_entry(req, &sc->sdo_configs, list) {
426  count++;
427  }
428 
429  return count;
430 }
431 
432 /****************************************************************************/
433 
441  const ec_slave_config_t *sc,
442  unsigned int pos
443  )
444 {
445  const ec_sdo_request_t *req;
446 
447  list_for_each_entry(req, &sc->sdo_configs, list) {
448  if (pos--)
449  continue;
450  return req;
451  }
452 
453  return NULL;
454 }
455 
456 /****************************************************************************/
457 
463  const ec_slave_config_t *sc
464  )
465 {
466  const ec_soe_request_t *req;
467  unsigned int count = 0;
468 
469  list_for_each_entry(req, &sc->soe_configs, list) {
470  count++;
471  }
472 
473  return count;
474 }
475 
476 /****************************************************************************/
477 
485  const ec_slave_config_t *sc,
486  unsigned int pos
487  )
488 {
489  const ec_soe_request_t *req;
490 
491  list_for_each_entry(req, &sc->soe_configs, list) {
492  if (pos--)
493  continue;
494  return req;
495  }
496 
497  return NULL;
498 }
499 
500 /****************************************************************************/
501 
507  const ec_slave_config_t *sc
508  )
509 {
510  const ec_flag_t *flag;
511  unsigned int count = 0;
512 
513  list_for_each_entry(flag, &sc->flags, list) {
514  count++;
515  }
516 
517  return count;
518 }
519 
520 /****************************************************************************/
521 
529  const ec_slave_config_t *sc,
530  unsigned int pos
531  )
532 {
533  const ec_flag_t *flag;
534 
535  list_for_each_entry(flag, &sc->flags, list) {
536  if (pos--)
537  continue;
538  return flag;
539  }
540 
541  return NULL;
542 }
543 
544 /****************************************************************************/
545 
551  ec_slave_config_t *sc,
552  unsigned int pos
553  )
554 {
555  ec_sdo_request_t *req;
556 
557  list_for_each_entry(req, &sc->sdo_requests, list) {
558  if (pos--)
559  continue;
560  return req;
561  }
562 
563  return NULL;
564 }
565 
566 /****************************************************************************/
567 
573  ec_slave_config_t *sc,
574  unsigned int pos
575  )
576 {
577  ec_soe_request_t *req;
578 
579  list_for_each_entry(req, &sc->soe_requests, list) {
580  if (pos--)
581  continue;
582  return req;
583  }
584 
585  return NULL;
586 }
587 
588 /****************************************************************************/
589 
595  ec_slave_config_t *sc,
596  unsigned int pos
597  )
598 {
599  ec_reg_request_t *reg;
600 
601  list_for_each_entry(reg, &sc->reg_requests, list) {
602  if (pos--)
603  continue;
604  return reg;
605  }
606 
607  return NULL;
608 }
609 
610 /****************************************************************************/
611 
617  ec_slave_config_t *sc,
618  unsigned int pos
619  )
620 {
621  ec_voe_handler_t *voe;
622 
623  list_for_each_entry(voe, &sc->voe_handlers, list) {
624  if (pos--)
625  continue;
626  return voe;
627  }
628 
629  return NULL;
630 }
631 
632 /****************************************************************************/
633 
639  ec_slave_config_t *sc,
640  const char *key
641  )
642 {
643  if (sc) {
644  ec_flag_t *flag;
645  list_for_each_entry(flag, &sc->flags, list) {
646  if (!strcmp(flag->key, key)) {
647  return flag;
648  }
649  }
650  }
651 
652  return NULL;
653 }
654 
655 /****************************************************************************/
656 
663 {
664  ec_al_timeout_t *timeout;
665 
666  list_for_each_entry(timeout, &sc->al_timeouts, list) {
667  if (timeout->from == from && timeout->to == to) {
668  return timeout->timeout_ms;
669  }
670  }
671 
672  return 0;
673 }
674 
675 /*****************************************************************************
676  * Application interface
677  ****************************************************************************/
678 
680  ec_direction_t dir, ec_watchdog_mode_t watchdog_mode)
681 {
682  ec_sync_config_t *sync_config;
683 
684  EC_CONFIG_DBG(sc, 1, "ecrt_slave_config_sync_manager(sc = 0x%p,"
685  " sync_index = %u, dir = %i, watchdog_mode = %i)\n",
686  sc, sync_index, dir, watchdog_mode);
687 
688  if (sync_index >= EC_MAX_SYNC_MANAGERS) {
689  EC_CONFIG_ERR(sc, "Invalid sync manager index %u!\n", sync_index);
690  return -ENOENT;
691  }
692 
693  if (dir != EC_DIR_OUTPUT && dir != EC_DIR_INPUT) {
694  EC_CONFIG_ERR(sc, "Invalid direction %u!\n", (unsigned int) dir);
695  return -EINVAL;
696  }
697 
698  sync_config = &sc->sync_configs[sync_index];
699  sync_config->dir = dir;
700  sync_config->watchdog_mode = watchdog_mode;
701  return 0;
702 }
703 
704 /****************************************************************************/
705 
707  uint16_t divider, uint16_t intervals)
708 {
709  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, divider = %u, intervals = %u)\n",
710  __func__, sc, divider, intervals);
711 
712  sc->watchdog_divider = divider;
713  sc->watchdog_intervals = intervals;
714  return 0;
715 }
716 
717 /****************************************************************************/
718 
720  uint8_t sync_index, uint16_t pdo_index)
721 {
722  ec_pdo_t *pdo;
723 
724  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, sync_index = %u, "
725  "pdo_index = 0x%04X)\n", __func__, sc, sync_index, pdo_index);
726 
727  if (sync_index >= EC_MAX_SYNC_MANAGERS) {
728  EC_CONFIG_ERR(sc, "Invalid sync manager index %u!\n", sync_index);
729  return -EINVAL;
730  }
731 
732  down(&sc->master->master_sem);
733 
734  pdo = ec_pdo_list_add_pdo(&sc->sync_configs[sync_index].pdos, pdo_index);
735  if (IS_ERR(pdo)) {
736  up(&sc->master->master_sem);
737  return PTR_ERR(pdo);
738  }
739  pdo->sync_index = sync_index;
740 
742 
743  up(&sc->master->master_sem);
744  return 0;
745 }
746 
747 /****************************************************************************/
748 
750  uint8_t sync_index)
751 {
752  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, sync_index = %u)\n",
753  __func__, sc, sync_index);
754 
755  if (sync_index >= EC_MAX_SYNC_MANAGERS) {
756  EC_CONFIG_ERR(sc, "Invalid sync manager index %u!\n", sync_index);
757  return -EINVAL;
758  }
759 
760  down(&sc->master->master_sem);
761  ec_pdo_list_clear_pdos(&sc->sync_configs[sync_index].pdos);
762  up(&sc->master->master_sem);
763  return 0;
764 }
765 
766 /****************************************************************************/
767 
769  uint16_t pdo_index, uint16_t entry_index, uint8_t entry_subindex,
770  uint8_t entry_bit_length)
771 {
772  uint8_t sync_index;
773  ec_pdo_t *pdo = NULL;
774  ec_pdo_entry_t *entry;
775  int retval = 0;
776 
777  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, "
778  "pdo_index = 0x%04X, entry_index = 0x%04X, "
779  "entry_subindex = 0x%02X, entry_bit_length = %u)\n",
780  __func__, sc, pdo_index, entry_index, entry_subindex,
781  entry_bit_length);
782 
783  for (sync_index = 0; sync_index < EC_MAX_SYNC_MANAGERS; sync_index++)
784  if ((pdo = ec_pdo_list_find_pdo(
785  &sc->sync_configs[sync_index].pdos, pdo_index)))
786  break;
787 
788  if (pdo) {
789  down(&sc->master->master_sem);
790  entry = ec_pdo_add_entry(pdo, entry_index, entry_subindex,
791  entry_bit_length);
792  up(&sc->master->master_sem);
793  if (IS_ERR(entry))
794  retval = PTR_ERR(entry);
795  } else {
796  EC_CONFIG_ERR(sc, "PDO 0x%04X is not assigned.\n", pdo_index);
797  retval = -ENOENT;
798  }
799 
800  return retval;
801 }
802 
803 /****************************************************************************/
804 
806  uint16_t pdo_index)
807 {
808  uint8_t sync_index;
809  ec_pdo_t *pdo = NULL;
810 
811  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, pdo_index = 0x%04X)\n",
812  __func__, sc, pdo_index);
813 
814  for (sync_index = 0; sync_index < EC_MAX_SYNC_MANAGERS; sync_index++)
815  if ((pdo = ec_pdo_list_find_pdo(
816  &sc->sync_configs[sync_index].pdos, pdo_index)))
817  break;
818 
819  if (pdo) {
820  down(&sc->master->master_sem);
822  up(&sc->master->master_sem);
823  } else {
824  EC_CONFIG_WARN(sc, "PDO 0x%04X is not assigned.\n", pdo_index);
825  }
826  return 0;
827 }
828 
829 /****************************************************************************/
830 
832  unsigned int n_syncs, const ec_sync_info_t syncs[])
833 {
834  int ret;
835  unsigned int i, j, k;
836  const ec_sync_info_t *sync_info;
837  const ec_pdo_info_t *pdo_info;
838  const ec_pdo_entry_info_t *entry_info;
839 
840  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, n_syncs = %u, syncs = 0x%p)\n",
841  __func__, sc, n_syncs, syncs);
842 
843  if (!syncs)
844  return 0;
845 
846  for (i = 0; i < n_syncs; i++) {
847  sync_info = &syncs[i];
848 
849  if (sync_info->index == (uint8_t) EC_END)
850  break;
851 
852  if (sync_info->index >= EC_MAX_SYNC_MANAGERS) {
853  EC_CONFIG_ERR(sc, "Invalid sync manager index %u!\n",
854  sync_info->index);
855  return -ENOENT;
856  }
857 
858  ret = ecrt_slave_config_sync_manager(sc, sync_info->index,
859  sync_info->dir, sync_info->watchdog_mode);
860  if (ret)
861  return ret;
862 
864 
865  if (sync_info->n_pdos && sync_info->pdos) {
866 
867  for (j = 0; j < sync_info->n_pdos; j++) {
868  pdo_info = &sync_info->pdos[j];
869 
871  sc, sync_info->index, pdo_info->index);
872  if (ret)
873  return ret;
874 
876 
877  if (pdo_info->n_entries && pdo_info->entries) {
878  for (k = 0; k < pdo_info->n_entries; k++) {
879  entry_info = &pdo_info->entries[k];
880 
882  pdo_info->index, entry_info->index,
883  entry_info->subindex,
884  entry_info->bit_length);
885  if (ret)
886  return ret;
887  }
888  }
889  }
890  }
891  }
892 
893  return 0;
894 }
895 
896 /****************************************************************************/
897 
899  ec_slave_config_t *sc,
900  uint16_t index,
901  uint8_t subindex,
902  ec_domain_t *domain,
903  unsigned int *bit_position
904  )
905 {
906  uint8_t sync_index;
907  const ec_sync_config_t *sync_config;
908  unsigned int bit_offset, bit_pos;
909  ec_pdo_t *pdo;
910  ec_pdo_entry_t *entry;
911  int sync_offset;
912 
913  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
914  "subindex = 0x%02X, domain = 0x%p, bit_position = 0x%p)\n",
915  __func__, sc, index, subindex, domain, bit_position);
916 
917  for (sync_index = 0; sync_index < EC_MAX_SYNC_MANAGERS; sync_index++) {
918  sync_config = &sc->sync_configs[sync_index];
919  bit_offset = 0;
920 
921  list_for_each_entry(pdo, &sync_config->pdos.list, list) {
922  list_for_each_entry(entry, &pdo->entries, list) {
923  if (entry->index != index || entry->subindex != subindex) {
924  bit_offset += entry->bit_length;
925  } else {
926  bit_pos = bit_offset % 8;
927  if (bit_position) {
928  *bit_position = bit_pos;
929  } else if (bit_pos) {
930  EC_CONFIG_ERR(sc, "PDO entry 0x%04X:%02X does"
931  " not byte-align.\n", index, subindex);
932  return -EFAULT;
933  }
934 
935  sync_offset = ec_slave_config_prepare_fmmu(
936  sc, domain, sync_index, sync_config->dir);
937  if (sync_offset < 0)
938  return sync_offset;
939 
940  return sync_offset + bit_offset / 8;
941  }
942  }
943  }
944  }
945 
946  EC_CONFIG_ERR(sc, "PDO entry 0x%04X:%02X is not mapped.\n",
947  index, subindex);
948  return -ENOENT;
949 }
950 
951 /****************************************************************************/
952 
954  ec_slave_config_t *sc,
955  uint8_t sync_index,
956  unsigned int pdo_pos,
957  unsigned int entry_pos,
958  ec_domain_t *domain,
959  unsigned int *bit_position
960  )
961 {
962  const ec_sync_config_t *sync_config;
963  unsigned int bit_offset, pp, ep;
964  ec_pdo_t *pdo;
965  ec_pdo_entry_t *entry;
966 
967  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, sync_index = %u, pdo_pos = %u,"
968  " entry_pos = %u, domain = 0x%p, bit_position = 0x%p)\n",
969  __func__, sc, sync_index, pdo_pos, entry_pos,
970  domain, bit_position);
971 
972  if (sync_index >= EC_MAX_SYNC_MANAGERS) {
973  EC_CONFIG_ERR(sc, "Invalid syncmanager position %u.\n", sync_index);
974  return -EINVAL;
975  }
976 
977  sync_config = &sc->sync_configs[sync_index];
978  bit_offset = 0;
979  pp = 0;
980 
981  list_for_each_entry(pdo, &sync_config->pdos.list, list) {
982  ep = 0;
983  list_for_each_entry(entry, &pdo->entries, list) {
984  if (pp != pdo_pos || ep != entry_pos) {
985  bit_offset += entry->bit_length;
986  } else {
987  unsigned int bit_pos = bit_offset % 8;
988  int sync_offset;
989 
990  if (bit_position) {
991  *bit_position = bit_pos;
992  } else if (bit_pos) {
993  EC_CONFIG_ERR(sc, "PDO entry 0x%04X:%02X does"
994  " not byte-align.\n",
995  pdo->index, entry->subindex);
996  return -EFAULT;
997  }
998 
999  sync_offset = ec_slave_config_prepare_fmmu(
1000  sc, domain, sync_index, sync_config->dir);
1001  if (sync_offset < 0)
1002  return sync_offset;
1003 
1004  return sync_offset + bit_offset / 8;
1005  }
1006  ep++;
1007  }
1008  pp++;
1009  }
1010 
1011  EC_CONFIG_ERR(sc, "PDO entry specification %u/%u/%u out of range.\n",
1012  sync_index, pdo_pos, entry_pos);
1013  return -ENOENT;
1014 }
1015 
1016 /****************************************************************************/
1017 
1018 int ecrt_slave_config_dc(ec_slave_config_t *sc, uint16_t assign_activate,
1019  uint32_t sync0_cycle_time, int32_t sync0_shift_time,
1020  uint32_t sync1_cycle_time, int32_t sync1_shift_time)
1021 {
1022  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, assign_activate = 0x%04X,"
1023  " sync0_cycle = %u, sync0_shift = %i,"
1024  " sync1_cycle = %u, sync1_shift = %i\n",
1025  __func__, sc, assign_activate, sync0_cycle_time, sync0_shift_time,
1026  sync1_cycle_time, sync1_shift_time);
1027 
1028  sc->dc_assign_activate = assign_activate;
1029  sc->dc_sync[0].cycle_time = sync0_cycle_time;
1030  sc->dc_sync[0].shift_time = sync0_shift_time;
1031  sc->dc_sync[1].cycle_time = sync1_cycle_time;
1032  sc->dc_sync[1].shift_time = sync1_shift_time;
1033  return 0;
1034 }
1035 
1036 /****************************************************************************/
1037 
1039  uint8_t subindex, const uint8_t *data, size_t size)
1040 {
1041  ec_slave_t *slave = sc->slave;
1042  ec_sdo_request_t *req;
1043  int ret;
1044 
1045  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
1046  "subindex = 0x%02X, data = 0x%p, size = %zu)\n",
1047  __func__, sc, index, subindex, data, size);
1048 
1049  if (slave && !(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
1050  EC_CONFIG_WARN(sc, "Attached slave does not support CoE!\n");
1051  }
1052 
1053  if (!(req = (ec_sdo_request_t *)
1054  kmalloc(sizeof(ec_sdo_request_t), GFP_KERNEL))) {
1055  EC_CONFIG_ERR(sc, "Failed to allocate memory for"
1056  " SDO configuration!\n");
1057  return -ENOMEM;
1058  }
1059 
1060  ec_sdo_request_init(req);
1061  ecrt_sdo_request_index(req, index, subindex);
1062 
1063  ret = ec_sdo_request_copy_data(req, data, size);
1064  if (ret < 0) {
1065  ec_sdo_request_clear(req);
1066  kfree(req);
1067  return ret;
1068  }
1069 
1070  down(&sc->master->master_sem);
1071  list_add_tail(&req->list, &sc->sdo_configs);
1072  up(&sc->master->master_sem);
1073  return 0;
1074 }
1075 
1076 /****************************************************************************/
1077 
1079  uint8_t subindex, uint8_t value)
1080 {
1081  uint8_t data[1];
1082 
1083  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
1084  "subindex = 0x%02X, value = %u)\n",
1085  __func__, sc, index, subindex, (unsigned int) value);
1086 
1087  EC_WRITE_U8(data, value);
1088  return ecrt_slave_config_sdo(sc, index, subindex, data, 1);
1089 }
1090 
1091 /****************************************************************************/
1092 
1094  uint8_t subindex, uint16_t value)
1095 {
1096  uint8_t data[2];
1097 
1098  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
1099  "subindex = 0x%02X, value = %u)\n",
1100  __func__, sc, index, subindex, value);
1101 
1102  EC_WRITE_U16(data, value);
1103  return ecrt_slave_config_sdo(sc, index, subindex, data, 2);
1104 }
1105 
1106 /****************************************************************************/
1107 
1109  uint8_t subindex, uint32_t value)
1110 {
1111  uint8_t data[4];
1112 
1113  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
1114  "subindex = 0x%02X, value = %u)\n",
1115  __func__, sc, index, subindex, value);
1116 
1117  EC_WRITE_U32(data, value);
1118  return ecrt_slave_config_sdo(sc, index, subindex, data, 4);
1119 }
1120 
1121 /****************************************************************************/
1122 
1124  const uint8_t *data, size_t size)
1125 {
1126  ec_slave_t *slave = sc->slave;
1127  ec_sdo_request_t *req;
1128  int ret;
1129 
1130  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
1131  "data = 0x%p, size = %zu)\n", __func__, sc, index, data, size);
1132 
1133  if (slave && !(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
1134  EC_CONFIG_WARN(sc, "Attached slave does not support CoE!\n");
1135  }
1136 
1137  if (!(req = (ec_sdo_request_t *)
1138  kmalloc(sizeof(ec_sdo_request_t), GFP_KERNEL))) {
1139  EC_CONFIG_ERR(sc, "Failed to allocate memory for"
1140  " SDO configuration!\n");
1141  return -ENOMEM;
1142  }
1143 
1144  ec_sdo_request_init(req);
1145  ecrt_sdo_request_index(req, index, 0);
1146  req->complete_access = 1;
1147 
1148  ret = ec_sdo_request_copy_data(req, data, size);
1149  if (ret < 0) {
1150  ec_sdo_request_clear(req);
1151  kfree(req);
1152  return ret;
1153  }
1154 
1155  down(&sc->master->master_sem);
1156  list_add_tail(&req->list, &sc->sdo_configs);
1157  up(&sc->master->master_sem);
1158  return 0;
1159 }
1160 
1161 /****************************************************************************/
1162 
1164 {
1165  return ec_coe_emerg_ring_size(&sc->emerg_ring, elements);
1166 }
1167 
1168 /****************************************************************************/
1169 
1171 {
1172  return ec_coe_emerg_ring_pop(&sc->emerg_ring, target);
1173 }
1174 
1175 /****************************************************************************/
1176 
1178 {
1180 }
1181 
1182 /****************************************************************************/
1183 
1185 {
1187 }
1188 
1189 /****************************************************************************/
1190 
1195  ec_slave_config_t *sc, uint16_t index, uint8_t subindex, size_t size)
1196 {
1197  ec_sdo_request_t *req;
1198  int ret;
1199 
1200  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, "
1201  "index = 0x%04X, subindex = 0x%02X, size = %zu)\n",
1202  __func__, sc, index, subindex, size);
1203 
1204  if (!(req = (ec_sdo_request_t *)
1205  kmalloc(sizeof(ec_sdo_request_t), GFP_KERNEL))) {
1206  EC_CONFIG_ERR(sc, "Failed to allocate SDO request memory!\n");
1207  return ERR_PTR(-ENOMEM);
1208  }
1209 
1210  ec_sdo_request_init(req);
1211  ecrt_sdo_request_index(req, index, subindex);
1212 
1213  ret = ec_sdo_request_alloc(req, size);
1214  if (ret < 0) {
1215  ec_sdo_request_clear(req);
1216  kfree(req);
1217  return ERR_PTR(ret);
1218  }
1219 
1220  // prepare data for optional writing
1221  memset(req->data, 0x00, size);
1222  req->data_size = size;
1223 
1224  down(&sc->master->master_sem);
1225  list_add_tail(&req->list, &sc->sdo_requests);
1226  up(&sc->master->master_sem);
1227 
1228  return req;
1229 }
1230 
1231 /****************************************************************************/
1232 
1234  ec_slave_config_t *sc, uint16_t index, uint8_t subindex, size_t size)
1235 {
1237  subindex, size);
1238  return IS_ERR(s) ? NULL : s;
1239 }
1240 
1241 /****************************************************************************/
1242 
1247  ec_slave_config_t *sc, uint8_t drive_no, uint16_t idn, size_t size)
1248 {
1249  ec_soe_request_t *req;
1250  int ret;
1251 
1252  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, "
1253  "drive_no = 0x%02X, idn = 0x%04X, size = %zu)\n",
1254  __func__, sc, drive_no, idn, size);
1255 
1256  if (!(req = (ec_soe_request_t *)
1257  kmalloc(sizeof(ec_soe_request_t), GFP_KERNEL))) {
1258  EC_CONFIG_ERR(sc, "Failed to allocate IDN request memory!\n");
1259  return ERR_PTR(-ENOMEM);
1260  }
1261 
1262  ec_soe_request_init(req);
1263  ecrt_soe_request_idn(req, drive_no, idn);
1264 
1265  ret = ec_soe_request_alloc(req, size);
1266  if (ret < 0) {
1267  ec_soe_request_clear(req);
1268  kfree(req);
1269  return ERR_PTR(ret);
1270  }
1271 
1272  // prepare data for optional writing
1273  memset(req->data, 0x00, size);
1274  req->data_size = size;
1275 
1276  down(&sc->master->master_sem);
1277  list_add_tail(&req->list, &sc->soe_requests);
1278  up(&sc->master->master_sem);
1279 
1280  return req;
1281 }
1282 
1283 /****************************************************************************/
1284 
1286  ec_slave_config_t *sc, uint8_t drive_no, uint16_t idn, size_t size)
1287 {
1289  drive_no, idn, size);
1290  return IS_ERR(req) ? NULL : req;
1291 }
1292 
1293 /****************************************************************************/
1294 
1299  ec_slave_config_t *sc, size_t size)
1300 {
1301  ec_reg_request_t *reg;
1302  int ret;
1303 
1304  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, size = %zu)\n",
1305  __func__, sc, size);
1306 
1307  if (!(reg = (ec_reg_request_t *)
1308  kmalloc(sizeof(ec_reg_request_t), GFP_KERNEL))) {
1309  EC_CONFIG_ERR(sc, "Failed to allocate register request memory!\n");
1310  return ERR_PTR(-ENOMEM);
1311  }
1312 
1313  ret = ec_reg_request_init(reg, size);
1314  if (ret) {
1315  kfree(reg);
1316  return ERR_PTR(ret);
1317  }
1318 
1319  down(&sc->master->master_sem);
1320  list_add_tail(&reg->list, &sc->reg_requests);
1321  up(&sc->master->master_sem);
1322 
1323  return reg;
1324 }
1325 
1326 /****************************************************************************/
1327 
1329  ec_slave_config_t *sc, size_t size)
1330 {
1331  ec_reg_request_t *reg =
1333  return IS_ERR(reg) ? NULL : reg;
1334 }
1335 
1336 /****************************************************************************/
1337 
1342  ec_slave_config_t *sc, size_t size)
1343 {
1344  ec_voe_handler_t *voe;
1345  int ret;
1346 
1347  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, size = %zu)\n", __func__, sc, size);
1348 
1349  if (!(voe = (ec_voe_handler_t *)
1350  kmalloc(sizeof(ec_voe_handler_t), GFP_KERNEL))) {
1351  EC_CONFIG_ERR(sc, "Failed to allocate VoE request memory!\n");
1352  return ERR_PTR(-ENOMEM);
1353  }
1354 
1355  ret = ec_voe_handler_init(voe, sc, size);
1356  if (ret < 0) {
1357  kfree(voe);
1358  return ERR_PTR(ret);
1359  }
1360 
1361  down(&sc->master->master_sem);
1362  list_add_tail(&voe->list, &sc->voe_handlers);
1363  up(&sc->master->master_sem);
1364 
1365  return voe;
1366 }
1367 
1368 /****************************************************************************/
1369 
1371  ec_slave_config_t *sc, size_t size)
1372 {
1374  size);
1375  return IS_ERR(voe) ? NULL : voe;
1376 }
1377 
1378 /****************************************************************************/
1379 
1381  ec_slave_config_state_t *state)
1382 {
1383  const ec_slave_t *slave = sc->slave;
1384 
1385  state->online = slave ? 1 : 0;
1386  if (state->online) {
1387  state->operational =
1388  slave->current_state == EC_SLAVE_STATE_OP && !slave->force_config;
1389  state->al_state = slave->current_state;
1390  } else {
1391  state->operational = 0;
1393  }
1394  return 0;
1395 }
1396 
1397 /****************************************************************************/
1398 
1399 int ecrt_slave_config_idn(ec_slave_config_t *sc, uint8_t drive_no,
1400  uint16_t idn, ec_al_state_t state, const uint8_t *data,
1401  size_t size)
1402 {
1403  ec_slave_t *slave = sc->slave;
1404  ec_soe_request_t *req;
1405  int ret;
1406 
1407  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, drive_no = %u, idn = 0x%04X, "
1408  "state = %u, data = 0x%p, size = %zu)\n",
1409  __func__, sc, drive_no, idn, state, data, size);
1410 
1411  if (drive_no > 7) {
1412  EC_CONFIG_ERR(sc, "Invalid drive number %u!\n",
1413  (unsigned int) drive_no);
1414  return -EINVAL;
1415  }
1416 
1417  if (state != EC_AL_STATE_PREOP && state != EC_AL_STATE_SAFEOP) {
1418  EC_CONFIG_ERR(sc, "AL state for IDN config"
1419  " must be PREOP or SAFEOP!\n");
1420  return -EINVAL;
1421  }
1422 
1423  if (slave && !(slave->sii.mailbox_protocols & EC_MBOX_SOE)) {
1424  EC_CONFIG_WARN(sc, "Attached slave does not support SoE!\n");
1425  }
1426 
1427  if (!(req = (ec_soe_request_t *)
1428  kmalloc(sizeof(ec_soe_request_t), GFP_KERNEL))) {
1429  EC_CONFIG_ERR(sc, "Failed to allocate memory for"
1430  " IDN configuration!\n");
1431  return -ENOMEM;
1432  }
1433 
1434  ec_soe_request_init(req);
1435  ec_soe_request_set_drive_no(req, drive_no);
1436  ec_soe_request_set_idn(req, idn);
1437  req->al_state = state;
1438 
1439  ret = ec_soe_request_copy_data(req, data, size);
1440  if (ret < 0) {
1441  ec_soe_request_clear(req);
1442  kfree(req);
1443  return ret;
1444  }
1445 
1446  down(&sc->master->master_sem);
1447  list_add_tail(&req->list, &sc->soe_configs);
1448  up(&sc->master->master_sem);
1449  return 0;
1450 }
1451 
1452 /****************************************************************************/
1453 
1455  int32_t value)
1456 {
1457  ec_flag_t *flag;
1458 
1459  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, key = %s, value = %i)\n",
1460  __func__, sc, key, value);
1461 
1462 
1463  flag = ec_slave_config_find_flag(sc, key);
1464  if (flag) {
1465  flag->value = value; // overwrite value
1466  }
1467  else { // new flag
1468  int ret;
1469 
1470  if (!(flag = (ec_flag_t *) kmalloc(sizeof(ec_flag_t), GFP_KERNEL))) {
1471  EC_CONFIG_ERR(sc, "Failed to allocate memory for flag!\n");
1472  return -ENOMEM;
1473  }
1474 
1475  ret = ec_flag_init(flag, key, value);
1476  if (ret) {
1477  kfree(flag);
1478  return ret;
1479  }
1480 
1481  down(&sc->master->master_sem);
1482  list_add_tail(&flag->list, &sc->flags);
1483  up(&sc->master->master_sem);
1484  }
1485  return 0;
1486 }
1487 
1488 /****************************************************************************/
1489 
1490 #ifdef EC_EOE
1491 
1493  const unsigned char *mac_address)
1494 {
1495  memcpy(sc->eoe_ip_param_request.mac_address, mac_address, EC_ETH_ALEN);
1496  sc->eoe_ip_param_request.mac_address_included = 1;
1497  return 0;
1498 }
1499 
1500 /****************************************************************************/
1501 
1503  struct in_addr ip_address)
1504 {
1505  sc->eoe_ip_param_request.ip_address = ip_address;
1506  sc->eoe_ip_param_request.ip_address_included = 1;
1507  return 0;
1508 }
1509 
1510 /****************************************************************************/
1511 
1513  struct in_addr subnet_mask)
1514 {
1515  sc->eoe_ip_param_request.subnet_mask = subnet_mask;
1516  sc->eoe_ip_param_request.subnet_mask_included = 1;
1517  return 0;
1518 }
1519 
1520 /****************************************************************************/
1521 
1523  struct in_addr gateway_address)
1524 {
1525  sc->eoe_ip_param_request.gateway = gateway_address;
1526  sc->eoe_ip_param_request.gateway_included = 1;
1527  return 0;
1528 }
1529 
1530 /****************************************************************************/
1531 
1533  struct in_addr dns_address)
1534 {
1535  sc->eoe_ip_param_request.dns = dns_address;
1536  sc->eoe_ip_param_request.dns_included = 1;
1537  return 0;
1538 }
1539 
1540 /****************************************************************************/
1541 
1543  const char *name)
1544 {
1545  strncpy(sc->eoe_ip_param_request.name, name, EC_MAX_HOSTNAME_SIZE - 1);
1546  sc->eoe_ip_param_request.name_included = 1;
1547  return 0;
1548 }
1549 
1550 #endif
1551 
1552 /****************************************************************************/
1553 
1555  ec_al_state_t from, ec_al_state_t to, unsigned int timeout_ms)
1556 {
1557  ec_al_timeout_t *timeout;
1558  ec_slave_state_t from_state, to_state;
1559 
1560  if (from != EC_AL_STATE_INIT && from != EC_AL_STATE_PREOP &&
1561  from != EC_AL_STATE_SAFEOP && from != EC_AL_STATE_OP) {
1562  EC_CONFIG_ERR(sc, "Invalid from state %i.\n", from);
1563  return -EINVAL;
1564  }
1565  if (to != EC_AL_STATE_INIT && to != EC_AL_STATE_PREOP &&
1566  to != EC_AL_STATE_SAFEOP && to != EC_AL_STATE_OP) {
1567  EC_CONFIG_ERR(sc, "Invalid to state %i.\n", to);
1568  return -EINVAL;
1569  }
1570 
1571  from_state = (ec_slave_state_t) from;
1572  to_state = (ec_slave_state_t) to;
1573 
1574  /* try to find an already configured timeout. */
1575  list_for_each_entry(timeout, &sc->al_timeouts, list) {
1576  if (timeout->from == from_state && timeout->to == to_state) {
1577  if (timeout_ms == 0) {
1578  // delete configured value
1579  list_del(&timeout->list);
1580  kfree(timeout);
1581  return 0;
1582  }
1583  timeout->timeout_ms = timeout_ms;
1584  return 0;
1585  }
1586  }
1587 
1588  if (timeout_ms == 0) {
1589  return 0;
1590  }
1591 
1592  /* no timeout found. create one. */
1593  if (!(timeout = (ec_al_timeout_t *)
1594  kmalloc(sizeof(ec_al_timeout_t), GFP_KERNEL))) {
1595  EC_CONFIG_ERR(sc, "Failed to allocate memory for"
1596  " AL timeout configuration!\n");
1597  return -ENOMEM;
1598  }
1599 
1600  timeout->from = from_state;
1601  timeout->to = to_state;
1602  timeout->timeout_ms = timeout_ms;
1603 
1604  down(&sc->master->master_sem);
1605  list_add_tail(&timeout->list, &sc->al_timeouts);
1606  up(&sc->master->master_sem);
1607  return 0;
1608 }
1609 
1610 /****************************************************************************/
1611 
1614 EXPORT_SYMBOL(ecrt_slave_config_sync_manager);
1615 EXPORT_SYMBOL(ecrt_slave_config_watchdog);
1616 EXPORT_SYMBOL(ecrt_slave_config_pdo_assign_add);
1617 EXPORT_SYMBOL(ecrt_slave_config_pdo_assign_clear);
1618 EXPORT_SYMBOL(ecrt_slave_config_pdo_mapping_add);
1620 EXPORT_SYMBOL(ecrt_slave_config_pdos);
1621 EXPORT_SYMBOL(ecrt_slave_config_reg_pdo_entry);
1623 EXPORT_SYMBOL(ecrt_slave_config_dc);
1624 EXPORT_SYMBOL(ecrt_slave_config_sdo);
1625 EXPORT_SYMBOL(ecrt_slave_config_sdo8);
1626 EXPORT_SYMBOL(ecrt_slave_config_sdo16);
1627 EXPORT_SYMBOL(ecrt_slave_config_sdo32);
1628 EXPORT_SYMBOL(ecrt_slave_config_complete_sdo);
1629 EXPORT_SYMBOL(ecrt_slave_config_emerg_size);
1630 EXPORT_SYMBOL(ecrt_slave_config_emerg_pop);
1631 EXPORT_SYMBOL(ecrt_slave_config_emerg_clear);
1632 EXPORT_SYMBOL(ecrt_slave_config_emerg_overruns);
1637 EXPORT_SYMBOL(ecrt_slave_config_state);
1638 EXPORT_SYMBOL(ecrt_slave_config_idn);
1639 EXPORT_SYMBOL(ecrt_slave_config_flag);
1640 #ifdef EOE
1641 EXPORT_SYMBOL(ecrt_slave_config_eoe_mac_address);
1642 EXPORT_SYMBOL(ecrt_slave_config_eoe_ip_address);
1643 EXPORT_SYMBOL(ecrt_slave_config_eoe_subnet_mask);
1645 EXPORT_SYMBOL(ecrt_slave_config_eoe_dns_address);
1646 EXPORT_SYMBOL(ecrt_slave_config_eoe_hostname);
1647 #endif
1648 EXPORT_SYMBOL(ecrt_slave_config_state_timeout);
1649 
1652 /****************************************************************************/
unsigned int ec_slave_config_flag_count(const ec_slave_config_t *sc)
Get the number of feature flags.
Definition: slave_config.c:506
CANopen over EtherCAT.
Definition: globals.h:146
uint16_t ring_position
Ring position.
Definition: slave.h:175
Pre-operational.
Definition: ecrt.h:617
struct list_head sdo_configs
List of SDO configurations.
Definition: slave_config.h:136
void ec_soe_request_set_idn(ec_soe_request_t *req, uint16_t idn)
Set IDN.
Definition: soe_request.c:111
ec_sii_t sii
Extracted SII data.
Definition: slave.h:215
ec_reg_request_t * ec_slave_config_find_reg_request(ec_slave_config_t *sc, unsigned int pos)
Finds a register handler via its position in the list.
Definition: slave_config.c:594
void ec_slave_config_init(ec_slave_config_t *sc, ec_master_t *master, uint16_t alias, uint16_t position, uint32_t vendor_id, uint32_t product_code)
Slave configuration constructor.
Definition: slave_config.c:72
int ecrt_slave_config_pdo_assign_clear(ec_slave_config_t *sc, uint8_t sync_index)
Clear a sync manager&#39;s PDO assignment.
Definition: slave_config.c:749
unsigned int n_entries
Number of PDO entries in entries to map.
Definition: ecrt.h:547
FMMU configuration.
Definition: fmmu_config.h:38
uint8_t bit_length
Size of the PDO entry in bit.
Definition: ecrt.h:534
EtherCAT application-layer transition timeout.
Definition: slave_config.c:58
ec_direction_t dir
Sync manager direction.
Definition: ecrt.h:568
ec_watchdog_mode_t
Watchdog mode for sync manager configuration.
Definition: ecrt.h:517
const ec_soe_request_t * ec_slave_config_get_idn_by_pos_const(const ec_slave_config_t *sc, unsigned int pos)
Finds an IDN configuration via its position in the list.
Definition: slave_config.c:484
ec_sdo_request_t * ecrt_slave_config_create_sdo_request_err(ec_slave_config_t *sc, uint16_t index, uint8_t subindex, size_t size)
Same as ecrt_slave_config_create_sdo_request(), but with ERR_PTR() return value.
ec_pdo_info_t const * pdos
Array with PDOs to assign.
Definition: ecrt.h:570
int ecrt_slave_config_sdo32(ec_slave_config_t *sc, uint16_t index, uint8_t subindex, uint32_t value)
Add a configuration value for a 32-bit SDO.
ec_al_state_t
Application-layer state.
Definition: ecrt.h:615
unsigned int ec_slave_config_al_timeout(const ec_slave_config_t *sc, ec_slave_state_t from, ec_slave_state_t to)
Return an AL state timeout.
Definition: slave_config.c:661
int32_t shift_time
Shift time [ns].
Definition: globals.h:182
OP (mailbox communication and input/output update)
Definition: globals.h:132
ec_reg_request_t * reg_request
Register request to process.
Definition: fsm_slave.h:59
const ec_flag_t * ec_slave_config_get_flag_by_pos_const(const ec_slave_config_t *sc, unsigned int pos)
Finds a flag via its position in the list.
Definition: slave_config.c:528
ec_soe_request_t * ec_slave_config_find_soe_request(ec_slave_config_t *sc, unsigned int pos)
Finds a SoE request via its position in the list.
Definition: slave_config.c:572
int ec_pdo_list_copy(ec_pdo_list_t *pl, const ec_pdo_list_t *other)
Makes a deep copy of another PDO list.
Definition: pdo_list.c:169
int ecrt_slave_config_watchdog(ec_slave_config_t *sc, uint16_t divider, uint16_t intervals)
Configure a slave&#39;s watchdog times.
Definition: slave_config.c:706
CANopen SDO request.
Definition: sdo_request.h:40
ec_slave_state_t current_state
Current application state.
Definition: slave.h:184
int ecrt_slave_config_reg_pdo_entry(ec_slave_config_t *sc, uint16_t index, uint8_t subindex, ec_domain_t *domain, unsigned int *bit_position)
Registers a PDO entry for process data exchange in a domain.
Definition: slave_config.c:898
Operational.
Definition: ecrt.h:619
Register request.
Definition: reg_request.h:40
uint8_t used_fmmus
Number of FMMUs used.
Definition: slave_config.h:132
uint32_t product_code
Slave product code.
Definition: slave_config.h:119
Safe-operational.
Definition: ecrt.h:618
Servo-Profile over EtherCAT.
Definition: globals.h:148
uint16_t position
Index after alias.
Definition: slave_config.h:116
#define EC_SLAVE_WARN(slave, fmt, args...)
Convenience macro for printing slave-specific warnings to syslog.
Definition: slave.h:82
int ecrt_slave_config_sdo(ec_slave_config_t *sc, uint16_t index, uint8_t subindex, const uint8_t *data, size_t size)
Add an SDO configuration.
void ec_sync_config_clear(ec_sync_config_t *sync_config)
Destructor.
Definition: sync_config.c:48
const ec_sdo_request_t * ec_slave_config_get_sdo_by_pos_const(const ec_slave_config_t *sc, unsigned int pos)
Finds an SDO configuration via its position in the list.
Definition: slave_config.c:440
void ec_fmmu_config_init(ec_fmmu_config_t *fmmu, ec_slave_config_t *sc, ec_domain_t *domain, uint8_t sync_index, ec_direction_t dir)
FMMU configuration constructor.
Definition: fmmu_config.c:42
struct list_head list
List of PDOs.
Definition: pdo_list.h:42
int ecrt_slave_config_sync_manager(ec_slave_config_t *sc, uint8_t sync_index, ec_direction_t dir, ec_watchdog_mode_t watchdog_mode)
Configure a sync manager.
Definition: slave_config.c:679
ec_master_t * master
Master owning the slave configuration.
Definition: slave_config.h:113
int ec_reg_request_init(ec_reg_request_t *reg, size_t size)
Register request constructor.
Definition: reg_request.c:40
int ec_pdo_set_name(ec_pdo_t *pdo, const char *name)
Set PDO name.
Definition: pdo.c:117
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition: ecrt.h:3137
struct list_head list
List item.
Definition: flag.h:39
uint16_t alias
Slave alias.
Definition: slave_config.h:115
void ec_pdo_list_clear_pdos(ec_pdo_list_t *pl)
Clears the list of mapped PDOs.
Definition: pdo_list.c:62
ec_eoe_request_t eoe_ip_param_request
EoE IP parameters.
Definition: slave_config.h:146
void ec_pdo_clear_entries(ec_pdo_t *pdo)
Clear PDO entry list.
Definition: pdo.c:98
int ecrt_slave_config_emerg_overruns(const ec_slave_config_t *sc)
Read the number of CoE emergency overruns.
uint32_t cycle_time
Cycle time [ns].
Definition: globals.h:181
ec_fsm_slave_t fsm
Slave state machine.
Definition: slave.h:227
int ecrt_soe_request_idn(ec_soe_request_t *req, uint8_t drive_no, uint16_t idn)
Set the request&#39;s drive and Sercos ID numbers.
Definition: soe_request.c:268
int ecrt_slave_config_idn(ec_slave_config_t *sc, uint8_t drive_no, uint16_t idn, ec_al_state_t state, const uint8_t *data, size_t size)
Add an SoE IDN configuration.
PDO configuration information.
Definition: ecrt.h:545
#define EC_CONFIG_ERR(sc, fmt, args...)
Convenience macro for printing configuration-specific errors to syslog.
Definition: slave_config.h:68
int ecrt_slave_config_state_timeout(ec_slave_config_t *sc, ec_al_state_t from, ec_al_state_t to, unsigned int timeout_ms)
Sets the application-layer state transition timeout in ms.
uint8_t * data
Pointer to SDO data.
Definition: sdo_request.h:44
ec_slave_t * ec_master_find_slave(ec_master_t *master, uint16_t alias, uint16_t position)
Finds a slave in the bus, given the alias and position.
Definition: master.c:1825
Sync manager configuration information.
Definition: ecrt.h:564
int ecrt_slave_config_eoe_dns_address(ec_slave_config_t *sc, struct in_addr dns_address)
Sets the IPv4 address of the DNS server for Ethernet-over-EtherCAT (EoE) operation.
int ecrt_slave_config_reg_pdo_entry_pos(ec_slave_config_t *sc, uint8_t sync_index, unsigned int pdo_pos, unsigned int entry_pos, ec_domain_t *domain, unsigned int *bit_position)
Registers a PDO entry using its position.
Definition: slave_config.c:953
struct list_head list
List item.
Definition: voe_handler.h:42
#define EC_MAX_HOSTNAME_SIZE
Maximum hostname size.
Definition: globals.h:110
size_t data_size
Size of SDO data.
Definition: soe_request.h:47
void ec_eoe_request_init(ec_eoe_request_t *req)
EoE request constructor.
Definition: eoe_request.c:38
int ecrt_slave_config_sdo8(ec_slave_config_t *sc, uint16_t index, uint8_t subindex, uint8_t value)
Add a configuration value for an 8-bit SDO.
int ecrt_slave_config_state(const ec_slave_config_t *sc, ec_slave_config_state_t *state)
Outputs the state of the slave configuration.
ec_direction_t ec_sync_default_direction(const ec_sync_t *sync)
Determines the default direction from the control register.
Definition: sync.c:159
ec_voe_handler_t * ecrt_slave_config_create_voe_handler(ec_slave_config_t *sc, size_t size)
Create an VoE handler to exchange vendor-specific data during realtime operation. ...
unsigned int sync_count
Number of sync managers.
Definition: slave.h:158
char * key
Flag key (null-terminated ASCII string.
Definition: flag.h:40
#define EC_MAX_FMMUS
Maximum number of FMMUs per slave.
Definition: globals.h:92
Global definitions and macros.
ec_al_state_t al_state
AL state (only valid for IDN config).
Definition: soe_request.h:44
void ec_coe_emerg_ring_init(ec_coe_emerg_ring_t *ring, ec_slave_config_t *sc)
Emergency ring buffer constructor.
void ec_flag_clear(ec_flag_t *flag)
SDO request destructor.
Definition: flag.c:59
ec_sdo_request_t * ecrt_slave_config_create_sdo_request(ec_slave_config_t *sc, uint16_t index, uint8_t subindex, size_t size)
Create an SDO request to exchange SDOs during realtime operation.
PDO entry description.
Definition: pdo_entry.h:40
ec_pdo_entry_t * ec_pdo_add_entry(ec_pdo_t *pdo, uint16_t index, uint8_t subindex, uint8_t bit_length)
Add a new PDO entry to the configuration.
Definition: pdo.c:149
EtherCAT master structure.
ec_fmmu_config_t fmmu_configs[EC_MAX_FMMUS]
FMMU configurations.
Definition: slave_config.h:131
ec_sync_signal_t dc_sync[EC_SYNC_SIGNAL_COUNT]
DC sync signals.
Definition: slave_config.h:134
struct list_head al_timeouts
List of specific AL state timeouts.
Definition: slave_config.h:143
uint16_t index
PDO index.
Definition: pdo.h:43
int8_t sync_index
Assigned sync manager.
Definition: pdo.h:44
int ec_soe_request_copy_data(ec_soe_request_t *req, const uint8_t *source, size_t size)
Copies SoE data from an external source.
Definition: soe_request.c:173
int ec_slave_config_prepare_fmmu(ec_slave_config_t *, ec_domain_t *, uint8_t, ec_direction_t)
Prepares an FMMU configuration.
Definition: slave_config.c:216
uint16_t index
PDO index.
Definition: ecrt.h:546
int ecrt_slave_config_emerg_clear(ec_slave_config_t *sc)
Clears CoE emergency ring buffer and the overrun counter.
uint16_t index
PDO entry index.
Definition: pdo_entry.h:42
struct list_head flags
List of feature flags.
Definition: slave_config.h:142
EtherCAT slave.
Definition: slave.h:168
struct semaphore master_sem
Master semaphore.
Definition: master.h:198
uint32_t logical_start_address
Logical start address.
Definition: fmmu_config.h:44
void ec_slave_config_load_default_mapping(const ec_slave_config_t *, ec_pdo_t *)
Loads the default mapping for a PDO from the slave object.
Definition: slave_config.c:362
void ec_sdo_request_clear(ec_sdo_request_t *req)
SDO request destructor.
Definition: sdo_request.c:70
ec_voe_handler_t * ecrt_slave_config_create_voe_handler_err(ec_slave_config_t *sc, size_t size)
Same as ecrt_slave_config_create_voe_handler(), but with ERR_PTR() return value.
int ecrt_sdo_request_index(ec_sdo_request_t *req, uint16_t index, uint8_t subindex)
Set the SDO index and subindex.
Definition: sdo_request.c:181
const ec_domain_t * domain
Domain.
Definition: fmmu_config.h:41
int ec_sdo_request_copy_data(ec_sdo_request_t *req, const uint8_t *source, size_t size)
Copies SDO data from an external source.
Definition: sdo_request.c:150
Slave configuration state.
Definition: ecrt.h:376
ec_watchdog_mode_t watchdog_mode
Watchdog mode.
Definition: ecrt.h:572
ec_sync_config_t sync_configs[EC_MAX_SYNC_MANAGERS]
Sync manager configurations.
Definition: slave_config.h:129
unsigned int n_pdos
Number of PDOs in pdos.
Definition: ecrt.h:569
ec_slave_config_t * config
Current configuration.
Definition: slave.h:182
struct list_head reg_requests
List of register requests.
Definition: slave_config.h:140
#define EC_WRITE_U32(DATA, VAL)
Write a 32-bit unsigned value to EtherCAT data.
Definition: ecrt.h:3171
unsigned int al_state
The application-layer state of the slave.
Definition: ecrt.h:380
uint8_t sync_index
Index of sync manager to use.
Definition: fmmu_config.h:42
Slave configutation feature flag.
Definition: flag.h:38
void ec_soe_request_set_drive_no(ec_soe_request_t *req, uint8_t drive_no)
Set drive number.
Definition: soe_request.c:99
PDO description.
Definition: pdo.h:41
struct list_head sdo_requests
List of SDO requests.
Definition: slave_config.h:137
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:139
ec_flag_t * ec_slave_config_find_flag(ec_slave_config_t *sc, const char *key)
Finds a flag.
Definition: slave_config.c:638
ec_reg_request_t * ecrt_slave_config_create_reg_request_err(ec_slave_config_t *sc, size_t size)
Same as ecrt_slave_config_create_reg_request(), but with ERR_PTR() return value.
unsigned int debug_level
Master debug level.
Definition: master.h:275
uint8_t bit_length
entry length in bit
Definition: pdo_entry.h:45
Sync manager.
Definition: sync.h:39
struct list_head list
List item.
Definition: soe_request.h:41
unsigned int operational
The slave was brought into OP state using the specified configuration.
Definition: ecrt.h:378
int ec_coe_emerg_ring_clear_ring(ec_coe_emerg_ring_t *ring)
Clear the ring.
void ec_soe_request_clear(ec_soe_request_t *req)
SoE request destructor.
Definition: soe_request.c:71
EtherCAT Slave Configuration Feature Flag.
ec_pdo_list_t pdos
Current PDO assignment.
Definition: sync_config.h:41
struct list_head voe_handlers
List of VoE handlers.
Definition: slave_config.h:139
uint16_t dc_assign_activate
Vendor-specific AssignActivate word.
Definition: slave_config.h:133
#define EC_CONFIG_WARN(sc, fmt, args...)
Convenience macro for printing configuration-specific warnings to syslog.
Definition: slave_config.h:82
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition: ecrt.h:3154
#define EC_CONFIG_DBG(sc, level, fmt, args...)
Convenience macro for printing configuration-specific debug messages to syslog.
Definition: slave_config.h:99
ec_direction_t
Direction type for PDO assignment functions.
Definition: ecrt.h:504
EtherCAT EoE request structure.
struct list_head entries
List of PDO entries.
Definition: pdo.h:46
uint16_t watchdog_intervals
Process data watchdog intervals (see spec.
Definition: slave_config.h:123
int ecrt_slave_config_flag(ec_slave_config_t *sc, const char *key, int32_t value)
Adds a feature flag to a slave configuration.
Vendor specific over EtherCAT handler.
Definition: voe_handler.h:41
struct list_head soe_requests
List of SoE requests.
Definition: slave_config.h:138
unsigned int ec_slave_config_sdo_count(const ec_slave_config_t *sc)
Get the number of SDO configurations.
Definition: slave_config.c:418
ec_pdo_t * ec_pdo_list_add_pdo(ec_pdo_list_t *pl, uint16_t index)
Add a new PDO to the list.
Definition: pdo_list.c:109
ec_pdo_entry_info_t const * entries
Array of PDO entries to map.
Definition: ecrt.h:551
int ecrt_slave_config_pdo_assign_add(ec_slave_config_t *sc, uint8_t sync_index, uint16_t pdo_index)
Add a PDO to a sync manager&#39;s PDO assignment.
Definition: slave_config.c:719
ec_slave_state_t
State of an EtherCAT slave.
Definition: globals.h:121
int ecrt_slave_config_dc(ec_slave_config_t *sc, uint16_t assign_activate, uint32_t sync0_cycle_time, int32_t sync0_shift_time, uint32_t sync1_cycle_time, int32_t sync1_shift_time)
Configure distributed clocks.
ec_reg_request_t * ecrt_slave_config_create_reg_request(ec_slave_config_t *sc, size_t size)
Create a register request to exchange EtherCAT register contents during realtime operation.
int ecrt_slave_config_eoe_ip_address(ec_slave_config_t *sc, struct in_addr ip_address)
Sets the IP address for Ethernet-over-EtherCAT (EoE) operation.
uint8_t subindex
PDO entry subindex.
Definition: pdo_entry.h:43
Values read by the master.
Definition: ecrt.h:507
int ec_slave_config_attach(ec_slave_config_t *sc)
Attaches the configuration to the addressed slave object.
Definition: slave_config.c:254
ec_direction_t dir
Sync manager direction.
Definition: sync_config.h:39
int ec_voe_handler_init(ec_voe_handler_t *voe, ec_slave_config_t *sc, size_t size)
VoE handler constructor.
Definition: voe_handler.c:64
ec_slave_t * slave
Slave pointer.
Definition: slave_config.h:126
unsigned int online
The slave is online.
Definition: ecrt.h:377
uint16_t watchdog_divider
Watchdog divider as a number of 40ns intervals (see spec.
Definition: slave_config.h:121
ec_sdo_request_t * ec_slave_config_find_sdo_request(ec_slave_config_t *sc, unsigned int pos)
Finds a CoE SDO request via its position in the list.
Definition: slave_config.c:550
int ec_soe_request_alloc(ec_soe_request_t *req, size_t size)
Pre-allocates the data memory.
Definition: soe_request.c:144
struct list_head soe_configs
List of SoE configurations.
Definition: slave_config.h:141
int ecrt_slave_config_pdo_mapping_clear(ec_slave_config_t *sc, uint16_t pdo_index)
Clear the mapping of a given PDO.
Definition: slave_config.c:805
ec_watchdog_mode_t watchdog_mode
Watchdog mode.
Definition: sync_config.h:40
char * name
PDO name.
Definition: pdo.h:45
int ec_pdo_copy_entries(ec_pdo_t *pdo, const ec_pdo_t *other)
Copy PDO entries from another PDO.
Definition: pdo.c:178
unsigned int ec_slave_config_idn_count(const ec_slave_config_t *sc)
Get the number of IDN configurations.
Definition: slave_config.c:462
uint16_t index
PDO entry index.
Definition: ecrt.h:532
size_t data_size
Size of SDO data.
Definition: sdo_request.h:46
ec_soe_request_t * ecrt_slave_config_create_soe_request_err(ec_slave_config_t *sc, uint8_t drive_no, uint16_t idn, size_t size)
Same as ecrt_slave_config_create_soe_request(), but with ERR_PTR() return value.
#define EC_END
End of list marker.
Definition: ecrt.h:263
ec_coe_emerg_ring_t emerg_ring
CoE emergency ring buffer.
Definition: slave_config.h:149
int ecrt_slave_config_eoe_default_gateway(ec_slave_config_t *sc, struct in_addr gateway_address)
Sets the gateway address for Ethernet-over-EtherCAT (EoE) operation.
Invalid direction.
Definition: ecrt.h:505
Vendor specific over EtherCAT protocol handler.
void ec_sdo_request_init(ec_sdo_request_t *req)
SDO request constructor.
Definition: sdo_request.c:48
Sync manager configuration.
Definition: sync_config.h:38
int ecrt_slave_config_emerg_pop(ec_slave_config_t *sc, uint8_t *target)
Read and remove one record from the CoE emergency ring buffer.
ec_soe_request_t * ecrt_slave_config_create_soe_request(ec_slave_config_t *sc, uint8_t drive_no, uint16_t idn, size_t size)
Create an SoE request to exchange SoE IDNs during realtime operation.
int ecrt_slave_config_complete_sdo(ec_slave_config_t *sc, uint16_t index, const uint8_t *data, size_t size)
Add configuration data for a complete SDO.
struct list_head list
List item.
Definition: sdo_request.h:41
void ec_coe_emerg_ring_clear(ec_coe_emerg_ring_t *ring)
Emergency ring buffer destructor.
int ec_coe_emerg_ring_overruns(const ec_coe_emerg_ring_t *ring)
Read the number of overruns.
uint32_t vendor_id
Slave vendor ID.
Definition: slave_config.h:118
int ecrt_slave_config_pdos(ec_slave_config_t *sc, unsigned int n_syncs, const ec_sync_info_t syncs[])
Specify a complete PDO configuration.
Definition: slave_config.c:831
int ecrt_slave_config_eoe_hostname(ec_slave_config_t *sc, const char *name)
Sets the host name for Ethernet-over-EtherCAT (EoE) operation.
ec_pdo_list_t pdos
Current PDO assignment.
Definition: sync.h:45
int32_t value
Flag value (meaning depends on key).
Definition: flag.h:41
void ec_sync_config_init(ec_sync_config_t *sync_config)
Constructor.
Definition: sync_config.c:35
void ec_reg_request_clear(ec_reg_request_t *reg)
Register request destructor.
Definition: reg_request.c:65
EtherCAT slave configuration.
Definition: slave_config.h:111
void ec_soe_request_init(ec_soe_request_t *req)
SoE request constructor.
Definition: soe_request.c:48
EtherCAT master character device IOCTL commands.
EtherCAT slave configuration structure.
void ec_slave_config_detach(ec_slave_config_t *sc)
Detaches the configuration from a slave object.
Definition: slave_config.c:312
PDO entry configuration information.
Definition: ecrt.h:531
int ec_sdo_request_alloc(ec_sdo_request_t *req, size_t size)
Pre-allocates the data memory.
Definition: sdo_request.c:121
uint32_t product_code
Vendor-specific product code.
Definition: slave.h:128
uint8_t index
Sync manager index.
Definition: ecrt.h:565
void ec_slave_config_clear(ec_slave_config_t *sc)
Slave configuration destructor.
Definition: slave_config.c:126
Values written by the master.
Definition: ecrt.h:506
int ecrt_slave_config_eoe_mac_address(ec_slave_config_t *sc, const unsigned char *mac_address)
Sets the link/MAC address for Ethernet-over-EtherCAT (EoE) operation.
Init.
Definition: ecrt.h:616
int ecrt_slave_config_sdo16(ec_slave_config_t *sc, uint16_t index, uint8_t subindex, uint16_t value)
Add a configuration value for a 16-bit SDO.
int ecrt_slave_config_eoe_subnet_mask(ec_slave_config_t *sc, struct in_addr subnet_mask)
Sets the subnet mask for Ethernet-over-EtherCAT (EoE) operation.
ec_pdo_t * ec_pdo_list_find_pdo(const ec_pdo_list_t *pl, uint16_t index)
Finds a PDO with the given index.
Definition: pdo_list.c:235
int ecrt_slave_config_pdo_mapping_add(ec_slave_config_t *sc, uint16_t pdo_index, uint16_t entry_index, uint8_t entry_subindex, uint8_t entry_bit_length)
Add a PDO entry to the given PDO&#39;s mapping.
Definition: slave_config.c:768
int ecrt_slave_config_emerg_size(ec_slave_config_t *sc, size_t elements)
Set the size of the CoE emergency ring buffer.
ec_sync_t * syncs
SYNC MANAGER categories.
Definition: slave.h:157
EtherCAT master.
Definition: master.h:187
struct list_head list
List item.
Definition: reg_request.h:41
uint8_t subindex
PDO entry subindex.
Definition: ecrt.h:533
#define EC_MAX_SYNC_MANAGERS
Maximum number of sync managers per slave.
Definition: ecrt.h:267
void ec_slave_config_load_default_sync_config(ec_slave_config_t *sc)
Loads the default PDO assignment from the slave object.
Definition: slave_config.c:337
int ec_coe_emerg_ring_size(ec_coe_emerg_ring_t *ring, size_t size)
Set the ring size.
Sercos-over-EtherCAT request.
Definition: soe_request.h:40
uint8_t * data
Pointer to SDO data.
Definition: soe_request.h:45
unknown state
Definition: globals.h:122
EtherCAT domain.
Definition: domain.h:46
uint32_t vendor_id
Vendor ID.
Definition: slave.h:127
uint8_t complete_access
SDO shall be transferred completely.
Definition: sdo_request.h:47
int ec_coe_emerg_ring_pop(ec_coe_emerg_ring_t *ring, u8 *msg)
Remove an emergency message from the ring.
unsigned int force_config
Force (re-)configuration.
Definition: slave.h:186
ec_voe_handler_t * ec_slave_config_find_voe_handler(ec_slave_config_t *sc, unsigned int pos)
Finds a VoE handler via its position in the list.
Definition: slave_config.c:616
void ec_voe_handler_clear(ec_voe_handler_t *voe)
VoE handler destructor.
Definition: voe_handler.c:87
ec_sync_t * ec_slave_get_sync(ec_slave_t *slave, uint8_t sync_index)
Get the sync manager given an index.
Definition: slave.c:600
int ec_flag_init(ec_flag_t *flag, const char *key, int32_t value)
SDO request constructor.
Definition: flag.c:36