IgH EtherCAT Master  1.7.0
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 
94 
95  sc->slave = NULL;
96 
97  for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++)
99 
100  sc->used_fmmus = 0;
101  sc->dc_assign_activate = 0x0000;
102  sc->dc_sync[0].cycle_time = 0U;
103  sc->dc_sync[1].cycle_time = 0;
104  sc->dc_sync[0].shift_time = 0U;
105  sc->dc_sync[1].shift_time = 0;
106 
107  INIT_LIST_HEAD(&sc->sdo_configs);
108  INIT_LIST_HEAD(&sc->sdo_requests);
109  INIT_LIST_HEAD(&sc->soe_requests);
110  INIT_LIST_HEAD(&sc->reg_requests);
111  INIT_LIST_HEAD(&sc->voe_handlers);
112  INIT_LIST_HEAD(&sc->soe_configs);
113  INIT_LIST_HEAD(&sc->flags);
114  INIT_LIST_HEAD(&sc->al_timeouts);
115 
116 #ifdef EC_EOE
118 #endif
119 
121 }
122 
123 /****************************************************************************/
124 
130  ec_slave_config_t *sc
131  )
132 {
133  unsigned int i;
134  ec_sdo_request_t *req, *next_req;
135  ec_voe_handler_t *voe, *next_voe;
136  ec_reg_request_t *reg, *next_reg;
137  ec_soe_request_t *soe, *next_soe;
138  ec_flag_t *flag, *next_flag;
139  ec_al_timeout_t *timeout, *next_timeout;
140 
142 
143  // Free sync managers
144  for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++)
146 
147  // free all SDO configurations
148  list_for_each_entry_safe(req, next_req, &sc->sdo_configs, list) {
149  list_del(&req->list);
151  kfree(req);
152  }
153 
154  // free all SDO requests
155  list_for_each_entry_safe(req, next_req, &sc->sdo_requests, list) {
156  list_del(&req->list);
158  kfree(req);
159  }
160 
161  // free all SoE requests
162  list_for_each_entry_safe(soe, next_soe, &sc->soe_requests, list) {
163  list_del(&soe->list);
165  kfree(soe);
166  }
167 
168  // free all register requests
169  list_for_each_entry_safe(reg, next_reg, &sc->reg_requests, list) {
170  list_del(&reg->list);
172  kfree(reg);
173  }
174 
175  // free all VoE handlers
176  list_for_each_entry_safe(voe, next_voe, &sc->voe_handlers, list) {
177  list_del(&voe->list);
179  kfree(voe);
180  }
181 
182  // free all SoE configurations
183  list_for_each_entry_safe(soe, next_soe, &sc->soe_configs, list) {
184  list_del(&soe->list);
186  kfree(soe);
187  }
188 
189  // free all flags
190  list_for_each_entry_safe(flag, next_flag, &sc->flags, list) {
191  list_del(&flag->list);
192  ec_flag_clear(flag);
193  kfree(flag);
194  }
195 
196  // free all AL timeouts
197  list_for_each_entry_safe(timeout, next_timeout, &sc->al_timeouts, list) {
198  list_del(&timeout->list);
199  kfree(timeout);
200  }
201 
203 }
204 
205 /****************************************************************************/
206 
220  ec_slave_config_t *sc,
221  ec_domain_t *domain,
222  uint8_t sync_index,
223  ec_direction_t dir
224  )
225 {
226  unsigned int i;
227  ec_fmmu_config_t *fmmu;
228 
229  // FMMU configuration already prepared?
230  for (i = 0; i < sc->used_fmmus; i++) {
231  fmmu = &sc->fmmu_configs[i];
232  if (fmmu->domain == domain && fmmu->sync_index == sync_index)
233  return fmmu->logical_start_address;
234  }
235 
236  if (sc->used_fmmus == EC_MAX_FMMUS) {
237  EC_CONFIG_ERR(sc, "FMMU limit reached!\n");
238  return -EOVERFLOW;
239  }
240 
241  fmmu = &sc->fmmu_configs[sc->used_fmmus++];
242 
243  down(&sc->master->master_sem);
244  ec_fmmu_config_init(fmmu, sc, domain, sync_index, dir);
245  up(&sc->master->master_sem);
246 
247  return fmmu->logical_start_address;
248 }
249 
250 /****************************************************************************/
251 
258  ec_slave_config_t *sc
259  )
260 {
261  ec_slave_t *slave;
262 
263  if (sc->slave)
264  return 0; // already attached
265 
266  if (!(slave = ec_master_find_slave(
267  sc->master, sc->alias, sc->position))) {
268  EC_CONFIG_DBG(sc, 1, "Failed to find slave for configuration.\n");
269  return -ENOENT;
270  }
271 
272  if (slave->config) {
273  EC_CONFIG_DBG(sc, 1, "Failed to attach configuration. Slave %u"
274  " already has a configuration!\n", slave->ring_position);
275  return -EEXIST;
276  }
277 
278  if (
279 #ifdef EC_IDENT_WILDCARDS
280  sc->vendor_id != 0xffffffff &&
281 #endif
282  slave->sii.vendor_id != sc->vendor_id
283  ) {
284  EC_CONFIG_DBG(sc, 1, "Slave %u has no matching vendor ID (0x%08X)"
285  " for configuration (0x%08X).\n",
286  slave->ring_position, slave->sii.vendor_id, sc->vendor_id);
287  return -EINVAL;
288  }
289 
290  if (
291 #ifdef EC_IDENT_WILDCARDS
292  sc->product_code != 0xffffffff &&
293 #endif
294  slave->sii.product_code != sc->product_code
295  ) {
296  EC_CONFIG_DBG(sc, 1, "Slave %u has no matching product code (0x%08X)"
297  " for configuration (0x%08X).\n",
298  slave->ring_position, slave->sii.product_code,
299  sc->product_code);
300  return -EINVAL;
301  }
302 
303  // attach slave
304  slave->config = sc;
305  sc->slave = slave;
306 
307  EC_CONFIG_DBG(sc, 1, "Attached slave %u.\n", slave->ring_position);
308  return 0;
309 }
310 
311 /****************************************************************************/
312 
316  ec_slave_config_t *sc
317  )
318 {
319  if (sc->slave) {
320  ec_reg_request_t *reg;
321 
322  sc->slave->config = NULL;
323 
324  // invalidate processing register request
325  list_for_each_entry(reg, &sc->reg_requests, list) {
326  if (sc->slave->fsm.reg_request == reg) {
327  sc->slave->fsm.reg_request = NULL;
328  break;
329  }
330  }
331 
332  sc->slave = NULL;
333  }
334 }
335 
336 /****************************************************************************/
337 
341 {
342  uint8_t sync_index;
343  ec_sync_config_t *sync_config;
344  const ec_sync_t *sync;
345 
346  if (!sc->slave)
347  return;
348 
349  for (sync_index = 0; sync_index < EC_MAX_SYNC_MANAGERS; sync_index++) {
350  sync_config = &sc->sync_configs[sync_index];
351  if ((sync = ec_slave_get_sync(sc->slave, sync_index))) {
352  sync_config->dir = ec_sync_default_direction(sync);
353  if (sync_config->dir == EC_DIR_INVALID)
354  EC_SLAVE_WARN(sc->slave,
355  "SM%u has an invalid direction field!\n", sync_index);
356  ec_pdo_list_copy(&sync_config->pdos, &sync->pdos);
357  }
358  }
359 }
360 
361 /****************************************************************************/
362 
366  const ec_slave_config_t *sc,
367  ec_pdo_t *pdo
368  )
369 {
370  unsigned int i;
371  const ec_sync_t *sync;
372  const ec_pdo_t *default_pdo;
373 
374  if (!sc->slave)
375  return;
376 
377  EC_CONFIG_DBG(sc, 1, "Loading default mapping for PDO 0x%04X.\n",
378  pdo->index);
379 
380  // find PDO in any sync manager (it could be reassigned later)
381  for (i = 0; i < sc->slave->sii.sync_count; i++) {
382  sync = &sc->slave->sii.syncs[i];
383 
384  list_for_each_entry(default_pdo, &sync->pdos.list, list) {
385  if (default_pdo->index != pdo->index)
386  continue;
387 
388  if (default_pdo->name) {
389  EC_CONFIG_DBG(sc, 1, "Found PDO name \"%s\".\n",
390  default_pdo->name);
391 
392  // take PDO name from assigned one
393  ec_pdo_set_name(pdo, default_pdo->name);
394  }
395 
396  // copy entries (= default PDO mapping)
397  if (ec_pdo_copy_entries(pdo, default_pdo))
398  return;
399 
400  if (sc->master->debug_level) {
401  const ec_pdo_entry_t *entry;
402  list_for_each_entry(entry, &pdo->entries, list) {
403  EC_CONFIG_DBG(sc, 1, "Entry 0x%04X:%02X.\n",
404  entry->index, entry->subindex);
405  }
406  }
407 
408  return;
409  }
410  }
411 
412  EC_CONFIG_DBG(sc, 1, "No default mapping found.\n");
413 }
414 
415 /****************************************************************************/
416 
422  const ec_slave_config_t *sc
423  )
424 {
425  const ec_sdo_request_t *req;
426  unsigned int count = 0;
427 
428  list_for_each_entry(req, &sc->sdo_configs, list) {
429  count++;
430  }
431 
432  return count;
433 }
434 
435 /****************************************************************************/
436 
444  const ec_slave_config_t *sc,
445  unsigned int pos
446  )
447 {
448  const ec_sdo_request_t *req;
449 
450  list_for_each_entry(req, &sc->sdo_configs, list) {
451  if (pos--)
452  continue;
453  return req;
454  }
455 
456  return NULL;
457 }
458 
459 /****************************************************************************/
460 
466  const ec_slave_config_t *sc
467  )
468 {
469  const ec_soe_request_t *req;
470  unsigned int count = 0;
471 
472  list_for_each_entry(req, &sc->soe_configs, list) {
473  count++;
474  }
475 
476  return count;
477 }
478 
479 /****************************************************************************/
480 
488  const ec_slave_config_t *sc,
489  unsigned int pos
490  )
491 {
492  const ec_soe_request_t *req;
493 
494  list_for_each_entry(req, &sc->soe_configs, list) {
495  if (pos--)
496  continue;
497  return req;
498  }
499 
500  return NULL;
501 }
502 
503 /****************************************************************************/
504 
510  const ec_slave_config_t *sc
511  )
512 {
513  const ec_flag_t *flag;
514  unsigned int count = 0;
515 
516  list_for_each_entry(flag, &sc->flags, list) {
517  count++;
518  }
519 
520  return count;
521 }
522 
523 /****************************************************************************/
524 
532  const ec_slave_config_t *sc,
533  unsigned int pos
534  )
535 {
536  const ec_flag_t *flag;
537 
538  list_for_each_entry(flag, &sc->flags, list) {
539  if (pos--)
540  continue;
541  return flag;
542  }
543 
544  return NULL;
545 }
546 
547 /****************************************************************************/
548 
554  ec_slave_config_t *sc,
555  unsigned int pos
556  )
557 {
558  ec_sdo_request_t *req;
559 
560  list_for_each_entry(req, &sc->sdo_requests, list) {
561  if (pos--)
562  continue;
563  return req;
564  }
565 
566  return NULL;
567 }
568 
569 /****************************************************************************/
570 
576  ec_slave_config_t *sc,
577  unsigned int pos
578  )
579 {
580  ec_soe_request_t *req;
581 
582  list_for_each_entry(req, &sc->soe_requests, list) {
583  if (pos--)
584  continue;
585  return req;
586  }
587 
588  return NULL;
589 }
590 
591 /****************************************************************************/
592 
598  ec_slave_config_t *sc,
599  unsigned int pos
600  )
601 {
602  ec_reg_request_t *reg;
603 
604  list_for_each_entry(reg, &sc->reg_requests, list) {
605  if (pos--)
606  continue;
607  return reg;
608  }
609 
610  return NULL;
611 }
612 
613 /****************************************************************************/
614 
620  ec_slave_config_t *sc,
621  unsigned int pos
622  )
623 {
624  ec_voe_handler_t *voe;
625 
626  list_for_each_entry(voe, &sc->voe_handlers, list) {
627  if (pos--)
628  continue;
629  return voe;
630  }
631 
632  return NULL;
633 }
634 
635 /****************************************************************************/
636 
642  ec_slave_config_t *sc,
643  const char *key
644  )
645 {
646  if (sc) {
647  ec_flag_t *flag;
648  list_for_each_entry(flag, &sc->flags, list) {
649  if (!strcmp(flag->key, key)) {
650  return flag;
651  }
652  }
653  }
654 
655  return NULL;
656 }
657 
658 /****************************************************************************/
659 
666 {
667  ec_al_timeout_t *timeout;
668 
669  list_for_each_entry(timeout, &sc->al_timeouts, list) {
670  if (timeout->from == from && timeout->to == to) {
671  return timeout->timeout_ms;
672  }
673  }
674 
675  return 0;
676 }
677 
678 /*****************************************************************************
679  * Application interface
680  ****************************************************************************/
681 
683  ec_direction_t dir, ec_watchdog_mode_t watchdog_mode)
684 {
685  ec_sync_config_t *sync_config;
686 
687  EC_CONFIG_DBG(sc, 1, "ecrt_slave_config_sync_manager(sc = 0x%p,"
688  " sync_index = %u, dir = %i, watchdog_mode = %i)\n",
689  sc, sync_index, dir, watchdog_mode);
690 
691  if (sync_index >= EC_MAX_SYNC_MANAGERS) {
692  EC_CONFIG_ERR(sc, "Invalid sync manager index %u!\n", sync_index);
693  return -ENOENT;
694  }
695 
696  if (dir != EC_DIR_OUTPUT && dir != EC_DIR_INPUT) {
697  EC_CONFIG_ERR(sc, "Invalid direction %u!\n", (unsigned int) dir);
698  return -EINVAL;
699  }
700 
701  sync_config = &sc->sync_configs[sync_index];
702  sync_config->dir = dir;
703  sync_config->watchdog_mode = watchdog_mode;
704  return 0;
705 }
706 
707 /****************************************************************************/
708 
710  uint16_t divider, uint16_t intervals)
711 {
712  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, divider = %u, intervals = %u)\n",
713  __func__, sc, divider, intervals);
714 
715  sc->watchdog_divider = divider;
716  sc->watchdog_intervals = intervals;
717  return 0;
718 }
719 
720 /****************************************************************************/
721 
723  ec_pdo_mode_t assign_mode, ec_pdo_mode_t config_mode)
724 {
725  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, assign_mode = %u,"
726  " config_mode = %u)\n", __func__, sc, assign_mode, config_mode);
727 
728  if (assign_mode > EC_PDO_MODE_WRITE_IF_DIFFERENT) {
729  EC_CONFIG_ERR(sc, "Invalid PDO assignment mode %u!\n", assign_mode);
730  return -EINVAL;
731  }
732 
733  if (config_mode > EC_PDO_MODE_WRITE_IF_DIFFERENT) {
734  EC_CONFIG_ERR(sc, "Invalid PDO configuration mode %u!\n",
735  config_mode);
736  return -EINVAL;
737  }
738 
739  sc->pdo_assign_mode = assign_mode;
740  sc->pdo_config_mode = config_mode;
741  return 0;
742 }
743 
744 /****************************************************************************/
745 
747  uint8_t sync_index, uint16_t pdo_index)
748 {
749  ec_pdo_t *pdo;
750 
751  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, sync_index = %u, "
752  "pdo_index = 0x%04X)\n", __func__, sc, sync_index, pdo_index);
753 
754  if (sync_index >= EC_MAX_SYNC_MANAGERS) {
755  EC_CONFIG_ERR(sc, "Invalid sync manager index %u!\n", sync_index);
756  return -EINVAL;
757  }
758 
759  down(&sc->master->master_sem);
760 
761  pdo = ec_pdo_list_add_pdo(&sc->sync_configs[sync_index].pdos, pdo_index);
762  if (IS_ERR(pdo)) {
763  up(&sc->master->master_sem);
764  return PTR_ERR(pdo);
765  }
766  pdo->sync_index = sync_index;
767 
769 
770  up(&sc->master->master_sem);
771  return 0;
772 }
773 
774 /****************************************************************************/
775 
777  uint8_t sync_index)
778 {
779  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, sync_index = %u)\n",
780  __func__, sc, sync_index);
781 
782  if (sync_index >= EC_MAX_SYNC_MANAGERS) {
783  EC_CONFIG_ERR(sc, "Invalid sync manager index %u!\n", sync_index);
784  return -EINVAL;
785  }
786 
787  down(&sc->master->master_sem);
788  ec_pdo_list_clear_pdos(&sc->sync_configs[sync_index].pdos);
789  up(&sc->master->master_sem);
790  return 0;
791 }
792 
793 /****************************************************************************/
794 
796  uint16_t pdo_index, uint16_t entry_index, uint8_t entry_subindex,
797  uint8_t entry_bit_length)
798 {
799  uint8_t sync_index;
800  ec_pdo_t *pdo = NULL;
801  ec_pdo_entry_t *entry;
802  int retval = 0;
803 
804  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, "
805  "pdo_index = 0x%04X, entry_index = 0x%04X, "
806  "entry_subindex = 0x%02X, entry_bit_length = %u)\n",
807  __func__, sc, pdo_index, entry_index, entry_subindex,
808  entry_bit_length);
809 
810  for (sync_index = 0; sync_index < EC_MAX_SYNC_MANAGERS; sync_index++)
811  if ((pdo = ec_pdo_list_find_pdo(
812  &sc->sync_configs[sync_index].pdos, pdo_index)))
813  break;
814 
815  if (pdo) {
816  down(&sc->master->master_sem);
817  entry = ec_pdo_add_entry(pdo, entry_index, entry_subindex,
818  entry_bit_length);
819  up(&sc->master->master_sem);
820  if (IS_ERR(entry))
821  retval = PTR_ERR(entry);
822  } else {
823  EC_CONFIG_ERR(sc, "PDO 0x%04X is not assigned.\n", pdo_index);
824  retval = -ENOENT;
825  }
826 
827  return retval;
828 }
829 
830 /****************************************************************************/
831 
833  uint16_t pdo_index)
834 {
835  uint8_t sync_index;
836  ec_pdo_t *pdo = NULL;
837 
838  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, pdo_index = 0x%04X)\n",
839  __func__, sc, pdo_index);
840 
841  for (sync_index = 0; sync_index < EC_MAX_SYNC_MANAGERS; sync_index++)
842  if ((pdo = ec_pdo_list_find_pdo(
843  &sc->sync_configs[sync_index].pdos, pdo_index)))
844  break;
845 
846  if (pdo) {
847  down(&sc->master->master_sem);
849  up(&sc->master->master_sem);
850  } else {
851  EC_CONFIG_WARN(sc, "PDO 0x%04X is not assigned.\n", pdo_index);
852  }
853  return 0;
854 }
855 
856 /****************************************************************************/
857 
859  unsigned int n_syncs, const ec_sync_info_t syncs[])
860 {
861  int ret;
862  unsigned int i, j, k;
863  const ec_sync_info_t *sync_info;
864  const ec_pdo_info_t *pdo_info;
865  const ec_pdo_entry_info_t *entry_info;
866 
867  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, n_syncs = %u, syncs = 0x%p)\n",
868  __func__, sc, n_syncs, syncs);
869 
870  if (!syncs)
871  return 0;
872 
873  for (i = 0; i < n_syncs; i++) {
874  sync_info = &syncs[i];
875 
876  if (sync_info->index == (uint8_t) EC_END)
877  break;
878 
879  if (sync_info->index >= EC_MAX_SYNC_MANAGERS) {
880  EC_CONFIG_ERR(sc, "Invalid sync manager index %u!\n",
881  sync_info->index);
882  return -ENOENT;
883  }
884 
885  ret = ecrt_slave_config_sync_manager(sc, sync_info->index,
886  sync_info->dir, sync_info->watchdog_mode);
887  if (ret)
888  return ret;
889 
891 
892  if (sync_info->n_pdos && sync_info->pdos) {
893  for (j = 0; j < sync_info->n_pdos; j++) {
894  pdo_info = &sync_info->pdos[j];
895 
897  sc, sync_info->index, pdo_info->index);
898  if (ret)
899  return ret;
900 
902 
903  if (pdo_info->n_entries && pdo_info->entries) {
904  for (k = 0; k < pdo_info->n_entries; k++) {
905  entry_info = &pdo_info->entries[k];
906 
908  pdo_info->index, entry_info->index,
909  entry_info->subindex,
910  entry_info->bit_length);
911  if (ret)
912  return ret;
913  }
914  }
915  }
916  }
917  }
918 
919  return 0;
920 }
921 
922 /****************************************************************************/
923 
925  ec_slave_config_t *sc,
926  uint16_t index,
927  uint8_t subindex,
928  ec_domain_t *domain,
929  unsigned int *bit_position
930  )
931 {
932  uint8_t sync_index;
933  const ec_sync_config_t *sync_config;
934  unsigned int bit_offset, bit_pos;
935  ec_pdo_t *pdo;
936  ec_pdo_entry_t *entry;
937  int sync_offset;
938 
939  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
940  "subindex = 0x%02X, domain = 0x%p, bit_position = 0x%p)\n",
941  __func__, sc, index, subindex, domain, bit_position);
942 
943  for (sync_index = 0; sync_index < EC_MAX_SYNC_MANAGERS; sync_index++) {
944  sync_config = &sc->sync_configs[sync_index];
945  bit_offset = 0;
946 
947  list_for_each_entry(pdo, &sync_config->pdos.list, list) {
948  list_for_each_entry(entry, &pdo->entries, list) {
949  if (entry->index != index || entry->subindex != subindex) {
950  bit_offset += entry->bit_length;
951  } else {
952  bit_pos = bit_offset % 8;
953  if (bit_position) {
954  *bit_position = bit_pos;
955  } else if (bit_pos) {
956  EC_CONFIG_ERR(sc, "PDO entry 0x%04X:%02X does"
957  " not byte-align.\n", index, subindex);
958  return -EFAULT;
959  }
960 
961  sync_offset = ec_slave_config_prepare_fmmu(
962  sc, domain, sync_index, sync_config->dir);
963  if (sync_offset < 0)
964  return sync_offset;
965 
966  return sync_offset + bit_offset / 8;
967  }
968  }
969  }
970  }
971 
972  EC_CONFIG_ERR(sc, "PDO entry 0x%04X:%02X is not mapped.\n",
973  index, subindex);
974  return -ENOENT;
975 }
976 
977 /****************************************************************************/
978 
980  ec_slave_config_t *sc,
981  uint8_t sync_index,
982  unsigned int pdo_pos,
983  unsigned int entry_pos,
984  ec_domain_t *domain,
985  unsigned int *bit_position
986  )
987 {
988  const ec_sync_config_t *sync_config;
989  unsigned int bit_offset, pp, ep;
990  ec_pdo_t *pdo;
991  ec_pdo_entry_t *entry;
992 
993  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, sync_index = %u, pdo_pos = %u,"
994  " entry_pos = %u, domain = 0x%p, bit_position = 0x%p)\n",
995  __func__, sc, sync_index, pdo_pos, entry_pos,
996  domain, bit_position);
997 
998  if (sync_index >= EC_MAX_SYNC_MANAGERS) {
999  EC_CONFIG_ERR(sc, "Invalid syncmanager position %u.\n", sync_index);
1000  return -EINVAL;
1001  }
1002 
1003  sync_config = &sc->sync_configs[sync_index];
1004  bit_offset = 0;
1005  pp = 0;
1006 
1007  list_for_each_entry(pdo, &sync_config->pdos.list, list) {
1008  ep = 0;
1009  list_for_each_entry(entry, &pdo->entries, list) {
1010  if (pp != pdo_pos || ep != entry_pos) {
1011  bit_offset += entry->bit_length;
1012  } else {
1013  unsigned int bit_pos = bit_offset % 8;
1014  int sync_offset;
1015 
1016  if (bit_position) {
1017  *bit_position = bit_pos;
1018  } else if (bit_pos) {
1019  EC_CONFIG_ERR(sc, "PDO entry 0x%04X:%02X does"
1020  " not byte-align.\n",
1021  pdo->index, entry->subindex);
1022  return -EFAULT;
1023  }
1024 
1025  sync_offset = ec_slave_config_prepare_fmmu(
1026  sc, domain, sync_index, sync_config->dir);
1027  if (sync_offset < 0)
1028  return sync_offset;
1029 
1030  return sync_offset + bit_offset / 8;
1031  }
1032  ep++;
1033  }
1034  pp++;
1035  }
1036 
1037  EC_CONFIG_ERR(sc, "PDO entry specification %u/%u/%u out of range.\n",
1038  sync_index, pdo_pos, entry_pos);
1039  return -ENOENT;
1040 }
1041 
1042 /****************************************************************************/
1043 
1044 int ecrt_slave_config_dc(ec_slave_config_t *sc, uint16_t assign_activate,
1045  uint32_t sync0_cycle_time, int32_t sync0_shift_time,
1046  uint32_t sync1_cycle_time, int32_t sync1_shift_time)
1047 {
1048  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, assign_activate = 0x%04X,"
1049  " sync0_cycle = %u, sync0_shift = %i,"
1050  " sync1_cycle = %u, sync1_shift = %i\n",
1051  __func__, sc, assign_activate, sync0_cycle_time, sync0_shift_time,
1052  sync1_cycle_time, sync1_shift_time);
1053 
1054  sc->dc_assign_activate = assign_activate;
1055  sc->dc_sync[0].cycle_time = sync0_cycle_time;
1056  sc->dc_sync[0].shift_time = sync0_shift_time;
1057  sc->dc_sync[1].cycle_time = sync1_cycle_time;
1058  sc->dc_sync[1].shift_time = sync1_shift_time;
1059  return 0;
1060 }
1061 
1062 /****************************************************************************/
1063 
1065  uint8_t subindex, const uint8_t *data, size_t size)
1066 {
1067  ec_slave_t *slave = sc->slave;
1068  ec_sdo_request_t *req;
1069  int ret;
1070 
1071  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
1072  "subindex = 0x%02X, data = 0x%p, size = %zu)\n",
1073  __func__, sc, index, subindex, data, size);
1074 
1075  if (slave && !(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
1076  EC_CONFIG_WARN(sc, "Attached slave does not support CoE!\n");
1077  }
1078 
1079  if (!(req = (ec_sdo_request_t *)
1080  kmalloc(sizeof(ec_sdo_request_t), GFP_KERNEL))) {
1081  EC_CONFIG_ERR(sc, "Failed to allocate memory for"
1082  " SDO configuration!\n");
1083  return -ENOMEM;
1084  }
1085 
1086  ec_sdo_request_init(req);
1087  ecrt_sdo_request_index(req, index, subindex);
1088 
1089  ret = ec_sdo_request_copy_data(req, data, size);
1090  if (ret < 0) {
1091  ec_sdo_request_clear(req);
1092  kfree(req);
1093  return ret;
1094  }
1095 
1096  down(&sc->master->master_sem);
1097  list_add_tail(&req->list, &sc->sdo_configs);
1098  up(&sc->master->master_sem);
1099  return 0;
1100 }
1101 
1102 /****************************************************************************/
1103 
1105  uint8_t subindex, uint8_t value)
1106 {
1107  uint8_t data[1];
1108 
1109  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
1110  "subindex = 0x%02X, value = %u)\n",
1111  __func__, sc, index, subindex, (unsigned int) value);
1112 
1113  EC_WRITE_U8(data, value);
1114  return ecrt_slave_config_sdo(sc, index, subindex, data, 1);
1115 }
1116 
1117 /****************************************************************************/
1118 
1120  uint8_t subindex, uint16_t value)
1121 {
1122  uint8_t data[2];
1123 
1124  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
1125  "subindex = 0x%02X, value = %u)\n",
1126  __func__, sc, index, subindex, value);
1127 
1128  EC_WRITE_U16(data, value);
1129  return ecrt_slave_config_sdo(sc, index, subindex, data, 2);
1130 }
1131 
1132 /****************************************************************************/
1133 
1135  uint8_t subindex, uint32_t value)
1136 {
1137  uint8_t data[4];
1138 
1139  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
1140  "subindex = 0x%02X, value = %u)\n",
1141  __func__, sc, index, subindex, value);
1142 
1143  EC_WRITE_U32(data, value);
1144  return ecrt_slave_config_sdo(sc, index, subindex, data, 4);
1145 }
1146 
1147 /****************************************************************************/
1148 
1150  const uint8_t *data, size_t size)
1151 {
1152  ec_slave_t *slave = sc->slave;
1153  ec_sdo_request_t *req;
1154  int ret;
1155 
1156  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
1157  "data = 0x%p, size = %zu)\n", __func__, sc, index, data, size);
1158 
1159  if (slave && !(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
1160  EC_CONFIG_WARN(sc, "Attached slave does not support CoE!\n");
1161  }
1162 
1163  if (!(req = (ec_sdo_request_t *)
1164  kmalloc(sizeof(ec_sdo_request_t), GFP_KERNEL))) {
1165  EC_CONFIG_ERR(sc, "Failed to allocate memory for"
1166  " SDO configuration!\n");
1167  return -ENOMEM;
1168  }
1169 
1170  ec_sdo_request_init(req);
1171  ecrt_sdo_request_index(req, index, 0);
1172  req->complete_access = 1;
1173 
1174  ret = ec_sdo_request_copy_data(req, data, size);
1175  if (ret < 0) {
1176  ec_sdo_request_clear(req);
1177  kfree(req);
1178  return ret;
1179  }
1180 
1181  down(&sc->master->master_sem);
1182  list_add_tail(&req->list, &sc->sdo_configs);
1183  up(&sc->master->master_sem);
1184  return 0;
1185 }
1186 
1187 /****************************************************************************/
1188 
1190 {
1191  return ec_coe_emerg_ring_size(&sc->emerg_ring, elements);
1192 }
1193 
1194 /****************************************************************************/
1195 
1197 {
1198  return ec_coe_emerg_ring_pop(&sc->emerg_ring, target);
1199 }
1200 
1201 /****************************************************************************/
1202 
1204 {
1206 }
1207 
1208 /****************************************************************************/
1209 
1211 {
1213 }
1214 
1215 /****************************************************************************/
1216 
1221  ec_slave_config_t *sc, uint16_t index, uint8_t subindex, size_t size)
1222 {
1223  ec_sdo_request_t *req;
1224  int ret;
1225 
1226  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, "
1227  "index = 0x%04X, subindex = 0x%02X, size = %zu)\n",
1228  __func__, sc, index, subindex, size);
1229 
1230  if (!(req = (ec_sdo_request_t *)
1231  kmalloc(sizeof(ec_sdo_request_t), GFP_KERNEL))) {
1232  EC_CONFIG_ERR(sc, "Failed to allocate SDO request memory!\n");
1233  return ERR_PTR(-ENOMEM);
1234  }
1235 
1236  ec_sdo_request_init(req);
1237  ecrt_sdo_request_index(req, index, subindex);
1238 
1239  ret = ec_sdo_request_alloc(req, size);
1240  if (ret < 0) {
1241  ec_sdo_request_clear(req);
1242  kfree(req);
1243  return ERR_PTR(ret);
1244  }
1245 
1246  // prepare data for optional writing
1247  memset(req->data, 0x00, size);
1248  req->data_size = size;
1249 
1250  down(&sc->master->master_sem);
1251  list_add_tail(&req->list, &sc->sdo_requests);
1252  up(&sc->master->master_sem);
1253 
1254  return req;
1255 }
1256 
1257 /****************************************************************************/
1258 
1260  ec_slave_config_t *sc, uint16_t index, uint8_t subindex, size_t size)
1261 {
1263  subindex, size);
1264  return IS_ERR(s) ? NULL : s;
1265 }
1266 
1267 /****************************************************************************/
1268 
1273  ec_slave_config_t *sc, uint8_t drive_no, uint16_t idn, size_t size)
1274 {
1275  ec_soe_request_t *req;
1276  int ret;
1277 
1278  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, "
1279  "drive_no = 0x%02X, idn = 0x%04X, size = %zu)\n",
1280  __func__, sc, drive_no, idn, size);
1281 
1282  if (!(req = (ec_soe_request_t *)
1283  kmalloc(sizeof(ec_soe_request_t), GFP_KERNEL))) {
1284  EC_CONFIG_ERR(sc, "Failed to allocate IDN request memory!\n");
1285  return ERR_PTR(-ENOMEM);
1286  }
1287 
1288  ec_soe_request_init(req);
1289  ecrt_soe_request_idn(req, drive_no, idn);
1290 
1291  ret = ec_soe_request_alloc(req, size);
1292  if (ret < 0) {
1293  ec_soe_request_clear(req);
1294  kfree(req);
1295  return ERR_PTR(ret);
1296  }
1297 
1298  // prepare data for optional writing
1299  memset(req->data, 0x00, size);
1300  req->data_size = size;
1301 
1302  down(&sc->master->master_sem);
1303  list_add_tail(&req->list, &sc->soe_requests);
1304  up(&sc->master->master_sem);
1305 
1306  return req;
1307 }
1308 
1309 /****************************************************************************/
1310 
1312  ec_slave_config_t *sc, uint8_t drive_no, uint16_t idn, size_t size)
1313 {
1315  drive_no, idn, size);
1316  return IS_ERR(req) ? NULL : req;
1317 }
1318 
1319 /****************************************************************************/
1320 
1325  ec_slave_config_t *sc, size_t size)
1326 {
1327  ec_reg_request_t *reg;
1328  int ret;
1329 
1330  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, size = %zu)\n",
1331  __func__, sc, size);
1332 
1333  if (!(reg = (ec_reg_request_t *)
1334  kmalloc(sizeof(ec_reg_request_t), GFP_KERNEL))) {
1335  EC_CONFIG_ERR(sc, "Failed to allocate register request memory!\n");
1336  return ERR_PTR(-ENOMEM);
1337  }
1338 
1339  ret = ec_reg_request_init(reg, size);
1340  if (ret) {
1341  kfree(reg);
1342  return ERR_PTR(ret);
1343  }
1344 
1345  down(&sc->master->master_sem);
1346  list_add_tail(&reg->list, &sc->reg_requests);
1347  up(&sc->master->master_sem);
1348 
1349  return reg;
1350 }
1351 
1352 /****************************************************************************/
1353 
1355  ec_slave_config_t *sc, size_t size)
1356 {
1357  ec_reg_request_t *reg =
1359  return IS_ERR(reg) ? NULL : reg;
1360 }
1361 
1362 /****************************************************************************/
1363 
1368  ec_slave_config_t *sc, size_t size)
1369 {
1370  ec_voe_handler_t *voe;
1371  int ret;
1372 
1373  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, size = %zu)\n", __func__, sc, size);
1374 
1375  if (!(voe = (ec_voe_handler_t *)
1376  kmalloc(sizeof(ec_voe_handler_t), GFP_KERNEL))) {
1377  EC_CONFIG_ERR(sc, "Failed to allocate VoE request memory!\n");
1378  return ERR_PTR(-ENOMEM);
1379  }
1380 
1381  ret = ec_voe_handler_init(voe, sc, size);
1382  if (ret < 0) {
1383  kfree(voe);
1384  return ERR_PTR(ret);
1385  }
1386 
1387  down(&sc->master->master_sem);
1388  list_add_tail(&voe->list, &sc->voe_handlers);
1389  up(&sc->master->master_sem);
1390 
1391  return voe;
1392 }
1393 
1394 /****************************************************************************/
1395 
1397  ec_slave_config_t *sc, size_t size)
1398 {
1400  size);
1401  return IS_ERR(voe) ? NULL : voe;
1402 }
1403 
1404 /****************************************************************************/
1405 
1407  ec_slave_config_state_t *state)
1408 {
1409  const ec_slave_t *slave = sc->slave;
1410 
1411  state->online = slave ? 1 : 0;
1412  if (state->online) {
1413  state->operational =
1414  slave->current_state == EC_SLAVE_STATE_OP && !slave->force_config;
1415  state->al_state = slave->current_state;
1416  } else {
1417  state->operational = 0;
1419  }
1420  return 0;
1421 }
1422 
1423 /****************************************************************************/
1424 
1425 int ecrt_slave_config_idn(ec_slave_config_t *sc, uint8_t drive_no,
1426  uint16_t idn, ec_al_state_t state, const uint8_t *data,
1427  size_t size)
1428 {
1429  ec_slave_t *slave = sc->slave;
1430  ec_soe_request_t *req;
1431  int ret;
1432 
1433  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, drive_no = %u, idn = 0x%04X, "
1434  "state = %u, data = 0x%p, size = %zu)\n",
1435  __func__, sc, drive_no, idn, state, data, size);
1436 
1437  if (drive_no > 7) {
1438  EC_CONFIG_ERR(sc, "Invalid drive number %u!\n",
1439  (unsigned int) drive_no);
1440  return -EINVAL;
1441  }
1442 
1443  if (state != EC_AL_STATE_PREOP && state != EC_AL_STATE_SAFEOP) {
1444  EC_CONFIG_ERR(sc, "AL state for IDN config"
1445  " must be PREOP or SAFEOP!\n");
1446  return -EINVAL;
1447  }
1448 
1449  if (slave && !(slave->sii.mailbox_protocols & EC_MBOX_SOE)) {
1450  EC_CONFIG_WARN(sc, "Attached slave does not support SoE!\n");
1451  }
1452 
1453  if (!(req = (ec_soe_request_t *)
1454  kmalloc(sizeof(ec_soe_request_t), GFP_KERNEL))) {
1455  EC_CONFIG_ERR(sc, "Failed to allocate memory for"
1456  " IDN configuration!\n");
1457  return -ENOMEM;
1458  }
1459 
1460  ec_soe_request_init(req);
1461  ec_soe_request_set_drive_no(req, drive_no);
1462  ec_soe_request_set_idn(req, idn);
1463  req->al_state = state;
1464 
1465  ret = ec_soe_request_copy_data(req, data, size);
1466  if (ret < 0) {
1467  ec_soe_request_clear(req);
1468  kfree(req);
1469  return ret;
1470  }
1471 
1472  down(&sc->master->master_sem);
1473  list_add_tail(&req->list, &sc->soe_configs);
1474  up(&sc->master->master_sem);
1475  return 0;
1476 }
1477 
1478 /****************************************************************************/
1479 
1481  int32_t value)
1482 {
1483  ec_flag_t *flag;
1484 
1485  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, key = %s, value = %i)\n",
1486  __func__, sc, key, value);
1487 
1488 
1489  flag = ec_slave_config_find_flag(sc, key);
1490  if (flag) {
1491  flag->value = value; // overwrite value
1492  }
1493  else { // new flag
1494  int ret;
1495 
1496  if (!(flag = (ec_flag_t *) kmalloc(sizeof(ec_flag_t), GFP_KERNEL))) {
1497  EC_CONFIG_ERR(sc, "Failed to allocate memory for flag!\n");
1498  return -ENOMEM;
1499  }
1500 
1501  ret = ec_flag_init(flag, key, value);
1502  if (ret) {
1503  kfree(flag);
1504  return ret;
1505  }
1506 
1507  down(&sc->master->master_sem);
1508  list_add_tail(&flag->list, &sc->flags);
1509  up(&sc->master->master_sem);
1510  }
1511  return 0;
1512 }
1513 
1514 /****************************************************************************/
1515 
1516 #ifdef EC_EOE
1517 
1519  const unsigned char *mac_address)
1520 {
1521  memcpy(sc->eoe_ip_param_request.mac_address, mac_address, EC_ETH_ALEN);
1522  sc->eoe_ip_param_request.mac_address_included = 1;
1523  return 0;
1524 }
1525 
1526 /****************************************************************************/
1527 
1529  struct in_addr ip_address)
1530 {
1531  sc->eoe_ip_param_request.ip_address = ip_address;
1532  sc->eoe_ip_param_request.ip_address_included = 1;
1533  return 0;
1534 }
1535 
1536 /****************************************************************************/
1537 
1539  struct in_addr subnet_mask)
1540 {
1541  sc->eoe_ip_param_request.subnet_mask = subnet_mask;
1542  sc->eoe_ip_param_request.subnet_mask_included = 1;
1543  return 0;
1544 }
1545 
1546 /****************************************************************************/
1547 
1549  struct in_addr gateway_address)
1550 {
1551  sc->eoe_ip_param_request.gateway = gateway_address;
1552  sc->eoe_ip_param_request.gateway_included = 1;
1553  return 0;
1554 }
1555 
1556 /****************************************************************************/
1557 
1559  struct in_addr dns_address)
1560 {
1561  sc->eoe_ip_param_request.dns = dns_address;
1562  sc->eoe_ip_param_request.dns_included = 1;
1563  return 0;
1564 }
1565 
1566 /****************************************************************************/
1567 
1569  const char *name)
1570 {
1571  strncpy(sc->eoe_ip_param_request.name, name, EC_MAX_HOSTNAME_SIZE - 1);
1572  sc->eoe_ip_param_request.name_included = 1;
1573  return 0;
1574 }
1575 
1576 #endif
1577 
1578 /****************************************************************************/
1579 
1581  ec_al_state_t from, ec_al_state_t to, unsigned int timeout_ms)
1582 {
1583  ec_al_timeout_t *timeout;
1584  ec_slave_state_t from_state, to_state;
1585 
1586  if (from != EC_AL_STATE_INIT && from != EC_AL_STATE_PREOP &&
1587  from != EC_AL_STATE_SAFEOP && from != EC_AL_STATE_OP) {
1588  EC_CONFIG_ERR(sc, "Invalid from state %i.\n", from);
1589  return -EINVAL;
1590  }
1591  if (to != EC_AL_STATE_INIT && to != EC_AL_STATE_PREOP &&
1592  to != EC_AL_STATE_SAFEOP && to != EC_AL_STATE_OP) {
1593  EC_CONFIG_ERR(sc, "Invalid to state %i.\n", to);
1594  return -EINVAL;
1595  }
1596 
1597  from_state = (ec_slave_state_t) from;
1598  to_state = (ec_slave_state_t) to;
1599 
1600  /* try to find an already configured timeout. */
1601  list_for_each_entry(timeout, &sc->al_timeouts, list) {
1602  if (timeout->from == from_state && timeout->to == to_state) {
1603  if (timeout_ms == 0) {
1604  // delete configured value
1605  list_del(&timeout->list);
1606  kfree(timeout);
1607  return 0;
1608  }
1609  timeout->timeout_ms = timeout_ms;
1610  return 0;
1611  }
1612  }
1613 
1614  if (timeout_ms == 0) {
1615  return 0;
1616  }
1617 
1618  /* no timeout found. create one. */
1619  if (!(timeout = (ec_al_timeout_t *)
1620  kmalloc(sizeof(ec_al_timeout_t), GFP_KERNEL))) {
1621  EC_CONFIG_ERR(sc, "Failed to allocate memory for"
1622  " AL timeout configuration!\n");
1623  return -ENOMEM;
1624  }
1625 
1626  timeout->from = from_state;
1627  timeout->to = to_state;
1628  timeout->timeout_ms = timeout_ms;
1629 
1630  down(&sc->master->master_sem);
1631  list_add_tail(&timeout->list, &sc->al_timeouts);
1632  up(&sc->master->master_sem);
1633  return 0;
1634 }
1635 
1636 /****************************************************************************/
1637 
1640 EXPORT_SYMBOL(ecrt_slave_config_sync_manager);
1641 EXPORT_SYMBOL(ecrt_slave_config_watchdog);
1642 EXPORT_SYMBOL(ecrt_slave_config_pdo_mode);
1643 EXPORT_SYMBOL(ecrt_slave_config_pdo_assign_add);
1644 EXPORT_SYMBOL(ecrt_slave_config_pdo_assign_clear);
1645 EXPORT_SYMBOL(ecrt_slave_config_pdo_mapping_add);
1647 EXPORT_SYMBOL(ecrt_slave_config_pdos);
1648 EXPORT_SYMBOL(ecrt_slave_config_reg_pdo_entry);
1650 EXPORT_SYMBOL(ecrt_slave_config_dc);
1651 EXPORT_SYMBOL(ecrt_slave_config_sdo);
1652 EXPORT_SYMBOL(ecrt_slave_config_sdo8);
1653 EXPORT_SYMBOL(ecrt_slave_config_sdo16);
1654 EXPORT_SYMBOL(ecrt_slave_config_sdo32);
1655 EXPORT_SYMBOL(ecrt_slave_config_complete_sdo);
1656 EXPORT_SYMBOL(ecrt_slave_config_emerg_size);
1657 EXPORT_SYMBOL(ecrt_slave_config_emerg_pop);
1658 EXPORT_SYMBOL(ecrt_slave_config_emerg_clear);
1659 EXPORT_SYMBOL(ecrt_slave_config_emerg_overruns);
1664 EXPORT_SYMBOL(ecrt_slave_config_state);
1665 EXPORT_SYMBOL(ecrt_slave_config_idn);
1666 EXPORT_SYMBOL(ecrt_slave_config_flag);
1667 #ifdef EOE
1668 EXPORT_SYMBOL(ecrt_slave_config_eoe_mac_address);
1669 EXPORT_SYMBOL(ecrt_slave_config_eoe_ip_address);
1670 EXPORT_SYMBOL(ecrt_slave_config_eoe_subnet_mask);
1672 EXPORT_SYMBOL(ecrt_slave_config_eoe_dns_address);
1673 EXPORT_SYMBOL(ecrt_slave_config_eoe_hostname);
1674 #endif
1675 EXPORT_SYMBOL(ecrt_slave_config_state_timeout);
1676 
1679 /****************************************************************************/
unsigned int ec_slave_config_flag_count(const ec_slave_config_t *sc)
Get the number of feature flags.
Definition: slave_config.c:509
CANopen over EtherCAT.
Definition: globals.h:152
uint16_t ring_position
Ring position.
Definition: slave.h:176
Pre-operational.
Definition: ecrt.h:671
struct list_head sdo_configs
List of SDO configurations.
Definition: slave_config.h:143
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:217
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:597
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:776
unsigned int n_entries
Number of PDO entries in entries to map.
Definition: ecrt.h:601
FMMU configuration.
Definition: fmmu_config.h:38
uint8_t bit_length
Size of the PDO entry in bit.
Definition: ecrt.h:588
EtherCAT application-layer transition timeout.
Definition: slave_config.c:58
ec_direction_t dir
Sync manager direction.
Definition: ecrt.h:622
ec_pdo_mode_t
PDO handling mode.
Definition: ecrt.h:551
ec_watchdog_mode_t
Watchdog mode for sync manager configuration.
Definition: ecrt.h:535
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:487
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:624
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:669
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:664
int32_t shift_time
Shift time [ns].
Definition: globals.h:187
OP (mailbox communication and input/output update)
Definition: globals.h:138
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:531
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:575
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:709
CANopen SDO request.
Definition: sdo_request.h:40
ec_slave_state_t current_state
Current application state.
Definition: slave.h:185
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:924
Operational.
Definition: ecrt.h:673
Register request.
Definition: reg_request.h:40
uint8_t used_fmmus
Number of FMMUs used.
Definition: slave_config.h:139
uint32_t product_code
Slave product code.
Definition: slave_config.h:119
Safe-operational.
Definition: ecrt.h:672
Servo-Profile over EtherCAT.
Definition: globals.h:154
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:83
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:443
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:682
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:3298
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:153
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:186
ec_fsm_slave_t fsm
Slave state machine.
Definition: slave.h:229
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:280
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:599
#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:1861
Sync manager configuration information.
Definition: ecrt.h:618
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:979
struct list_head list
List item.
Definition: voe_handler.h:42
#define EC_MAX_HOSTNAME_SIZE
Maximum hostname size.
Definition: globals.h:116
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
ec_pdo_mode_t pdo_config_mode
Whether/how to read resp.
Definition: slave_config.h:129
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:159
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:98
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:138
ec_sync_signal_t dc_sync[EC_SYNC_SIGNAL_COUNT]
DC sync signals.
Definition: slave_config.h:141
struct list_head al_timeouts
List of specific AL state timeouts.
Definition: slave_config.h:150
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:219
uint16_t index
PDO index.
Definition: ecrt.h:600
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:149
EtherCAT slave.
Definition: slave.h:169
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:365
void ec_sdo_request_clear(ec_sdo_request_t *req)
SDO request destructor.
Definition: sdo_request.c:70
Read the current state via CoE while scanning the slave, and write it back only if it differs from th...
Definition: ecrt.h:562
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:394
ec_watchdog_mode_t watchdog_mode
Watchdog mode.
Definition: ecrt.h:626
ec_sync_config_t sync_configs[EC_MAX_SYNC_MANAGERS]
Sync manager configurations.
Definition: slave_config.h:136
ec_pdo_mode_t pdo_assign_mode
Whether/how to read resp.
Definition: slave_config.h:126
unsigned int n_pdos
Number of PDOs in pdos.
Definition: ecrt.h:623
ec_slave_config_t * config
Current configuration.
Definition: slave.h:183
struct list_head reg_requests
List of register requests.
Definition: slave_config.h:147
#define EC_WRITE_U32(DATA, VAL)
Write a 32-bit unsigned value to EtherCAT data.
Definition: ecrt.h:3332
unsigned int al_state
The application-layer state of the slave.
Definition: ecrt.h:398
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:144
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:140
ec_flag_t * ec_slave_config_find_flag(ec_slave_config_t *sc, const char *key)
Finds a flag.
Definition: slave_config.c:641
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:277
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:396
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:146
uint16_t dc_assign_activate
Vendor-specific AssignActivate word.
Definition: slave_config.h:140
#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:3315
#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:522
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:145
unsigned int ec_slave_config_sdo_count(const ec_slave_config_t *sc)
Get the number of SDO configurations.
Definition: slave_config.c:421
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:605
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:746
ec_slave_state_t
State of an EtherCAT slave.
Definition: globals.h:127
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:525
int ec_slave_config_attach(ec_slave_config_t *sc)
Attaches the configuration to the addressed slave object.
Definition: slave_config.c:257
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:133
unsigned int online
The slave is online.
Definition: ecrt.h:395
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:553
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:148
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:832
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:465
uint16_t index
PDO entry index.
Definition: ecrt.h:586
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:281
ec_coe_emerg_ring_t emerg_ring
CoE emergency ring buffer.
Definition: slave_config.h:156
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:523
Vendor specific over EtherCAT protocol handler.
void ec_sdo_request_init(ec_sdo_request_t *req)
SDO request constructor.
Definition: sdo_request.c:48
#define EC_PDO_MODE_DEFAULT
Default PDO handling mode: read via CoE while scanning, and unconditionally (re-)write via CoE every ...
Definition: ecrt.h:575
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:858
int ecrt_slave_config_eoe_hostname(ec_slave_config_t *sc, const char *name)
Sets the host name for Ethernet-over-EtherCAT (EoE) operation.
int ecrt_slave_config_pdo_mode(ec_slave_config_t *sc, ec_pdo_mode_t assign_mode, ec_pdo_mode_t config_mode)
Selects how a slave&#39;s PDO assignment and PDO configuration are read from resp.
Definition: slave_config.c:722
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:315
PDO entry configuration information.
Definition: ecrt.h:585
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:129
uint8_t index
Sync manager index.
Definition: ecrt.h:619
void ec_slave_config_clear(ec_slave_config_t *sc)
Slave configuration destructor.
Definition: slave_config.c:129
Values written by the master.
Definition: ecrt.h:524
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:670
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:795
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:158
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:587
#define EC_MAX_SYNC_MANAGERS
Maximum number of sync managers per slave.
Definition: ecrt.h:285
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:340
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:128
EtherCAT domain.
Definition: domain.h:46
uint32_t vendor_id
Vendor ID.
Definition: slave.h:128
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:187
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:619
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:815
int ec_flag_init(ec_flag_t *flag, const char *key, int32_t value)
SDO request constructor.
Definition: flag.c:36