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