Arduino Helpers master
Utility library for Arduino
ExtendedInputOutput.cpp
Go to the documentation of this file.
3#include <AH/Error/Error.hpp>
4
6
7namespace ExtIO {
8
9template <class T>
10static bool inRange(T target, T start, T end) {
11 return target >= start && target < end;
12}
13
15 for (auto &el : ExtendedIOElement::getAll())
16 if (pin < el.getStart())
17 break;
18 else if (inRange(pin, el.getStart(), el.getEnd()))
19 return &el;
20 return nullptr;
21}
22
24 auto *el = getIOElementOfPinOrNull(pin);
25 if (el == nullptr)
27 F("The given pin does not correspond to an Extended IO element."),
28 0x8888);
29 return el;
30}
31
32template <class T>
34 return static_cast<ArduinoPin_t>(t);
35}
36
37void pinMode(pin_t pin, PinMode_t mode) {
38 if (pin == NO_PIN)
39 return; // LCOV_EXCL_LINE
40 else if (isNativePin(pin)) {
41 ::pinMode(pin, mode);
42 } else {
43 auto el = getIOElementOfPin(pin);
44 el->pinMode(pin - el->getStart(), mode);
45 }
46}
47void pinMode(int pin, PinMode_t mode) {
48 ::pinMode(arduino_pin_cast(pin), mode);
49}
50
52 if (pin == NO_PIN)
53 return; // LCOV_EXCL_LINE
54 else if (isNativePin(pin)) {
55 ::digitalWrite(pin, val);
56 } else {
57 auto el = getIOElementOfPin(pin);
58 el->digitalWrite(pin - el->getStart(), val);
59 }
60}
61void digitalWrite(int pin, PinStatus_t val) {
63}
64
66 if (pin == NO_PIN)
67 return LOW; // LCOV_EXCL_LINE
68 else if (isNativePin(pin)) {
70 } else {
71 auto el = getIOElementOfPin(pin);
72 return el->digitalRead(pin - el->getStart());
73 }
74}
77}
78
80 if (pin == NO_PIN)
81 return 0; // LCOV_EXCL_LINE
82 else if (isNativePin(pin)) {
84 } else {
85 auto el = getIOElementOfPin(pin);
86 return el->analogRead(pin - el->getStart());
87 }
88}
90
91void analogWrite(pin_t pin, analog_t val) {
92 if (pin == NO_PIN)
93 return; // LCOV_EXCL_LINE
94 else if (isNativePin(pin)) {
95#ifndef ESP32
96 ::analogWrite(pin, val);
97#endif
98 } else {
99 auto el = getIOElementOfPin(pin);
100 el->analogWrite(pin - el->getStart(), val);
101 }
102}
103void analogWrite(pin_t pin, int val) { analogWrite(pin, (analog_t)val); }
104#ifndef ESP32
105void analogWrite(int pin, analog_t val) {
107}
108void analogWrite(int pin, int val) {
110}
111#endif
112
114 if (pin == NO_PIN)
115 return; // LCOV_EXCL_LINE
116 else if (isNativePin(pin)) {
117 ::pinMode(pin, mode);
118 } else {
119 auto el = getIOElementOfPin(pin);
120 el->pinModeBuffered(pin - el->getStart(), mode);
121 }
122}
123
125 if (pin == NO_PIN)
126 return; // LCOV_EXCL_LINE
127 else if (isNativePin(pin)) {
128 ::digitalWrite(pin, val);
129 } else {
130 auto el = getIOElementOfPin(pin);
131 el->digitalWriteBuffered(pin - el->getStart(), val);
132 }
133}
134
136 if (pin == NO_PIN)
137 return LOW; // LCOV_EXCL_LINE
138 else if (isNativePin(pin)) {
140 } else {
141 auto el = getIOElementOfPin(pin);
142 return el->digitalReadBuffered(pin - el->getStart());
143 }
144}
145
147 if (pin == NO_PIN)
148 return 0; // LCOV_EXCL_LINE
149 else if (isNativePin(pin)) {
151 } else {
152 auto el = getIOElementOfPin(pin);
153 return el->analogReadBuffered(pin - el->getStart());
154 }
155 return 0;
156}
157
159 if (pin == NO_PIN)
160 return; // LCOV_EXCL_LINE
161 else if (isNativePin(pin)) {
162#ifndef ESP32
163 ::analogWrite(pin, val);
164#endif
165 } else {
166 auto el = getIOElementOfPin(pin);
167 el->analogWriteBuffered(pin - el->getStart(), val);
168 }
169}
170void analogWriteBuffered(pin_t pin, int val) {
171 analogWriteBuffered(pin, (analog_t)val);
172}
173
174void shiftOut(pin_t dataPin, pin_t clockPin, BitOrder_t bitOrder, uint8_t val) {
175 if (dataPin == NO_PIN || clockPin == NO_PIN)
176 return;
177 // Native version
178 if (isNativePin(dataPin) && isNativePin(clockPin)) {
179 ::shiftOut((int)dataPin, (int)clockPin, bitOrder, val);
180 }
181 // ExtIO version
182 else if (!isNativePin(dataPin) && !isNativePin(clockPin)) {
183 auto dataEl = getIOElementOfPin(dataPin);
184 auto dataPinN = dataPin - dataEl->getStart();
185 auto clockEl = getIOElementOfPin(clockPin);
186 auto clockPinN = clockPin - clockEl->getStart();
187 for (uint8_t i = 0; i < 8; i++) {
188 uint8_t mask = bitOrder == LSBFIRST ? (1 << i) : (1 << (7 - i));
189 dataEl->digitalWrite(dataPinN, (val & mask) ? HIGH : LOW);
190 clockEl->digitalWrite(clockPinN, HIGH);
191 clockEl->digitalWrite(clockPinN, LOW);
192 }
193 }
194 // Mixed version (slow)
195 else {
196 for (uint8_t i = 0; i < 8; i++) {
197 uint8_t mask = bitOrder == LSBFIRST ? (1 << i) : (1 << (7 - i));
198 digitalWrite(dataPin, (val & mask) ? HIGH : LOW);
199 digitalWrite(clockPin, HIGH);
200 digitalWrite(clockPin, LOW);
201 }
202 }
203}
204void shiftOut(int dataPin, int clockPin, BitOrder_t bitOrder, uint8_t val) {
205 ::shiftOut(arduino_pin_cast(dataPin), arduino_pin_cast(clockPin), bitOrder,
206 val);
207}
208
209#if UINT16_MAX != UINT_MAX
210void pinMode(unsigned int pin, PinMode_t mode) {
211 ::pinMode(arduino_pin_cast(pin), mode);
212}
213void digitalWrite(unsigned int pin, PinStatus_t val) {
215}
216PinStatus_t digitalRead(unsigned int pin) {
218}
219analog_t analogRead(unsigned int pin) {
221}
222#ifndef ESP32
223void analogWrite(unsigned int pin, analog_t val) {
225}
226void analogWrite(unsigned int pin, int val) {
228}
229#endif
230void shiftOut(unsigned int dataPin, unsigned int clockPin, BitOrder_t bitOrder,
231 uint8_t val) {
232 ::shiftOut(arduino_pin_cast(dataPin), arduino_pin_cast(clockPin), bitOrder,
233 val);
234}
235#endif
236
237} // namespace ExtIO
238
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
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).
#define END_AH_NAMESPACE
#define BEGIN_AH_NAMESPACE
An abstract base class for Extended Input/Output elements.
static DoublyLinkedList< ExtendedIOElement > & getAll()
Get the list of all Extended IO elements.
#define FATAL_ERROR(msg, errc)
Print the error message and error code, and stop the execution.
Definition: Error.hpp:57
PinStatus_t digitalRead(int pin)
Overload to Arduino digitalRead function.
void analogWriteBuffered(pin_t pin, analog_t val)
A buffered ExtIO version of the Arduino 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.
void analogWrite(pin_t pin, analog_t val)
An ExtIO version of the Arduino function.
void pinMode(pin_t pin, PinMode_t mode)
An ExtIO version of the Arduino function.
ExtendedIOElement * getIOElementOfPinOrNull(pin_t pin)
Find the IO element of a given extended IO pin number.
PinStatus_t digitalReadBuffered(pin_t pin)
A buffered ExtIO version of the Arduino function.
analog_t analogRead(pin_t pin)
An ExtIO version of the Arduino function.
analog_t analogReadBuffered(pin_t pin)
A buffered ExtIO version of the Arduino function.
PinStatus_t digitalRead(pin_t pin)
An ExtIO version of the Arduino function.
void shiftOut(pin_t dataPin, pin_t clockPin, BitOrder_t bitOrder, uint8_t val)
An ExtIO version of the Arduino function.
analog_t analogRead(int pin)
Overload to Arduino analogRead function.
void digitalWrite(pin_t pin, PinStatus_t val)
An ExtIO version of the Arduino function.
A namespace with alternatives to the standard Arduino IO functions that can be used with extended IO ...
static bool inRange(T target, T start, T end)
ArduinoPin_t arduino_pin_cast(T t)