GCC Code Coverage Report


Directory: ./
File: src/devices/Ex3xxx.h
Date: 2026-09-23 16:22:15
Exec Total Coverage
Lines: 1 1 100.0%
Branches: 0 0 -%

Line Branch Exec Source
1 /*****************************************************************************
2 *
3 * This file is part of the ecapp library (EtherCAT application devices).
4 *
5 * Copyright (C) 2026 Florian Pose <fp@igh.de>
6 *
7 * The ecapp library is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation, version 3 of the
10 * License.
11 *
12 * The ecapp library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with the ecapp library. If not, see
19 * <https://www.gnu.org/licenses/>.
20 *
21 * Beckhoff/Wago-style analog input terminals with a scaled double-value
22 * channel plus a status byte per channel: EL3008, EL3024, EL3054,
23 * EL3062(-0030), EL3068, EL3074, EL3102, EL3104, EL3122, EL3164,
24 * EL3182, EL3311, EL3318, EL3602-0010, EM3702, EPP3184. This grouping
25 * is an implementation detail -- application code never names Ex3xxx
26 * directly, it goes through createSubDevice("EL3008") and gets an
27 * EcApp::SubDevice back.
28 *
29 * A subset (EL3074, EPP3184) supports a switchable measuring range,
30 * exposed generically via the IAnalogInputType capability rather than
31 * as a plain virtual on SubDevice -- most Ex3xxx types don't have it,
32 * and every future analog family would otherwise have to grow the base
33 * interface too.
34 *
35 ****************************************************************************/
36
37 #ifndef ECAPP_EX3XXX_H
38 #define ECAPP_EX3XXX_H
39
40 /****************************************************************************/
41
42 #include "ecapp/Mode.h"
43
44 #include <ecrt.h> // EtherCAT realtime interface
45 #include <stdint.h>
46 #include <string>
47 #include <vector>
48
49 /****************************************************************************/
50
51 namespace EcApp {
52
53 class Master;
54 class Domain;
55
56 struct Ex3xxxType;
57
58 template <Mode mode>
59 class Ex3xxxAdapter; // Ex3xxx.cpp -- the SubDevice wrapping this class,
60 // friended below so it can reach the raw
61 // input/status/scale/offset vectors directly for
62 // pdserv publishing, without a dedicated getter
63 // per vector.
64
65 template <Mode mode>
66 2 class Ex3xxx
67 {
68 friend class Ex3xxxAdapter<mode>;
69
70 public:
71 enum Type {
72 EL3008,
73 EL3024,
74 EL3054,
75 EL3062,
76 EL3062_0030,
77 EL3068,
78 EL3074,
79 EL3102,
80 EL3104,
81 EL3122,
82 EL3164,
83 EL3182,
84 EL3311,
85 EL3318,
86 EL3602_0010,
87 EM3702,
88 EPP3184,
89 NumTypes
90 };
91
92 Ex3xxx(Master *, uint16_t, uint16_t, Domain *, Type);
93
94 enum InputType {
95 InputPlusMinus10V = 0,
96 Input0To20mA = 1,
97 Input4To20mA = 2,
98 InputPlusMinus20mA = 3,
99 Input0To10V = 6
100 };
101
102 // Pushes the requested range to the slave via SDO immediately; does
103 // nothing for a channel whose terminal type has no switchable range
104 // (see supportsInputType()). Must be called before the master is
105 // activated, and at most once per channel: the EtherCAT master
106 // queues every ecrt_slave_config_sdo*() call as a separate SDO
107 // download rather than replacing an earlier one for the same
108 // index/subindex, so a second call would not be an overwrite but
109 // an extra (wasted) download at activation time. Throws
110 // std::logic_error if called twice for the same channel.
111 void setInputType(unsigned int, InputType);
112
113 void update(); // reads status + scaled input for every channel
114
115 void setScale(unsigned int, double);
116 void setOffset(unsigned int, double);
117
118 uint8_t getStatus(unsigned int) const; // Control
119 double getInput(unsigned int) const; // Control
120
121 void setStatus(unsigned int, uint8_t) const; // Simulation
122 void setInput(unsigned int, double) const; // Simulation
123
124 unsigned int numChannels() const;
125 bool supportsInputType() const;
126
127 private:
128 const Ex3xxxType &type;
129 ec_slave_config_t *sc;
130 Domain *const domainIn;
131
132 std::vector<InputType> inputType;
133 std::vector<bool> inputTypeSet; // guards against a second
134 // setInputType() call per channel
135
136 std::vector<int> off_sts;
137 std::vector<int> off_in;
138 std::vector<uint8_t> status;
139 std::vector<double> scale;
140 std::vector<double> offset;
141 std::vector<double> input;
142 };
143
144 } // namespace EcApp
145
146 #endif // ECAPP_EX3XXX_H
147
148 /****************************************************************************/
149