Control Surface main
MIDI Control Surface library for Arduino
ExtendedInputOutput.cpp
Go to the documentation of this file.
2AH_DIAGNOSTIC_WERROR() // Enable errors on warnings
3
4#include "ExtendedIOElement.hpp"
6#include <AH/Error/Error.hpp>
7
9
10namespace ExtIO {
11
12template <class T>
13static bool inRange(T target, T start, T end) {
14 return target >= start && target < end;
15}
16
18 for (auto &el : ExtendedIOElement::getAll())
19 if (pin < el.getStart())
20 break;
21 else if (inRange(pin, el.getStart(), el.getEnd()))
22 return &el;
23 return nullptr;
24}
25
27 auto *el = getIOElementOfPinOrNull(pin);
28 if (el == nullptr)
30 F("The given pin does not correspond to an Extended IO element."),
31 0x8888);
32 return el;
33}
34
35template <class T>
37 return static_cast<ArduinoPin_t>(t);
38}
39
40void pinMode(pin_t pin, PinMode_t mode) {
41 if (pin == NO_PIN)
42 return; // LCOV_EXCL_LINE
43 else if (isNativePin(pin)) {
44 ::pinMode(pin, mode);
45 } else {
46 auto el = getIOElementOfPin(pin);
47 el->pinMode(pin - el->getStart(), mode);
48 }
49}
50void pinMode(int pin, PinMode_t mode) {
51 ::pinMode(arduino_pin_cast(pin), mode);
52}
53
55 if (pin == NO_PIN)
56 return; // LCOV_EXCL_LINE
57 else if (isNativePin(pin)) {
58 ::digitalWrite(pin, val);
59 } else {
60 auto el = getIOElementOfPin(pin);
61 el->digitalWrite(pin - el->getStart(), val);
62 }
63}
64void digitalWrite(int pin, PinStatus_t val) {
66}
67
69 if (pin == NO_PIN)
70 return LOW; // LCOV_EXCL_LINE
71 else if (isNativePin(pin)) {
73 } else {
74 auto el = getIOElementOfPin(pin);
75 return el->digitalRead(pin - el->getStart());
76 }
77}
80}
81
83 if (pin == NO_PIN)
84 return 0; // LCOV_EXCL_LINE
85 else if (isNativePin(pin)) {
87 } else {
88 auto el = getIOElementOfPin(pin);
89 return el->analogRead(pin - el->getStart());
90 }
91}
93
94void analogWrite(pin_t pin, analog_t val) {
95 if (pin == NO_PIN)
96 return; // LCOV_EXCL_LINE
97 else if (isNativePin(pin)) {
98#ifndef ESP32
99 ::analogWrite(pin, val);
100#endif
101 } else {
102 auto el = getIOElementOfPin(pin);
103 el->analogWrite(pin - el->getStart(), val);
104 }
105}
106void analogWrite(pin_t pin, int val) { analogWrite(pin, (analog_t)val); }
107#ifndef ESP32
108void analogWrite(int pin, analog_t val) {
110}
111void analogWrite(int pin, int val) {
113}
114#endif
115
117 if (pin == NO_PIN)
118 return; // LCOV_EXCL_LINE
119 else if (isNativePin(pin)) {
120 ::pinMode(pin, mode);
121 } else {
122 auto el = getIOElementOfPin(pin);
123 el->pinModeBuffered(pin - el->getStart(), mode);
124 }
125}
126
128 if (pin == NO_PIN)
129 return; // LCOV_EXCL_LINE
130 else if (isNativePin(pin)) {
131 ::digitalWrite(pin, val);
132 } else {
133 auto el = getIOElementOfPin(pin);
134 el->digitalWriteBuffered(pin - el->getStart(), val);
135 }
136}
137
139 if (pin == NO_PIN)
140 return LOW; // LCOV_EXCL_LINE
141 else if (isNativePin(pin)) {
143 } else {
144 auto el = getIOElementOfPin(pin);
145 return el->digitalReadBuffered(pin - el->getStart());
146 }
147}
148
150 if (pin == NO_PIN)
151 return 0; // LCOV_EXCL_LINE
152 else if (isNativePin(pin)) {
154 } else {
155 auto el = getIOElementOfPin(pin);
156 return el->analogReadBuffered(pin - el->getStart());
157 }
158 return 0;
159}
160
162 if (pin == NO_PIN)
163 return; // LCOV_EXCL_LINE
164 else if (isNativePin(pin)) {
165#ifndef ESP32
166 ::analogWrite(pin, val);
167#endif
168 } else {
169 auto el = getIOElementOfPin(pin);
170 el->analogWriteBuffered(pin - el->getStart(), val);
171 }
172}
173void analogWriteBuffered(pin_t pin, int val) {
174 analogWriteBuffered(pin, (analog_t)val);
175}
176
177void shiftOut(pin_t dataPin, pin_t clockPin, BitOrder_t bitOrder, uint8_t val) {
178 if (dataPin == NO_PIN || clockPin == NO_PIN)
179 return;
180 // Native version
181 if (isNativePin(dataPin) && isNativePin(clockPin)) {
182 ::shiftOut((int)dataPin, (int)clockPin, bitOrder, val);
183 }
184 // ExtIO version
185 else if (!isNativePin(dataPin) && !isNativePin(clockPin)) {
186 auto dataEl = getIOElementOfPin(dataPin);
187 auto dataPinN = dataPin - dataEl->getStart();
188 auto clockEl = getIOElementOfPin(clockPin);
189 auto clockPinN = clockPin - clockEl->getStart();
190 for (uint8_t i = 0; i < 8; i++) {
191 uint8_t mask = bitOrder == LSBFIRST ? (1 << i) : (1 << (7 - i));
192 dataEl->digitalWrite(dataPinN, (val & mask) ? HIGH : LOW);
193 clockEl->digitalWrite(clockPinN, HIGH);
194 clockEl->digitalWrite(clockPinN, LOW);
195 }
196 }
197 // Mixed version (slow)
198 else {
199 for (uint8_t i = 0; i < 8; i++) {
200 uint8_t mask = bitOrder == LSBFIRST ? (1 << i) : (1 << (7 - i));
201 digitalWrite(dataPin, (val & mask) ? HIGH : LOW);
202 digitalWrite(clockPin, HIGH);
203 digitalWrite(clockPin, LOW);
204 }
205 }
206}
207void shiftOut(int dataPin, int clockPin, BitOrder_t bitOrder, uint8_t val) {
208 ::shiftOut(arduino_pin_cast(dataPin), arduino_pin_cast(clockPin), bitOrder,
209 val);
210}
211
212#if UINT16_MAX != UINT_MAX
213void pinMode(unsigned int pin, PinMode_t mode) {
214 ::pinMode(arduino_pin_cast(pin), mode);
215}
216void digitalWrite(unsigned int pin, PinStatus_t val) {
218}
219PinStatus_t digitalRead(unsigned int pin) {
221}
222analog_t analogRead(unsigned int pin) {
224}
225#ifndef ESP32
226void analogWrite(unsigned int pin, analog_t val) {
228}
229void analogWrite(unsigned int pin, int val) {
231}
232#endif
233void shiftOut(unsigned int dataPin, unsigned int clockPin, BitOrder_t bitOrder,
234 uint8_t val) {
235 ::shiftOut(arduino_pin_cast(dataPin), arduino_pin_cast(clockPin), bitOrder,
236 val);
237}
238#endif
239
240} // namespace ExtIO
241
243
#define END_AH_NAMESPACE
#define BEGIN_AH_NAMESPACE
constexpr PinStatus_t LOW
AH::function_traits< decltype(::digitalWrite)>::argument_t< 0 > ArduinoPin_t
uint8_t BitOrder_t
constexpr PinStatus_t HIGH
AH::function_traits< decltype(::pinMode)>::argument_t< 1 > PinMode_t
AH::function_traits< decltype(::digitalWrite)>::argument_t< 1 > PinStatus_t
#define AH_DIAGNOSTIC_POP()
Definition: Warnings.hpp:37
#define AH_DIAGNOSTIC_WERROR()
Definition: Warnings.hpp:36
An abstract base class for Extended Input/Output elements.
#define FATAL_ERROR(msg, errc)
Print the error message and error code, and stop the execution.
Definition: Error.hpp:60
PinStatus_t digitalRead(int pin)
Overload to Arduino digitalRead function.
bool isNativePin(pin_t pin)
Check if the given pin number is a real Arduino pin number, and not an ExtIO pin number.
void pinModeBuffered(pin_t pin, PinMode_t mode)
A buffered ExtIO version of the Arduino function.
ExtendedIOElement * getIOElementOfPin(pin_t pin)
Find the IO element of a given extended IO pin number.
void digitalWriteBuffered(pin_t pin, PinStatus_t val)
A buffered ExtIO version of the Arduino function.
ExtendedIOElement * getIOElementOfPinOrNull(pin_t pin)
Find the IO element of a given extended IO pin number.
void shiftOut(int dataPin, int clockPin, BitOrder_t bitOrder, uint8_t val)
Overload to Arduino shiftOut function.
void analogWriteBuffered(pin_t pin, int val)
A buffered ExtIO version of the Arduino function.
PinStatus_t digitalReadBuffered(pin_t pin)
A buffered ExtIO version of the Arduino function.
void digitalWrite(int pin, PinStatus_t val)
Overload to Arduino digitalWrite function.
void analogWrite(int pin, int val)
Overload to Arduino analogWrite function.
void pinMode(int pin, PinMode_t mode)
Overload to Arduino pinMode function.
analog_t analogReadBuffered(pin_t pin)
A buffered ExtIO version of the Arduino function.
analog_t analogRead(int pin)
Overload to Arduino analogRead function.
static bool inRange(T target, T start, T end)
ArduinoPin_t arduino_pin_cast(T t)
uint16_t analog_t
The type returned from analogRead and similar functions.
constexpr pin_t NO_PIN
A special pin number that indicates an unused or invalid pin.
uint16_t pin_t
The type for Arduino pins (and ExtendedIOElement pins).