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 171 : bool inRange(T target, T start, T end) {
14 171 : return target >= start && target < end;
15 : }
16 :
17 150 : ExtendedIOElement &getIOElementOfPin(pin_t pin) {
18 173 : for (ExtendedIOElement &el : ExtendedIOElement::getAll())
19 172 : if (pin < el.getStart())
20 1 : break;
21 171 : else if (inRange(pin, el.getStart(), el.getEnd()))
22 148 : return el;
23 :
24 2 : FATAL_ERROR(
25 : F("The given pin does not correspond to an Extended IO element."),
26 : 0x8888);
27 :
28 : // TODO: why doesn't this give a compilation error?
29 : // No return statement. On desktop, FATAL_ERROR throws an exception, so
30 : // I get why that works, but on Arduino, it just calls fatalErrorExit, which
31 : // is marked 'noreturn'. However, if I remove the 'noreturn' attribute, and
32 : // have it return immediately, it still compiles, without returning a valid
33 : // reference.
34 2 : }
35 :
36 184 : void pinMode(pin_t pin, uint8_t mode) {
37 : // DEBUGFN(DEBUGVAR(pin) << '\t' << DEBUGVAR(mode));
38 184 : if (pin < NUM_DIGITAL_PINS + NUM_ANALOG_INPUTS) {
39 175 : ::pinMode(pin, mode);
40 175 : } else {
41 9 : ExtendedIOElement &el = getIOElementOfPin(pin);
42 9 : el.pinMode(pin - el.getStart(), mode);
43 : }
44 184 : }
45 5 : void pinMode(int pin, uint8_t mode) { pinMode((pin_t)pin, mode); }
46 :
47 198 : void digitalWrite(pin_t pin, uint8_t val) {
48 : // DEBUGFN(DEBUGVAR(pin) << '\t' << DEBUGVAR(val));
49 198 : if (pin < NUM_DIGITAL_PINS + NUM_ANALOG_INPUTS) {
50 94 : ::digitalWrite(pin, val);
51 94 : } else {
52 104 : ExtendedIOElement &el = getIOElementOfPin(pin);
53 104 : el.digitalWrite(pin - el.getStart(), val);
54 : }
55 198 : }
56 5 : void digitalWrite(int pin, uint8_t val) { digitalWrite((pin_t)pin, val); }
57 :
58 308 : int digitalRead(pin_t pin) {
59 308 : if (pin < NUM_DIGITAL_PINS + NUM_ANALOG_INPUTS) {
60 296 : return ::digitalRead(pin);
61 : } else {
62 12 : ExtendedIOElement &el = getIOElementOfPin(pin);
63 12 : return el.digitalRead(pin - el.getStart());
64 : }
65 : return 0;
66 306 : }
67 5 : int digitalRead(int pin) { return digitalRead((pin_t)pin); }
68 :
69 4 : void shiftOut(pin_t dataPin, pin_t clockPin, uint8_t bitOrder, uint8_t val) {
70 : uint8_t i;
71 :
72 36 : for (i = 0; i < 8; i++) {
73 32 : if (bitOrder == LSBFIRST)
74 16 : digitalWrite(dataPin, !!(val & (1 << i)));
75 : else
76 16 : digitalWrite(dataPin, !!(val & (1 << (7 - i))));
77 :
78 32 : digitalWrite(clockPin, HIGH);
79 32 : digitalWrite(clockPin, LOW);
80 32 : }
81 4 : }
82 2 : void shiftOut(int dataPin, int clockPin, uint8_t bitOrder, uint8_t val) {
83 2 : shiftOut((pin_t)dataPin, (pin_t)clockPin, bitOrder, val);
84 2 : }
85 :
86 48 : analog_t analogRead(pin_t pin) {
87 48 : if (pin < NUM_DIGITAL_PINS + NUM_ANALOG_INPUTS) {
88 33 : return ::analogRead(pin);
89 : } else {
90 15 : ExtendedIOElement &el = getIOElementOfPin(pin);
91 15 : return el.analogRead(pin - el.getStart());
92 : }
93 : return 0;
94 48 : }
95 5 : analog_t analogRead(int pin) { return analogRead((pin_t)pin); }
96 :
97 11 : void analogWrite(pin_t pin, analog_t val) {
98 : // DEBUGFN(DEBUGVAR(pin) << '\t' << DEBUGVAR(val));
99 11 : if (pin < NUM_DIGITAL_PINS + NUM_ANALOG_INPUTS) {
100 : #ifndef ESP32
101 1 : ::analogWrite(pin, val);
102 : #endif
103 1 : } else {
104 10 : ExtendedIOElement &el = getIOElementOfPin(pin);
105 10 : el.analogWrite(pin - el.getStart(), val);
106 : }
107 11 : }
108 2 : void analogWrite(int pin, analog_t val) { analogWrite((pin_t)pin, val); }
109 5 : void analogWrite(int pin, int val) { analogWrite((pin_t)pin, (analog_t)val); }
110 4 : void analogWrite(pin_t pin, int val) { analogWrite(pin, (analog_t)val); }
111 :
112 : } // namespace ExtIO
113 :
114 : END_AH_NAMESPACE
115 :
116 : AH_DIAGNOSTIC_POP()
|