Control Surface new-input
MIDI Control Surface library for Arduino
ExtendedInputOutput.cpp
Go to the documentation of this file.
2 AH_DIAGNOSTIC_WERROR() // Enable errors on warnings
3 
4 #include "ExtendedIOElement.hpp"
6 #include <AH/Error/Error.hpp>
7 
9 
10 namespace ExtIO {
11 
12 bool isNativePin(pin_t pin) {
13  return pin < NUM_DIGITAL_PINS + NUM_ANALOG_INPUTS;
14 }
15 
16 template <class T>
17 bool inRange(T target, T start, T end) {
18  return target >= start && target < end;
19 }
20 
22  for (auto &el : ExtendedIOElement::getAll())
23  if (pin < el.getStart())
24  break;
25  else if (inRange(pin, el.getStart(), el.getEnd()))
26  return &el;
27 
29  F("The given pin does not correspond to an Extended IO element."),
30  0x8888);
31  return nullptr;
32 }
33 
34 template <class T>
36  return static_cast<ArduinoPin_t>(t);
37 }
38 
39 void pinMode(pin_t pin, PinMode_t mode) {
40  if (pin == NO_PIN)
41  return; // LCOV_EXCL_LINE
42  else if (isNativePin(pin)) {
43  ::pinMode(pin, mode);
44  } else {
45  auto el = getIOElementOfPin(pin);
46  el->pinMode(pin - el->getStart(), mode);
47  }
48 }
49 void pinMode(int pin, PinMode_t mode) {
50  ::pinMode(arduino_pin_cast(pin), mode);
51 }
52 
53 void digitalWrite(pin_t pin, PinStatus_t val) {
54  if (pin == NO_PIN)
55  return; // LCOV_EXCL_LINE
56  else if (isNativePin(pin)) {
57  ::digitalWrite(pin, val);
58  } else {
59  auto el = getIOElementOfPin(pin);
60  el->digitalWrite(pin - el->getStart(), val);
61  }
62 }
63 void digitalWrite(int pin, PinStatus_t val) {
65 }
66 
68  if (pin == NO_PIN)
69  return LOW; // LCOV_EXCL_LINE
70  else if (isNativePin(pin)) {
72  } else {
73  auto el = getIOElementOfPin(pin);
74  return el->digitalRead(pin - el->getStart());
75  }
76 }
79 }
80 
82  if (pin == NO_PIN)
83  return 0; // LCOV_EXCL_LINE
84  else if (isNativePin(pin)) {
86  } else {
87  auto el = getIOElementOfPin(pin);
88  return el->analogRead(pin - el->getStart());
89  }
90 }
92 
93 void analogWrite(pin_t pin, analog_t val) {
94  if (pin == NO_PIN)
95  return; // LCOV_EXCL_LINE
96  else if (isNativePin(pin)) {
97 #ifndef ESP32
98  ::analogWrite(pin, val);
99 #endif
100  } else {
101  auto el = getIOElementOfPin(pin);
102  el->analogWrite(pin - el->getStart(), val);
103  }
104 }
105 void analogWrite(pin_t pin, int val) { analogWrite(pin, (analog_t)val); }
106 #ifndef ESP32
107 void analogWrite(int pin, analog_t val) {
108  ::analogWrite(arduino_pin_cast(pin), val);
109 }
110 void analogWrite(int pin, int val) {
111  ::analogWrite(arduino_pin_cast(pin), val);
112 }
113 #endif
114 
115 void pinModeBuffered(pin_t pin, PinMode_t mode) {
116  if (pin == NO_PIN)
117  return; // LCOV_EXCL_LINE
118  else if (isNativePin(pin)) {
119  ::pinMode(pin, mode);
120  } else {
121  auto el = getIOElementOfPin(pin);
122  el->pinModeBuffered(pin - el->getStart(), mode);
123  }
124 }
125 
127  if (pin == NO_PIN)
128  return; // LCOV_EXCL_LINE
129  else if (isNativePin(pin)) {
130  ::digitalWrite(pin, val);
131  } else {
132  auto el = getIOElementOfPin(pin);
133  el->digitalWriteBuffered(pin - el->getStart(), val);
134  }
135 }
136 
138  if (pin == NO_PIN)
139  return LOW; // LCOV_EXCL_LINE
140  else if (isNativePin(pin)) {
142  } else {
143  auto el = getIOElementOfPin(pin);
144  return el->digitalReadBuffered(pin - el->getStart());
145  }
146 }
147 
149  if (pin == NO_PIN)
150  return 0; // LCOV_EXCL_LINE
151  else if (isNativePin(pin)) {
152  return ::analogRead(pin);
153  } else {
154  auto el = getIOElementOfPin(pin);
155  return el->analogReadBuffered(pin - el->getStart());
156  }
157  return 0;
158 }
159 
161  if (pin == NO_PIN)
162  return; // LCOV_EXCL_LINE
163  else if (isNativePin(pin)) {
164 #ifndef ESP32
165  ::analogWrite(pin, val);
166 #endif
167  } else {
168  auto el = getIOElementOfPin(pin);
169  el->analogWriteBuffered(pin - el->getStart(), val);
170  }
171 }
172 void analogWriteBuffered(pin_t pin, int val) {
173  analogWriteBuffered(pin, (analog_t)val);
174 }
175 
176 void shiftOut(pin_t dataPin, pin_t clockPin, BitOrder_t bitOrder, uint8_t val) {
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 
188  for (uint8_t i = 0; i < 8; i++) {
189  uint8_t mask = bitOrder == LSBFIRST ? (1 << i) : (1 << (7 - i));
190  dataEl->digitalWrite(dataPinN, (val & mask) ? HIGH : LOW);
191  clockEl->digitalWrite(clockPinN, HIGH);
192  clockEl->digitalWrite(clockPinN, LOW);
193  }
194  }
195  // Mixed version (slow)
196  else {
197  for (uint8_t i = 0; i < 8; i++) {
198  uint8_t mask = bitOrder == LSBFIRST ? (1 << i) : (1 << (7 - i));
199  digitalWrite(dataPin, (val & mask) ? HIGH : LOW);
200 
201  digitalWrite(clockPin, HIGH);
202  digitalWrite(clockPin, LOW);
203  }
204  }
205 }
206 void shiftOut(int dataPin, int clockPin, BitOrder_t bitOrder, uint8_t val) {
207  ::shiftOut(arduino_pin_cast(dataPin), arduino_pin_cast(clockPin), bitOrder,
208  val);
209 }
210 
211 #if UINT16_MAX != UINT_MAX
212 void pinMode(unsigned int pin, PinMode_t mode) {
213  ::pinMode(arduino_pin_cast(pin), mode);
214 }
215 void digitalWrite(unsigned int pin, PinStatus_t val) {
216  ::digitalWrite(arduino_pin_cast(pin), val);
217 }
218 PinStatus_t digitalRead(unsigned int pin) {
220 }
221 analog_t analogRead(unsigned int pin) {
223 }
224 #ifndef ESP32
225 void analogWrite(unsigned int pin, analog_t val) {
226  ::analogWrite(arduino_pin_cast(pin), val);
227 }
228 void analogWrite(unsigned int pin, int val) {
229  ::analogWrite(arduino_pin_cast(pin), val);
230 }
231 #endif
232 void shiftOut(unsigned int dataPin, unsigned int clockPin, BitOrder_t bitOrder,
233  uint8_t val) {
234  ::shiftOut(arduino_pin_cast(dataPin), arduino_pin_cast(clockPin), bitOrder,
235  val);
236 }
237 #endif
238 
239 } // namespace ExtIO
240 
242 
#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:36
#define AH_DIAGNOSTIC_WERROR()
Definition: Warnings.hpp:35
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.
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 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.
ArduinoPin_t arduino_pin_cast(T t)
bool isNativePin(pin_t pin)
bool inRange(T target, T start, T end)
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).