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