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 : template <class T>
36 16 : ArduinoPin_t arduino_pin_cast(T t) {
37 16 : return static_cast<ArduinoPin_t>(t);
38 : }
39 :
40 129 : void pinMode(pin_t pin, PinMode_t mode) {
41 129 : if (pin == NO_PIN)
42 : return; // LCOV_EXCL_LINE
43 128 : else if (isNativePin(pin)) {
44 122 : ::pinMode(pin, mode);
45 : } else {
46 6 : auto el = getIOElementOfPin(pin);
47 6 : el->pinMode(pin - el->getStart(), mode);
48 : }
49 : }
50 1 : void pinMode(int pin, PinMode_t mode) {
51 1 : ::pinMode(arduino_pin_cast(pin), mode);
52 1 : }
53 :
54 203 : void digitalWrite(pin_t pin, PinStatus_t val) {
55 203 : if (pin == NO_PIN)
56 : return; // LCOV_EXCL_LINE
57 202 : else if (isNativePin(pin)) {
58 181 : ::digitalWrite(pin, val);
59 : } else {
60 21 : auto el = getIOElementOfPin(pin);
61 21 : el->digitalWrite(pin - el->getStart(), val);
62 : }
63 : }
64 1 : void digitalWrite(int pin, PinStatus_t val) {
65 1 : ::digitalWrite(arduino_pin_cast(pin), val);
66 1 : }
67 :
68 243 : PinStatus_t digitalRead(pin_t pin) {
69 243 : if (pin == NO_PIN)
70 : return LOW; // LCOV_EXCL_LINE
71 242 : else if (isNativePin(pin)) {
72 233 : return ::digitalRead(pin);
73 : } else {
74 9 : auto el = getIOElementOfPin(pin);
75 7 : return el->digitalRead(pin - el->getStart());
76 : }
77 : }
78 1 : PinStatus_t digitalRead(int pin) {
79 1 : return ::digitalRead(arduino_pin_cast(pin));
80 : }
81 :
82 85 : analog_t analogRead(pin_t pin) {
83 85 : if (pin == NO_PIN)
84 : return 0; // LCOV_EXCL_LINE
85 84 : else if (isNativePin(pin)) {
86 69 : return ::analogRead(pin);
87 : } else {
88 15 : auto el = getIOElementOfPin(pin);
89 15 : return el->analogRead(pin - el->getStart());
90 : }
91 : }
92 1 : analog_t analogRead(int pin) { return ::analogRead(arduino_pin_cast(pin)); }
93 :
94 14 : void analogWrite(pin_t pin, analog_t val) {
95 14 : if (pin == NO_PIN)
96 : return; // LCOV_EXCL_LINE
97 13 : else if (isNativePin(pin)) {
98 : #ifndef ESP32
99 8 : ::analogWrite(pin, val);
100 : #endif
101 : } else {
102 5 : auto el = getIOElementOfPin(pin);
103 5 : el->analogWrite(pin - el->getStart(), val);
104 : }
105 : }
106 11 : void analogWrite(pin_t pin, int val) { analogWrite(pin, (analog_t)val); }
107 : #ifndef ESP32
108 1 : void analogWrite(int pin, analog_t val) {
109 1 : ::analogWrite(arduino_pin_cast(pin), val);
110 1 : }
111 1 : void analogWrite(int pin, int val) {
112 1 : ::analogWrite(arduino_pin_cast(pin), val);
113 1 : }
114 : #endif
115 :
116 3 : void pinModeBuffered(pin_t pin, PinMode_t mode) {
117 3 : if (pin == NO_PIN)
118 : return; // LCOV_EXCL_LINE
119 3 : else if (isNativePin(pin)) {
120 1 : ::pinMode(pin, mode);
121 : } else {
122 2 : auto el = getIOElementOfPin(pin);
123 2 : el->pinModeBuffered(pin - el->getStart(), mode);
124 : }
125 : }
126 :
127 2 : void digitalWriteBuffered(pin_t pin, PinStatus_t val) {
128 2 : if (pin == NO_PIN)
129 : return; // LCOV_EXCL_LINE
130 2 : else if (isNativePin(pin)) {
131 1 : ::digitalWrite(pin, val);
132 : } else {
133 1 : auto el = getIOElementOfPin(pin);
134 1 : el->digitalWriteBuffered(pin - el->getStart(), val);
135 : }
136 : }
137 :
138 3 : PinStatus_t digitalReadBuffered(pin_t pin) {
139 3 : if (pin == NO_PIN)
140 : return LOW; // LCOV_EXCL_LINE
141 3 : else if (isNativePin(pin)) {
142 1 : return ::digitalRead(pin);
143 : } else {
144 2 : auto el = getIOElementOfPin(pin);
145 2 : return el->digitalReadBuffered(pin - el->getStart());
146 : }
147 : }
148 :
149 3 : analog_t analogReadBuffered(pin_t pin) {
150 3 : if (pin == NO_PIN)
151 : return 0; // LCOV_EXCL_LINE
152 3 : else if (isNativePin(pin)) {
153 1 : return ::analogRead(pin);
154 : } else {
155 2 : auto el = getIOElementOfPin(pin);
156 2 : return el->analogReadBuffered(pin - el->getStart());
157 : }
158 : return 0;
159 : }
160 :
161 4 : void analogWriteBuffered(pin_t pin, analog_t val) {
162 4 : if (pin == NO_PIN)
163 : return; // LCOV_EXCL_LINE
164 4 : else if (isNativePin(pin)) {
165 : #ifndef ESP32
166 2 : ::analogWrite(pin, val);
167 : #endif
168 : } else {
169 2 : auto el = getIOElementOfPin(pin);
170 2 : el->analogWriteBuffered(pin - el->getStart(), val);
171 : }
172 : }
173 2 : void analogWriteBuffered(pin_t pin, int val) {
174 2 : analogWriteBuffered(pin, (analog_t)val);
175 2 : }
176 :
177 6 : void shiftOut(pin_t dataPin, pin_t clockPin, BitOrder_t bitOrder, uint8_t val) {
178 6 : if (dataPin == NO_PIN || clockPin == NO_PIN)
179 1 : return;
180 : // Native version
181 5 : if (isNativePin(dataPin) && isNativePin(clockPin)) {
182 1 : ::shiftOut((int)dataPin, (int)clockPin, bitOrder, val);
183 : }
184 : // ExtIO version
185 4 : else if (!isNativePin(dataPin) && !isNativePin(clockPin)) {
186 2 : auto dataEl = getIOElementOfPin(dataPin);
187 2 : auto dataPinN = dataPin - dataEl->getStart();
188 2 : auto clockEl = getIOElementOfPin(clockPin);
189 2 : auto clockPinN = clockPin - clockEl->getStart();
190 18 : for (uint8_t i = 0; i < 8; i++) {
191 16 : uint8_t mask = bitOrder == LSBFIRST ? (1 << i) : (1 << (7 - i));
192 16 : dataEl->digitalWrite(dataPinN, (val & mask) ? HIGH : LOW);
193 16 : clockEl->digitalWrite(clockPinN, HIGH);
194 16 : clockEl->digitalWrite(clockPinN, LOW);
195 : }
196 : }
197 : // Mixed version (slow)
198 : else {
199 18 : for (uint8_t i = 0; i < 8; i++) {
200 16 : uint8_t mask = bitOrder == LSBFIRST ? (1 << i) : (1 << (7 - i));
201 16 : digitalWrite(dataPin, (val & mask) ? HIGH : LOW);
202 16 : digitalWrite(clockPin, HIGH);
203 16 : digitalWrite(clockPin, LOW);
204 : }
205 : }
206 : }
207 1 : void shiftOut(int dataPin, int clockPin, BitOrder_t bitOrder, uint8_t val) {
208 1 : ::shiftOut(arduino_pin_cast(dataPin), arduino_pin_cast(clockPin), bitOrder,
209 : val);
210 1 : }
211 :
212 : #if UINT16_MAX != UINT_MAX
213 1 : void pinMode(unsigned int pin, PinMode_t mode) {
214 1 : ::pinMode(arduino_pin_cast(pin), mode);
215 1 : }
216 1 : void digitalWrite(unsigned int pin, PinStatus_t val) {
217 1 : ::digitalWrite(arduino_pin_cast(pin), val);
218 1 : }
219 1 : PinStatus_t digitalRead(unsigned int pin) {
220 1 : return ::digitalRead(arduino_pin_cast(pin));
221 : }
222 1 : analog_t analogRead(unsigned int pin) {
223 1 : return ::analogRead(arduino_pin_cast(pin));
224 : }
225 : #ifndef ESP32
226 1 : void analogWrite(unsigned int pin, analog_t val) {
227 1 : ::analogWrite(arduino_pin_cast(pin), val);
228 1 : }
229 1 : void analogWrite(unsigned int pin, int val) {
230 1 : ::analogWrite(arduino_pin_cast(pin), val);
231 1 : }
232 : #endif
233 1 : void shiftOut(unsigned int dataPin, unsigned int clockPin, BitOrder_t bitOrder,
234 : uint8_t val) {
235 1 : ::shiftOut(arduino_pin_cast(dataPin), arduino_pin_cast(clockPin), bitOrder,
236 : val);
237 1 : }
238 : #endif
239 :
240 : } // namespace ExtIO
241 :
242 : END_AH_NAMESPACE
243 :
244 : AH_DIAGNOSTIC_POP()
|