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