1 /*
2   Optimized digital functions for AVR microcontrollers
3   by Watterott electronic (www.watterott.com)
4   based on http://code.google.com/p/digitalwritefast
5  */
6 
7 #ifndef __digitalWriteFast_h_
8 #define __digitalWriteFast_h_ 1
9 
10 //#define SANGUINO_PINOUT //define for Sanguino pinout
11 
12 // general macros/defines
13 #ifndef BIT_READ
14 # define BIT_READ(value, bit)            ((value) &   (1UL << (bit)))
15 #endif
16 #ifndef BIT_SET
17 # define BIT_SET(value, bit)             ((value) |=  (1UL << (bit)))
18 #endif
19 #ifndef BIT_CLEAR
20 # define BIT_CLEAR(value, bit)           ((value) &= ~(1UL << (bit)))
21 #endif
22 #ifndef BIT_WRITE
23 # define BIT_WRITE(value, bit, bitvalue) (bitvalue ? BIT_SET(value, bit) : BIT_CLEAR(value, bit))
24 #endif
25 
26 #ifndef SWAP
27 # define SWAP(x,y) do{ (x)=(x)^(y); (y)=(x)^(y); (x)=(x)^(y); }while(0)
28 #endif
29 
30 #ifndef DEC
31 # define DEC (10)
32 #endif
33 #ifndef HEX
34 # define HEX (16)
35 #endif
36 #ifndef OCT
37 # define OCT (8)
38 #endif
39 #ifndef BIN
40 # define BIN (2)
41 #endif
42 
43 
44 // workarounds for ARM microcontrollers
45 #if (!defined(__AVR__) || \
46      defined(ARDUINO_ARCH_SAM) || \
47      defined(ARDUINO_ARCH_SAMD))
48 
49 #ifndef PROGMEM
50 # define PROGMEM
51 #endif
52 #ifndef PGM_P
53 # define PGM_P const char *
54 #endif
55 #ifndef PSTR
56 # define PSTR(str) (str)
57 #endif
58 
59 #ifndef memcpy_P
60 # define memcpy_P(dest, src, num) memcpy((dest), (src), (num))
61 #endif
62 #ifndef strcpy_P
63 # define strcpy_P(dst, src)       strcpy((dst), (src))
64 #endif
65 #ifndef strcat_P
66 # define strcat_P(dst, src)       strcat((dst), (src))
67 #endif
68 #ifndef strcmp_P
69 # define strcmp_P(a, b)           strcmp((a), (b))
70 #endif
71 #ifndef strcasecmp_P
72 # define strcasecmp_P(a, b)       strcasecmp((a), (b))
73 #endif
74 #ifndef strncmp_P
75 # define strncmp_P(a, b, n)       strncmp((a), (b), (n))
76 #endif
77 #ifndef strncasecmp_P
78 # define strncasecmp_P(a, b, n)   strncasecmp((a), (b), (n))
79 #endif
80 #ifndef strstr_P
81 # define strstr_P(a, b)           strstr((a), (b))
82 #endif
83 #ifndef strlen_P
84 # define strlen_P(a)              strlen((a))
85 #endif
86 #ifndef sprintf_P
87 # define sprintf_P(s, f, ...)     sprintf((s), (f), __VA_ARGS__)
88 #endif
89 
90 #ifndef pgm_read_byte
91 # define pgm_read_byte(addr)      (*(const unsigned char *)(addr))
92 #endif
93 #ifndef pgm_read_word
94 # define pgm_read_word(addr)      (*(const unsigned short *)(addr))
95 #endif
96 #ifndef pgm_read_dword
97 # define pgm_read_dword(addr)     (*(const unsigned long *)(addr))
98 #endif
99 
100 #endif
101 
102 
103 // digital functions
104 //#ifndef digitalPinToPortReg
105 #define SPI_SW_SS_PIN   (10) //SS on Uno (for software SPI)
106 #define SPI_SW_MOSI_PIN (11) //MOSI on Uno (for software SPI)
107 #define SPI_SW_MISO_PIN (12) //MISO on Uno (for software SPI)
108 #define SPI_SW_SCK_PIN  (13) //SCK on Uno (for software SPI)
109 
110 
111 // --- Arduino Due and SAM3X8E based boards ---
112 #if (defined(ARDUINO_SAM_DUE) || \
113      defined(__SAM3X8E__))
114 
115 #define UART_RX_PIN     (0)
116 #define UART_TX_PIN     (1)
117 
118 #define I2C_SDA_PIN     (20)
119 #define I2C_SCL_PIN     (21)
120 
121 #define SPI_HW_SS_PIN   (78) //SS0:77, SS1:87, SS2:86, SS3:78
122 #define SPI_HW_MOSI_PIN (75) //75
123 #define SPI_HW_MISO_PIN (74) //74
124 #define SPI_HW_SCK_PIN  (76) //76
125 
126 
127 // --- Arduino Zero and SAMD21G18 based boards ---
128 #elif (defined(ARDUINO_SAMD_ZERO) || \
129        defined(__SAMD21G18A__))
130 
131 #define UART_RX_PIN     (0)
132 #define UART_TX_PIN     (1)
133 
134 #define I2C_SDA_PIN     (16)
135 #define I2C_SCL_PIN     (17)
136 
137 #define SPI_HW_SS_PIN   (14) //14
138 #define SPI_HW_MOSI_PIN (21) //21
139 #define SPI_HW_MISO_PIN (18) //18
140 #define SPI_HW_SCK_PIN  (20) //20
141 
142 
143 // --- Arduino Mega and ATmega128x/256x based boards ---
144 #elif (defined(ARDUINO_AVR_MEGA) || \
145        defined(ARDUINO_AVR_MEGA1280) || \
146        defined(ARDUINO_AVR_MEGA2560) || \
147        defined(__AVR_ATmega1280__) || \
148        defined(__AVR_ATmega1281__) || \
149        defined(__AVR_ATmega2560__) || \
150        defined(__AVR_ATmega2561__))
151 
152 #define UART_RX_PIN     (0) //PE0
153 #define UART_TX_PIN     (1) //PE1
154 
155 #define I2C_SDA_PIN     (20)
156 #define I2C_SCL_PIN     (21)
157 
158 #define SPI_HW_SS_PIN   (53) //PB0
159 #define SPI_HW_MOSI_PIN (51) //PB2
160 #define SPI_HW_MISO_PIN (50) //PB3
161 #define SPI_HW_SCK_PIN  (52) //PB1
162 
163 #define __digitalPinToPortReg(P) \
164 (((P) >= 22 && (P) <= 29) ? &PORTA : \
165 ((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PORTB : \
166 (((P) >= 30 && (P) <= 37) ? &PORTC : \
167 ((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PORTD : \
168 ((((P) >= 0 && (P) <= 3) || (P) == 5) ? &PORTE : \
169 (((P) >= 54 && (P) <= 61) ? &PORTF : \
170 ((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PORTG : \
171 ((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PORTH : \
172 (((P) == 14 || (P) == 15) ? &PORTJ : \
173 (((P) >= 62 && (P) <= 69) ? &PORTK : &PORTL))))))))))
174 
175 #define __digitalPinToDDRReg(P) \
176 (((P) >= 22 && (P) <= 29) ? &DDRA : \
177 ((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &DDRB : \
178 (((P) >= 30 && (P) <= 37) ? &DDRC : \
179 ((((P) >= 18 && (P) <= 21) || (P) == 38) ? &DDRD : \
180 ((((P) >= 0 && (P) <= 3) || (P) == 5) ? &DDRE : \
181 (((P) >= 54 && (P) <= 61) ? &DDRF : \
182 ((((P) >= 39 && (P) <= 41) || (P) == 4) ? &DDRG : \
183 ((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &DDRH : \
184 (((P) == 14 || (P) == 15) ? &DDRJ : \
185 (((P) >= 62 && (P) <= 69) ? &DDRK : &DDRL))))))))))
186 
187 #define __digitalPinToPINReg(P) \
188 (((P) >= 22 && (P) <= 29) ? &PINA : \
189 ((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PINB : \
190 (((P) >= 30 && (P) <= 37) ? &PINC : \
191 ((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PIND : \
192 ((((P) >= 0 && (P) <= 3) || (P) == 5) ? &PINE : \
193 (((P) >= 54 && (P) <= 61) ? &PINF : \
194 ((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PING : \
195 ((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PINH : \
196 (((P) == 14 || (P) == 15) ? &PINJ : \
197 (((P) >= 62 && (P) <= 69) ? &PINK : &PINL))))))))))
198 
199 #define __digitalPinToBit(P) \
200 (((P) >=  7 && (P) <=  9) ? (P) - 3 : \
201 (((P) >= 10 && (P) <= 13) ? (P) - 6 : \
202 (((P) >= 22 && (P) <= 29) ? (P) - 22 : \
203 (((P) >= 30 && (P) <= 37) ? 37 - (P) : \
204 (((P) >= 39 && (P) <= 41) ? 41 - (P) : \
205 (((P) >= 42 && (P) <= 49) ? 49 - (P) : \
206 (((P) >= 50 && (P) <= 53) ? 53 - (P) : \
207 (((P) >= 54 && (P) <= 61) ? (P) - 54 : \
208 (((P) >= 62 && (P) <= 69) ? (P) - 62 : \
209 (((P) == 0 || (P) == 15 || (P) == 17 || (P) == 21) ? 0 : \
210 (((P) == 1 || (P) == 14 || (P) == 16 || (P) == 20) ? 1 : \
211 (((P) == 19) ? 2 : \
212 (((P) == 5 || (P) == 6 || (P) == 18) ? 3 : \
213 (((P) == 2) ? 4 : \
214 (((P) == 3 || (P) == 4) ? 5 : 7)))))))))))))))
215 
216 
217 // --- Arduino MightyCore standard pinout ---
218 #elif (defined(__AVR_ATmega1284P__) || \
219        defined(__AVR_ATmega1284__)  || \
220        defined(__AVR_ATmega644P__)  || \
221        defined(__AVR_ATmega644A__)  || \
222        defined(__AVR_ATmega644__)   || \
223        defined(__AVR_ATmega324PB__) || \
224        defined(__AVR_ATmega324PA__) || \
225        defined(__AVR_ATmega324P__)  || \
226        defined(__AVR_ATmega324A__)  || \
227        defined(__AVR_ATmega164P__)  || \
228        defined(__AVR_ATmega164A__)  || \
229        defined(__AVR_ATmega32__)    || \
230        defined(__AVR_ATmega16__)    || \
231        defined(__AVR_ATmega8535__))  && \
232       !defined(BOBUINO_PINOUT)
233 
234 #define UART_RX_PIN     (8) //PD0
235 #define UART_TX_PIN     (9) //PD1
236 
237 #define I2C_SDA_PIN     (17) //PC1
238 #define I2C_SCL_PIN     (16) //PC0
239 
240 #define SPI_HW_SS_PIN   (4) //PB4
241 #define SPI_HW_MOSI_PIN (5) //PB5
242 #define SPI_HW_MISO_PIN (6) //PB6
243 #define SPI_HW_SCK_PIN  (7) //PB7
244 
245 #if defined(__AVR_ATmega324PB__)
246 #define __digitalPinToPortReg(P) \
247 (((P) >= 0 && (P) <= 7) ? &PORTB : (((P) >= 8 && (P) <= 15) ? &PORTD : (((P) >= 16 && (P) <= 23) ? &PORTC : (((P) >= 24 && (P) <= 31) ? &PORTA : &PORTE))))
248 #define __digitalPinToDDRReg(P) \
249 (((P) >= 0 && (P) <= 7) ? &DDRB : (((P) >= 8 && (P) <= 15) ? &DDRD : (((P) >= 16 && (P) <= 23) ? &DDRC : (((P) >= 24 && (P) <= 31) ? &DDRA : &DDRE))))
250 #define __digitalPinToPINReg(P) \
251 (((P) >= 0 && (P) <= 7) ? &PINB : (((P) >= 8 && (P) <= 15) ? &PIND : (((P) >= 16 && (P) <= 23) ? &PINC : (((P) >= 24 && (P) <= 31) ? &PINA : &PINE))))
252 # if defined(SANGUINO_PINOUT)
253 #define __digitalPinToBit(P) \
254 (((P) >= 0 && (P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (((P) >= 16 && (P) <= 23) ? (7 - ((P) - 24)) : (P) - 32))))
255 # else //MightyCore Pinout
256 #define __digitalPinToBit(P) \
257 (((P) >= 0 && (P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (((P) >= 16 && (P) <= 23) ? (P) - 24 : (P) - 32))))
258 # endif
259 #else
260 #define __digitalPinToPortReg(P) \
261 (((P) >= 0 && (P) <= 7) ? &PORTB : (((P) >= 8 && (P) <= 15) ? &PORTD : (((P) >= 16 && (P) <= 23) ? &PORTC : &PORTA)))
262 #define __digitalPinToDDRReg(P) \
263 (((P) >= 0 && (P) <= 7) ? &DDRB : (((P) >= 8 && (P) <= 15) ? &DDRD : (((P) >= 16 && (P) <= 23) ? &DDRC : &DDRA)))
264 #define __digitalPinToPINReg(P) \
265 (((P) >= 0 && (P) <= 7) ? &PINB : (((P) >= 8 && (P) <= 15) ? &PIND : (((P) >= 16 && (P) <= 23) ? &PINC : &PINA)))
266 # if defined(SANGUINO_PINOUT)
267 #define __digitalPinToBit(P) \
268 (((P) >= 0 && (P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (7 - ((P) - 24)))))
269 # else //MightyCore Pinout
270 #define __digitalPinToBit(P) \
271 (((P) >= 0 && (P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (P) - 24)))
272 # endif
273 #endif
274 
275 
276 // --- Arduino Leonardo and ATmega16U4/32U4 based boards ---
277 #elif (defined(ARDUINO_AVR_LEONARDO) || \
278        defined(__AVR_ATmega16U4__) || \
279        defined(__AVR_ATmega32U4__))
280 
281 #define UART_RX_PIN     (0) //PD2
282 #define UART_TX_PIN     (1) //PD3
283 
284 #define I2C_SDA_PIN     (2) //PD1
285 #define I2C_SCL_PIN     (3) //PD0
286 
287 #define SPI_HW_SS_PIN   (17) //PB0
288 #define SPI_HW_MOSI_PIN (16) //PB2
289 #define SPI_HW_MISO_PIN (14) //PB3
290 #define SPI_HW_SCK_PIN  (15) //PB1
291 
292 #define __digitalPinToPortReg(P) \
293 ((((P) >= 0 && (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)))
294 #define __digitalPinToDDRReg(P) \
295 ((((P) >= 0 && (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)))
296 #define __digitalPinToPINReg(P) \
297 ((((P) >= 0 && (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)))
298 #define __digitalPinToBit(P) \
299 (((P) >= 8 && (P) <= 11) ? (P) - 4 : (((P) >= 18 && (P) <= 21) ? 25 - (P) : (((P) == 0) ? 2 : (((P) == 1) ? 3 : (((P) == 2) ? 1 : (((P) == 3) ? 0 : (((P) == 4) ? 4 : (((P) == 6) ? 7 : (((P) == 13) ? 7 : (((P) == 14) ? 3 : (((P) == 15) ? 1 : (((P) == 16) ? 2 : (((P) == 17) ? 0 : (((P) == 22) ? 1 : (((P) == 23) ? 0 : (((P) == 24) ? 4 : (((P) == 25) ? 7 : (((P) == 26) ? 4 : (((P) == 27) ? 5 : 6 )))))))))))))))))))
300 
301 
302 // --- Arduino Uno and ATmega168/328 based boards ---
303 #elif (defined(ARDUINO_AVR_UNO) || \
304        defined(ARDUINO_AVR_DUEMILANOVE) || \
305        defined(__AVR_ATmega8__) || \
306        defined(__AVR_ATmega48__) || \
307        defined(__AVR_ATmega48P__) || \
308        defined(__AVR_ATmega48PB__) || \
309        defined(__AVR_ATmega88P__) || \
310        defined(__AVR_ATmega88PB__) || \
311        defined(__AVR_ATmega168__) || \
312        defined(__AVR_ATmega168PA__) || \
313        defined(__AVR_ATmega168PB__) || \
314        defined(__AVR_ATmega328__) || \
315        defined(__AVR_ATmega328P__) || \
316        defined(__AVR_ATmega328PB__))
317 
318 #define UART_RX_PIN     (0) //PD0
319 #define UART_TX_PIN     (1) //PD1
320 
321 #define I2C_SDA_PIN     (18) //A4
322 #define I2C_SCL_PIN     (19) //A5
323 
324 #define SPI_HW_SS_PIN   (10) //PB0
325 #define SPI_HW_MOSI_PIN (11) //PB2
326 #define SPI_HW_MISO_PIN (12) //PB3
327 #define SPI_HW_SCK_PIN  (13) //PB1
328 
329 #if defined(__AVR_ATmega48PB__) || defined(__AVR_ATmega88PB__) || defined(__AVR_ATmega168PB__) || defined(__AVR_ATmega328PB__)
330 #define __digitalPinToPortReg(P) \
331 (((P) >= 0 && (P) <= 7) ? &PORTD : (((P) >= 8 && (P) <= 13) ? &PORTB : (((P) >= 14 && (P) <= 19) ? &PORTC : &PORTE)))
332 #define __digitalPinToDDRReg(P) \
333 (((P) >= 0 && (P) <= 7) ? &DDRD : (((P) >= 8 && (P) <= 13) ? &DDRB : (((P) >= 14 && (P) <= 19) ? &DDRC : &DDRE)))
334 #define __digitalPinToPINReg(P) \
335 (((P) >= 0 && (P) <= 7) ? &PIND : (((P) >= 8 && (P) <= 13) ? &PINB : (((P) >= 14 && (P) <= 19) ? &PINC : &PINE)))
336 #define __digitalPinToBit(P) \
337 (((P) >= 0 && (P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P) - 8 : (((P) >= 14 && (P) <= 19) ? (P) - 14 : (((P) >= 20 && (P) <= 21) ? (P) - 18 : (P) - 22))))
338 #else
339 #define __digitalPinToPortReg(P) \
340 (((P) >= 0 && (P) <= 7) ? &PORTD : (((P) >= 8 && (P) <= 13) ? &PORTB : &PORTC))
341 #define __digitalPinToDDRReg(P) \
342 (((P) >= 0 && (P) <= 7) ? &DDRD : (((P) >= 8 && (P) <= 13) ? &DDRB : &DDRC))
343 #define __digitalPinToPINReg(P) \
344 (((P) >= 0 && (P) <= 7) ? &PIND : (((P) >= 8 && (P) <= 13) ? &PINB : &PINC))
345 #define __digitalPinToBit(P) \
346 (((P) >= 0 && (P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P) - 8 : (P) - 14))
347 #endif
348 
349 
350 // --- Arduino Uno WiFi Rev 2, Nano Every ---
351 #elif defined(__AVR_ATmega4809__)
352 
353 #define UART_RX_PIN     (0) //PB0
354 #define UART_TX_PIN     (1) //PB1
355 
356 #define I2C_SDA_PIN     (22) //PA2
357 #define I2C_SCL_PIN     (23) //PA3
358 
359 #define SPI_HW_SS_PIN   (8)  //PE3
360 #define SPI_HW_MOSI_PIN (11) //PE0
361 #define SPI_HW_MISO_PIN (12) //PE1
362 #define SPI_HW_SCK_PIN  (13) //PE2
363 
364 #define __digitalPinToPortReg(P) \
365 (((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)
366 #define __digitalPinToDDRReg(P) \
367 (((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)
368 #define __digitalPinToPINReg(P) \
369 (((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)
370 #define __digitalPinToBit(P) \
371 (((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 )
372 
373 
374 // TinyCore
375 // https://raw.githubusercontent.com/xukangmin/TinyCore/master/avr/package/package_tinycore_index.json
376 // https://docs.tinycore.dev/en/latest/
377 #elif  defined(__AVR_ATtiny1616__)  || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)
378 #define __digitalPinToPortReg(P) ((P) <= 5 ? &VPORTB.OUT : ((P) <= 9 ? &VPORTC.OUT : ((P) <= 16 ? &VPORTA.OUT : ((P) <= 18 ? &VPORTB.OUT : &VPORTC.OUT))))
379 #define __digitalPinToDDRReg(P) ((P) <= 5 ? &VPORTB.DIR : ((P) <= 9 ? &VPORTC.DIR : ((P) <= 16 ? &VPORTA.DIR : ((P) <= 18 ? &VPORTB.DIR : &VPORTC.DIR))))
380 #define __digitalPinToPINReg(P) ((P) <= 5 ? &VPORTB.IN : ((P) <= 9 ? &VPORTC.IN : ((P) <= 16 ? &VPORTA.IN : ((P) <= 18 ? &VPORTB.IN : &VPORTC.IN))))
381 #define __digitalPinToBit(P) ( (P) <= 3 ? (3 - P) : ((P) <= 5 ? (P) : ((P) <= 9 ? (P - 6) : ((P) <= 16 ? ((P) - 9) : ((P) <= 18 ? ((P) - 11) : ((P) - 15))))) )
382 
383 
384 // --- ATtinyX5 ---
385 #elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
386 // we have only PORTB
387 #define __digitalPinToPortReg(P) (&PORTB)
388 #define __digitalPinToDDRReg(P)  (&DDRB)
389 #define __digitalPinToPINReg(P)  (&PINB)
390 #define __digitalPinToBit(P)     (((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P) - 8 : (P) - 14))
391 
392 
393 // --- ATtiny88 ---
394 #elif defined(__AVR_ATtiny88__)
395 # if defined(ARDUINO_AVR_DIGISPARKPRO)
396 #define __digitalPinToPortReg(P) ((P) <= 7 ? &PORTD : ((P) <= 14 ? &PORTB : ((P) <= 18 ? &PORTA : &PORTC)))
397 #define __digitalPinToDDRReg(P)  ((P) <= 7 ? &DDRD : ((P) <= 14 ? &DDRB : ((P) <= 18 ? &DDRA : &DDRC)))
398 #define __digitalPinToPINReg(P)  ((P) <= 7 ? &PIND : ((P) <= 14 ? &PINB : ((P) <= 18 ? &PINA : &PINC)))
399 #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)))))) )
400 # else
401 #define __digitalPinToPortReg(P) ((P) <= 7 ? &PORTD : ((P) <= 15 ? &PORTB : ((P) <= 22 ? &PORTC : ((P) <= 26 ? &PORTA : &PORTC))))
402 #define __digitalPinToDDRReg(P) ((P) <= 7 ? &DDRD : ((P) <= 15 ? &DDRB : ((P) <= 22 ? &DDRC : ((P) <= 26 ? &DDRA : &DDRC))))
403 #define __digitalPinToPINReg(P) ((P) <= 7 ? &PIND : ((P) <= 15 ? &PINB : ((P) <= 22 ? &PINC : ((P) <= 26 ? &PINA : &PINC))))
404 #define __digitalPinToBit(P) ((P) <= 15 ? ((P) & 0x7) : ((P) == 16 ? (7) : ((P) <= 22 ? ((P) - 17) : ((P) == 27 ? (6) : ((P) - 23)))))
405 # endif
406 
407 
408 // --- ATtinyX4 + ATtinyX7 ---
409 #elif  defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)
410 # if defined(ARDUINO_AVR_DIGISPARKPRO) || PIN_PA7 == 5
411 // Strange enumeration of pins on Digispark board and core library
412 #define __digitalPinToPortReg(P) (((P) <= 4) ? &PORTB : &PORTA)
413 #define __digitalPinToDDRReg(P)  (((P) <= 4) ? &DDRB : &DDRA)
414 #define __digitalPinToPINReg(P)  (((P) <= 4) ? &PINB : &PINA)
415 #define __digitalPinToBit(P)     (((P) <= 2) ? (P) : (((P) == 3) ? 6 : (((P) == 4) ? 3 : (((P) == 5) ? 7 : (P) - 6 ))))
416 # else
417 // ATtinyX4: PORTA for 0 to 7, PORTB for 8 to 11
418 // ATtinyX7: PORTA for 0 to 7, PORTB for 8 to 15
419 #define __digitalPinToPortReg(P) (((P) <= 7) ? &PORTA : &PORTB)
420 #define __digitalPinToDDRReg(P)  (((P) <= 7) ? &DDRA : &DDRB)
421 #define __digitalPinToPINReg(P)  (((P) <= 7) ? &PINA : &PINB)
422 #define __digitalPinToBit(P)     (((P) <= 7) ? (P) : (P) - 8 )
423 # endif
424 
425 // --- Other ---
426 #else
427 
428 #define I2C_SDA_PIN     SDA
429 #define I2C_SCL_PIN     SCL
430 
431 #define SPI_HW_SS_PIN   SS
432 #define SPI_HW_MOSI_PIN MOSI
433 #define SPI_HW_MISO_PIN MISO
434 #define SPI_HW_SCK_PIN  SCK
435 
436 
437 #endif
438 //#endif  //#ifndef digitalPinToPortReg
439 
440 
441 #ifndef digitalWriteFast
442 #if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) && defined(__digitalPinToPortReg)
443 #define digitalWriteFast(P, V) \
444 if (__builtin_constant_p(P)) { \
445   BIT_WRITE(*__digitalPinToPortReg(P), __digitalPinToBit(P), (V)); \
446 } else { \
447   digitalWrite((P), (V)); \
448 }
449 #else
450 #define digitalWriteFast digitalWrite
451 #endif
452 #endif
453 
454 
455 #ifndef pinModeFast
456 #if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) && defined(__digitalPinToPortReg)
457 #define pinModeFast(P, V) \
458 if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \
459   if (V == INPUT_PULLUP) {\
460     BIT_CLEAR(*__digitalPinToDDRReg(P), __digitalPinToBit(P)); \
461     BIT_SET(*__digitalPinToPortReg(P), __digitalPinToBit(P)); \
462   } else { \
463     BIT_WRITE(*__digitalPinToDDRReg(P), __digitalPinToBit(P), (V)); \
464   } \
465 } else { \
466   pinMode((P), (V)); \
467 }
468 #else
469 #define pinModeFast pinMode
470 #endif
471 #endif
472 
473 
474 #ifndef digitalReadFast
475 #if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
476 #define digitalReadFast(P) ( (int) __digitalReadFast((P)) )
477 #define __digitalReadFast(P ) \
478   (__builtin_constant_p(P) ) ? \
479   (( BIT_READ(*__digitalPinToPINReg(P), __digitalPinToBit(P))) ? HIGH:LOW ) : \
480   digitalRead((P))
481 #else
482 #define digitalReadFast digitalRead
483 #endif
484 #endif
485 
486 
487 #ifndef digitalToggleFast
488 #if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
489 #define digitalToggleFast(P) \
490 if (__builtin_constant_p(P)) { \
491   BIT_SET(*__digitalPinToPINReg(P), __digitalPinToBit(P)); \
492 } else { \
493   digitalWrite(P, ! digitalRead(P)); \
494 }
495 #else
496 #define digitalToggleFast(P) digitalWrite(P, ! digitalRead(P))
497 #endif
498 #endif
499 
500 
501 #endif //__digitalWriteFast_h_
502