OpenSourceSimWheelESP32
Open-source wireless steering wheel/button box for ESP32 boards
Loading...
Searching...
No Matches
InputHardware.hpp
Go to the documentation of this file.
1
12#pragma once
13
14//-------------------------------------------------------------------
15// Imports
16//-------------------------------------------------------------------
17
18#include "InternalTypes.hpp" // For BitQueue
20
21//-------------------------------------------------------------------
22// (Abstract) DigitalInput
23//-------------------------------------------------------------------
24
32{
33public:
38 uint64_t mask = ~0ULL;
39
40public:
41 virtual ~DigitalInput() noexcept {}
42
56 virtual uint64_t read(uint64_t lastState) = 0;
57
58protected:
64 void addToMask(uint64_t bitmap) { mask &= ~bitmap; }
65};
66
67//-------------------------------------------------------------------
68// Single button
69//-------------------------------------------------------------------
70
76{
77protected:
81 uint64_t bitmap;
82
83public:
91
92 virtual uint64_t read(uint64_t lastState) override;
93};
94
95//-------------------------------------------------------------------
96// Rotary encoder
97//-------------------------------------------------------------------
98
104{
105private:
106 InputGPIO clkPin, dtPin; // pins
107 uint8_t code; // State of the decoding algorithm
108 uint16_t sequence; // Last sequence of states
109 uint64_t cwButtonBitmap;
110 uint64_t ccwButtonBitmap;
111 BitQueue queue;
112
113 // duration of the current "pulse" event in polling cycles
114 uint8_t currentPulseWidth;
115
116 // a "virtual button" press event was notified at read(),
117 // so a release event must be notified next
118 bool pressEventNotified;
119
120 static void isrh(void *instance);
121 static void isrhAlternateEncoding(void *instance);
122
123public:
130 inline static uint8_t pulseMultiplier = 1;
131
145 InputGPIO clkPin,
146 InputGPIO dtPin,
147 InputNumber cwButtonNumber,
148 InputNumber ccwButtonNumber,
149 bool useAlternateEncoding = false);
150
159 static bool setPulseMultiplier(uint8_t multiplier)
160 {
161 if ((multiplier > 0) && (multiplier < 7) && (pulseMultiplier != multiplier))
162 {
163 pulseMultiplier = multiplier;
164 return true;
165 }
166 return false;
167 };
168
169 virtual uint64_t read(uint64_t lastState) override;
170};
171
172//-------------------------------------------------------------------
173// Button matrix
174//-------------------------------------------------------------------
175
181{
182private:
183 // InputGPIOCollection inputPins = {};
184 // OutputGPIOCollection outputPins = {};
185 ButtonMatrix matrix;
186 bool negativeLogic;
187
188public:
196 const ButtonMatrix &matrix,
197 bool negativeLogic = false);
198
199 virtual uint64_t read(uint64_t lastState) override;
200};
201
202//-------------------------------------------------------------------
203// Analog Multiplexers
204//-------------------------------------------------------------------
205
213{
214private:
215 OutputGPIOCollection selectorPins;
216 InputGPIOCollection inputPins;
217 const uint64_t *bitmap;
218 size_t switchCount;
219
220public:
230 OutputGPIO selectorPin1,
231 OutputGPIO selectorPin2,
232 OutputGPIO selectorPin3,
234
245 OutputGPIO selectorPin1,
246 OutputGPIO selectorPin2,
247 OutputGPIO selectorPin3,
248 OutputGPIO selectorPin4,
250
262 OutputGPIO selectorPin1,
263 OutputGPIO selectorPin2,
264 OutputGPIO selectorPin3,
265 OutputGPIO selectorPin4,
266 OutputGPIO selectorPin5,
268
269 virtual uint64_t read(uint64_t lastState) override;
270
271private:
272 void initializeMux();
273};
274
275//-------------------------------------------------------------------
276// Coded rotary switch
277//-------------------------------------------------------------------
278
284{
285private:
286 InputGPIOCollection inputPins;
287 uint64_t *bitmap = nullptr;
288 bool complementaryCode;
289
290public:
299 const RotaryCodedSwitch &spec,
300 const InputGPIOCollection &pins,
301 bool complementaryCode);
303
304 virtual uint64_t read(uint64_t lastState) override;
305};
306
307//-------------------------------------------------------------------
308// I2C input hardware
309//-------------------------------------------------------------------
310
316class I2CInput : public DigitalInput // : public I2CInput
317{
318protected:
320 void *device = nullptr;
321
322public:
331 uint8_t address7Bits,
332 I2CBus bus = I2CBus::PRIMARY,
333 uint8_t max_speed_mult = 1);
334
335 virtual ~I2CInput();
336};
337
343{
344private:
345 PCF8574Expander inputNumbers;
346 bool getGPIOstate(uint64_t &state);
347
348public:
357 const PCF8574Expander &inputNumbers,
358 uint8_t address7Bits,
359 I2CBus bus = I2CBus::PRIMARY);
360
361 virtual uint64_t read(uint64_t lastState) override;
362};
363
369{
370private:
371 MCP23017Expander inputNumbers;
372 bool getGPIOstate(uint64_t &state);
373 void configure();
374
375public:
384 const MCP23017Expander &inputNumbers,
385 uint8_t address7Bits,
386 I2CBus bus = I2CBus::PRIMARY);
387
388 virtual uint64_t read(uint64_t lastState) override;
389};
390
391//-------------------------------------------------------------------
392// Shift registers
393//-------------------------------------------------------------------
394
400{
401private:
402 size_t switchCount;
403 InputGPIO serialPin;
404 OutputGPIO loadPin;
405 OutputGPIO nextPin;
406 const uint64_t *bitmap;
407 bool loadHighOrLow;
408 bool nextHighToLowOrLowToHigh;
409 bool negativeLogic;
410
411public:
430 OutputGPIO loadPin,
431 OutputGPIO nextPin,
432 InputGPIO inputPin,
433 const ShiftRegisterChain &chain,
434 InputNumber SER_inputNumber = UNSPECIFIED::VALUE,
435 const bool loadHighOrLow = false,
436 const bool nextHighToLowOrLowToHigh = false,
437 const bool negativeLogic = true);
438
439 virtual uint64_t read(uint64_t lastState) override;
440};
441
442//-------------------------------------------------------------------
443// Potentiometers
444//-------------------------------------------------------------------
445
451{
452public:
459 virtual void getCalibrationData(int &minReading, int &maxReading) = 0;
460
467 virtual void setCalibrationData(int minReading, int maxReading) = 0;
468
473 virtual void resetCalibrationData() = 0;
474
483 virtual void read(uint8_t &value, bool &autoCalibrated) = 0;
484
485 virtual ~AnalogInput() noexcept {}
486};
487
493{
494protected:
504 uint8_t lastValue;
505
506public:
513
514 void resetCalibrationData() override;
515
516 void getCalibrationData(int &minReading, int &maxReading) override;
517
518 void setCalibrationData(int minReading, int maxReading) override;
519
520 void read(uint8_t &value, bool &autoCalibrated) override;
521};
522
523//-------------------------------------------------------------------
524// Fake input hardware for testing
525//-------------------------------------------------------------------
526
532{
533private:
534 FakeInput *_instance;
535
536public:
542 FakeDigitalInput(FakeInput *instance) { _instance = instance; }
543
544 virtual uint64_t read(uint64_t lastState) override
545 {
546 return _instance->state;
547 }
548};
549
554class FakeAxis : public AnalogInput
555{
556private:
557 FakeInput *_instance;
558 bool _leftOrRight;
559
560public:
568 FakeAxis(FakeInput *instance, bool leftOrRight)
569 {
570 _leftOrRight = leftOrRight;
571 _instance = instance;
572 }
573
574 void resetCalibrationData() override
575 {
576 _instance->recalibrationRequestCount++;
577 };
578
579 void getCalibrationData(int &minReading, int &maxReading) override
580 {
581 minReading = 0;
582 maxReading = 254;
583 }
584
585 void setCalibrationData(int minReading, int maxReading) override {};
586
587 void read(uint8_t &value, bool &autoCalibrated)
588 {
589 autoCalibrated = false;
590 if (_leftOrRight)
591 value = _instance->leftAxis;
592 else
593 value = _instance->rightAxis;
594 };
595};
Configure input hardware and specify input numbers.
GPIOExpanderChip< PCF8574Pin > PCF8574Expander
PCF8574 GPIO Expander for switches.
std::vector< AnalogMultiplexerChip< PinTags > > AnalogMultiplexerGroup
Group of analog multiplexer chips sharing the same selector pins.
std::vector< ShiftRegisterChip > ShiftRegisterChain
Chain of PISO shift registers for switches.
std::map< uint8_t, InputNumber > RotaryCodedSwitch
Rotary coded switch.
std::map< OutputGPIO, std::map< InputGPIO, InputNumber > > ButtonMatrix
Button matrix specification.
GPIOExpanderChip< MCP23017Pin > MCP23017Expander
MCP23017 GPIO Expander for switches.
Types and constants used everywhere for firmware implementation.
@ VALUE
Unspecified value.
I2CBus
I2C bus controller.
std::vector< InputGPIO > InputGPIOCollection
Collection of input GPIOs.
std::vector< OutputGPIO > OutputGPIOCollection
Collection of output GPIOs.
Class for analog clutch paddles.
int minADCReading
Minimum ADC reading for auto-calibration.
ADC_GPIO pinNumber
Configured ADC pin.
int maxADCReading
Maximum ADC reading for auto-calibration.
int lastADCReading
Last ADC reading.
void resetCalibrationData() override
Force auto-calibration.
AnalogClutchInput(ADC_GPIO pinNumber)
Construct a new Analog Clutch Input object.
void getCalibrationData(int &minReading, int &maxReading) override
Get auto-calibration data. Required for persistent storage.
uint8_t lastValue
Last axis position.
void setCalibrationData(int minReading, int maxReading) override
Set auto-calibration data (loaded from persistent storage).
void read(uint8_t &value, bool &autoCalibrated) override
Read current axis position. The axis must go from one end to the other for auto- calibration.
Class for all polled analog inputs (axis)
virtual void setCalibrationData(int minReading, int maxReading)=0
Set auto-calibration data (loaded from persistent storage).
virtual void getCalibrationData(int &minReading, int &maxReading)=0
Get auto-calibration data. Required for persistent storage.
virtual void resetCalibrationData()=0
Force auto-calibration.
virtual void read(uint8_t &value, bool &autoCalibrated)=0
Read current axis position. The axis must go from one end to the other for auto- calibration.
State of switches connected to analog multiplexers.
virtual uint64_t read(uint64_t lastState) override
Read the current state of the inputs (pressed or released)
AnalogMultiplexerInput(OutputGPIO selectorPin1, OutputGPIO selectorPin2, OutputGPIO selectorPin3, const AnalogMultiplexerGroup< Mux8Pin > &chips)
Construct a new Analog Multiplexer Input object.
AnalogMultiplexerInput(OutputGPIO selectorPin1, OutputGPIO selectorPin2, OutputGPIO selectorPin3, OutputGPIO selectorPin4, const AnalogMultiplexerGroup< Mux16Pin > &chips)
Construct a new Analog Multiplexer Input object.
AnalogMultiplexerInput(OutputGPIO selectorPin1, OutputGPIO selectorPin2, OutputGPIO selectorPin3, OutputGPIO selectorPin4, OutputGPIO selectorPin5, const AnalogMultiplexerGroup< Mux32Pin > &chips)
Construct a new Analog Multiplexer Input object.
Queue for 61 bits.
Button matrix hardware.
virtual uint64_t read(uint64_t lastState) override
Read the current state of the inputs (pressed or released)
ButtonMatrixInput(const ButtonMatrix &matrix, bool negativeLogic=false)
Construct a new Button Matrix Input object.
Single button.
InputGPIO pinNumber
Configured input pin.
DigitalButton(InputGPIO pinNumber, InputNumber buttonNumber)
Construct a new Digital Button object.
uint64_t bitmap
Input bitmap.
virtual uint64_t read(uint64_t lastState) override
Read the current state of the inputs (pressed or released)
Base class for all polled switches.
void addToMask(uint64_t bitmap)
Add an input bitmap to the current mask.
virtual uint64_t read(uint64_t lastState)=0
Read the current state of the inputs (pressed or released)
uint64_t mask
Input mask. For read-only.
Fake analog input for testing.
void getCalibrationData(int &minReading, int &maxReading) override
Get auto-calibration data. Required for persistent storage.
void resetCalibrationData() override
Force auto-calibration.
void setCalibrationData(int minReading, int maxReading) override
Set auto-calibration data (loaded from persistent storage).
FakeAxis(FakeInput *instance, bool leftOrRight)
Construct a new Fake Digital Input object.
void read(uint8_t &value, bool &autoCalibrated)
Read current axis position. The axis must go from one end to the other for auto- calibration.
Fake digital input for testing.
virtual uint64_t read(uint64_t lastState) override
Read the current state of the inputs (pressed or released)
FakeDigitalInput(FakeInput *instance)
Construct a new Fake Digital Input object.
Base class for switches/buttons attached to an I2C GPIO expander.
void * device
Slave device in the I2C API (must be type-casted)
I2CInput(uint8_t address7Bits, I2CBus bus=I2CBus::PRIMARY, uint8_t max_speed_mult=1)
Construct a new I2CButtonsInput object.
Class for buttons attached to a MCP23017 GPIO expander.
virtual uint64_t read(uint64_t lastState) override
Read the current state of the inputs (pressed or released)
MCP23017ButtonsInput(const MCP23017Expander &inputNumbers, uint8_t address7Bits, I2CBus bus=I2CBus::PRIMARY)
Construct a new MCP23017ButtonsInput object.
Class for buttons attached to a PCF8574 GPIO expander.
virtual uint64_t read(uint64_t lastState) override
Read the current state of the inputs (pressed or released)
PCF8574ButtonsInput(const PCF8574Expander &inputNumbers, uint8_t address7Bits, I2CBus bus=I2CBus::PRIMARY)
Construct a new PCF8574ButtonsInput object.
Class for coded rotary switches.
RotaryCodedSwitchInput(const RotaryCodedSwitch &spec, const InputGPIOCollection &pins, bool complementaryCode)
Construct a new Rotary Coded Switch Input object.
virtual uint64_t read(uint64_t lastState) override
Read the current state of the inputs (pressed or released)
Relative Rotary Encoder.
virtual uint64_t read(uint64_t lastState) override
Read the current state of the inputs (pressed or released)
static bool setPulseMultiplier(uint8_t multiplier)
Set a time multiplier for "pulse" events.
static uint8_t pulseMultiplier
Pulse multiplier for rotary encoders.
RotaryEncoderInput(InputGPIO clkPin, InputGPIO dtPin, InputNumber cwButtonNumber, InputNumber ccwButtonNumber, bool useAlternateEncoding=false)
Construct a new Rotary Encoder Input object.
State of switches connected to PISO shift registers.
ShiftRegistersInput(OutputGPIO loadPin, OutputGPIO nextPin, InputGPIO inputPin, const ShiftRegisterChain &chain, InputNumber SER_inputNumber=UNSPECIFIED::VALUE, const bool loadHighOrLow=false, const bool nextHighToLowOrLowToHigh=false, const bool negativeLogic=true)
Construct a new Shift Registers Input object.
virtual uint64_t read(uint64_t lastState) override
Read the current state of the inputs (pressed or released)
ADC-capable GPIO pin number.
Fake input specification used for testing.
uint8_t leftAxis
Left axis position.
uint8_t rightAxis
Right axis position.
size_t recalibrationRequestCount
Count of times axis recalibration was asked.
uint64_t state
Input bitmap.
Input-capable GPIO pin number.
Firmware-defined input numbers in the range [0,63] or unspecified.
Output-capable GPIO pin number.