GCC Code Coverage Report


Directory: ./
File: src/devices/Ex3xxx.h
Date: 2026-09-03 16:05:57
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 <pdserv.h>
46 #include <stdint.h>
47 #include <string>
48 #include <vector>
49
50 /****************************************************************************/
51
52 namespace EcApp {
53
54 class Master;
55 class Domain;
56
57 struct Ex3xxxType;
58
59 template <Mode mode>
60 2 class Ex3xxx
61 {
62 public:
63 enum Type {
64 EL3008,
65 EL3024,
66 EL3054,
67 EL3062,
68 EL3062_0030,
69 EL3068,
70 EL3074,
71 EL3102,
72 EL3104,
73 EL3122,
74 EL3164,
75 EL3182,
76 EL3311,
77 EL3318,
78 EL3602_0010,
79 EM3702,
80 EPP3184,
81 NumTypes
82 };
83
84 Ex3xxx(pdserv *,
85 pdtask *,
86 const std::string &,
87 Master *,
88 uint16_t,
89 uint16_t,
90 Domain *,
91 Type);
92
93 enum InputType {
94 InputPlusMinus10V = 0,
95 Input0To20mA = 1,
96 Input4To20mA = 2,
97 InputPlusMinus20mA = 3,
98 Input0To10V = 6
99 };
100
101 // Pushes the requested range to the slave via SDO immediately; does
102 // nothing for a channel whose terminal type has no switchable range
103 // (see supportsInputType()). Must be called before the master is
104 // activated, and at most once per channel: the EtherCAT master
105 // queues every ecrt_slave_config_sdo*() call as a separate SDO
106 // download rather than replacing an earlier one for the same
107 // index/subindex, so a second call would not be an overwrite but
108 // an extra (wasted) download at activation time. Throws
109 // std::logic_error if called twice for the same channel.
110 void setInputType(unsigned int, InputType);
111
112 void update(); // reads status + scaled input for every channel
113
114 void setScale(unsigned int, double);
115 void setOffset(unsigned int, double);
116
117 uint8_t getStatus(unsigned int) const; // Control
118 double getInput(unsigned int) const; // Control
119
120 void setStatus(unsigned int, uint8_t) const; // Simulation
121 void setInput(unsigned int, double) const; // Simulation
122
123 unsigned int numChannels() const;
124 bool supportsInputType() const;
125
126 private:
127 const Ex3xxxType &type;
128 ec_slave_config_t *sc;
129 Domain *const domainIn;
130
131 std::vector<InputType> inputType;
132 std::vector<bool> inputTypeSet; // guards against a second
133 // setInputType() call per channel
134
135 std::vector<int> off_sts;
136 std::vector<int> off_in;
137 std::vector<uint8_t> status;
138 std::vector<double> scale;
139 std::vector<double> offset;
140 std::vector<double> input;
141 };
142
143 } // namespace EcApp
144
145 #endif // ECAPP_EX3XXX_H
146
147 /****************************************************************************/
148