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 
46 #include "slave_config.h"
47 
48 /*****************************************************************************/
49 
56  ec_slave_config_t *sc,
57  ec_master_t *master,
58  uint16_t alias,
59  uint16_t position,
60  uint32_t vendor_id,
61  uint32_t product_code
62  )
63 {
64  unsigned int i;
65 
66  sc->master = master;
67 
68  sc->alias = alias;
69  sc->position = position;
70  sc->vendor_id = vendor_id;
71  sc->product_code = product_code;
72  sc->watchdog_divider = 0; // use default
73  sc->watchdog_intervals = 0; // use default
74 
75  sc->slave = NULL;
76 
77  for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++)
79 
80  sc->used_fmmus = 0;
81  sc->dc_assign_activate = 0x0000;
82  sc->dc_sync[0].cycle_time = 0U;
83  sc->dc_sync[1].cycle_time = 0;
84  sc->dc_sync[0].shift_time = 0U;
85  sc->dc_sync[1].shift_time = 0;
86 
87  INIT_LIST_HEAD(&sc->sdo_configs);
88  INIT_LIST_HEAD(&sc->sdo_requests);
89  INIT_LIST_HEAD(&sc->reg_requests);
90  INIT_LIST_HEAD(&sc->voe_handlers);
91  INIT_LIST_HEAD(&sc->soe_configs);
92 
94 }
95 
96 /*****************************************************************************/
97 
103  ec_slave_config_t *sc
104  )
105 {
106  unsigned int i;
107  ec_sdo_request_t *req, *next_req;
108  ec_voe_handler_t *voe, *next_voe;
109  ec_reg_request_t *reg, *next_reg;
110  ec_soe_request_t *soe, *next_soe;
111 
113 
114  // Free sync managers
115  for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++)
117 
118  // free all SDO configurations
119  list_for_each_entry_safe(req, next_req, &sc->sdo_configs, list) {
120  list_del(&req->list);
122  kfree(req);
123  }
124 
125  // free all SDO requests
126  list_for_each_entry_safe(req, next_req, &sc->sdo_requests, list) {
127  list_del(&req->list);
129  kfree(req);
130  }
131 
132  // free all register requests
133  list_for_each_entry_safe(reg, next_reg, &sc->reg_requests, list) {
134  list_del(&reg->list);
136  kfree(reg);
137  }
138 
139  // free all VoE handlers
140  list_for_each_entry_safe(voe, next_voe, &sc->voe_handlers, list) {
141  list_del(&voe->list);
143  kfree(voe);
144  }
145 
146  // free all SoE configurations
147  list_for_each_entry_safe(soe, next_soe, &sc->soe_configs, list) {
148  list_del(&soe->list);
150  kfree(soe);
151  }
152 
154 }
155 
156 /*****************************************************************************/
157 
171  ec_slave_config_t *sc,
172  ec_domain_t *domain,
173  uint8_t sync_index,
174  ec_direction_t dir
175  )
176 {
177  unsigned int i;
178  ec_fmmu_config_t *fmmu;
179 
180  // FMMU configuration already prepared?
181  for (i = 0; i < sc->used_fmmus; i++) {
182  fmmu = &sc->fmmu_configs[i];
183  if (fmmu->domain == domain && fmmu->sync_index == sync_index)
184  return fmmu->logical_start_address;
185  }
186 
187  if (sc->used_fmmus == EC_MAX_FMMUS) {
188  EC_CONFIG_ERR(sc, "FMMU limit reached!\n");
189  return -EOVERFLOW;
190  }
191 
192  fmmu = &sc->fmmu_configs[sc->used_fmmus++];
193 
194  down(&sc->master->master_sem);
195  ec_fmmu_config_init(fmmu, sc, domain, sync_index, dir);
196  up(&sc->master->master_sem);
197 
198  return fmmu->logical_start_address;
199 }
200 
201 /*****************************************************************************/
202 
209  ec_slave_config_t *sc
210  )
211 {
212  ec_slave_t *slave;
213 
214  if (sc->slave)
215  return 0; // already attached
216 
217  if (!(slave = ec_master_find_slave(
218  sc->master, sc->alias, sc->position))) {
219  EC_CONFIG_DBG(sc, 1, "Failed to find slave for configuration.\n");
220  return -ENOENT;
221  }
222 
223  if (slave->config) {
224  EC_CONFIG_DBG(sc, 1, "Failed to attach configuration. Slave %u"
225  " already has a configuration!\n", slave->ring_position);
226  return -EEXIST;
227  }
228 
229  if (
230 #ifdef EC_IDENT_WILDCARDS
231  sc->vendor_id != 0xffffffff &&
232 #endif
233  slave->sii.vendor_id != sc->vendor_id
234  ) {
235  EC_CONFIG_DBG(sc, 1, "Slave %u has no matching vendor ID (0x%08X)"
236  " for configuration (0x%08X).\n",
237  slave->ring_position, slave->sii.vendor_id, sc->vendor_id);
238  return -EINVAL;
239  }
240 
241  if (
242 #ifdef EC_IDENT_WILDCARDS
243  sc->product_code != 0xffffffff &&
244 #endif
245  slave->sii.product_code != sc->product_code
246  ) {
247  EC_CONFIG_DBG(sc, 1, "Slave %u has no matching product code (0x%08X)"
248  " for configuration (0x%08X).\n",
249  slave->ring_position, slave->sii.product_code,
250  sc->product_code);
251  return -EINVAL;
252  }
253 
254  // attach slave
255  slave->config = sc;
256  sc->slave = slave;
257 
258  EC_CONFIG_DBG(sc, 1, "Attached slave %u.\n", slave->ring_position);
259  return 0;
260 }
261 
262 /*****************************************************************************/
263 
267  ec_slave_config_t *sc
268  )
269 {
270  if (sc->slave) {
271  ec_reg_request_t *reg;
272 
273  sc->slave->config = NULL;
274 
275  // invalidate processing register request
276  list_for_each_entry(reg, &sc->reg_requests, list) {
277  if (sc->slave->fsm.reg_request == reg) {
278  sc->slave->fsm.reg_request = NULL;
279  break;
280  }
281  }
282 
283  sc->slave = NULL;
284  }
285 }
286 
287 /*****************************************************************************/
288 
292 {
293  uint8_t sync_index;
294  ec_sync_config_t *sync_config;
295  const ec_sync_t *sync;
296 
297  if (!sc->slave)
298  return;
299 
300  for (sync_index = 0; sync_index < EC_MAX_SYNC_MANAGERS; sync_index++) {
301  sync_config = &sc->sync_configs[sync_index];
302  if ((sync = ec_slave_get_sync(sc->slave, sync_index))) {
303  sync_config->dir = ec_sync_default_direction(sync);
304  if (sync_config->dir == EC_DIR_INVALID)
305  EC_SLAVE_WARN(sc->slave,
306  "SM%u has an invalid direction field!\n", sync_index);
307  ec_pdo_list_copy(&sync_config->pdos, &sync->pdos);
308  }
309  }
310 }
311 
312 /*****************************************************************************/
313 
317  const ec_slave_config_t *sc,
318  ec_pdo_t *pdo
319  )
320 {
321  unsigned int i;
322  const ec_sync_t *sync;
323  const ec_pdo_t *default_pdo;
324 
325  if (!sc->slave)
326  return;
327 
328  EC_CONFIG_DBG(sc, 1, "Loading default mapping for PDO 0x%04X.\n",
329  pdo->index);
330 
331  // find PDO in any sync manager (it could be reassigned later)
332  for (i = 0; i < sc->slave->sii.sync_count; i++) {
333  sync = &sc->slave->sii.syncs[i];
334 
335  list_for_each_entry(default_pdo, &sync->pdos.list, list) {
336  if (default_pdo->index != pdo->index)
337  continue;
338 
339  if (default_pdo->name) {
340  EC_CONFIG_DBG(sc, 1, "Found PDO name \"%s\".\n",
341  default_pdo->name);
342 
343  // take PDO name from assigned one
344  ec_pdo_set_name(pdo, default_pdo->name);
345  }
346 
347  // copy entries (= default PDO mapping)
348  if (ec_pdo_copy_entries(pdo, default_pdo))
349  return;
350 
351  if (sc->master->debug_level) {
352  const ec_pdo_entry_t *entry;
353  list_for_each_entry(entry, &pdo->entries, list) {
354  EC_CONFIG_DBG(sc, 1, "Entry 0x%04X:%02X.\n",
355  entry->index, entry->subindex);
356  }
357  }
358 
359  return;
360  }
361  }
362 
363  EC_CONFIG_DBG(sc, 1, "No default mapping found.\n");
364 }
365 
366 /*****************************************************************************/
367 
373  const ec_slave_config_t *sc
374  )
375 {
376  const ec_sdo_request_t *req;
377  unsigned int count = 0;
378 
379  list_for_each_entry(req, &sc->sdo_configs, list) {
380  count++;
381  }
382 
383  return count;
384 }
385 
386 /*****************************************************************************/
387 
395  const ec_slave_config_t *sc,
396  unsigned int pos
397  )
398 {
399  const ec_sdo_request_t *req;
400 
401  list_for_each_entry(req, &sc->sdo_configs, list) {
402  if (pos--)
403  continue;
404  return req;
405  }
406 
407  return NULL;
408 }
409 
410 /*****************************************************************************/
411 
417  const ec_slave_config_t *sc
418  )
419 {
420  const ec_soe_request_t *req;
421  unsigned int count = 0;
422 
423  list_for_each_entry(req, &sc->soe_configs, list) {
424  count++;
425  }
426 
427  return count;
428 }
429 
430 /*****************************************************************************/
431 
439  const ec_slave_config_t *sc,
440  unsigned int pos
441  )
442 {
443  const ec_soe_request_t *req;
444 
445  list_for_each_entry(req, &sc->soe_configs, list) {
446  if (pos--)
447  continue;
448  return req;
449  }
450 
451  return NULL;
452 }
453 
454 /*****************************************************************************/
455 
461  ec_slave_config_t *sc,
462  unsigned int pos
463  )
464 {
465  ec_sdo_request_t *req;
466 
467  list_for_each_entry(req, &sc->sdo_requests, list) {
468  if (pos--)
469  continue;
470  return req;
471  }
472 
473  return NULL;
474 }
475 
476 /*****************************************************************************/
477 
483  ec_slave_config_t *sc,
484  unsigned int pos
485  )
486 {
487  ec_reg_request_t *reg;
488 
489  list_for_each_entry(reg, &sc->reg_requests, list) {
490  if (pos--)
491  continue;
492  return reg;
493  }
494 
495  return NULL;
496 }
497 
498 /*****************************************************************************/
499 
505  ec_slave_config_t *sc,
506  unsigned int pos
507  )
508 {
509  ec_voe_handler_t *voe;
510 
511  list_for_each_entry(voe, &sc->voe_handlers, list) {
512  if (pos--)
513  continue;
514  return voe;
515  }
516 
517  return NULL;
518 }
519 
520 /******************************************************************************
521  * Application interface
522  *****************************************************************************/
523 
525  ec_direction_t dir, ec_watchdog_mode_t watchdog_mode)
526 {
527  ec_sync_config_t *sync_config;
528 
529  EC_CONFIG_DBG(sc, 1, "ecrt_slave_config_sync_manager(sc = 0x%p,"
530  " sync_index = %u, dir = %i, watchdog_mode = %i)\n",
531  sc, sync_index, dir, watchdog_mode);
532 
533  if (sync_index >= EC_MAX_SYNC_MANAGERS) {
534  EC_CONFIG_ERR(sc, "Invalid sync manager index %u!\n", sync_index);
535  return -ENOENT;
536  }
537 
538  if (dir != EC_DIR_OUTPUT && dir != EC_DIR_INPUT) {
539  EC_CONFIG_ERR(sc, "Invalid direction %u!\n", (unsigned int) dir);
540  return -EINVAL;
541  }
542 
543  sync_config = &sc->sync_configs[sync_index];
544  sync_config->dir = dir;
545  sync_config->watchdog_mode = watchdog_mode;
546  return 0;
547 }
548 
549 /*****************************************************************************/
550 
552  uint16_t divider, uint16_t intervals)
553 {
554  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, divider = %u, intervals = %u)\n",
555  __func__, sc, divider, intervals);
556 
557  sc->watchdog_divider = divider;
558  sc->watchdog_intervals = intervals;
559 }
560 
561 /*****************************************************************************/
562 
564  uint8_t sync_index, uint16_t pdo_index)
565 {
566  ec_pdo_t *pdo;
567 
568  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, sync_index = %u, "
569  "pdo_index = 0x%04X)\n", __func__, sc, sync_index, pdo_index);
570 
571  if (sync_index >= EC_MAX_SYNC_MANAGERS) {
572  EC_CONFIG_ERR(sc, "Invalid sync manager index %u!\n", sync_index);
573  return -EINVAL;
574  }
575 
576  down(&sc->master->master_sem);
577 
578  pdo = ec_pdo_list_add_pdo(&sc->sync_configs[sync_index].pdos, pdo_index);
579  if (IS_ERR(pdo)) {
580  up(&sc->master->master_sem);
581  return PTR_ERR(pdo);
582  }
583  pdo->sync_index = sync_index;
584 
586 
587  up(&sc->master->master_sem);
588  return 0;
589 }
590 
591 /*****************************************************************************/
592 
594  uint8_t sync_index)
595 {
596  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, sync_index = %u)\n",
597  __func__, sc, sync_index);
598 
599  if (sync_index >= EC_MAX_SYNC_MANAGERS) {
600  EC_CONFIG_ERR(sc, "Invalid sync manager index %u!\n", sync_index);
601  return;
602  }
603 
604  down(&sc->master->master_sem);
605  ec_pdo_list_clear_pdos(&sc->sync_configs[sync_index].pdos);
606  up(&sc->master->master_sem);
607 }
608 
609 /*****************************************************************************/
610 
612  uint16_t pdo_index, uint16_t entry_index, uint8_t entry_subindex,
613  uint8_t entry_bit_length)
614 {
615  uint8_t sync_index;
616  ec_pdo_t *pdo = NULL;
617  ec_pdo_entry_t *entry;
618  int retval = 0;
619 
620  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, "
621  "pdo_index = 0x%04X, entry_index = 0x%04X, "
622  "entry_subindex = 0x%02X, entry_bit_length = %u)\n",
623  __func__, sc, pdo_index, entry_index, entry_subindex,
624  entry_bit_length);
625 
626  for (sync_index = 0; sync_index < EC_MAX_SYNC_MANAGERS; sync_index++)
627  if ((pdo = ec_pdo_list_find_pdo(
628  &sc->sync_configs[sync_index].pdos, pdo_index)))
629  break;
630 
631  if (pdo) {
632  down(&sc->master->master_sem);
633  entry = ec_pdo_add_entry(pdo, entry_index, entry_subindex,
634  entry_bit_length);
635  up(&sc->master->master_sem);
636  if (IS_ERR(entry))
637  retval = PTR_ERR(entry);
638  } else {
639  EC_CONFIG_ERR(sc, "PDO 0x%04X is not assigned.\n", pdo_index);
640  retval = -ENOENT;
641  }
642 
643  return retval;
644 }
645 
646 /*****************************************************************************/
647 
649  uint16_t pdo_index)
650 {
651  uint8_t sync_index;
652  ec_pdo_t *pdo = NULL;
653 
654  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, pdo_index = 0x%04X)\n",
655  __func__, sc, pdo_index);
656 
657  for (sync_index = 0; sync_index < EC_MAX_SYNC_MANAGERS; sync_index++)
658  if ((pdo = ec_pdo_list_find_pdo(
659  &sc->sync_configs[sync_index].pdos, pdo_index)))
660  break;
661 
662  if (pdo) {
663  down(&sc->master->master_sem);
665  up(&sc->master->master_sem);
666  } else {
667  EC_CONFIG_WARN(sc, "PDO 0x%04X is not assigned.\n", pdo_index);
668  }
669 }
670 
671 /*****************************************************************************/
672 
674  unsigned int n_syncs, const ec_sync_info_t syncs[])
675 {
676  int ret;
677  unsigned int i, j, k;
678  const ec_sync_info_t *sync_info;
679  const ec_pdo_info_t *pdo_info;
680  const ec_pdo_entry_info_t *entry_info;
681 
682  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, n_syncs = %u, syncs = 0x%p)\n",
683  __func__, sc, n_syncs, syncs);
684 
685  if (!syncs)
686  return 0;
687 
688  for (i = 0; i < n_syncs; i++) {
689  sync_info = &syncs[i];
690 
691  if (sync_info->index == (uint8_t) EC_END)
692  break;
693 
694  if (sync_info->index >= EC_MAX_SYNC_MANAGERS) {
695  EC_CONFIG_ERR(sc, "Invalid sync manager index %u!\n",
696  sync_info->index);
697  return -ENOENT;
698  }
699 
700  ret = ecrt_slave_config_sync_manager(sc, sync_info->index,
701  sync_info->dir, sync_info->watchdog_mode);
702  if (ret)
703  return ret;
704 
705  if (sync_info->n_pdos && sync_info->pdos) {
707 
708  for (j = 0; j < sync_info->n_pdos; j++) {
709  pdo_info = &sync_info->pdos[j];
710 
712  sc, sync_info->index, pdo_info->index);
713  if (ret)
714  return ret;
715 
716  if (pdo_info->n_entries && pdo_info->entries) {
718 
719  for (k = 0; k < pdo_info->n_entries; k++) {
720  entry_info = &pdo_info->entries[k];
721 
723  pdo_info->index, entry_info->index,
724  entry_info->subindex,
725  entry_info->bit_length);
726  if (ret)
727  return ret;
728  }
729  }
730  }
731  }
732  }
733 
734  return 0;
735 }
736 
737 /*****************************************************************************/
738 
740  ec_slave_config_t *sc,
741  uint16_t index,
742  uint8_t subindex,
743  ec_domain_t *domain,
744  unsigned int *bit_position
745  )
746 {
747  uint8_t sync_index;
748  const ec_sync_config_t *sync_config;
749  unsigned int bit_offset, bit_pos;
750  ec_pdo_t *pdo;
751  ec_pdo_entry_t *entry;
752  int sync_offset;
753 
754  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
755  "subindex = 0x%02X, domain = 0x%p, bit_position = 0x%p)\n",
756  __func__, sc, index, subindex, domain, bit_position);
757 
758  for (sync_index = 0; sync_index < EC_MAX_SYNC_MANAGERS; sync_index++) {
759  sync_config = &sc->sync_configs[sync_index];
760  bit_offset = 0;
761 
762  list_for_each_entry(pdo, &sync_config->pdos.list, list) {
763  list_for_each_entry(entry, &pdo->entries, list) {
764  if (entry->index != index || entry->subindex != subindex) {
765  bit_offset += entry->bit_length;
766  } else {
767  bit_pos = bit_offset % 8;
768  if (bit_position) {
769  *bit_position = bit_pos;
770  } else if (bit_pos) {
771  EC_CONFIG_ERR(sc, "PDO entry 0x%04X:%02X does"
772  " not byte-align.\n", index, subindex);
773  return -EFAULT;
774  }
775 
776  sync_offset = ec_slave_config_prepare_fmmu(
777  sc, domain, sync_index, sync_config->dir);
778  if (sync_offset < 0)
779  return sync_offset;
780 
781  return sync_offset + bit_offset / 8;
782  }
783  }
784  }
785  }
786 
787  EC_CONFIG_ERR(sc, "PDO entry 0x%04X:%02X is not mapped.\n",
788  index, subindex);
789  return -ENOENT;
790 }
791 
792 /*****************************************************************************/
793 
795  ec_slave_config_t *sc,
796  uint8_t sync_index,
797  unsigned int pdo_pos,
798  unsigned int entry_pos,
799  ec_domain_t *domain,
800  unsigned int *bit_position
801  )
802 {
803  const ec_sync_config_t *sync_config;
804  unsigned int bit_offset, pp, ep;
805  ec_pdo_t *pdo;
806  ec_pdo_entry_t *entry;
807 
808  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, sync_index = %u, pdo_pos = %u,"
809  " entry_pos = %u, domain = 0x%p, bit_position = 0x%p)\n",
810  __func__, sc, sync_index, pdo_pos, entry_pos,
811  domain, bit_position);
812 
813  if (sync_index >= EC_MAX_SYNC_MANAGERS) {
814  EC_CONFIG_ERR(sc, "Invalid syncmanager position %u.\n", sync_index);
815  return -EINVAL;
816  }
817 
818  sync_config = &sc->sync_configs[sync_index];
819  bit_offset = 0;
820  pp = 0;
821 
822  list_for_each_entry(pdo, &sync_config->pdos.list, list) {
823  ep = 0;
824  list_for_each_entry(entry, &pdo->entries, list) {
825  if (pp != pdo_pos || ep != entry_pos) {
826  bit_offset += entry->bit_length;
827  } else {
828  unsigned int bit_pos = bit_offset % 8;
829  int sync_offset;
830 
831  if (bit_position) {
832  *bit_position = bit_pos;
833  } else if (bit_pos) {
834  EC_CONFIG_ERR(sc, "PDO entry 0x%04X:%02X does"
835  " not byte-align.\n",
836  pdo->index, entry->subindex);
837  return -EFAULT;
838  }
839 
840  sync_offset = ec_slave_config_prepare_fmmu(
841  sc, domain, sync_index, sync_config->dir);
842  if (sync_offset < 0)
843  return sync_offset;
844 
845  return sync_offset + bit_offset / 8;
846  }
847  ep++;
848  }
849  pp++;
850  }
851 
852  EC_CONFIG_ERR(sc, "PDO entry specification %u/%u/%u out of range.\n",
853  sync_index, pdo_pos, entry_pos);
854  return -ENOENT;
855 }
856 
857 /*****************************************************************************/
858 
859 void ecrt_slave_config_dc(ec_slave_config_t *sc, uint16_t assign_activate,
860  uint32_t sync0_cycle_time, int32_t sync0_shift_time,
861  uint32_t sync1_cycle_time, int32_t sync1_shift_time)
862 {
863  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, assign_activate = 0x%04X,"
864  " sync0_cycle = %u, sync0_shift = %i,"
865  " sync1_cycle = %u, sync1_shift = %i\n",
866  __func__, sc, assign_activate, sync0_cycle_time, sync0_shift_time,
867  sync1_cycle_time, sync1_shift_time);
868 
869  sc->dc_assign_activate = assign_activate;
870  sc->dc_sync[0].cycle_time = sync0_cycle_time;
871  sc->dc_sync[0].shift_time = sync0_shift_time;
872  sc->dc_sync[1].cycle_time = sync1_cycle_time;
873  sc->dc_sync[1].shift_time = sync1_shift_time;
874 }
875 
876 /*****************************************************************************/
877 
878 int ecrt_slave_config_sdo(ec_slave_config_t *sc, uint16_t index,
879  uint8_t subindex, const uint8_t *data, size_t size)
880 {
881  ec_slave_t *slave = sc->slave;
882  ec_sdo_request_t *req;
883  int ret;
884 
885  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
886  "subindex = 0x%02X, data = 0x%p, size = %zu)\n",
887  __func__, sc, index, subindex, data, size);
888 
889  if (slave && !(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
890  EC_CONFIG_WARN(sc, "Attached slave does not support CoE!\n");
891  }
892 
893  if (!(req = (ec_sdo_request_t *)
894  kmalloc(sizeof(ec_sdo_request_t), GFP_KERNEL))) {
895  EC_CONFIG_ERR(sc, "Failed to allocate memory for"
896  " SDO configuration!\n");
897  return -ENOMEM;
898  }
899 
900  ec_sdo_request_init(req);
901  ecrt_sdo_request_index(req, index, subindex);
902 
903  ret = ec_sdo_request_copy_data(req, data, size);
904  if (ret < 0) {
906  kfree(req);
907  return ret;
908  }
909 
910  down(&sc->master->master_sem);
911  list_add_tail(&req->list, &sc->sdo_configs);
912  up(&sc->master->master_sem);
913  return 0;
914 }
915 
916 /*****************************************************************************/
917 
919  uint8_t subindex, uint8_t value)
920 {
921  uint8_t data[1];
922 
923  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
924  "subindex = 0x%02X, value = %u)\n",
925  __func__, sc, index, subindex, (unsigned int) value);
926 
927  EC_WRITE_U8(data, value);
928  return ecrt_slave_config_sdo(sc, index, subindex, data, 1);
929 }
930 
931 /*****************************************************************************/
932 
934  uint8_t subindex, uint16_t value)
935 {
936  uint8_t data[2];
937 
938  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
939  "subindex = 0x%02X, value = %u)\n",
940  __func__, sc, index, subindex, value);
941 
942  EC_WRITE_U16(data, value);
943  return ecrt_slave_config_sdo(sc, index, subindex, data, 2);
944 }
945 
946 /*****************************************************************************/
947 
949  uint8_t subindex, uint32_t value)
950 {
951  uint8_t data[4];
952 
953  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
954  "subindex = 0x%02X, value = %u)\n",
955  __func__, sc, index, subindex, value);
956 
957  EC_WRITE_U32(data, value);
958  return ecrt_slave_config_sdo(sc, index, subindex, data, 4);
959 }
960 
961 /*****************************************************************************/
962 
964  const uint8_t *data, size_t size)
965 {
966  ec_slave_t *slave = sc->slave;
967  ec_sdo_request_t *req;
968  int ret;
969 
970  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
971  "data = 0x%p, size = %zu)\n", __func__, sc, index, data, size);
972 
973  if (slave && !(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
974  EC_CONFIG_WARN(sc, "Attached slave does not support CoE!\n");
975  }
976 
977  if (!(req = (ec_sdo_request_t *)
978  kmalloc(sizeof(ec_sdo_request_t), GFP_KERNEL))) {
979  EC_CONFIG_ERR(sc, "Failed to allocate memory for"
980  " SDO configuration!\n");
981  return -ENOMEM;
982  }
983 
984  ec_sdo_request_init(req);
985  ecrt_sdo_request_index(req, index, 0);
986  req->complete_access = 1;
987 
988  ret = ec_sdo_request_copy_data(req, data, size);
989  if (ret < 0) {
991  kfree(req);
992  return ret;
993  }
994 
995  down(&sc->master->master_sem);
996  list_add_tail(&req->list, &sc->sdo_configs);
997  up(&sc->master->master_sem);
998  return 0;
999 }
1000 
1001 /*****************************************************************************/
1002 
1004 {
1005  return ec_coe_emerg_ring_size(&sc->emerg_ring, elements);
1006 }
1007 
1008 /*****************************************************************************/
1009 
1011 {
1012  return ec_coe_emerg_ring_pop(&sc->emerg_ring, target);
1013 }
1014 
1015 /*****************************************************************************/
1016 
1018 {
1020 }
1021 
1022 /*****************************************************************************/
1023 
1025 {
1027 }
1028 
1029 /*****************************************************************************/
1030 
1035  ec_slave_config_t *sc, uint16_t index, uint8_t subindex, size_t size)
1036 {
1037  ec_sdo_request_t *req;
1038  int ret;
1039 
1040  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, "
1041  "index = 0x%04X, subindex = 0x%02X, size = %zu)\n",
1042  __func__, sc, index, subindex, size);
1043 
1044  if (!(req = (ec_sdo_request_t *)
1045  kmalloc(sizeof(ec_sdo_request_t), GFP_KERNEL))) {
1046  EC_CONFIG_ERR(sc, "Failed to allocate SDO request memory!\n");
1047  return ERR_PTR(-ENOMEM);
1048  }
1049 
1050  ec_sdo_request_init(req);
1051  ecrt_sdo_request_index(req, index, subindex);
1052 
1053  ret = ec_sdo_request_alloc(req, size);
1054  if (ret < 0) {
1055  ec_sdo_request_clear(req);
1056  kfree(req);
1057  return ERR_PTR(ret);
1058  }
1059 
1060  // prepare data for optional writing
1061  memset(req->data, 0x00, size);
1062  req->data_size = size;
1063 
1064  down(&sc->master->master_sem);
1065  list_add_tail(&req->list, &sc->sdo_requests);
1066  up(&sc->master->master_sem);
1067 
1068  return req;
1069 }
1070 
1071 /*****************************************************************************/
1072 
1074  ec_slave_config_t *sc, uint16_t index, uint8_t subindex, size_t size)
1075 {
1077  subindex, size);
1078  return IS_ERR(s) ? NULL : s;
1079 }
1080 
1081 /*****************************************************************************/
1082 
1087  ec_slave_config_t *sc, size_t size)
1088 {
1089  ec_reg_request_t *reg;
1090  int ret;
1091 
1092  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, size = %zu)\n",
1093  __func__, sc, size);
1094 
1095  if (!(reg = (ec_reg_request_t *)
1096  kmalloc(sizeof(ec_reg_request_t), GFP_KERNEL))) {
1097  EC_CONFIG_ERR(sc, "Failed to allocate register request memory!\n");
1098  return ERR_PTR(-ENOMEM);
1099  }
1100 
1101  ret = ec_reg_request_init(reg, size);
1102  if (ret) {
1103  kfree(reg);
1104  return ERR_PTR(ret);
1105  }
1106 
1107  down(&sc->master->master_sem);
1108  list_add_tail(&reg->list, &sc->reg_requests);
1109  up(&sc->master->master_sem);
1110 
1111  return reg;
1112 }
1113 
1114 /*****************************************************************************/
1115 
1117  ec_slave_config_t *sc, size_t size)
1118 {
1119  ec_reg_request_t *reg =
1121  return IS_ERR(reg) ? NULL : reg;
1122 }
1123 
1124 /*****************************************************************************/
1125 
1130  ec_slave_config_t *sc, size_t size)
1131 {
1132  ec_voe_handler_t *voe;
1133  int ret;
1134 
1135  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, size = %zu)\n", __func__, sc, size);
1136 
1137  if (!(voe = (ec_voe_handler_t *)
1138  kmalloc(sizeof(ec_voe_handler_t), GFP_KERNEL))) {
1139  EC_CONFIG_ERR(sc, "Failed to allocate VoE request memory!\n");
1140  return ERR_PTR(-ENOMEM);
1141  }
1142 
1143  ret = ec_voe_handler_init(voe, sc, size);
1144  if (ret < 0) {
1145  kfree(voe);
1146  return ERR_PTR(ret);
1147  }
1148 
1149  down(&sc->master->master_sem);
1150  list_add_tail(&voe->list, &sc->voe_handlers);
1151  up(&sc->master->master_sem);
1152 
1153  return voe;
1154 }
1155 
1156 /*****************************************************************************/
1157 
1159  ec_slave_config_t *sc, size_t size)
1160 {
1162  size);
1163  return IS_ERR(voe) ? NULL : voe;
1164 }
1165 
1166 /*****************************************************************************/
1167 
1169  ec_slave_config_state_t *state)
1170 {
1171  state->online = sc->slave ? 1 : 0;
1172  if (state->online) {
1173  state->operational =
1175  && !sc->slave->force_config;
1176  state->al_state = sc->slave->current_state;
1177  } else {
1178  state->operational = 0;
1180  }
1181 }
1182 
1183 /*****************************************************************************/
1184 
1185 int ecrt_slave_config_idn(ec_slave_config_t *sc, uint8_t drive_no,
1186  uint16_t idn, ec_al_state_t state, const uint8_t *data,
1187  size_t size)
1188 {
1189  ec_slave_t *slave = sc->slave;
1190  ec_soe_request_t *req;
1191  int ret;
1192 
1193  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, drive_no = %u, idn = 0x%04X, "
1194  "state = %u, data = 0x%p, size = %zu)\n",
1195  __func__, sc, drive_no, idn, state, data, size);
1196 
1197  if (drive_no > 7) {
1198  EC_CONFIG_ERR(sc, "Invalid drive number %u!\n",
1199  (unsigned int) drive_no);
1200  return -EINVAL;
1201  }
1202 
1203  if (state != EC_AL_STATE_PREOP && state != EC_AL_STATE_SAFEOP) {
1204  EC_CONFIG_ERR(sc, "AL state for IDN config"
1205  " must be PREOP or SAFEOP!\n");
1206  return -EINVAL;
1207  }
1208 
1209  if (slave && !(slave->sii.mailbox_protocols & EC_MBOX_SOE)) {
1210  EC_CONFIG_WARN(sc, "Attached slave does not support SoE!\n");
1211  }
1212 
1213  if (!(req = (ec_soe_request_t *)
1214  kmalloc(sizeof(ec_soe_request_t), GFP_KERNEL))) {
1215  EC_CONFIG_ERR(sc, "Failed to allocate memory for"
1216  " IDN configuration!\n");
1217  return -ENOMEM;
1218  }
1219 
1220  ec_soe_request_init(req);
1221  ec_soe_request_set_drive_no(req, drive_no);
1222  ec_soe_request_set_idn(req, idn);
1223  req->al_state = state;
1224 
1225  ret = ec_soe_request_copy_data(req, data, size);
1226  if (ret < 0) {
1227  ec_soe_request_clear(req);
1228  kfree(req);
1229  return ret;
1230  }
1231 
1232  down(&sc->master->master_sem);
1233  list_add_tail(&req->list, &sc->soe_configs);
1234  up(&sc->master->master_sem);
1235  return 0;
1236 }
1237 
1238 /*****************************************************************************/
1239 
1242 EXPORT_SYMBOL(ecrt_slave_config_sync_manager);
1243 EXPORT_SYMBOL(ecrt_slave_config_watchdog);
1244 EXPORT_SYMBOL(ecrt_slave_config_pdo_assign_add);
1245 EXPORT_SYMBOL(ecrt_slave_config_pdo_assign_clear);
1246 EXPORT_SYMBOL(ecrt_slave_config_pdo_mapping_add);
1248 EXPORT_SYMBOL(ecrt_slave_config_pdos);
1249 EXPORT_SYMBOL(ecrt_slave_config_reg_pdo_entry);
1250 EXPORT_SYMBOL(ecrt_slave_config_dc);
1251 EXPORT_SYMBOL(ecrt_slave_config_sdo);
1252 EXPORT_SYMBOL(ecrt_slave_config_sdo8);
1253 EXPORT_SYMBOL(ecrt_slave_config_sdo16);
1254 EXPORT_SYMBOL(ecrt_slave_config_sdo32);
1255 EXPORT_SYMBOL(ecrt_slave_config_complete_sdo);
1256 EXPORT_SYMBOL(ecrt_slave_config_emerg_size);
1257 EXPORT_SYMBOL(ecrt_slave_config_emerg_pop);
1258 EXPORT_SYMBOL(ecrt_slave_config_emerg_clear);
1259 EXPORT_SYMBOL(ecrt_slave_config_emerg_overruns);
1263 EXPORT_SYMBOL(ecrt_slave_config_state);
1264 EXPORT_SYMBOL(ecrt_slave_config_idn);
1265 
1268 /*****************************************************************************/
uint16_t ring_position
Ring position.
Definition: slave.h:183
Pre-operational.
Definition: ecrt.h:530
struct list_head sdo_configs
List of SDO configurations.
Definition: slave_config.h:143
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:482
CANopen over EtherCAT.
Definition: globals.h:149
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:55
unsigned int n_entries
Number of PDO entries in entries to map.
Definition: ecrt.h:460
FMMU configuration.
Definition: fmmu_config.h:46
uint8_t bit_length
Size of the PDO entry in bit.
Definition: ecrt.h:447
ec_direction_t dir
Sync manager direction.
Definition: ecrt.h:481
ec_watchdog_mode_t
Watchdog mode for sync manager configuration.
Definition: ecrt.h:430
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:438
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:878
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:528
int32_t shift_time
Shift time [ns].
Definition: globals.h:185
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:61
ec_pdo_info_t * pdos
Array with PDOs to assign.
Definition: ecrt.h:483
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:563
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:139
uint32_t product_code
Slave product code.
Definition: slave_config.h:126
Safe-operational.
Definition: ecrt.h:531
uint16_t position
Index after alias.
Definition: slave_config.h:123
#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:394
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:120
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:2187
uint16_t alias
Slave alias.
Definition: slave_config.h:122
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:794
uint32_t cycle_time
Cycle time [ns].
Definition: globals.h:184
ec_fsm_slave_t fsm
Slave state machine.
Definition: slave.h:234
PDO configuration information.
Definition: ecrt.h:458
#define EC_CONFIG_ERR(sc, fmt, args...)
Convenience macro for printing configuration-specific errors to syslog.
Definition: slave_config.h:75
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:1815
Sync manager configuration information.
Definition: ecrt.h:477
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. ...
#define EC_MAX_FMMUS
Maximum number of FMMUs per slave.
Definition: globals.h:104
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:859
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.
Definition: slave_config.c:933
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.
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:138
ec_sync_signal_t dc_sync[EC_SYNC_SIGNAL_COUNT]
DC sync signals.
Definition: slave_config.h:141
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:170
uint16_t index
PDO index.
Definition: ecrt.h:459
uint16_t index
PDO entry index.
Definition: pdo_entry.h:50
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:316
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.
Definition: slave_config.c:963
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:306
ec_watchdog_mode_t watchdog_mode
Watchdog mode.
Definition: ecrt.h:485
ec_sync_config_t sync_configs[EC_MAX_SYNC_MANAGERS]
Sync manager configurations.
Definition: slave_config.h:136
unsigned int n_pdos
Number of PDOs in pdos.
Definition: ecrt.h:482
ec_slave_config_t * config
Current configuration.
Definition: slave.h:190
struct list_head reg_requests
List of register requests.
Definition: slave_config.h:146
#define EC_WRITE_U32(DATA, VAL)
Write a 32-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2221
unsigned int al_state
The application-layer state of the slave.
Definition: ecrt.h:310
uint8_t sync_index
Index of sync manager to use.
Definition: fmmu_config.h:50
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:144
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:147
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:286
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:308
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
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:145
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:89
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:2204
#define EC_CONFIG_DBG(sc, level, fmt, args...)
Convenience macro for printing configuration-specific debug messages to syslog.
Definition: slave_config.h:106
ec_direction_t
Direction type for PDO assignment functions.
Definition: ecrt.h:417
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:130
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.
Definition: slave_config.c:948
unsigned int ec_slave_config_sdo_count(const ec_slave_config_t *sc)
Get the number of SDO configurations.
Definition: slave_config.c:372
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:420
int ec_slave_config_attach(ec_slave_config_t *sc)
Attaches the configuration to the addressed slave object.
Definition: slave_config.c:208
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:76
ec_slave_t * slave
Slave pointer.
Definition: slave_config.h:133
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:307
uint16_t watchdog_divider
Watchdog divider as a number of 40ns intervals (see spec.
Definition: slave_config.h:128
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:460
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:147
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:918
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:611
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:416
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:739
uint16_t index
PDO entry index.
Definition: ecrt.h:445
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:673
#define EC_END
End of list marker.
Definition: ecrt.h:196
ec_coe_emerg_ring_t emerg_ring
CoE emergency ring buffer.
Definition: slave_config.h:149
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:648
Invalid direction.
Definition: ecrt.h:418
Vendor specific over EtherCAT protocol handler.
Servo-Profile over EtherCAT.
Definition: globals.h:151
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:125
ec_pdo_list_t pdos
Current PDO assignment.
Definition: sync.h:53
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:551
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:524
EtherCAT slave configuration.
Definition: slave_config.h:118
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:266
PDO entry configuration information.
Definition: ecrt.h:444
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:593
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:478
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:102
Values written by the master.
Definition: ecrt.h:419
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:446
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:200
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:291
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:128
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:504
ec_pdo_entry_info_t * entries
Array of PDO entries to map.
Definition: ecrt.h:464
void ec_voe_handler_clear(ec_voe_handler_t *voe)
VoE handler destructor.
Definition: voe_handler.c:99
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