IgH EtherCAT Master  1.5.2
slave_config.c
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * $Id$
4  *
5  * Copyright (C) 2006-2012 Florian Pose, Ingenieurgemeinschaft IgH
6  *
7  * This file is part of the IgH EtherCAT Master.
8  *
9  * The IgH EtherCAT Master is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License version 2, as
11  * published by the Free Software Foundation.
12  *
13  * The IgH EtherCAT Master is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16  * Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with the IgH EtherCAT Master; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21  *
22  * ---
23  *
24  * The license mentioned above concerns the source code only. Using the
25  * EtherCAT technology and brand is only permitted in compliance with the
26  * industrial property and similar rights of Beckhoff Automation GmbH.
27  *
28  * vim: expandtab
29  *
30  *****************************************************************************/
31 
37 /*****************************************************************************/
38 
39 #include <linux/module.h>
40 #include <linux/slab.h>
41 
42 #include "globals.h"
43 #include "master.h"
44 #include "voe_handler.h"
45 #include "flag.h"
46 
47 #include "slave_config.h"
48 
49 /*****************************************************************************/
50 
57  ec_slave_config_t *sc,
58  ec_master_t *master,
59  uint16_t alias,
60  uint16_t position,
61  uint32_t vendor_id,
62  uint32_t product_code
63  )
64 {
65  unsigned int i;
66 
67  sc->master = master;
68 
69  sc->alias = alias;
70  sc->position = position;
71  sc->vendor_id = vendor_id;
72  sc->product_code = product_code;
73  sc->watchdog_divider = 0; // use default
74  sc->watchdog_intervals = 0; // use default
75 
76  sc->slave = NULL;
77 
78  for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++)
80 
81  sc->used_fmmus = 0;
82  sc->dc_assign_activate = 0x0000;
83  sc->dc_sync[0].cycle_time = 0U;
84  sc->dc_sync[1].cycle_time = 0;
85  sc->dc_sync[0].shift_time = 0U;
86  sc->dc_sync[1].shift_time = 0;
87 
88  INIT_LIST_HEAD(&sc->sdo_configs);
89  INIT_LIST_HEAD(&sc->sdo_requests);
90  INIT_LIST_HEAD(&sc->reg_requests);
91  INIT_LIST_HEAD(&sc->voe_handlers);
92  INIT_LIST_HEAD(&sc->soe_configs);
93  INIT_LIST_HEAD(&sc->flags);
94 
96 }
97 
98 /*****************************************************************************/
99 
105  ec_slave_config_t *sc
106  )
107 {
108  unsigned int i;
109  ec_sdo_request_t *req, *next_req;
110  ec_voe_handler_t *voe, *next_voe;
111  ec_reg_request_t *reg, *next_reg;
112  ec_soe_request_t *soe, *next_soe;
113  ec_flag_t *flag, *next_flag;
114 
116 
117  // Free sync managers
118  for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++)
120 
121  // free all SDO configurations
122  list_for_each_entry_safe(req, next_req, &sc->sdo_configs, list) {
123  list_del(&req->list);
125  kfree(req);
126  }
127 
128  // free all SDO requests
129  list_for_each_entry_safe(req, next_req, &sc->sdo_requests, list) {
130  list_del(&req->list);
132  kfree(req);
133  }
134 
135  // free all register requests
136  list_for_each_entry_safe(reg, next_reg, &sc->reg_requests, list) {
137  list_del(&reg->list);
139  kfree(reg);
140  }
141 
142  // free all VoE handlers
143  list_for_each_entry_safe(voe, next_voe, &sc->voe_handlers, list) {
144  list_del(&voe->list);
146  kfree(voe);
147  }
148 
149  // free all SoE configurations
150  list_for_each_entry_safe(soe, next_soe, &sc->soe_configs, list) {
151  list_del(&soe->list);
153  kfree(soe);
154  }
155 
156  // free all flags
157  list_for_each_entry_safe(flag, next_flag, &sc->flags, list) {
158  list_del(&flag->list);
159  ec_flag_clear(flag);
160  kfree(flag);
161  }
162 
164 }
165 
166 /*****************************************************************************/
167 
181  ec_slave_config_t *sc,
182  ec_domain_t *domain,
183  uint8_t sync_index,
184  ec_direction_t dir
185  )
186 {
187  unsigned int i;
188  ec_fmmu_config_t *fmmu;
189 
190  // FMMU configuration already prepared?
191  for (i = 0; i < sc->used_fmmus; i++) {
192  fmmu = &sc->fmmu_configs[i];
193  if (fmmu->domain == domain && fmmu->sync_index == sync_index)
194  return fmmu->logical_start_address;
195  }
196 
197  if (sc->used_fmmus == EC_MAX_FMMUS) {
198  EC_CONFIG_ERR(sc, "FMMU limit reached!\n");
199  return -EOVERFLOW;
200  }
201 
202  fmmu = &sc->fmmu_configs[sc->used_fmmus++];
203 
204  down(&sc->master->master_sem);
205  ec_fmmu_config_init(fmmu, sc, domain, sync_index, dir);
206  up(&sc->master->master_sem);
207 
208  return fmmu->logical_start_address;
209 }
210 
211 /*****************************************************************************/
212 
219  ec_slave_config_t *sc
220  )
221 {
222  ec_slave_t *slave;
223 
224  if (sc->slave)
225  return 0; // already attached
226 
227  if (!(slave = ec_master_find_slave(
228  sc->master, sc->alias, sc->position))) {
229  EC_CONFIG_DBG(sc, 1, "Failed to find slave for configuration.\n");
230  return -ENOENT;
231  }
232 
233  if (slave->config) {
234  EC_CONFIG_DBG(sc, 1, "Failed to attach configuration. Slave %u"
235  " already has a configuration!\n", slave->ring_position);
236  return -EEXIST;
237  }
238 
239  if (
240 #ifdef EC_IDENT_WILDCARDS
241  sc->vendor_id != 0xffffffff &&
242 #endif
243  slave->sii.vendor_id != sc->vendor_id
244  ) {
245  EC_CONFIG_DBG(sc, 1, "Slave %u has no matching vendor ID (0x%08X)"
246  " for configuration (0x%08X).\n",
247  slave->ring_position, slave->sii.vendor_id, sc->vendor_id);
248  return -EINVAL;
249  }
250 
251  if (
252 #ifdef EC_IDENT_WILDCARDS
253  sc->product_code != 0xffffffff &&
254 #endif
255  slave->sii.product_code != sc->product_code
256  ) {
257  EC_CONFIG_DBG(sc, 1, "Slave %u has no matching product code (0x%08X)"
258  " for configuration (0x%08X).\n",
259  slave->ring_position, slave->sii.product_code,
260  sc->product_code);
261  return -EINVAL;
262  }
263 
264  // attach slave
265  slave->config = sc;
266  sc->slave = slave;
267 
268  EC_CONFIG_DBG(sc, 1, "Attached slave %u.\n", slave->ring_position);
269  return 0;
270 }
271 
272 /*****************************************************************************/
273 
277  ec_slave_config_t *sc
278  )
279 {
280  if (sc->slave) {
281  ec_reg_request_t *reg;
282 
283  sc->slave->config = NULL;
284 
285  // invalidate processing register request
286  list_for_each_entry(reg, &sc->reg_requests, list) {
287  if (sc->slave->fsm.reg_request == reg) {
288  sc->slave->fsm.reg_request = NULL;
289  break;
290  }
291  }
292 
293  sc->slave = NULL;
294  }
295 }
296 
297 /*****************************************************************************/
298 
302 {
303  uint8_t sync_index;
304  ec_sync_config_t *sync_config;
305  const ec_sync_t *sync;
306 
307  if (!sc->slave)
308  return;
309 
310  for (sync_index = 0; sync_index < EC_MAX_SYNC_MANAGERS; sync_index++) {
311  sync_config = &sc->sync_configs[sync_index];
312  if ((sync = ec_slave_get_sync(sc->slave, sync_index))) {
313  sync_config->dir = ec_sync_default_direction(sync);
314  if (sync_config->dir == EC_DIR_INVALID)
315  EC_SLAVE_WARN(sc->slave,
316  "SM%u has an invalid direction field!\n", sync_index);
317  ec_pdo_list_copy(&sync_config->pdos, &sync->pdos);
318  }
319  }
320 }
321 
322 /*****************************************************************************/
323 
327  const ec_slave_config_t *sc,
328  ec_pdo_t *pdo
329  )
330 {
331  unsigned int i;
332  const ec_sync_t *sync;
333  const ec_pdo_t *default_pdo;
334 
335  if (!sc->slave)
336  return;
337 
338  EC_CONFIG_DBG(sc, 1, "Loading default mapping for PDO 0x%04X.\n",
339  pdo->index);
340 
341  // find PDO in any sync manager (it could be reassigned later)
342  for (i = 0; i < sc->slave->sii.sync_count; i++) {
343  sync = &sc->slave->sii.syncs[i];
344 
345  list_for_each_entry(default_pdo, &sync->pdos.list, list) {
346  if (default_pdo->index != pdo->index)
347  continue;
348 
349  if (default_pdo->name) {
350  EC_CONFIG_DBG(sc, 1, "Found PDO name \"%s\".\n",
351  default_pdo->name);
352 
353  // take PDO name from assigned one
354  ec_pdo_set_name(pdo, default_pdo->name);
355  }
356 
357  // copy entries (= default PDO mapping)
358  if (ec_pdo_copy_entries(pdo, default_pdo))
359  return;
360 
361  if (sc->master->debug_level) {
362  const ec_pdo_entry_t *entry;
363  list_for_each_entry(entry, &pdo->entries, list) {
364  EC_CONFIG_DBG(sc, 1, "Entry 0x%04X:%02X.\n",
365  entry->index, entry->subindex);
366  }
367  }
368 
369  return;
370  }
371  }
372 
373  EC_CONFIG_DBG(sc, 1, "No default mapping found.\n");
374 }
375 
376 /*****************************************************************************/
377 
383  const ec_slave_config_t *sc
384  )
385 {
386  const ec_sdo_request_t *req;
387  unsigned int count = 0;
388 
389  list_for_each_entry(req, &sc->sdo_configs, list) {
390  count++;
391  }
392 
393  return count;
394 }
395 
396 /*****************************************************************************/
397 
405  const ec_slave_config_t *sc,
406  unsigned int pos
407  )
408 {
409  const ec_sdo_request_t *req;
410 
411  list_for_each_entry(req, &sc->sdo_configs, list) {
412  if (pos--)
413  continue;
414  return req;
415  }
416 
417  return NULL;
418 }
419 
420 /*****************************************************************************/
421 
427  const ec_slave_config_t *sc
428  )
429 {
430  const ec_soe_request_t *req;
431  unsigned int count = 0;
432 
433  list_for_each_entry(req, &sc->soe_configs, list) {
434  count++;
435  }
436 
437  return count;
438 }
439 
440 /*****************************************************************************/
441 
449  const ec_slave_config_t *sc,
450  unsigned int pos
451  )
452 {
453  const ec_soe_request_t *req;
454 
455  list_for_each_entry(req, &sc->soe_configs, list) {
456  if (pos--)
457  continue;
458  return req;
459  }
460 
461  return NULL;
462 }
463 
464 /*****************************************************************************/
465 
471  const ec_slave_config_t *sc
472  )
473 {
474  const ec_flag_t *flag;
475  unsigned int count = 0;
476 
477  list_for_each_entry(flag, &sc->flags, list) {
478  count++;
479  }
480 
481  return count;
482 }
483 
484 /*****************************************************************************/
485 
493  const ec_slave_config_t *sc,
494  unsigned int pos
495  )
496 {
497  const ec_flag_t *flag;
498 
499  list_for_each_entry(flag, &sc->flags, list) {
500  if (pos--)
501  continue;
502  return flag;
503  }
504 
505  return NULL;
506 }
507 
508 /*****************************************************************************/
509 
515  ec_slave_config_t *sc,
516  unsigned int pos
517  )
518 {
519  ec_sdo_request_t *req;
520 
521  list_for_each_entry(req, &sc->sdo_requests, list) {
522  if (pos--)
523  continue;
524  return req;
525  }
526 
527  return NULL;
528 }
529 
530 /*****************************************************************************/
531 
537  ec_slave_config_t *sc,
538  unsigned int pos
539  )
540 {
541  ec_reg_request_t *reg;
542 
543  list_for_each_entry(reg, &sc->reg_requests, list) {
544  if (pos--)
545  continue;
546  return reg;
547  }
548 
549  return NULL;
550 }
551 
552 /*****************************************************************************/
553 
559  ec_slave_config_t *sc,
560  unsigned int pos
561  )
562 {
563  ec_voe_handler_t *voe;
564 
565  list_for_each_entry(voe, &sc->voe_handlers, list) {
566  if (pos--)
567  continue;
568  return voe;
569  }
570 
571  return NULL;
572 }
573 
574 /*****************************************************************************/
575 
581  ec_slave_config_t *sc,
582  const char *key
583  )
584 {
585  if (sc) {
586  ec_flag_t *flag;
587  list_for_each_entry(flag, &sc->flags, list) {
588  if (!strcmp(flag->key, key)) {
589  return flag;
590  }
591  }
592  }
593 
594  return NULL;
595 }
596 
597 /******************************************************************************
598  * Application interface
599  *****************************************************************************/
600 
602  ec_direction_t dir, ec_watchdog_mode_t watchdog_mode)
603 {
604  ec_sync_config_t *sync_config;
605 
606  EC_CONFIG_DBG(sc, 1, "ecrt_slave_config_sync_manager(sc = 0x%p,"
607  " sync_index = %u, dir = %i, watchdog_mode = %i)\n",
608  sc, sync_index, dir, watchdog_mode);
609 
610  if (sync_index >= EC_MAX_SYNC_MANAGERS) {
611  EC_CONFIG_ERR(sc, "Invalid sync manager index %u!\n", sync_index);
612  return -ENOENT;
613  }
614 
615  if (dir != EC_DIR_OUTPUT && dir != EC_DIR_INPUT) {
616  EC_CONFIG_ERR(sc, "Invalid direction %u!\n", (unsigned int) dir);
617  return -EINVAL;
618  }
619 
620  sync_config = &sc->sync_configs[sync_index];
621  sync_config->dir = dir;
622  sync_config->watchdog_mode = watchdog_mode;
623  return 0;
624 }
625 
626 /*****************************************************************************/
627 
629  uint16_t divider, uint16_t intervals)
630 {
631  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, divider = %u, intervals = %u)\n",
632  __func__, sc, divider, intervals);
633 
634  sc->watchdog_divider = divider;
635  sc->watchdog_intervals = intervals;
636 }
637 
638 /*****************************************************************************/
639 
641  uint8_t sync_index, uint16_t pdo_index)
642 {
643  ec_pdo_t *pdo;
644 
645  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, sync_index = %u, "
646  "pdo_index = 0x%04X)\n", __func__, sc, sync_index, pdo_index);
647 
648  if (sync_index >= EC_MAX_SYNC_MANAGERS) {
649  EC_CONFIG_ERR(sc, "Invalid sync manager index %u!\n", sync_index);
650  return -EINVAL;
651  }
652 
653  down(&sc->master->master_sem);
654 
655  pdo = ec_pdo_list_add_pdo(&sc->sync_configs[sync_index].pdos, pdo_index);
656  if (IS_ERR(pdo)) {
657  up(&sc->master->master_sem);
658  return PTR_ERR(pdo);
659  }
660  pdo->sync_index = sync_index;
661 
663 
664  up(&sc->master->master_sem);
665  return 0;
666 }
667 
668 /*****************************************************************************/
669 
671  uint8_t sync_index)
672 {
673  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, sync_index = %u)\n",
674  __func__, sc, sync_index);
675 
676  if (sync_index >= EC_MAX_SYNC_MANAGERS) {
677  EC_CONFIG_ERR(sc, "Invalid sync manager index %u!\n", sync_index);
678  return;
679  }
680 
681  down(&sc->master->master_sem);
682  ec_pdo_list_clear_pdos(&sc->sync_configs[sync_index].pdos);
683  up(&sc->master->master_sem);
684 }
685 
686 /*****************************************************************************/
687 
689  uint16_t pdo_index, uint16_t entry_index, uint8_t entry_subindex,
690  uint8_t entry_bit_length)
691 {
692  uint8_t sync_index;
693  ec_pdo_t *pdo = NULL;
694  ec_pdo_entry_t *entry;
695  int retval = 0;
696 
697  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, "
698  "pdo_index = 0x%04X, entry_index = 0x%04X, "
699  "entry_subindex = 0x%02X, entry_bit_length = %u)\n",
700  __func__, sc, pdo_index, entry_index, entry_subindex,
701  entry_bit_length);
702 
703  for (sync_index = 0; sync_index < EC_MAX_SYNC_MANAGERS; sync_index++)
704  if ((pdo = ec_pdo_list_find_pdo(
705  &sc->sync_configs[sync_index].pdos, pdo_index)))
706  break;
707 
708  if (pdo) {
709  down(&sc->master->master_sem);
710  entry = ec_pdo_add_entry(pdo, entry_index, entry_subindex,
711  entry_bit_length);
712  up(&sc->master->master_sem);
713  if (IS_ERR(entry))
714  retval = PTR_ERR(entry);
715  } else {
716  EC_CONFIG_ERR(sc, "PDO 0x%04X is not assigned.\n", pdo_index);
717  retval = -ENOENT;
718  }
719 
720  return retval;
721 }
722 
723 /*****************************************************************************/
724 
726  uint16_t pdo_index)
727 {
728  uint8_t sync_index;
729  ec_pdo_t *pdo = NULL;
730 
731  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, pdo_index = 0x%04X)\n",
732  __func__, sc, pdo_index);
733 
734  for (sync_index = 0; sync_index < EC_MAX_SYNC_MANAGERS; sync_index++)
735  if ((pdo = ec_pdo_list_find_pdo(
736  &sc->sync_configs[sync_index].pdos, pdo_index)))
737  break;
738 
739  if (pdo) {
740  down(&sc->master->master_sem);
742  up(&sc->master->master_sem);
743  } else {
744  EC_CONFIG_WARN(sc, "PDO 0x%04X is not assigned.\n", pdo_index);
745  }
746 }
747 
748 /*****************************************************************************/
749 
751  unsigned int n_syncs, const ec_sync_info_t syncs[])
752 {
753  int ret;
754  unsigned int i, j, k;
755  const ec_sync_info_t *sync_info;
756  const ec_pdo_info_t *pdo_info;
757  const ec_pdo_entry_info_t *entry_info;
758 
759  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, n_syncs = %u, syncs = 0x%p)\n",
760  __func__, sc, n_syncs, syncs);
761 
762  if (!syncs)
763  return 0;
764 
765  for (i = 0; i < n_syncs; i++) {
766  sync_info = &syncs[i];
767 
768  if (sync_info->index == (uint8_t) EC_END)
769  break;
770 
771  if (sync_info->index >= EC_MAX_SYNC_MANAGERS) {
772  EC_CONFIG_ERR(sc, "Invalid sync manager index %u!\n",
773  sync_info->index);
774  return -ENOENT;
775  }
776 
777  ret = ecrt_slave_config_sync_manager(sc, sync_info->index,
778  sync_info->dir, sync_info->watchdog_mode);
779  if (ret)
780  return ret;
781 
783 
784  if (sync_info->n_pdos && sync_info->pdos) {
785 
786  for (j = 0; j < sync_info->n_pdos; j++) {
787  pdo_info = &sync_info->pdos[j];
788 
790  sc, sync_info->index, pdo_info->index);
791  if (ret)
792  return ret;
793 
795 
796  if (pdo_info->n_entries && pdo_info->entries) {
797  for (k = 0; k < pdo_info->n_entries; k++) {
798  entry_info = &pdo_info->entries[k];
799 
801  pdo_info->index, entry_info->index,
802  entry_info->subindex,
803  entry_info->bit_length);
804  if (ret)
805  return ret;
806  }
807  }
808  }
809  }
810  }
811 
812  return 0;
813 }
814 
815 /*****************************************************************************/
816 
818  ec_slave_config_t *sc,
819  uint16_t index,
820  uint8_t subindex,
821  ec_domain_t *domain,
822  unsigned int *bit_position
823  )
824 {
825  uint8_t sync_index;
826  const ec_sync_config_t *sync_config;
827  unsigned int bit_offset, bit_pos;
828  ec_pdo_t *pdo;
829  ec_pdo_entry_t *entry;
830  int sync_offset;
831 
832  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
833  "subindex = 0x%02X, domain = 0x%p, bit_position = 0x%p)\n",
834  __func__, sc, index, subindex, domain, bit_position);
835 
836  for (sync_index = 0; sync_index < EC_MAX_SYNC_MANAGERS; sync_index++) {
837  sync_config = &sc->sync_configs[sync_index];
838  bit_offset = 0;
839 
840  list_for_each_entry(pdo, &sync_config->pdos.list, list) {
841  list_for_each_entry(entry, &pdo->entries, list) {
842  if (entry->index != index || entry->subindex != subindex) {
843  bit_offset += entry->bit_length;
844  } else {
845  bit_pos = bit_offset % 8;
846  if (bit_position) {
847  *bit_position = bit_pos;
848  } else if (bit_pos) {
849  EC_CONFIG_ERR(sc, "PDO entry 0x%04X:%02X does"
850  " not byte-align.\n", index, subindex);
851  return -EFAULT;
852  }
853 
854  sync_offset = ec_slave_config_prepare_fmmu(
855  sc, domain, sync_index, sync_config->dir);
856  if (sync_offset < 0)
857  return sync_offset;
858 
859  return sync_offset + bit_offset / 8;
860  }
861  }
862  }
863  }
864 
865  EC_CONFIG_ERR(sc, "PDO entry 0x%04X:%02X is not mapped.\n",
866  index, subindex);
867  return -ENOENT;
868 }
869 
870 /*****************************************************************************/
871 
873  ec_slave_config_t *sc,
874  uint8_t sync_index,
875  unsigned int pdo_pos,
876  unsigned int entry_pos,
877  ec_domain_t *domain,
878  unsigned int *bit_position
879  )
880 {
881  const ec_sync_config_t *sync_config;
882  unsigned int bit_offset, pp, ep;
883  ec_pdo_t *pdo;
884  ec_pdo_entry_t *entry;
885 
886  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, sync_index = %u, pdo_pos = %u,"
887  " entry_pos = %u, domain = 0x%p, bit_position = 0x%p)\n",
888  __func__, sc, sync_index, pdo_pos, entry_pos,
889  domain, bit_position);
890 
891  if (sync_index >= EC_MAX_SYNC_MANAGERS) {
892  EC_CONFIG_ERR(sc, "Invalid syncmanager position %u.\n", sync_index);
893  return -EINVAL;
894  }
895 
896  sync_config = &sc->sync_configs[sync_index];
897  bit_offset = 0;
898  pp = 0;
899 
900  list_for_each_entry(pdo, &sync_config->pdos.list, list) {
901  ep = 0;
902  list_for_each_entry(entry, &pdo->entries, list) {
903  if (pp != pdo_pos || ep != entry_pos) {
904  bit_offset += entry->bit_length;
905  } else {
906  unsigned int bit_pos = bit_offset % 8;
907  int sync_offset;
908 
909  if (bit_position) {
910  *bit_position = bit_pos;
911  } else if (bit_pos) {
912  EC_CONFIG_ERR(sc, "PDO entry 0x%04X:%02X does"
913  " not byte-align.\n",
914  pdo->index, entry->subindex);
915  return -EFAULT;
916  }
917 
918  sync_offset = ec_slave_config_prepare_fmmu(
919  sc, domain, sync_index, sync_config->dir);
920  if (sync_offset < 0)
921  return sync_offset;
922 
923  return sync_offset + bit_offset / 8;
924  }
925  ep++;
926  }
927  pp++;
928  }
929 
930  EC_CONFIG_ERR(sc, "PDO entry specification %u/%u/%u out of range.\n",
931  sync_index, pdo_pos, entry_pos);
932  return -ENOENT;
933 }
934 
935 /*****************************************************************************/
936 
937 void ecrt_slave_config_dc(ec_slave_config_t *sc, uint16_t assign_activate,
938  uint32_t sync0_cycle_time, int32_t sync0_shift_time,
939  uint32_t sync1_cycle_time, int32_t sync1_shift_time)
940 {
941  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, assign_activate = 0x%04X,"
942  " sync0_cycle = %u, sync0_shift = %i,"
943  " sync1_cycle = %u, sync1_shift = %i\n",
944  __func__, sc, assign_activate, sync0_cycle_time, sync0_shift_time,
945  sync1_cycle_time, sync1_shift_time);
946 
947  sc->dc_assign_activate = assign_activate;
948  sc->dc_sync[0].cycle_time = sync0_cycle_time;
949  sc->dc_sync[0].shift_time = sync0_shift_time;
950  sc->dc_sync[1].cycle_time = sync1_cycle_time;
951  sc->dc_sync[1].shift_time = sync1_shift_time;
952 }
953 
954 /*****************************************************************************/
955 
956 int ecrt_slave_config_sdo(ec_slave_config_t *sc, uint16_t index,
957  uint8_t subindex, const uint8_t *data, size_t size)
958 {
959  ec_slave_t *slave = sc->slave;
960  ec_sdo_request_t *req;
961  int ret;
962 
963  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
964  "subindex = 0x%02X, data = 0x%p, size = %zu)\n",
965  __func__, sc, index, subindex, data, size);
966 
967  if (slave && !(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
968  EC_CONFIG_WARN(sc, "Attached slave does not support CoE!\n");
969  }
970 
971  if (!(req = (ec_sdo_request_t *)
972  kmalloc(sizeof(ec_sdo_request_t), GFP_KERNEL))) {
973  EC_CONFIG_ERR(sc, "Failed to allocate memory for"
974  " SDO configuration!\n");
975  return -ENOMEM;
976  }
977 
978  ec_sdo_request_init(req);
979  ecrt_sdo_request_index(req, index, subindex);
980 
981  ret = ec_sdo_request_copy_data(req, data, size);
982  if (ret < 0) {
984  kfree(req);
985  return ret;
986  }
987 
988  down(&sc->master->master_sem);
989  list_add_tail(&req->list, &sc->sdo_configs);
990  up(&sc->master->master_sem);
991  return 0;
992 }
993 
994 /*****************************************************************************/
995 
997  uint8_t subindex, uint8_t value)
998 {
999  uint8_t data[1];
1000 
1001  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
1002  "subindex = 0x%02X, value = %u)\n",
1003  __func__, sc, index, subindex, (unsigned int) value);
1004 
1005  EC_WRITE_U8(data, value);
1006  return ecrt_slave_config_sdo(sc, index, subindex, data, 1);
1007 }
1008 
1009 /*****************************************************************************/
1010 
1012  uint8_t subindex, uint16_t value)
1013 {
1014  uint8_t data[2];
1015 
1016  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
1017  "subindex = 0x%02X, value = %u)\n",
1018  __func__, sc, index, subindex, value);
1019 
1020  EC_WRITE_U16(data, value);
1021  return ecrt_slave_config_sdo(sc, index, subindex, data, 2);
1022 }
1023 
1024 /*****************************************************************************/
1025 
1027  uint8_t subindex, uint32_t value)
1028 {
1029  uint8_t data[4];
1030 
1031  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
1032  "subindex = 0x%02X, value = %u)\n",
1033  __func__, sc, index, subindex, value);
1034 
1035  EC_WRITE_U32(data, value);
1036  return ecrt_slave_config_sdo(sc, index, subindex, data, 4);
1037 }
1038 
1039 /*****************************************************************************/
1040 
1042  const uint8_t *data, size_t size)
1043 {
1044  ec_slave_t *slave = sc->slave;
1045  ec_sdo_request_t *req;
1046  int ret;
1047 
1048  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
1049  "data = 0x%p, size = %zu)\n", __func__, sc, index, data, size);
1050 
1051  if (slave && !(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
1052  EC_CONFIG_WARN(sc, "Attached slave does not support CoE!\n");
1053  }
1054 
1055  if (!(req = (ec_sdo_request_t *)
1056  kmalloc(sizeof(ec_sdo_request_t), GFP_KERNEL))) {
1057  EC_CONFIG_ERR(sc, "Failed to allocate memory for"
1058  " SDO configuration!\n");
1059  return -ENOMEM;
1060  }
1061 
1062  ec_sdo_request_init(req);
1063  ecrt_sdo_request_index(req, index, 0);
1064  req->complete_access = 1;
1065 
1066  ret = ec_sdo_request_copy_data(req, data, size);
1067  if (ret < 0) {
1068  ec_sdo_request_clear(req);
1069  kfree(req);
1070  return ret;
1071  }
1072 
1073  down(&sc->master->master_sem);
1074  list_add_tail(&req->list, &sc->sdo_configs);
1075  up(&sc->master->master_sem);
1076  return 0;
1077 }
1078 
1079 /*****************************************************************************/
1080 
1082 {
1083  return ec_coe_emerg_ring_size(&sc->emerg_ring, elements);
1084 }
1085 
1086 /*****************************************************************************/
1087 
1089 {
1090  return ec_coe_emerg_ring_pop(&sc->emerg_ring, target);
1091 }
1092 
1093 /*****************************************************************************/
1094 
1096 {
1098 }
1099 
1100 /*****************************************************************************/
1101 
1103 {
1105 }
1106 
1107 /*****************************************************************************/
1108 
1113  ec_slave_config_t *sc, uint16_t index, uint8_t subindex, size_t size)
1114 {
1115  ec_sdo_request_t *req;
1116  int ret;
1117 
1118  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, "
1119  "index = 0x%04X, subindex = 0x%02X, size = %zu)\n",
1120  __func__, sc, index, subindex, size);
1121 
1122  if (!(req = (ec_sdo_request_t *)
1123  kmalloc(sizeof(ec_sdo_request_t), GFP_KERNEL))) {
1124  EC_CONFIG_ERR(sc, "Failed to allocate SDO request memory!\n");
1125  return ERR_PTR(-ENOMEM);
1126  }
1127 
1128  ec_sdo_request_init(req);
1129  ecrt_sdo_request_index(req, index, subindex);
1130 
1131  ret = ec_sdo_request_alloc(req, size);
1132  if (ret < 0) {
1133  ec_sdo_request_clear(req);
1134  kfree(req);
1135  return ERR_PTR(ret);
1136  }
1137 
1138  // prepare data for optional writing
1139  memset(req->data, 0x00, size);
1140  req->data_size = size;
1141 
1142  down(&sc->master->master_sem);
1143  list_add_tail(&req->list, &sc->sdo_requests);
1144  up(&sc->master->master_sem);
1145 
1146  return req;
1147 }
1148 
1149 /*****************************************************************************/
1150 
1152  ec_slave_config_t *sc, uint16_t index, uint8_t subindex, size_t size)
1153 {
1155  subindex, size);
1156  return IS_ERR(s) ? NULL : s;
1157 }
1158 
1159 /*****************************************************************************/
1160 
1165  ec_slave_config_t *sc, size_t size)
1166 {
1167  ec_reg_request_t *reg;
1168  int ret;
1169 
1170  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, size = %zu)\n",
1171  __func__, sc, size);
1172 
1173  if (!(reg = (ec_reg_request_t *)
1174  kmalloc(sizeof(ec_reg_request_t), GFP_KERNEL))) {
1175  EC_CONFIG_ERR(sc, "Failed to allocate register request memory!\n");
1176  return ERR_PTR(-ENOMEM);
1177  }
1178 
1179  ret = ec_reg_request_init(reg, size);
1180  if (ret) {
1181  kfree(reg);
1182  return ERR_PTR(ret);
1183  }
1184 
1185  down(&sc->master->master_sem);
1186  list_add_tail(&reg->list, &sc->reg_requests);
1187  up(&sc->master->master_sem);
1188 
1189  return reg;
1190 }
1191 
1192 /*****************************************************************************/
1193 
1195  ec_slave_config_t *sc, size_t size)
1196 {
1197  ec_reg_request_t *reg =
1199  return IS_ERR(reg) ? NULL : reg;
1200 }
1201 
1202 /*****************************************************************************/
1203 
1208  ec_slave_config_t *sc, size_t size)
1209 {
1210  ec_voe_handler_t *voe;
1211  int ret;
1212 
1213  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, size = %zu)\n", __func__, sc, size);
1214 
1215  if (!(voe = (ec_voe_handler_t *)
1216  kmalloc(sizeof(ec_voe_handler_t), GFP_KERNEL))) {
1217  EC_CONFIG_ERR(sc, "Failed to allocate VoE request memory!\n");
1218  return ERR_PTR(-ENOMEM);
1219  }
1220 
1221  ret = ec_voe_handler_init(voe, sc, size);
1222  if (ret < 0) {
1223  kfree(voe);
1224  return ERR_PTR(ret);
1225  }
1226 
1227  down(&sc->master->master_sem);
1228  list_add_tail(&voe->list, &sc->voe_handlers);
1229  up(&sc->master->master_sem);
1230 
1231  return voe;
1232 }
1233 
1234 /*****************************************************************************/
1235 
1237  ec_slave_config_t *sc, size_t size)
1238 {
1240  size);
1241  return IS_ERR(voe) ? NULL : voe;
1242 }
1243 
1244 /*****************************************************************************/
1245 
1247  ec_slave_config_state_t *state)
1248 {
1249  state->online = sc->slave ? 1 : 0;
1250  if (state->online) {
1251  state->operational =
1253  && !sc->slave->force_config;
1254  state->al_state = sc->slave->current_state;
1255  } else {
1256  state->operational = 0;
1258  }
1259 }
1260 
1261 /*****************************************************************************/
1262 
1263 int ecrt_slave_config_idn(ec_slave_config_t *sc, uint8_t drive_no,
1264  uint16_t idn, ec_al_state_t state, const uint8_t *data,
1265  size_t size)
1266 {
1267  ec_slave_t *slave = sc->slave;
1268  ec_soe_request_t *req;
1269  int ret;
1270 
1271  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, drive_no = %u, idn = 0x%04X, "
1272  "state = %u, data = 0x%p, size = %zu)\n",
1273  __func__, sc, drive_no, idn, state, data, size);
1274 
1275  if (drive_no > 7) {
1276  EC_CONFIG_ERR(sc, "Invalid drive number %u!\n",
1277  (unsigned int) drive_no);
1278  return -EINVAL;
1279  }
1280 
1281  if (state != EC_AL_STATE_PREOP && state != EC_AL_STATE_SAFEOP) {
1282  EC_CONFIG_ERR(sc, "AL state for IDN config"
1283  " must be PREOP or SAFEOP!\n");
1284  return -EINVAL;
1285  }
1286 
1287  if (slave && !(slave->sii.mailbox_protocols & EC_MBOX_SOE)) {
1288  EC_CONFIG_WARN(sc, "Attached slave does not support SoE!\n");
1289  }
1290 
1291  if (!(req = (ec_soe_request_t *)
1292  kmalloc(sizeof(ec_soe_request_t), GFP_KERNEL))) {
1293  EC_CONFIG_ERR(sc, "Failed to allocate memory for"
1294  " IDN configuration!\n");
1295  return -ENOMEM;
1296  }
1297 
1298  ec_soe_request_init(req);
1299  ec_soe_request_set_drive_no(req, drive_no);
1300  ec_soe_request_set_idn(req, idn);
1301  req->al_state = state;
1302 
1303  ret = ec_soe_request_copy_data(req, data, size);
1304  if (ret < 0) {
1305  ec_soe_request_clear(req);
1306  kfree(req);
1307  return ret;
1308  }
1309 
1310  down(&sc->master->master_sem);
1311  list_add_tail(&req->list, &sc->soe_configs);
1312  up(&sc->master->master_sem);
1313  return 0;
1314 }
1315 
1316 /*****************************************************************************/
1317 
1319  int32_t value)
1320 {
1321  ec_flag_t *flag;
1322 
1323  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, key = %s, value = %i)\n",
1324  __func__, sc, key, value);
1325 
1326 
1327  flag = ec_slave_config_find_flag(sc, key);
1328  if (flag) {
1329  flag->value = value; // overwrite value
1330  }
1331  else { // new flag
1332  int ret;
1333 
1334  if (!(flag = (ec_flag_t *) kmalloc(sizeof(ec_flag_t), GFP_KERNEL))) {
1335  EC_CONFIG_ERR(sc, "Failed to allocate memory for flag!\n");
1336  return -ENOMEM;
1337  }
1338 
1339  ret = ec_flag_init(flag, key, value);
1340  if (ret) {
1341  kfree(flag);
1342  return ret;
1343  }
1344 
1345  down(&sc->master->master_sem);
1346  list_add_tail(&flag->list, &sc->flags);
1347  up(&sc->master->master_sem);
1348  }
1349  return 0;
1350 }
1351 
1352 /*****************************************************************************/
1353 
1356 EXPORT_SYMBOL(ecrt_slave_config_sync_manager);
1357 EXPORT_SYMBOL(ecrt_slave_config_watchdog);
1358 EXPORT_SYMBOL(ecrt_slave_config_pdo_assign_add);
1359 EXPORT_SYMBOL(ecrt_slave_config_pdo_assign_clear);
1360 EXPORT_SYMBOL(ecrt_slave_config_pdo_mapping_add);
1362 EXPORT_SYMBOL(ecrt_slave_config_pdos);
1363 EXPORT_SYMBOL(ecrt_slave_config_reg_pdo_entry);
1365 EXPORT_SYMBOL(ecrt_slave_config_dc);
1366 EXPORT_SYMBOL(ecrt_slave_config_sdo);
1367 EXPORT_SYMBOL(ecrt_slave_config_sdo8);
1368 EXPORT_SYMBOL(ecrt_slave_config_sdo16);
1369 EXPORT_SYMBOL(ecrt_slave_config_sdo32);
1370 EXPORT_SYMBOL(ecrt_slave_config_complete_sdo);
1371 EXPORT_SYMBOL(ecrt_slave_config_emerg_size);
1372 EXPORT_SYMBOL(ecrt_slave_config_emerg_pop);
1373 EXPORT_SYMBOL(ecrt_slave_config_emerg_clear);
1374 EXPORT_SYMBOL(ecrt_slave_config_emerg_overruns);
1378 EXPORT_SYMBOL(ecrt_slave_config_state);
1379 EXPORT_SYMBOL(ecrt_slave_config_idn);
1380 EXPORT_SYMBOL(ecrt_slave_config_flag);
1381 
1384 /*****************************************************************************/
unsigned int ec_slave_config_flag_count(const ec_slave_config_t *sc)
Get the number of feature flags.
Definition: slave_config.c:470
uint16_t ring_position
Ring position.
Definition: slave.h:183
Pre-operational.
Definition: ecrt.h:543
struct list_head sdo_configs
List of SDO configurations.
Definition: slave_config.h:144
int ecrt_slave_config_emerg_size(ec_slave_config_t *sc, size_t elements)
Set the size of the CoE emergency ring buffer.
void ec_soe_request_set_idn(ec_soe_request_t *req, uint16_t idn)
Set IDN.
Definition: soe_request.c:117
ec_sii_t sii
Extracted SII data.
Definition: slave.h:223
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:536
CANopen over EtherCAT.
Definition: globals.h:137
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:56
unsigned int n_entries
Number of PDO entries in entries to map.
Definition: ecrt.h:473
FMMU configuration.
Definition: fmmu_config.h:46
uint8_t bit_length
Size of the PDO entry in bit.
Definition: ecrt.h:460
ec_direction_t dir
Sync manager direction.
Definition: ecrt.h:494
ec_watchdog_mode_t
Watchdog mode for sync manager configuration.
Definition: ecrt.h:443
struct list_head list
List item.
Definition: soe_request.h:49
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:448
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.
Definition: slave_config.c:956
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_al_state_t
Application-layer state.
Definition: ecrt.h:541
int32_t shift_time
Shift time [ns].
Definition: globals.h:173
OP (mailbox communication and input/output update)
Definition: globals.h:126
ec_reg_request_t * reg_request
Register request to process.
Definition: fsm_slave.h:61
ec_pdo_info_t * pdos
Array with PDOs to assign.
Definition: ecrt.h:496
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's PDO assignment.
Definition: slave_config.c:640
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:492
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:177
CANopen SDO request.
Definition: sdo_request.h:48
ec_slave_state_t current_state
Current application state.
Definition: slave.h:192
Register request.
Definition: reg_request.h:48
uint8_t used_fmmus
Number of FMMUs used.
Definition: slave_config.h:140
uint32_t product_code
Slave product code.
Definition: slave_config.h:127
Safe-operational.
Definition: ecrt.h:544
uint16_t position
Index after alias.
Definition: slave_config.h:124
#define EC_SLAVE_WARN(slave, fmt, args...)
Convenience macro for printing slave-specific warnings to syslog.
Definition: slave.h:90
void ec_sync_config_clear(ec_sync_config_t *sync_config)
Destructor.
Definition: sync_config.c:56
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:404
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:50
struct list_head list
List of PDOs.
Definition: pdo_list.h:50
ec_master_t * master
Master owning the slave configuration.
Definition: slave_config.h:121
int ec_reg_request_init(ec_reg_request_t *reg, size_t size)
Register request constructor.
Definition: reg_request.c:48
int ec_pdo_set_name(ec_pdo_t *pdo, const char *name)
Set PDO name.
Definition: pdo.c:125
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2266
struct list_head list
List item.
Definition: flag.h:39
uint16_t alias
Slave alias.
Definition: slave_config.h:123
void ec_pdo_list_clear_pdos(ec_pdo_list_t *pl)
Clears the list of mapped PDOs.
Definition: pdo_list.c:70
void ec_pdo_clear_entries(ec_pdo_t *pdo)
Clear PDO entry list.
Definition: pdo.c:106
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:872
uint32_t cycle_time
Cycle time [ns].
Definition: globals.h:172
ec_fsm_slave_t fsm
Slave state machine.
Definition: slave.h:234
PDO configuration information.
Definition: ecrt.h:471
#define EC_CONFIG_ERR(sc, fmt, args...)
Convenience macro for printing configuration-specific errors to syslog.
Definition: slave_config.h:76
uint8_t * data
Pointer to SDO data.
Definition: sdo_request.h:52
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:1848
Sync manager configuration information.
Definition: ecrt.h:490
struct list_head list
List item.
Definition: voe_handler.h:50
int ecrt_slave_config_emerg_clear(ec_slave_config_t *sc)
Clears CoE emergency ring buffer and the overrun counter.
ec_direction_t ec_sync_default_direction(const ec_sync_t *sync)
Determines the default direction from the control register.
Definition: sync.c:167
unsigned int sync_count
Number of sync managers.
Definition: slave.h:166
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. ...
char * key
Flag key (null-terminated ASCII string.
Definition: flag.h:40
int ecrt_slave_config_flag(ec_slave_config_t *sc, const char *key, int32_t value)
Adds a feature flag to a slave configuration.
#define EC_MAX_FMMUS
Maximum number of FMMUs per slave.
Definition: globals.h:92
void 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.
Definition: slave_config.c:937
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.
Global definitions and macros.
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
PDO entry description.
Definition: pdo_entry.h:48
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:157
EtherCAT master structure.
ec_fmmu_config_t fmmu_configs[EC_MAX_FMMUS]
FMMU configurations.
Definition: slave_config.h:139
ec_sync_signal_t dc_sync[EC_SYNC_SIGNAL_COUNT]
DC sync signals.
Definition: slave_config.h:142
uint16_t index
PDO index.
Definition: pdo.h:51
int8_t sync_index
Assigned sync manager.
Definition: pdo.h:52
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:179
int ec_slave_config_prepare_fmmu(ec_slave_config_t *sc, ec_domain_t *domain, uint8_t sync_index, ec_direction_t dir)
Prepares an FMMU configuration.
Definition: slave_config.c:180
uint16_t index
PDO index.
Definition: ecrt.h:472
uint16_t index
PDO entry index.
Definition: pdo_entry.h:50
struct list_head flags
List of feature flags.
Definition: slave_config.h:149
EtherCAT slave.
Definition: slave.h:176
struct semaphore master_sem
Master semaphore.
Definition: master.h:209
uint32_t logical_start_address
Logical start address.
Definition: fmmu_config.h:52
void ec_slave_config_load_default_mapping(const ec_slave_config_t *sc, ec_pdo_t *pdo)
Loads the default mapping for a PDO from the slave object.
Definition: slave_config.c:326
void ec_sdo_request_clear(ec_sdo_request_t *req)
SDO request destructor.
Definition: sdo_request.c:76
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_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.
const ec_domain_t * domain
Domain.
Definition: fmmu_config.h:49
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:156
Slave configuration state.
Definition: ecrt.h:319
ec_watchdog_mode_t watchdog_mode
Watchdog mode.
Definition: ecrt.h:498
ec_sync_config_t sync_configs[EC_MAX_SYNC_MANAGERS]
Sync manager configurations.
Definition: slave_config.h:137
unsigned int n_pdos
Number of PDOs in pdos.
Definition: ecrt.h:495
ec_slave_config_t * config
Current configuration.
Definition: slave.h:190
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:2300
unsigned int al_state
The application-layer state of the slave.
Definition: ecrt.h:323
uint8_t sync_index
Index of sync manager to use.
Definition: fmmu_config.h:50
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:105
PDO description.
Definition: pdo.h:49
struct list_head sdo_requests
List of SDO requests.
Definition: slave_config.h:145
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:147
ec_flag_t * ec_slave_config_find_flag(ec_slave_config_t *sc, const char *key)
Finds a flag.
Definition: slave_config.c:580
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:285
uint8_t bit_length
entry length in bit
Definition: pdo_entry.h:53
Sync manager.
Definition: sync.h:47
unsigned int operational
The slave was brought into OP state using the specified configuration.
Definition: ecrt.h:321
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:77
EtherCAT Slave Configuration Feature Flag.
ec_pdo_list_t pdos
Current PDO assignment.
Definition: sync_config.h:49
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:141
#define EC_CONFIG_WARN(sc, fmt, args...)
Convenience macro for printing configuration-specific warnings to syslog.
Definition: slave_config.h:90
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.
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2283
#define EC_CONFIG_DBG(sc, level, fmt, args...)
Convenience macro for printing configuration-specific debug messages to syslog.
Definition: slave_config.h:107
ec_direction_t
Direction type for PDO assignment functions.
Definition: ecrt.h:430
struct list_head entries
List of PDO entries.
Definition: pdo.h:54
uint16_t watchdog_intervals
Process data watchdog intervals (see spec.
Definition: slave_config.h:131
Vendor specific over EtherCAT handler.
Definition: voe_handler.h:49
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.
unsigned int ec_slave_config_sdo_count(const ec_slave_config_t *sc)
Get the number of SDO configurations.
Definition: slave_config.c:382
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:117
uint8_t subindex
PDO entry subindex.
Definition: pdo_entry.h:51
Values read by the master.
Definition: ecrt.h:433
int ec_slave_config_attach(ec_slave_config_t *sc)
Attaches the configuration to the addressed slave object.
Definition: slave_config.c:218
ec_direction_t dir
Sync manager direction.
Definition: sync_config.h:47
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:72
ec_slave_t * slave
Slave pointer.
Definition: slave_config.h:134
int ec_coe_emerg_ring_overruns(ec_coe_emerg_ring_t *ring)
Read the number of overruns.
unsigned int online
The slave is online.
Definition: ecrt.h:320
uint16_t watchdog_divider
Watchdog divider as a number of 40ns intervals (see spec.
Definition: slave_config.h:129
ec_sdo_request_t * ec_slave_config_find_sdo_request(ec_slave_config_t *sc, unsigned int pos)
Finds a CoE handler via its position in the list.
Definition: slave_config.c:514
ec_al_state_t al_state
AL state (only valid for IDN config).
Definition: soe_request.h:52
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.
struct list_head soe_configs
List of SoE configurations.
Definition: slave_config.h:148
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.
Definition: slave_config.c:996
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's mapping.
Definition: slave_config.c:688
ec_watchdog_mode_t watchdog_mode
Watchdog mode.
Definition: sync_config.h:48
char * name
PDO name.
Definition: pdo.h:53
int ec_pdo_copy_entries(ec_pdo_t *pdo, const ec_pdo_t *other)
Copy PDO entries from another PDO.
Definition: pdo.c:186
unsigned int ec_slave_config_idn_count(const ec_slave_config_t *sc)
Get the number of IDN configurations.
Definition: slave_config.c:426
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:817
uint16_t index
PDO entry index.
Definition: ecrt.h:458
size_t data_size
Size of SDO data.
Definition: sdo_request.h:54
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:750
#define EC_END
End of list marker.
Definition: ecrt.h:209
ec_coe_emerg_ring_t emerg_ring
CoE emergency ring buffer.
Definition: slave_config.h:151
void 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:725
Invalid direction.
Definition: ecrt.h:431
Vendor specific over EtherCAT protocol handler.
Servo-Profile over EtherCAT.
Definition: globals.h:139
void ec_sdo_request_init(ec_sdo_request_t *req)
SDO request constructor.
Definition: sdo_request.c:56
Sync manager configuration.
Definition: sync_config.h:46
struct list_head list
List item.
Definition: sdo_request.h:49
void ec_coe_emerg_ring_clear(ec_coe_emerg_ring_t *ring)
Emergency ring buffer destructor.
uint32_t vendor_id
Slave vendor ID.
Definition: slave_config.h:126
ec_pdo_list_t pdos
Current PDO assignment.
Definition: sync.h:53
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:43
void ecrt_slave_config_watchdog(ec_slave_config_t *sc, uint16_t divider, uint16_t intervals)
Configure a slave's watchdog times.
Definition: slave_config.c:628
void ec_reg_request_clear(ec_reg_request_t *reg)
Register request destructor.
Definition: reg_request.c:73
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:601
EtherCAT slave configuration.
Definition: slave_config.h:119
void ec_soe_request_init(ec_soe_request_t *req)
SoE request constructor.
Definition: soe_request.c:56
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:276
PDO entry configuration information.
Definition: ecrt.h:457
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.
void ecrt_slave_config_pdo_assign_clear(ec_slave_config_t *sc, uint8_t sync_index)
Clear a sync manager's PDO assignment.
Definition: slave_config.c:670
int ec_sdo_request_alloc(ec_sdo_request_t *req, size_t size)
Pre-allocates the data memory.
Definition: sdo_request.c:127
uint32_t product_code
Vendor-specific product code.
Definition: slave.h:136
uint8_t index
Sync manager index.
Definition: ecrt.h:491
void ecrt_slave_config_state(const ec_slave_config_t *sc, ec_slave_config_state_t *state)
Outputs the state of the slave configuration.
void ec_slave_config_clear(ec_slave_config_t *sc)
Slave configuration destructor.
Definition: slave_config.c:104
Values written by the master.
Definition: ecrt.h:432
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:243
ec_sync_t * syncs
SYNC MANAGER categories.
Definition: slave.h:165
EtherCAT master.
Definition: master.h:194
struct list_head list
List item.
Definition: reg_request.h:49
uint8_t subindex
PDO entry subindex.
Definition: ecrt.h:459
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.
#define EC_MAX_SYNC_MANAGERS
Maximum number of sync managers per slave.
Definition: ecrt.h:213
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:301
int ecrt_slave_config_emerg_overruns(ec_slave_config_t *sc)
Read the number of CoE emergency overruns.
int ec_coe_emerg_ring_size(ec_coe_emerg_ring_t *ring, size_t size)
Set the ring size.
unknown state
Definition: globals.h:116
EtherCAT domain.
Definition: domain.h:54
uint32_t vendor_id
Vendor ID.
Definition: slave.h:135
uint8_t complete_access
SDO shall be transferred completely.
Definition: sdo_request.h:55
int ec_coe_emerg_ring_pop(ec_coe_emerg_ring_t *ring, u8 *msg)
Remove an emergency message from the ring.
void 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:187
unsigned int force_config
Force (re-)configuration.
Definition: slave.h:194
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:558
ec_pdo_entry_info_t * entries
Array of PDO entries to map.
Definition: ecrt.h:477
void ec_voe_handler_clear(ec_voe_handler_t *voe)
VoE handler destructor.
Definition: voe_handler.c:95
Sercos-over-EtherCAT request.
Definition: soe_request.h:48
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:590
int ec_flag_init(ec_flag_t *flag, const char *key, int32_t value)
SDO request constructor.
Definition: flag.c:36