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