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 
706 
707  if (sync_info->n_pdos && sync_info->pdos) {
708 
709  for (j = 0; j < sync_info->n_pdos; j++) {
710  pdo_info = &sync_info->pdos[j];
711 
713  sc, sync_info->index, pdo_info->index);
714  if (ret)
715  return ret;
716 
718 
719  if (pdo_info->n_entries && pdo_info->entries) {
720  for (k = 0; k < pdo_info->n_entries; k++) {
721  entry_info = &pdo_info->entries[k];
722 
724  pdo_info->index, entry_info->index,
725  entry_info->subindex,
726  entry_info->bit_length);
727  if (ret)
728  return ret;
729  }
730  }
731  }
732  }
733  }
734 
735  return 0;
736 }
737 
738 /*****************************************************************************/
739 
741  ec_slave_config_t *sc,
742  uint16_t index,
743  uint8_t subindex,
744  ec_domain_t *domain,
745  unsigned int *bit_position
746  )
747 {
748  uint8_t sync_index;
749  const ec_sync_config_t *sync_config;
750  unsigned int bit_offset, bit_pos;
751  ec_pdo_t *pdo;
752  ec_pdo_entry_t *entry;
753  int sync_offset;
754 
755  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
756  "subindex = 0x%02X, domain = 0x%p, bit_position = 0x%p)\n",
757  __func__, sc, index, subindex, domain, bit_position);
758 
759  for (sync_index = 0; sync_index < EC_MAX_SYNC_MANAGERS; sync_index++) {
760  sync_config = &sc->sync_configs[sync_index];
761  bit_offset = 0;
762 
763  list_for_each_entry(pdo, &sync_config->pdos.list, list) {
764  list_for_each_entry(entry, &pdo->entries, list) {
765  if (entry->index != index || entry->subindex != subindex) {
766  bit_offset += entry->bit_length;
767  } else {
768  bit_pos = bit_offset % 8;
769  if (bit_position) {
770  *bit_position = bit_pos;
771  } else if (bit_pos) {
772  EC_CONFIG_ERR(sc, "PDO entry 0x%04X:%02X does"
773  " not byte-align.\n", index, subindex);
774  return -EFAULT;
775  }
776 
777  sync_offset = ec_slave_config_prepare_fmmu(
778  sc, domain, sync_index, sync_config->dir);
779  if (sync_offset < 0)
780  return sync_offset;
781 
782  return sync_offset + bit_offset / 8;
783  }
784  }
785  }
786  }
787 
788  EC_CONFIG_ERR(sc, "PDO entry 0x%04X:%02X is not mapped.\n",
789  index, subindex);
790  return -ENOENT;
791 }
792 
793 /*****************************************************************************/
794 
796  ec_slave_config_t *sc,
797  uint8_t sync_index,
798  unsigned int pdo_pos,
799  unsigned int entry_pos,
800  ec_domain_t *domain,
801  unsigned int *bit_position
802  )
803 {
804  const ec_sync_config_t *sync_config;
805  unsigned int bit_offset, pp, ep;
806  ec_pdo_t *pdo;
807  ec_pdo_entry_t *entry;
808 
809  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, sync_index = %u, pdo_pos = %u,"
810  " entry_pos = %u, domain = 0x%p, bit_position = 0x%p)\n",
811  __func__, sc, sync_index, pdo_pos, entry_pos,
812  domain, bit_position);
813 
814  if (sync_index >= EC_MAX_SYNC_MANAGERS) {
815  EC_CONFIG_ERR(sc, "Invalid syncmanager position %u.\n", sync_index);
816  return -EINVAL;
817  }
818 
819  sync_config = &sc->sync_configs[sync_index];
820  bit_offset = 0;
821  pp = 0;
822 
823  list_for_each_entry(pdo, &sync_config->pdos.list, list) {
824  ep = 0;
825  list_for_each_entry(entry, &pdo->entries, list) {
826  if (pp != pdo_pos || ep != entry_pos) {
827  bit_offset += entry->bit_length;
828  } else {
829  unsigned int bit_pos = bit_offset % 8;
830  int sync_offset;
831 
832  if (bit_position) {
833  *bit_position = bit_pos;
834  } else if (bit_pos) {
835  EC_CONFIG_ERR(sc, "PDO entry 0x%04X:%02X does"
836  " not byte-align.\n",
837  pdo->index, entry->subindex);
838  return -EFAULT;
839  }
840 
841  sync_offset = ec_slave_config_prepare_fmmu(
842  sc, domain, sync_index, sync_config->dir);
843  if (sync_offset < 0)
844  return sync_offset;
845 
846  return sync_offset + bit_offset / 8;
847  }
848  ep++;
849  }
850  pp++;
851  }
852 
853  EC_CONFIG_ERR(sc, "PDO entry specification %u/%u/%u out of range.\n",
854  sync_index, pdo_pos, entry_pos);
855  return -ENOENT;
856 }
857 
858 /*****************************************************************************/
859 
860 void ecrt_slave_config_dc(ec_slave_config_t *sc, uint16_t assign_activate,
861  uint32_t sync0_cycle_time, int32_t sync0_shift_time,
862  uint32_t sync1_cycle_time, int32_t sync1_shift_time)
863 {
864  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, assign_activate = 0x%04X,"
865  " sync0_cycle = %u, sync0_shift = %i,"
866  " sync1_cycle = %u, sync1_shift = %i\n",
867  __func__, sc, assign_activate, sync0_cycle_time, sync0_shift_time,
868  sync1_cycle_time, sync1_shift_time);
869 
870  sc->dc_assign_activate = assign_activate;
871  sc->dc_sync[0].cycle_time = sync0_cycle_time;
872  sc->dc_sync[0].shift_time = sync0_shift_time;
873  sc->dc_sync[1].cycle_time = sync1_cycle_time;
874  sc->dc_sync[1].shift_time = sync1_shift_time;
875 }
876 
877 /*****************************************************************************/
878 
879 int ecrt_slave_config_sdo(ec_slave_config_t *sc, uint16_t index,
880  uint8_t subindex, const uint8_t *data, size_t size)
881 {
882  ec_slave_t *slave = sc->slave;
883  ec_sdo_request_t *req;
884  int ret;
885 
886  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
887  "subindex = 0x%02X, data = 0x%p, size = %zu)\n",
888  __func__, sc, index, subindex, data, size);
889 
890  if (slave && !(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
891  EC_CONFIG_WARN(sc, "Attached slave does not support CoE!\n");
892  }
893 
894  if (!(req = (ec_sdo_request_t *)
895  kmalloc(sizeof(ec_sdo_request_t), GFP_KERNEL))) {
896  EC_CONFIG_ERR(sc, "Failed to allocate memory for"
897  " SDO configuration!\n");
898  return -ENOMEM;
899  }
900 
901  ec_sdo_request_init(req);
902  ecrt_sdo_request_index(req, index, subindex);
903 
904  ret = ec_sdo_request_copy_data(req, data, size);
905  if (ret < 0) {
907  kfree(req);
908  return ret;
909  }
910 
911  down(&sc->master->master_sem);
912  list_add_tail(&req->list, &sc->sdo_configs);
913  up(&sc->master->master_sem);
914  return 0;
915 }
916 
917 /*****************************************************************************/
918 
920  uint8_t subindex, uint8_t value)
921 {
922  uint8_t data[1];
923 
924  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
925  "subindex = 0x%02X, value = %u)\n",
926  __func__, sc, index, subindex, (unsigned int) value);
927 
928  EC_WRITE_U8(data, value);
929  return ecrt_slave_config_sdo(sc, index, subindex, data, 1);
930 }
931 
932 /*****************************************************************************/
933 
935  uint8_t subindex, uint16_t value)
936 {
937  uint8_t data[2];
938 
939  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
940  "subindex = 0x%02X, value = %u)\n",
941  __func__, sc, index, subindex, value);
942 
943  EC_WRITE_U16(data, value);
944  return ecrt_slave_config_sdo(sc, index, subindex, data, 2);
945 }
946 
947 /*****************************************************************************/
948 
950  uint8_t subindex, uint32_t value)
951 {
952  uint8_t data[4];
953 
954  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
955  "subindex = 0x%02X, value = %u)\n",
956  __func__, sc, index, subindex, value);
957 
958  EC_WRITE_U32(data, value);
959  return ecrt_slave_config_sdo(sc, index, subindex, data, 4);
960 }
961 
962 /*****************************************************************************/
963 
965  const uint8_t *data, size_t size)
966 {
967  ec_slave_t *slave = sc->slave;
968  ec_sdo_request_t *req;
969  int ret;
970 
971  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, index = 0x%04X, "
972  "data = 0x%p, size = %zu)\n", __func__, sc, index, data, size);
973 
974  if (slave && !(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
975  EC_CONFIG_WARN(sc, "Attached slave does not support CoE!\n");
976  }
977 
978  if (!(req = (ec_sdo_request_t *)
979  kmalloc(sizeof(ec_sdo_request_t), GFP_KERNEL))) {
980  EC_CONFIG_ERR(sc, "Failed to allocate memory for"
981  " SDO configuration!\n");
982  return -ENOMEM;
983  }
984 
985  ec_sdo_request_init(req);
986  ecrt_sdo_request_index(req, index, 0);
987  req->complete_access = 1;
988 
989  ret = ec_sdo_request_copy_data(req, data, size);
990  if (ret < 0) {
992  kfree(req);
993  return ret;
994  }
995 
996  down(&sc->master->master_sem);
997  list_add_tail(&req->list, &sc->sdo_configs);
998  up(&sc->master->master_sem);
999  return 0;
1000 }
1001 
1002 /*****************************************************************************/
1003 
1005 {
1006  return ec_coe_emerg_ring_size(&sc->emerg_ring, elements);
1007 }
1008 
1009 /*****************************************************************************/
1010 
1012 {
1013  return ec_coe_emerg_ring_pop(&sc->emerg_ring, target);
1014 }
1015 
1016 /*****************************************************************************/
1017 
1019 {
1021 }
1022 
1023 /*****************************************************************************/
1024 
1026 {
1028 }
1029 
1030 /*****************************************************************************/
1031 
1036  ec_slave_config_t *sc, uint16_t index, uint8_t subindex, size_t size)
1037 {
1038  ec_sdo_request_t *req;
1039  int ret;
1040 
1041  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, "
1042  "index = 0x%04X, subindex = 0x%02X, size = %zu)\n",
1043  __func__, sc, index, subindex, size);
1044 
1045  if (!(req = (ec_sdo_request_t *)
1046  kmalloc(sizeof(ec_sdo_request_t), GFP_KERNEL))) {
1047  EC_CONFIG_ERR(sc, "Failed to allocate SDO request memory!\n");
1048  return ERR_PTR(-ENOMEM);
1049  }
1050 
1051  ec_sdo_request_init(req);
1052  ecrt_sdo_request_index(req, index, subindex);
1053 
1054  ret = ec_sdo_request_alloc(req, size);
1055  if (ret < 0) {
1056  ec_sdo_request_clear(req);
1057  kfree(req);
1058  return ERR_PTR(ret);
1059  }
1060 
1061  // prepare data for optional writing
1062  memset(req->data, 0x00, size);
1063  req->data_size = size;
1064 
1065  down(&sc->master->master_sem);
1066  list_add_tail(&req->list, &sc->sdo_requests);
1067  up(&sc->master->master_sem);
1068 
1069  return req;
1070 }
1071 
1072 /*****************************************************************************/
1073 
1075  ec_slave_config_t *sc, uint16_t index, uint8_t subindex, size_t size)
1076 {
1078  subindex, size);
1079  return IS_ERR(s) ? NULL : s;
1080 }
1081 
1082 /*****************************************************************************/
1083 
1088  ec_slave_config_t *sc, size_t size)
1089 {
1090  ec_reg_request_t *reg;
1091  int ret;
1092 
1093  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, size = %zu)\n",
1094  __func__, sc, size);
1095 
1096  if (!(reg = (ec_reg_request_t *)
1097  kmalloc(sizeof(ec_reg_request_t), GFP_KERNEL))) {
1098  EC_CONFIG_ERR(sc, "Failed to allocate register request memory!\n");
1099  return ERR_PTR(-ENOMEM);
1100  }
1101 
1102  ret = ec_reg_request_init(reg, size);
1103  if (ret) {
1104  kfree(reg);
1105  return ERR_PTR(ret);
1106  }
1107 
1108  down(&sc->master->master_sem);
1109  list_add_tail(&reg->list, &sc->reg_requests);
1110  up(&sc->master->master_sem);
1111 
1112  return reg;
1113 }
1114 
1115 /*****************************************************************************/
1116 
1118  ec_slave_config_t *sc, size_t size)
1119 {
1120  ec_reg_request_t *reg =
1122  return IS_ERR(reg) ? NULL : reg;
1123 }
1124 
1125 /*****************************************************************************/
1126 
1131  ec_slave_config_t *sc, size_t size)
1132 {
1133  ec_voe_handler_t *voe;
1134  int ret;
1135 
1136  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, size = %zu)\n", __func__, sc, size);
1137 
1138  if (!(voe = (ec_voe_handler_t *)
1139  kmalloc(sizeof(ec_voe_handler_t), GFP_KERNEL))) {
1140  EC_CONFIG_ERR(sc, "Failed to allocate VoE request memory!\n");
1141  return ERR_PTR(-ENOMEM);
1142  }
1143 
1144  ret = ec_voe_handler_init(voe, sc, size);
1145  if (ret < 0) {
1146  kfree(voe);
1147  return ERR_PTR(ret);
1148  }
1149 
1150  down(&sc->master->master_sem);
1151  list_add_tail(&voe->list, &sc->voe_handlers);
1152  up(&sc->master->master_sem);
1153 
1154  return voe;
1155 }
1156 
1157 /*****************************************************************************/
1158 
1160  ec_slave_config_t *sc, size_t size)
1161 {
1163  size);
1164  return IS_ERR(voe) ? NULL : voe;
1165 }
1166 
1167 /*****************************************************************************/
1168 
1170  ec_slave_config_state_t *state)
1171 {
1172  state->online = sc->slave ? 1 : 0;
1173  if (state->online) {
1174  state->operational =
1176  && !sc->slave->force_config;
1177  state->al_state = sc->slave->current_state;
1178  } else {
1179  state->operational = 0;
1181  }
1182 }
1183 
1184 /*****************************************************************************/
1185 
1186 int ecrt_slave_config_idn(ec_slave_config_t *sc, uint8_t drive_no,
1187  uint16_t idn, ec_al_state_t state, const uint8_t *data,
1188  size_t size)
1189 {
1190  ec_slave_t *slave = sc->slave;
1191  ec_soe_request_t *req;
1192  int ret;
1193 
1194  EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, drive_no = %u, idn = 0x%04X, "
1195  "state = %u, data = 0x%p, size = %zu)\n",
1196  __func__, sc, drive_no, idn, state, data, size);
1197 
1198  if (drive_no > 7) {
1199  EC_CONFIG_ERR(sc, "Invalid drive number %u!\n",
1200  (unsigned int) drive_no);
1201  return -EINVAL;
1202  }
1203 
1204  if (state != EC_AL_STATE_PREOP && state != EC_AL_STATE_SAFEOP) {
1205  EC_CONFIG_ERR(sc, "AL state for IDN config"
1206  " must be PREOP or SAFEOP!\n");
1207  return -EINVAL;
1208  }
1209 
1210  if (slave && !(slave->sii.mailbox_protocols & EC_MBOX_SOE)) {
1211  EC_CONFIG_WARN(sc, "Attached slave does not support SoE!\n");
1212  }
1213 
1214  if (!(req = (ec_soe_request_t *)
1215  kmalloc(sizeof(ec_soe_request_t), GFP_KERNEL))) {
1216  EC_CONFIG_ERR(sc, "Failed to allocate memory for"
1217  " IDN configuration!\n");
1218  return -ENOMEM;
1219  }
1220 
1221  ec_soe_request_init(req);
1222  ec_soe_request_set_drive_no(req, drive_no);
1223  ec_soe_request_set_idn(req, idn);
1224  req->al_state = state;
1225 
1226  ret = ec_soe_request_copy_data(req, data, size);
1227  if (ret < 0) {
1228  ec_soe_request_clear(req);
1229  kfree(req);
1230  return ret;
1231  }
1232 
1233  down(&sc->master->master_sem);
1234  list_add_tail(&req->list, &sc->soe_configs);
1235  up(&sc->master->master_sem);
1236  return 0;
1237 }
1238 
1239 /*****************************************************************************/
1240 
1243 EXPORT_SYMBOL(ecrt_slave_config_sync_manager);
1244 EXPORT_SYMBOL(ecrt_slave_config_watchdog);
1245 EXPORT_SYMBOL(ecrt_slave_config_pdo_assign_add);
1246 EXPORT_SYMBOL(ecrt_slave_config_pdo_assign_clear);
1247 EXPORT_SYMBOL(ecrt_slave_config_pdo_mapping_add);
1249 EXPORT_SYMBOL(ecrt_slave_config_pdos);
1250 EXPORT_SYMBOL(ecrt_slave_config_reg_pdo_entry);
1251 EXPORT_SYMBOL(ecrt_slave_config_dc);
1252 EXPORT_SYMBOL(ecrt_slave_config_sdo);
1253 EXPORT_SYMBOL(ecrt_slave_config_sdo8);
1254 EXPORT_SYMBOL(ecrt_slave_config_sdo16);
1255 EXPORT_SYMBOL(ecrt_slave_config_sdo32);
1256 EXPORT_SYMBOL(ecrt_slave_config_complete_sdo);
1257 EXPORT_SYMBOL(ecrt_slave_config_emerg_size);
1258 EXPORT_SYMBOL(ecrt_slave_config_emerg_pop);
1259 EXPORT_SYMBOL(ecrt_slave_config_emerg_clear);
1260 EXPORT_SYMBOL(ecrt_slave_config_emerg_overruns);
1264 EXPORT_SYMBOL(ecrt_slave_config_state);
1265 EXPORT_SYMBOL(ecrt_slave_config_idn);
1266 
1269 /*****************************************************************************/
uint16_t ring_position
Ring position.
Definition: slave.h:183
Pre-operational.
Definition: ecrt.h:534
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:464
FMMU configuration.
Definition: fmmu_config.h:46
uint8_t bit_length
Size of the PDO entry in bit.
Definition: ecrt.h:451
ec_direction_t dir
Sync manager direction.
Definition: ecrt.h:485
ec_watchdog_mode_t
Watchdog mode for sync manager configuration.
Definition: ecrt.h:434
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:879
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:532
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:487
int ecrt_slave_config_pdo_assign_add(ec_slave_config_t *sc, uint8_t sync_index, uint16_t pdo_index)
Add a PDO to a sync manager&#39;s PDO assignment.
Definition: slave_config.c: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:535
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:2231
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:795
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:462
#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:1834
Sync manager configuration information.
Definition: ecrt.h:481
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:860
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:934
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:463
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:964
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:310
ec_watchdog_mode_t watchdog_mode
Watchdog mode.
Definition: ecrt.h:489
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:486
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:2265
unsigned int al_state
The application-layer state of the slave.
Definition: ecrt.h:314
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: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:312
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:2248
#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:421
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:949
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:424
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:311
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:919
int ecrt_slave_config_pdo_mapping_add(ec_slave_config_t *sc, uint16_t pdo_index, uint16_t entry_index, uint8_t entry_subindex, uint8_t entry_bit_length)
Add a PDO entry to the given PDO&#39;s mapping.
Definition: slave_config.c: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:740
uint16_t index
PDO entry index.
Definition: ecrt.h:449
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:200
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:422
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&#39;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:448
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&#39;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:482
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:423
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:450
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:204
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:468
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