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