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