IRremote
digitalWriteFast.h
Go to the documentation of this file.
1 /*
2  * digitalWriteFast.h
3  *
4  * Optimized digital functions for AVR microcontrollers
5  * by Watterott electronic (www.watterott.com)
6  * based on https://code.google.com/p/digitalwritefast
7  *
8  * The value of DigitalReadFast() is the content of the input register e.g. 0x04 for pin2 and NOT always 0 or 1.
9  *
10  * License: BSD 3-Clause License (https://opensource.org/licenses/BSD-3-Clause)
11  */
12 
13 #ifndef __digitalWriteFast_h_
14 #define __digitalWriteFast_h_ 1
15 
16 //#define THROW_ERROR_IF_NOT_FAST // If activated, an error is thrown if pin is not a compile time constant
17 void NonConstantsUsedForPinModeFast( void ) __attribute__ (( error("Parameter for pinModeFast() function is not constant") ));
18 void NonConstantsUsedForDigitalWriteFast( void ) __attribute__ (( error("Parameter for digitalWriteFast() function is not constant") ));
19 void NonConstantsUsedForDigitalToggleFast( void ) __attribute__ (( error("Parameter for digitalToggleFast() function is not constant") ));
20 int NonConstantsUsedForDigitalReadFast( void ) __attribute__ (( error("Parameter for digitalReadFast() function is not constant") ));
21 
22 #if !defined(MEGATINYCORE) // megaTinyCore has it own digitalWriteFast function set, except digitalToggleFast().
23 
24 //#define SANGUINO_PINOUT // define for Sanguino pinout
25 
26 // general macros/defines
27 #if !defined(BIT_READ)
28 # define BIT_READ(value, bit) ((value) & (1UL << (bit)))
29 #endif
30 #if !defined(BIT_SET)
31 # define BIT_SET(value, bit) ((value) |= (1UL << (bit)))
32 #endif
33 #if !defined(BIT_CLEAR)
34 # define BIT_CLEAR(value, bit) ((value) &= ~(1UL << (bit)))
35 #endif
36 #if !defined(BIT_WRITE)
37 # define BIT_WRITE(value, bit, bitvalue) (bitvalue ? BIT_SET(value, bit) : BIT_CLEAR(value, bit))
38 #endif
39 
40 #include <Arduino.h> // declarations for the fallback to digitalWrite(), digitalRead() etc.
41 
42 // --- Arduino Mega and ATmega128x/256x based boards ---
43 #if (defined(ARDUINO_AVR_MEGA) || \
44  defined(ARDUINO_AVR_MEGA1280) || \
45  defined(ARDUINO_AVR_MEGA2560) || \
46  defined(__AVR_ATmega1280__) || \
47  defined(__AVR_ATmega1281__) || \
48  defined(__AVR_ATmega2560__) || \
49  defined(__AVR_ATmega2561__))
50 
51 #define __digitalPinToPortReg(P) \
52 (((P) >= 22 && (P) <= 29) ? &PORTA : \
53 ((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PORTB : \
54 (((P) >= 30 && (P) <= 37) ? &PORTC : \
55 ((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PORTD : \
56 ((((P) <= 3) || (P) == 5) ? &PORTE : \
57 (((P) >= 54 && (P) <= 61) ? &PORTF : \
58 ((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PORTG : \
59 ((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PORTH : \
60 (((P) == 14 || (P) == 15) ? &PORTJ : \
61 (((P) >= 62 && (P) <= 69) ? &PORTK : &PORTL))))))))))
62 
63 #define __digitalPinToDDRReg(P) \
64 (((P) >= 22 && (P) <= 29) ? &DDRA : \
65 ((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &DDRB : \
66 (((P) >= 30 && (P) <= 37) ? &DDRC : \
67 ((((P) >= 18 && (P) <= 21) || (P) == 38) ? &DDRD : \
68 ((((P) <= 3) || (P) == 5) ? &DDRE : \
69 (((P) >= 54 && (P) <= 61) ? &DDRF : \
70 ((((P) >= 39 && (P) <= 41) || (P) == 4) ? &DDRG : \
71 ((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &DDRH : \
72 (((P) == 14 || (P) == 15) ? &DDRJ : \
73 (((P) >= 62 && (P) <= 69) ? &DDRK : &DDRL))))))))))
74 
75 #define __digitalPinToPINReg(P) \
76 (((P) >= 22 && (P) <= 29) ? &PINA : \
77 ((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PINB : \
78 (((P) >= 30 && (P) <= 37) ? &PINC : \
79 ((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PIND : \
80 ((((P) <= 3) || (P) == 5) ? &PINE : \
81 (((P) >= 54 && (P) <= 61) ? &PINF : \
82 ((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PING : \
83 ((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PINH : \
84 (((P) == 14 || (P) == 15) ? &PINJ : \
85 (((P) >= 62 && (P) <= 69) ? &PINK : &PINL))))))))))
86 
87 #define __digitalPinToBit(P) \
88 (((P) >= 7 && (P) <= 9) ? (P) - 3 : \
89 (((P) >= 10 && (P) <= 13) ? (P) - 6 : \
90 (((P) >= 22 && (P) <= 29) ? (P) - 22 : \
91 (((P) >= 30 && (P) <= 37) ? 37 - (P) : \
92 (((P) >= 39 && (P) <= 41) ? 41 - (P) : \
93 (((P) >= 42 && (P) <= 49) ? 49 - (P) : \
94 (((P) >= 50 && (P) <= 53) ? 53 - (P) : \
95 (((P) >= 54 && (P) <= 61) ? (P) - 54 : \
96 (((P) >= 62 && (P) <= 69) ? (P) - 62 : \
97 (((P) == 0 || (P) == 15 || (P) == 17 || (P) == 21) ? 0 : \
98 (((P) == 1 || (P) == 14 || (P) == 16 || (P) == 20) ? 1 : \
99 (((P) == 19) ? 2 : \
100 (((P) == 5 || (P) == 6 || (P) == 18) ? 3 : \
101 (((P) == 2) ? 4 : \
102 (((P) == 3 || (P) == 4) ? 5 : 7)))))))))))))))
103 
104 
105 // --- Arduino MightyCore standard pinout ---
106 #elif (defined(__AVR_ATmega1284P__) || \
107  defined(__AVR_ATmega1284__) || \
108  defined(__AVR_ATmega644P__) || \
109  defined(__AVR_ATmega644A__) || \
110  defined(__AVR_ATmega644__) || \
111  defined(__AVR_ATmega324PB__) || \
112  defined(__AVR_ATmega324PA__) || \
113  defined(__AVR_ATmega324P__) || \
114  defined(__AVR_ATmega324A__) || \
115  defined(__AVR_ATmega164P__) || \
116  defined(__AVR_ATmega164A__) || \
117  defined(__AVR_ATmega32__) || \
118  defined(__AVR_ATmega16__) || \
119  defined(__AVR_ATmega8535__)) && \
120  !defined(BOBUINO_PINOUT)
121 
122 #if defined(__AVR_ATmega324PB__)
123 #define __digitalPinToPortReg(P) \
124 (((P) <= 7) ? &PORTB : (((P) >= 8 && (P) <= 15) ? &PORTD : (((P) >= 16 && (P) <= 23) ? &PORTC : (((P) >= 24 && (P) <= 31) ? &PORTA : &PORTE))))
125 #define __digitalPinToDDRReg(P) \
126 (((P) <= 7) ? &DDRB : (((P) >= 8 && (P) <= 15) ? &DDRD : (((P) >= 16 && (P) <= 23) ? &DDRC : (((P) >= 24 && (P) <= 31) ? &DDRA : &DDRE))))
127 #define __digitalPinToPINReg(P) \
128 (((P) <= 7) ? &PINB : (((P) >= 8 && (P) <= 15) ? &PIND : (((P) >= 16 && (P) <= 23) ? &PINC : (((P) >= 24 && (P) <= 31) ? &PINA : &PINE))))
129 # if defined(SANGUINO_PINOUT)
130 #define __digitalPinToBit(P) \
131 (((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (((P) >= 16 && (P) <= 23) ? (7 - ((P) - 24)) : (P) - 32))))
132 # else //MightyCore Pinout
133 #define __digitalPinToBit(P) \
134 (((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (((P) >= 16 && (P) <= 23) ? (P) - 24 : (P) - 32))))
135 # endif
136 #elif defined(PORTA)
137 #define __digitalPinToPortReg(P) \
138 (((P) <= 7) ? &PORTB : (((P) >= 8 && (P) <= 15) ? &PORTD : (((P) >= 16 && (P) <= 23) ? &PORTC : &PORTA)))
139 #define __digitalPinToDDRReg(P) \
140 (((P) <= 7) ? &DDRB : (((P) >= 8 && (P) <= 15) ? &DDRD : (((P) >= 16 && (P) <= 23) ? &DDRC : &DDRA)))
141 #define __digitalPinToPINReg(P) \
142 (((P) <= 7) ? &PINB : (((P) >= 8 && (P) <= 15) ? &PIND : (((P) >= 16 && (P) <= 23) ? &PINC : &PINA)))
143 # if defined(SANGUINO_PINOUT)
144 #define __digitalPinToBit(P) \
145 (((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (7 - ((P) - 24)))))
146 # else //MightyCore Pinout
147 #define __digitalPinToBit(P) \
148 (((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (P) - 24)))
149 # endif
150 #else
151 #define __digitalPinToPortReg(P) \
152 (((P) <= 7) ? &PORTB : (((P) >= 8 && (P) <= 15) ? &PORTD : &PORTC))
153 #define __digitalPinToDDRReg(P) \
154 (((P) <= 7) ? &DDRB : (((P) >= 8 && (P) <= 15) ? &DDRD : &DDRC))
155 #define __digitalPinToPINReg(P) \
156 (((P) <= 7) ? &PINB : (((P) >= 8 && (P) <= 15) ? &PIND : &PINC))
157 # if defined(SANGUINO_PINOUT)
158 #define __digitalPinToBit(P) \
159 (((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (7 - ((P) - 24)))))
160 # else //MightyCore Pinout
161 #define __digitalPinToBit(P) \
162 (((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (P) - 24)))
163 # endif
164 #endif
165 
166 
167 // --- Arduino Leonardo and ATmega16U4/32U4 based boards ---
168 #elif (defined(ARDUINO_AVR_LEONARDO) || \
169  defined(__AVR_ATmega16U4__) || \
170  defined(__AVR_ATmega32U4__))
171 # if defined(TEENSYDUINO)
172 
173 #define __digitalPinToPortReg(P) \
174 ((((P) <= 4) || ((P) >= 13 && (P) <= 15)) ? &PORTB : (((P) == 9 || (P) == 10) ? &PORTC : (((P) >= 16 && (P) <= 21)) ? &PORTF : &PORTD))
175 #define __digitalPinToDDRReg(P) \
176 ((((P) <= 4) || ((P) >= 13 && (P) <= 15)) ? &DDRB : (((P) == 9 || (P) == 10) ? &DDRC : (((P) >= 16 && (P) <= 21)) ? &DDRF : &DDRD))
177 #define __digitalPinToPINReg(P) \
178 ((((P) <= 4) || ((P) >= 13 && (P) <= 15)) ? &PINB : (((P) == 9 || (P) == 10) ? &PINC : (((P) >= 16 && (P) <= 21)) ? &PINF : &PIND))
179 #define __digitalPinToBit(P) \
180 (((P) <= 3) ? (P) : \
181 (((P) == 4 || (P) == 12) ? 7 : \
182 (((P) <= 8) ? (P) - 5 : \
183 (((P) <= 10) ? (P) - 3 : \
184 (((P) == 11) ? 6 : \
185 (((P) <= 15) ? (P) - 9 : \
186 (((P) <= 19) ? 23 - (P) : \
187 (((P) <= 21) ? 21 - (P) : (P) - 18))))))))
188 # else
189 
190 #define __digitalPinToPortReg(P) \
191 ((((P) <= 4) || (P) == 6 || (P) == 12 || (P) == 24 || (P) == 25 || (P) == 29) ? &PORTD : (((P) == 5 || (P) == 13) ? &PORTC : (((P) >= 18 && (P) <= 23)) ? &PORTF : (((P) == 7) ? &PORTE : &PORTB)))
192 #define __digitalPinToDDRReg(P) \
193 ((((P) <= 4) || (P) == 6 || (P) == 12 || (P) == 24 || (P) == 25 || (P) == 29) ? &DDRD : (((P) == 5 || (P) == 13) ? &DDRC : (((P) >= 18 && (P) <= 23)) ? &DDRF : (((P) == 7) ? &DDRE : &DDRB)))
194 #define __digitalPinToPINReg(P) \
195 ((((P) <= 4) || (P) == 6 || (P) == 12 || (P) == 24 || (P) == 25 || (P) == 29) ? &PIND : (((P) == 5 || (P) == 13) ? &PINC : (((P) >= 18 && (P) <= 23)) ? &PINF : (((P) == 7) ? &PINE : &PINB)))
196 #define __digitalPinToBit(P) \
197 (((P) >= 8 && (P) <= 11) ? (P) - 4 : \
198 (((P) >= 18 && (P) <= 21) ? 25 - (P) : \
199 (((P) == 0) ? 2 : (((P) == 1) ? 3 : (((P) == 2) ? 1 : (((P) == 3) ? 0 : (((P) == 4) ? 4 : (((P) == 6) ? 7 : (((P) == 13) ? 7 : \
200 (((P) == 14) ? 3 : (((P) == 15) ? 1 : (((P) == 16) ? 2 : (((P) == 17) ? 0 : (((P) == 22) ? 1 : (((P) == 23) ? 0 : \
201 (((P) == 24) ? 4 : (((P) == 25) ? 7 : (((P) == 26) ? 4 : (((P) == 27) ? 5 : 6 )))))))))))))))))))
202 # endif
203 
204 // --- Arduino Uno and ATmega168/328 based boards ---
205 #elif (defined(ARDUINO_AVR_UNO) || \
206  defined(ARDUINO_AVR_DUEMILANOVE) || \
207  defined(__AVR_ATmega8__) || \
208  defined(__AVR_ATmega48__) || \
209  defined(__AVR_ATmega48P__) || \
210  defined(__AVR_ATmega48PB__) || \
211  defined(__AVR_ATmega88P__) || \
212  defined(__AVR_ATmega88PB__) || \
213  defined(__AVR_ATmega168__) || \
214  defined(__AVR_ATmega168PA__) || \
215  defined(__AVR_ATmega168PB__) || \
216  defined(__AVR_ATmega328__) || \
217  defined(__AVR_ATmega328P__) || \
218  defined(__AVR_ATmega328PB__))
219 
220 #if defined(__AVR_ATmega48PB__) || defined(__AVR_ATmega88PB__) || defined(__AVR_ATmega168PB__) || defined(__AVR_ATmega328PB__)
221 #define __digitalPinToPortReg(P) \
222 (((P) <= 7) ? &PORTD : (((P) >= 8 && (P) <= 13) ? &PORTB : (((P) >= 14 && (P) <= 19) ? &PORTC : &PORTE)))
223 #define __digitalPinToDDRReg(P) \
224 (((P) <= 7) ? &DDRD : (((P) >= 8 && (P) <= 13) ? &DDRB : (((P) >= 14 && (P) <= 19) ? &DDRC : &DDRE)))
225 #define __digitalPinToPINReg(P) \
226 (((P) <= 7) ? &PIND : (((P) >= 8 && (P) <= 13) ? &PINB : (((P) >= 14 && (P) <= 19) ? &PINC : &PINE)))
227 #define __digitalPinToBit(P) \
228 (((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P) - 8 : (((P) >= 14 && (P) <= 19) ? (P) - 14 : (((P) >= 20 && (P) <= 21) ? (P) - 18 : (P) - 22))))
229 #else
230 #define __digitalPinToPortReg(P) \
231 (((P) <= 7) ? &PORTD : (((P) >= 8 && (P) <= 13) ? &PORTB : &PORTC))
232 #define __digitalPinToDDRReg(P) \
233 (((P) <= 7) ? &DDRD : (((P) >= 8 && (P) <= 13) ? &DDRB : &DDRC))
234 #define __digitalPinToPINReg(P) \
235 (((P) <= 7) ? &PIND : (((P) >= 8 && (P) <= 13) ? &PINB : &PINC))
236 #define __digitalPinToBit(P) \
237 (((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P) - 8 : (P) - 14))
238 #endif
239 
240 // --- Arduino Uno WiFi Rev 2, Nano Every ---
241 #elif defined(__AVR_ATmega4809__)
242 
243 #define __digitalPinToPortReg(P) \
244 (((P) == 2 || (P) == 7 ) ? &VPORTA.OUT : ((P) == 5 || (P) == 9 || (P) == 10) ? &VPORTB.OUT : ((P) == 4) ? &VPORTC.OUT : (((P) >= 14 && (P) <= 17) || (P) == 20 || (P) == 21) ? &VPORTD.OUT : ((P) == 8 || (P) == 11 || (P) == 12 || (P) == 13) ? &VPORTE.OUT : &VPORTF.OUT)
245 #define __digitalPinToDDRReg(P) \
246 (((P) == 2 || (P) == 7 ) ? &VPORTA.DIR : ((P) == 5 || (P) == 9 || (P) == 10) ? &VPORTB.DIR : ((P) == 4) ? &VPORTC.DIR : (((P) >= 14 && (P) <= 17) || (P) == 20 || (P) == 21) ? &VPORTD.DIR : ((P) == 8 || (P) == 11 || (P) == 12 || (P) == 13) ? &VPORTE.DIR : &VPORTF.DIR)
247 #define __digitalPinToPINReg(P) \
248 (((P) == 2 || (P) == 7 ) ? &VPORTA.IN : ((P) == 5 || (P) == 9 || (P) == 10) ? &VPORTB.IN : ((P) == 4) ? &VPORTC.IN : (((P) >= 14 && (P) <= 17) || (P) == 20 || (P) == 21) ? &VPORTD.IN : ((P) == 8 || (P) == 11 || (P) == 12 || (P) == 13) ? &VPORTE.IN : &VPORTF.IN)
249 #define __digitalPinToBit(P) \
250 (((P) == 2 || (P) == 9 || (P) == 11 || (P) == 17) ? 0 : ((P) == 7 || (P) == 10 || (P) == 12 || (P) == 16) ? 1 : ((P) == 5 || (P) == 13 || (P) == 15 || (P) == 18) ? 2 : ((P) == 9 || (P) == 14 || (P) == 19) ? 3 : ((P) == 6 || (P) == 20) ? 4 : ((P) == 3 || (P) == 21) ? 5 : 6 )
251 
252 
253 // TinyCore
254 // https://raw.githubusercontent.com/xukangmin/TinyCore/master/avr/package/package_tinycore_index.json
255 // https://docs.tinycore.dev/en/latest/
256 #elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)
257 #define __digitalPinToPortReg(P) ((P) <= 5 ? &VPORTB.OUT : ((P) <= 9 ? &VPORTC.OUT : ((P) <= 16 ? &VPORTA.OUT : ((P) <= 18 ? &VPORTB.OUT : &VPORTC.OUT))))
258 #define __digitalPinToDDRReg(P) ((P) <= 5 ? &VPORTB.DIR : ((P) <= 9 ? &VPORTC.DIR : ((P) <= 16 ? &VPORTA.DIR : ((P) <= 18 ? &VPORTB.DIR : &VPORTC.DIR))))
259 #define __digitalPinToPINReg(P) ((P) <= 5 ? &VPORTB.IN : ((P) <= 9 ? &VPORTC.IN : ((P) <= 16 ? &VPORTA.IN : ((P) <= 18 ? &VPORTB.IN : &VPORTC.IN))))
260 #define __digitalPinToBit(P) ( (P) <= 3 ? (3 - P) : ((P) <= 5 ? (P) : ((P) <= 9 ? (P - 6) : ((P) <= 16 ? ((P) - 9) : ((P) <= 18 ? ((P) - 11) : ((P) - 15))))) )
261 
262 #elif defined(__AVR_ATtiny1614__)
263 #define __digitalPinToPortReg(P) ((P) <= 3 ? &VPORTA.OUT : ((P) <= 7 ? &VPORTB.OUT : &VPORTA.OUT))
264 #define __digitalPinToDDRReg(P) ((P) <= 3 ? &VPORTA.DIR : ((P) <= 7 ? &VPORTB.DIR : &VPORTA.DIR))
265 #define __digitalPinToPINReg(P) ((P) <= 3 ? &VPORTA.IN : ((P) <= 7 ? &VPORTB.IN : &VPORTA.IN))
266 #define __digitalPinToBit(P) ( (P) <= 3 ? (P + 4) : ((P) <= 7 ? (7 - P) : ((P) <= 10 ? (P - 7) : (P) - 11)) )
267 
268 #elif defined(__AVR_ATtiny816__)
269 // https://github.com/Arduino-IRremote/Arduino-IRremote/discussions/1029
270 #define __digitalPinToPortReg(P) ((P) <= 3 ? &VPORTA.OUT : ((P) <= 9 ? &VPORTB.OUT : ((P) <= 13 ? &VPORTC.OUT : ((P) <= 17 ? &VPORTA.OUT : &VPORTC.OUT))))
271 #define __digitalPinToDDRReg(P) ((P) <= 3 ? &VPORTA.DIR : ((P) <= 9 ? &VPORTB.DIR : ((P) <= 13 ? &VPORTC.DIR : ((P) <= 17 ? &VPORTA.DIR : &VPORTC.DIR))))
272 #define __digitalPinToPINReg(P) ((P) <= 3 ? &VPORTA.IN : ((P) <= 9 ? &VPORTB.IN : ((P) <= 13 ? &VPORTC.IN : ((P) <= 17 ? &VPORTA.IN : &VPORTC.IN))))
273 #define __digitalPinToBit(P) ( (P) <= 3 ? (P + 4) : ((P) <= 9 ? (9 - P) : ((P) <= 13 ? (P - 10) : ((P) <= 16 ? (P - 13) : ((P) - 17)))) )
274 
275 // --- ATtinyX5 ---
276 #elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
277 // we have only PORTB
278 #define __digitalPinToPortReg(P) (&PORTB)
279 #define __digitalPinToDDRReg(P) (&DDRB)
280 #define __digitalPinToPINReg(P) (&PINB)
281 #define __digitalPinToBit(P) (((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P) - 8 : (P) - 14))
282 
283 
284 // --- ATtiny88 ---
285 #elif defined(__AVR_ATtiny88__)
286 # if defined(ARDUINO_AVR_DIGISPARKPRO)
287 #define __digitalPinToPortReg(P) ((P) <= 7 ? &PORTD : ((P) <= 14 ? &PORTB : ((P) <= 18 ? &PORTA : &PORTC)))
288 #define __digitalPinToDDRReg(P) ((P) <= 7 ? &DDRD : ((P) <= 14 ? &DDRB : ((P) <= 18 ? &DDRA : &DDRC)))
289 #define __digitalPinToPINReg(P) ((P) <= 7 ? &PIND : ((P) <= 14 ? &PINB : ((P) <= 18 ? &PINA : &PINC)))
290 #define __digitalPinToBit(P) ( (P) <= 7 ? (P) : ((P) <= 13 ? ((P) - 8) : ((P) == 14 ? 7 : ((P) <= 16 ? ((P) - 14) : ((P) <= 18 ? ((P) - 17) : ((P) == 25 ? 7 : ((P) - 19)))))) )
291 # else
292 #define __digitalPinToPortReg(P) ((P) <= 7 ? &PORTD : ((P) <= 15 ? &PORTB : ((P) <= 22 ? &PORTC : ((P) <= 26 ? &PORTA : &PORTC))))
293 #define __digitalPinToDDRReg(P) ((P) <= 7 ? &DDRD : ((P) <= 15 ? &DDRB : ((P) <= 22 ? &DDRC : ((P) <= 26 ? &DDRA : &DDRC))))
294 #define __digitalPinToPINReg(P) ((P) <= 7 ? &PIND : ((P) <= 15 ? &PINB : ((P) <= 22 ? &PINC : ((P) <= 26 ? &PINA : &PINC))))
295 #define __digitalPinToBit(P) ((P) <= 15 ? ((P) & 0x7) : ((P) == 16 ? (7) : ((P) <= 22 ? ((P) - 17) : ((P) == 27 ? (6) : ((P) - 23)))))
296 # endif
297 
298 
299 // --- ATtinyX4 + ATtinyX7 ---
300 #elif defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) \
301  || defined(__AVR_ATtiny441__) || defined(__AVR_ATtiny841__) || defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)
302 # if defined(ARDUINO_AVR_DIGISPARKPRO) || PIN_PA7 == 5
303 // Strange enumeration of pins on Digispark board and core library
304 #define __digitalPinToPortReg(P) (((P) <= 4) ? &PORTB : &PORTA)
305 #define __digitalPinToDDRReg(P) (((P) <= 4) ? &DDRB : &DDRA)
306 #define __digitalPinToPINReg(P) (((P) <= 4) ? &PINB : &PINA)
307 #define __digitalPinToBit(P) (((P) <= 2) ? (P) : (((P) == 3) ? 6 : (((P) == 4) ? 3 : (((P) == 5) ? 7 : (P) - 6 ))))
308 # else
309 // ATtinyX4: PORTA for 0 to 7, PORTB for 8 to 11
310 // ATtinyX7: PORTA for 0 to 7, PORTB for 8 to 15
311 #define __digitalPinToPortReg(P) (((P) <= 7) ? &PORTA : &PORTB)
312 #define __digitalPinToDDRReg(P) (((P) <= 7) ? &DDRA : &DDRB)
313 #define __digitalPinToPINReg(P) (((P) <= 7) ? &PINA : &PINB)
314 # endif
315 # if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny441__) || defined(__AVR_ATtiny841__)
316 // https://github.com/SpenceKonde/ATTinyCore/blob/v2.0.0-devThis-is-the-head-submit-PRs-against-this/avr/variants/tinyx41_cw/pins_arduino.h#L334
317 // Clockwise layout
318 #define __digitalPinToBit(P) (((P) <= 7) ? (P) : ((P) == 11 ? (3) : 10 - (P)))
319 # else
320 #define __digitalPinToBit(P) (((P) <= 7) ? (P) : (P) - 8 )
321 # endif
322 
323 #endif
324 
325 #if !defined(digitalWriteFast)
326 # if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) && defined(__digitalPinToPortReg)
327 # if defined(THROW_ERROR_IF_NOT_FAST)
328 #define digitalWriteFast(P, V) \
329 do { \
330  if (__builtin_constant_p(P)) { \
331  BIT_WRITE(*__digitalPinToPortReg(P), __digitalPinToBit(P), (V)); \
332  } else { \
333  NonConstantsUsedForDigitalWriteFast(); \
334  } \
335 } while (0)
336 # else
337 #define digitalWriteFast(P, V) \
338 do { \
339  if (__builtin_constant_p(P)) { \
340  BIT_WRITE(*__digitalPinToPortReg(P), __digitalPinToBit(P), (V)); \
341  } else { \
342  digitalWrite((P), (V)); \
343  } \
344 } while (0)
345 # endif // defined(THROW_ERROR_IF_NOT_FAST)
346 # else
347 #define digitalWriteFast digitalWrite
348 # endif
349 #endif
350 
351 #if !defined(pinModeFast)
352 # if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) && defined(__digitalPinToPortReg)
353 # if defined(THROW_ERROR_IF_NOT_FAST)
354 #define pinModeFast(P, V) \
355 do { \
356  if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \
357  if (V == INPUT_PULLUP) {\
358  BIT_CLEAR(*__digitalPinToDDRReg(P), __digitalPinToBit(P)); \
359  BIT_SET(*__digitalPinToPortReg(P), __digitalPinToBit(P)); \
360  } else { \
361  BIT_WRITE(*__digitalPinToDDRReg(P), __digitalPinToBit(P), (V)); \
362  } \
363  } else { \
364  NonConstantsUsedForPinModeFast(); \
365  } \
366 } while (0)
367 # else
368 #define pinModeFast(P, V) \
369 do { \
370  if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \
371  if (V == INPUT_PULLUP) {\
372  BIT_CLEAR(*__digitalPinToDDRReg(P), __digitalPinToBit(P)); \
373  BIT_SET(*__digitalPinToPortReg(P), __digitalPinToBit(P)); \
374  } else { \
375  BIT_WRITE(*__digitalPinToDDRReg(P), __digitalPinToBit(P), (V)); \
376  } \
377  } else { \
378  pinMode((P), (V)); \
379  } \
380 } while (0)
381 # endif // defined(THROW_ERROR_IF_NOT_FAST)
382 # else
383 #define pinModeFast pinMode
384 # endif
385 #endif // !defined(pinModeFast)
386 
387 #if !defined(digitalReadFast)
388 # if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) && defined(__digitalPinToPINReg)
389 # if defined(THROW_ERROR_IF_NOT_FAST)
390 #define digitalReadFast(P) ( (int) __digitalReadFast((P)) )
391 // since we have return values, it is easier to implement it by ?:
392 #define __digitalReadFast(P ) ( (__builtin_constant_p(P) ) ? (( BIT_READ(*__digitalPinToPINReg(P), __digitalPinToBit(P))) ? HIGH:LOW ) : NonConstantsUsedForDigitalReadFast() )
393 # else
394 #define digitalReadFast(P) ( (int) __digitalReadFast((P)) )
395 // since we have return values, it is easier to implement it by ?:
396 #define __digitalReadFast(P ) ( (__builtin_constant_p(P) ) ? (( BIT_READ(*__digitalPinToPINReg(P), __digitalPinToBit(P))) ? HIGH:LOW ) : digitalRead((P)) )
397 # endif // defined(THROW_ERROR_IF_NOT_FAST)
398 # else
399 #define digitalReadFast digitalRead
400 # endif
401 #endif // !defined(digitalReadFast)
402 
403 #if !defined(digitalToggleFast)
404 # if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) && defined(__digitalPinToPINReg)
405 # if defined(THROW_ERROR_IF_NOT_FAST)
406 #define digitalToggleFast(P) \
407 do { \
408  if (__builtin_constant_p(P)) { \
409  BIT_SET(*__digitalPinToPINReg(P), __digitalPinToBit(P)); \
410  } else { \
411  NonConstantsUsedForDigitalToggleFast(); \
412  } \
413 } while (0)
414 # else
415 #define digitalToggleFast(P) \
416 do { \
417  if (__builtin_constant_p(P)) { \
418  BIT_SET(*__digitalPinToPINReg(P), __digitalPinToBit(P)); \
419  } else { \
420  digitalWrite(P, ! digitalRead(P)); \
421  } \
422 } while (0)
423 # endif // defined(THROW_ERROR_IF_NOT_FAST)
424 # else
425 #define digitalToggleFast(P) digitalWrite(P, ! digitalRead(P))
426 # endif
427 #endif // !defined(digitalToggleFast)
428 
429 #endif // !defined(MEGATINYCORE)
430 #endif //__digitalWriteFast_h_
NonConstantsUsedForPinModeFast
void NonConstantsUsedForPinModeFast(void) __attribute__((error("Parameter for pinModeFast() function is not const ant")))
NonConstantsUsedForDigitalWriteFast
void NonConstantsUsedForDigitalWriteFast(void) __attribute__((error("Parameter for digitalWriteFast() function is not const ant")))
NonConstantsUsedForDigitalReadFast
int NonConstantsUsedForDigitalReadFast(void) __attribute__((error("Parameter for digitalReadFast() function is not const ant")))
NonConstantsUsedForDigitalToggleFast
void NonConstantsUsedForDigitalToggleFast(void) __attribute__((error("Parameter for digitalToggleFast() function is not const ant")))