-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathiopin.hpp
328 lines (241 loc) · 9.91 KB
/
iopin.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
// SPDX-License-Identifier: GPL-3.0-or-later
//
// Copyright (c) 2013-2023 plan44.ch / Lukas Zeller, Zurich, Switzerland
//
// Author: Lukas Zeller <luz@plan44.ch>
//
// This file is part of p44utils.
//
// p44utils is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// p44utils is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with p44utils. If not, see <http://www.gnu.org/licenses/>.
//
#ifndef __p44utils__iopin__
#define __p44utils__iopin__
#include "p44utils_main.hpp"
#ifndef DISABLE_CONSOLEKEY
#include "consolekey.hpp"
#endif
using namespace std;
namespace p44 {
// MARK: - digital pins
/// callback for input pin state change reporting
/// @param aNewState the new state of the Input pin
typedef boost::function<void (bool aNewState)> InputChangedCB;
/// wrapper class for digital I/O pin
class IOPin : public P44Obj
{
protected:
InputChangedCB inputChangedCB;
bool currentState;
bool invertedReporting;
MLTicket pollTicket;
MLMicroSeconds pollInterval;
MLMicroSeconds debounceTime;
MLMicroSeconds lastReportedChange;
MLTicket debounceTicket;
/// this can be called by derived classes' input change detection or polling routine to report the current input state
/// Note: the current state does not necessarily need to be "new", inputHasChangedTo() prevents re-reporting the same state
void inputHasChangedTo(bool aCurrentState);
public:
IOPin();
virtual ~IOPin();
/// get state of pin
/// @return current state (from actual GPIO pin for inputs, from last set state for outputs)
virtual bool getState() = 0;
/// install state change detector
/// @param aInputChangedCB will be called when the input state changes. Passing NULL disables input state change reporting.
/// @param aInverted if set, the state will be reported inverted to what getState() would report. This is a shortcut
/// for efficient implementation of higher level classes (which support inverting), to avoid two stage callbacks
/// @param aInitialState the initial state (of the pin) assumed present when callback is installed
/// @param aDebounceTime after a reported state change, next input sampling will take place only after specified interval
/// @param aPollInterval if <0 (Infinite), the state change detector only works if the input pin supports state change
/// detection without polling (e.g. with GPIO edge trigger). If aPollInterval is >=0, and the
/// input pin does not support edge detection, the state detection will be implemented via polling
/// on the current mainloop - if pollInterval==0 then polling will be done with a default interval, otherwise in
/// the specified interval
/// @return true if input supports the type of state change detection requested
virtual bool setInputChangedHandler(InputChangedCB aInputChangedCB, bool aInverted, bool aInitialState, MLMicroSeconds aDebounceTime, MLMicroSeconds aPollInterval);
/// set state of pin (NOP for inputs)
/// @param aState new state to set output to
virtual void setState(bool aState) = 0;
private:
void clearChangeHandling();
void timedpoll(MLTimer &aTimer);
void debounceSample();
};
typedef boost::intrusive_ptr<IOPin> IOPinPtr;
/// simulated digital I/O pin
class SimPin : public IOPin
{
typedef IOPin inherited;
#ifndef DISABLE_CONSOLEKEY
ConsoleKeyPtr consoleKey;
#endif
bool output;
string name;
bool pinState;
public:
// create a simulated pin (using console I/O)
SimPin(const char *aName, bool aOutput, bool aInitialState);
/// get state of pin
/// @return current state (from actual GPIO pin for inputs, from last set state for outputs)
virtual bool getState();
/// set state of pin (NOP for inputs)
/// @param aState new state to set output to
virtual void setState(bool aState);
};
/// missing (dummy) digital I/O pin
class MissingPin : public IOPin
{
typedef IOPin inherited;
bool pinState;
public:
// create a missing pin (not connected, just keeping state)
MissingPin(bool aInitialState) : pinState(aInitialState) {};
/// get state of pin
/// @return current state (from actual GPIO pin for inputs, from last set state for outputs)
virtual bool getState() { return pinState; } // return state (which is initialstate or state set with setState later on)
/// set state of pin (NOP)
/// @param aState new state (changes initial state)
virtual void setState(bool aState) { pinState = aState; }; // remember
};
#if !DISABLE_SYSTEMCMDIO && !defined(ESP_PLATFORM)
/// Digital System Command I/O pin
class SysCommandPin : public IOPin
{
typedef IOPin inherited;
string onCommand;
string offCommand;
bool pinState;
bool output;
bool changing;
bool changePending;
public:
// create a pin using a command line to act
SysCommandPin(const char *aConfig, bool aOutput, bool aInitialState);
/// get state of pin
/// @return current state (from actual GPIO pin for inputs, from last set state for outputs)
virtual bool getState() { return pinState; } // return state (which is initialstate or state set with setState later on)
/// set state of pin (NOP for inputs)
/// @param aState new state to set output to
virtual void setState(bool aState);
private:
string stateSetCommand(bool aState);
void applyState(bool aState);
void stateUpdated(ErrorPtr aError, const string &aOutputString);
};
#endif // !DISABLE_SYSTEMCMDIO && !defined(ESP_PLATFORM)
// MARK: - analog pins
/// abstract wrapper class for analog I/O pin
class AnalogIOPin : public P44Obj
{
public:
/// get value of pin
/// @return current value (from actual pin for inputs, from last set state for outputs)
virtual double getValue() = 0;
/// set value of pin (NOP for inputs)
/// @param aValue new value to set output to
virtual void setValue(double aValue) = 0;
/// get range and resolution of this input
/// @param aMin minimum value
/// @param aMax maximum value
/// @param aResolution resolution (LSBit value)
/// @return false if no range information is available (arguments are not touched then)
virtual bool getRange(double &aMin, double &aMax, double &aResolution) { return false; };
};
typedef boost::intrusive_ptr<AnalogIOPin> AnalogIOPinPtr;
/// simulated I/O pin
class AnalogSimPin : public AnalogIOPin
{
typedef AnalogIOPin inherited;
#ifndef DISABLE_CONSOLEKEY
ConsoleKeyPtr consoleKeyUp;
ConsoleKeyPtr consoleKeyDown;
#endif
bool output;
string name;
double pinValue;
public:
// create a simulated pin (using console I/O)
AnalogSimPin(const char *aName, bool aOutput, double aInitialValue);
/// get value of pin
/// @return current value (from actual pin for inputs, from last set state for outputs)
virtual double getValue();
/// set value of pin (NOP for inputs)
/// @param aValue new value to set output to
virtual void setValue(double aValue);
#ifndef DISABLE_CONSOLEKEY
void simKeyPress(int aDir, bool aNewState);
#endif
};
/// missing (dummy) I/O pin
class AnalogMissingPin : public AnalogIOPin
{
typedef AnalogIOPin inherited;
double pinValue;
public:
// create a missing pin (not connected, just keeping state)
AnalogMissingPin(double aInitialValue) : pinValue(aInitialValue) {};
/// get value of pin
/// @return current value (from actual pin for inputs, from last set state for outputs)
virtual double getValue() { return pinValue; } // return value (which is initial value or value set with setValue later on)
/// set value of pin (NOP for inputs)
/// @param aValue new value to set output to
virtual void setValue(double aValue) { pinValue = aValue; } // remember
};
#if !DISABLE_SYSTEMCMDIO && !defined(ESP_PLATFORM)
/// Digital System Command I/O pin
class AnalogSysCommandPin : public AnalogIOPin
{
typedef AnalogIOPin inherited;
string setCommand;
double pinValue;
int range;
bool output;
bool changing;
bool changePending;
public:
// create a pin using a command line to act
AnalogSysCommandPin(const char *aConfig, bool aOutput, double aInitialValue);
/// get value of pin
/// @return current value (from actual pin for inputs, from last set state for outputs)
virtual double getValue() { return pinValue; } // return value (which is initial value or value set with setValue later on)
/// set value of pin (NOP for inputs)
/// @param aValue new value to set output to
virtual void setValue(double aValue);
private:
string valueSetCommand(double aValue);
void applyValue(double aValue);
void valueUpdated(ErrorPtr aError, const string &aOutputString);
};
#endif // !DISABLE_SYSTEMCMDIO && !defined(ESP_PLATFORM)
/// simulated I/O pin via file device
class AnalogSimPinFd : public AnalogIOPin
{
typedef AnalogIOPin inherited;
bool output;
string name;
int fd;
double pinValue;
public:
// create a simulated pin (using console I/O)
AnalogSimPinFd(const char *aName, bool aOutput, double aInitialValue);
/// get value of pin
/// @return current value (from actual pin for inputs, from last set state for outputs)
virtual double getValue();
/// set value of pin (NOP for inputs)
/// @param aValue new value to set output to
virtual void setValue(double aValue);
};
} // namespace
#endif /* defined(__p44utils__iopin__) */