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