├── Examples ├── ReadFast │ └── ReadFast.ino ├── ToggleFast │ └── ToggleFast.ino └── ToggleSlow │ └── ToggleSlow.ino ├── NOTES ├── NOTES.md └── graphs │ ├── 1.png │ ├── 2.png │ └── 3.png ├── README.md └── digitalWriteFast.h /Examples/ReadFast/ReadFast.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #define pinNum 9 3 | //int pinNum = 9; //do not use variables, macro will revert to the slower pinMode() 4 | //const int pinNum = 9; //this is a constant, will use port manipulation (fast) 5 | 6 | void setup() { 7 | pinModeFast(pinNum, INPUT); 8 | } 9 | 10 | void loop() { 11 | bool reading = digitalReadFast(pinNum); 12 | 13 | if (reading == ERROR_SEQUENCE) { //ERROR_SEQUENCE defined as 0b10101010 14 | // pinNum is not a const and will always return as HIGH 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Examples/ToggleFast/ToggleFast.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #define pinNum 9 3 | //int pinNum = 9; //do not use variables, macro will revert to the slower digitalWrite() 4 | //const int pinNum = 9; //this is a constant, will use port manipulation (fast) 5 | void setup() { 6 | pinModeFast(pinNum, OUTPUT); 7 | } 8 | 9 | void loop() { 10 | //the pin is toggled multiple time before looping is because it took too long that the pin stayed low for 600ns, while clearing or setting the pin only took 125ns. For 16MHz Arduino Uno. 11 | digitalWriteFast(pinNum, HIGH); 12 | digitalWriteFast(pinNum, LOW); 13 | digitalWriteFast(pinNum, HIGH); 14 | digitalWriteFast(pinNum, LOW); 15 | digitalWriteFast(pinNum, HIGH); 16 | digitalWriteFast(pinNum, LOW); 17 | digitalWriteFast(pinNum, HIGH); 18 | digitalWriteFast(pinNum, LOW); 19 | digitalWriteFast(pinNum, HIGH); 20 | digitalWriteFast(pinNum, LOW); 21 | digitalWriteFast(pinNum, HIGH); 22 | digitalWriteFast(pinNum, LOW); 23 | digitalWriteFast(pinNum, HIGH); 24 | digitalWriteFast(pinNum, LOW); 25 | digitalWriteFast(pinNum, HIGH); 26 | digitalWriteFast(pinNum, LOW); 27 | digitalWriteFast(pinNum, HIGH); 28 | digitalWriteFast(pinNum, LOW); 29 | digitalWriteFast(pinNum, HIGH); 30 | digitalWriteFast(pinNum, LOW); 31 | digitalWriteFast(pinNum, HIGH); 32 | digitalWriteFast(pinNum, LOW); 33 | digitalWriteFast(pinNum, HIGH); 34 | digitalWriteFast(pinNum, LOW); 35 | digitalWriteFast(pinNum, HIGH); 36 | digitalWriteFast(pinNum, LOW); 37 | digitalWriteFast(pinNum, HIGH); 38 | digitalWriteFast(pinNum, LOW); 39 | digitalWriteFast(pinNum, HIGH); 40 | digitalWriteFast(pinNum, LOW); 41 | digitalWriteFast(pinNum, HIGH); 42 | digitalWriteFast(pinNum, LOW); 43 | digitalWriteFast(pinNum, HIGH); 44 | digitalWriteFast(pinNum, LOW); 45 | } -------------------------------------------------------------------------------- /Examples/ToggleSlow/ToggleSlow.ino: -------------------------------------------------------------------------------- 1 | #define pinNum 9 2 | //int pinNum = 9; //for regular digitalWrite(), does matter constant or variable 3 | //const int pinNum = 9; //this is a constant 4 | 5 | void setup() { 6 | pinMode(pinNum, OUTPUT); 7 | } 8 | 9 | void loop() { 10 | //digitalWrite is so slow that , you don't actually need to toggle multiple times in 1 loop 11 | // because digitalWrite takes 6280ns but to return to the start of loop takes only 600ns. 12 | // this only makes a big deal when using digitalWriteFast(pinNum, state); 13 | digitalWrite(pinNum, HIGH); 14 | digitalWrite(pinNum, LOW); 15 | digitalWrite(pinNum, HIGH); 16 | digitalWrite(pinNum, LOW); 17 | digitalWrite(pinNum, HIGH); 18 | digitalWrite(pinNum, LOW); 19 | digitalWrite(pinNum, HIGH); 20 | digitalWrite(pinNum, LOW); 21 | digitalWrite(pinNum, HIGH); 22 | digitalWrite(pinNum, LOW); 23 | digitalWrite(pinNum, HIGH); 24 | digitalWrite(pinNum, LOW); 25 | digitalWrite(pinNum, HIGH); 26 | digitalWrite(pinNum, LOW); 27 | digitalWrite(pinNum, HIGH); 28 | digitalWrite(pinNum, LOW); 29 | digitalWrite(pinNum, HIGH); 30 | digitalWrite(pinNum, LOW); 31 | digitalWrite(pinNum, HIGH); 32 | digitalWrite(pinNum, LOW); 33 | digitalWrite(pinNum, HIGH); 34 | digitalWrite(pinNum, LOW); 35 | digitalWrite(pinNum, HIGH); 36 | digitalWrite(pinNum, LOW); 37 | } 38 | -------------------------------------------------------------------------------- /NOTES/NOTES.md: -------------------------------------------------------------------------------- 1 | # Notes 2 | 3 | Notes down the observations, experiences and occurrences during the development of the repo. 4 | 5 | Useful for explaining certain decisions. 6 | 7 | 8 | ###### speed of digitalWriteFast: 9 | 10 | On Arduino Uno clone, 16MHz 11 | 12 | digitalWriteFast is so fast that 13 | 14 | ```C++ 15 | void loop() { 16 | digitalWriteFast(pinNum, HIGH); 17 | digitalWriteFast(pinNum, LOW); 18 | } 19 | ``` 20 | 21 | The above did not result in 50% duty cycle. 22 | ![Graph 1](graphs/1.png) 23 | 24 | Rather, the pin stays low for quite some time until the program loops again. 25 | 26 | Took around 600ns for the program to repeat 27 | 28 | 29 | So, the below was done instead: 30 | 31 | ```C++ 32 | void loop() { 33 | digitalWriteFast(pinNum, HIGH); 34 | digitalWriteFast(pinNum, LOW); 35 | digitalWriteFast(pinNum, HIGH); 36 | digitalWriteFast(pinNum, LOW); 37 | // ... and it goes on, multiple times 38 | digitalWriteFast(pinNum, HIGH); 39 | digitalWriteFast(pinNum, LOW); 40 | digitalWriteFast(pinNum, HIGH); 41 | digitalWriteFast(pinNum, LOW); 42 | } 43 | ``` 44 | 45 | It only took 250ns to toggle, meaning it took only 250ns/2= **125ns** to set or clear the pin/port. 46 | ![Graph 2](graphs/2.png) 47 | 48 | ###### speed of digitalWrite: 49 | 50 | On Arduino Uno clone, 16MHz 51 | 52 | It took 12.56us to toggle, meaning it took 12.56us/2= **6280ns** to set or clear the pin/port. 53 | 54 | **50 times slower than direct port manipulation!** 55 | 56 | ![Graph 3](graphs/3.png) 57 | 58 | -------------------------------------------------------------------------------- /NOTES/graphs/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NicksonYap/digitalWriteFast/045456cba96d640ffdf110f756233792de231b0d/NOTES/graphs/1.png -------------------------------------------------------------------------------- /NOTES/graphs/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NicksonYap/digitalWriteFast/045456cba96d640ffdf110f756233792de231b0d/NOTES/graphs/2.png -------------------------------------------------------------------------------- /NOTES/graphs/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NicksonYap/digitalWriteFast/045456cba96d640ffdf110f756233792de231b0d/NOTES/graphs/3.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # digitalWriteFast 2 | Arduino library for faster `digitalWrite()` using direct port manipulation and macro for ease in pin assignments. 3 | Which actually also does faster `pinMode()` and `digitalRead()`. 4 | 5 | ## Usage 6 | Include the library: 7 | `#include ` 8 | 9 | Macro definitions: 10 | * `digitalWriteFast(pinNum, state)` (sets or clears pin/port faster) 11 | * `pinModeFast(pinNum, mode)` (sets pin/port as input or output faster) 12 | * `digitalReadFast(pinNum)`(reads the state of pin/port faster) 13 | 14 | Parameters: 15 | * `pinNum` is the number written on the Arduino board. 16 | * `state` is weather pin is to be set `HIGH` or `LOW` 17 | * `mode` is weather pin is to be set `INPUT` or `OUTPUT` 18 | 19 | In order to toggle fast, all the three parameters above must be constant or defined by the macro for ease in changes during compilation. 20 | 21 | For example: 22 | * use '#define pinNum 10' instead of `int pinNum = 10;` 23 | * use 'const int pinNum 10' instead of `int pinNum = 10;` 24 | 25 | Setting the parameter as a variable would cause the macro to return an error during compilation. 26 | 27 | This makes sure `digitalWriteFast` that produces faster toggling, and notifies the programmer the specific area where toggling is slow. Otherwise, use normal `digitalWrite` 28 | 29 | This is opposed to the forked library form Watterott, where if a variable is used as the parameter, the macro would revert to use old `digitalWrite`, and remain undetected. 30 | 31 | 32 | ## Speed 33 | 34 | The regular `digitalWrite()` in Arduino Uno core (16MHz) takes about **6280nS** while `digitalWriteFast()` port manipulation takes **125nS**. 35 | > More info in: [/NOTES/NOTES.md](/NOTES/NOTES.md) 36 | 37 | This is a huge difference, especially or timing sensitive applications. 38 | 39 | Direct port manipulation is troublesome where one has to refer to the pin assignment of the package and manipulate specific ports, instead of pin numbers on the Arduino board. 40 | 41 | This library makes it easier by using `digitalWriteFast()` and the macro will replace it will the approritate port manipulation commands. 42 | 43 | ## Compatibility 44 | * Arduino Due 45 | * Arduino Zero 46 | * Arduino Mega 47 | * Arduino with ATmega644 or Atmega644P chip 48 | * Arduino Leonardo 49 | * Arduino Uno (I have only tested with uno) 50 | 51 | If not in the list, the macro will revert back to `digitalWrite()`, `pinMode()` or `digitalRead()` 52 | 53 | ## Installation 54 | 1. Download the repo as zip, extract and place into Arduino IDE libraries folder. 55 | 2. Rename "digitalWriteFast-master" to "digitalWriteFast" Arduino IDE does not accept dash character. 56 | 57 | 58 | ## Reference 59 | Fork of Watterott's https://github.com/watterott/Arduino-Libs/tree/master/digitalWriteFast 60 | I just forked the whole repo, and delete unrelated files, I tried sparse checkout and gave up. 61 | 62 | Watterott's digitalWriteFast could have used the below links as referrence. 63 | * https://code.google.com/archive/p/digitalwritefast/downloads 64 | * http://forum.arduino.cc/index.php?topic=46896.0 65 | -------------------------------------------------------------------------------- /digitalWriteFast.h: -------------------------------------------------------------------------------- 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 ERROR_SEQUENCE 0b10101010 //digitalReadFast will return this value if pin number is not constant 11 | // general macros/defines 12 | #ifndef BIT_READ 13 | # define BIT_READ(value, bit) ((value) & (1UL << (bit))) 14 | #endif 15 | #ifndef BIT_SET 16 | # define BIT_SET(value, bit) ((value) |= (1UL << (bit))) 17 | #endif 18 | #ifndef BIT_CLEAR 19 | # define BIT_CLEAR(value, bit) ((value) &= ~(1UL << (bit))) 20 | #endif 21 | #ifndef BIT_WRITE 22 | # define BIT_WRITE(value, bit, bitvalue) (bitvalue ? BIT_SET(value, bit) : BIT_CLEAR(value, bit)) 23 | #endif 24 | 25 | #ifndef SWAP 26 | #define SWAP(x,y) do{ (x)=(x)^(y); (y)=(x)^(y); (x)=(x)^(y); }while(0) 27 | #endif 28 | 29 | /* //not needed, rather it produces annoying warnings when compiled 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__) || defined(ARDUINO_ARCH_SAM)) 46 | #ifndef PROGMEM 47 | # define PROGMEM 48 | #endif 49 | #ifndef PGM_P 50 | # define PGM_P const char * 51 | #endif 52 | #ifndef PSTR 53 | # define PSTR(str) (str) 54 | #endif 55 | 56 | #ifndef memcpy_P 57 | # define memcpy_P(dest, src, num) memcpy((dest), (src), (num)) 58 | #endif 59 | #ifndef strcpy_P 60 | # define strcpy_P(dst, src) strcpy((dst), (src)) 61 | #endif 62 | #ifndef strcat_P 63 | # define strcat_P(dst, src) strcat((dst), (src)) 64 | #endif 65 | #ifndef strcmp_P 66 | # define strcmp_P(a, b) strcmp((a), (b)) 67 | #endif 68 | #ifndef strcasecmp_P 69 | # define strcasecmp_P(a, b) strcasecmp((a), (b)) 70 | #endif 71 | #ifndef strncmp_P 72 | # define strncmp_P(a, b, n) strncmp((a), (b), (n)) 73 | #endif 74 | #ifndef strncasecmp_P 75 | # define strncasecmp_P(a, b, n) strncasecmp((a), (b), (n)) 76 | #endif 77 | #ifndef strstr_P 78 | # define strstr_P(a, b) strstr((a), (b)) 79 | #endif 80 | #ifndef strlen_P 81 | # define strlen_P(a) strlen((a)) 82 | #endif 83 | #ifndef sprintf_P 84 | # define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__) 85 | #endif 86 | 87 | #ifndef pgm_read_byte 88 | # define pgm_read_byte(addr) (*(const unsigned char *)(addr)) 89 | #endif 90 | #ifndef pgm_read_word 91 | # define pgm_read_word(addr) (*(const unsigned short *)(addr)) 92 | #endif 93 | #ifndef pgm_read_dword 94 | # define pgm_read_dword(addr) (*(const unsigned long *)(addr)) 95 | #endif 96 | 97 | #endif 98 | 99 | 100 | // digital functions 101 | //#ifndef digitalPinToPortReg 102 | #define SPI_SW_SS_PIN (10) //SS on Uno (for software SPI) 103 | #define SPI_SW_MOSI_PIN (11) //MOSI on Uno (for software SPI) 104 | #define SPI_SW_MISO_PIN (12) //MISO on Uno (for software SPI) 105 | #define SPI_SW_SCK_PIN (13) //SCK on Uno (for software SPI) 106 | 107 | 108 | // --- Arduino Due --- 109 | #if (defined(ARDUINO_SAM_DUE) || defined(__SAM3X8E__)) 110 | 111 | #define UART_RX_PIN (0) 112 | #define UART_TX_PIN (1) 113 | 114 | #define I2C_SDA_PIN (20) 115 | #define I2C_SCL_PIN (21) 116 | 117 | #define SPI_HW_SS_PIN (78) //SS0:77, SS1:87, SS2:86, SS3:78 118 | #define SPI_HW_MOSI_PIN (75) //75 119 | #define SPI_HW_MISO_PIN (74) //74 120 | #define SPI_HW_SCK_PIN (76) //76 121 | 122 | 123 | // --- Arduino Zero --- 124 | #elif (defined(ARDUINO_SAM_ZERO) || defined(__SAMD21G18A__)) 125 | 126 | #define UART_RX_PIN (0) 127 | #define UART_TX_PIN (1) 128 | 129 | #define I2C_SDA_PIN (16) 130 | #define I2C_SCL_PIN (17) 131 | 132 | #define SPI_HW_SS_PIN (14) //14 133 | #define SPI_HW_MOSI_PIN (21) //21 134 | #define SPI_HW_MISO_PIN (18) //18 135 | #define SPI_HW_SCK_PIN (20) //20 136 | 137 | 138 | // --- Arduino Mega --- 139 | #elif (defined(ARDUINO_AVR_MEGA) || \ 140 | defined(ARDUINO_AVR_MEGA1280) || \ 141 | defined(ARDUINO_AVR_MEGA2560) || \ 142 | defined(__AVR_ATmega1280__) || \ 143 | defined(__AVR_ATmega1281__) || \ 144 | defined(__AVR_ATmega2560__) || \ 145 | defined(__AVR_ATmega2561__)) 146 | 147 | #define UART_RX_PIN (0) //PE0 148 | #define UART_TX_PIN (1) //PE1 149 | 150 | #define I2C_SDA_PIN (20) 151 | #define I2C_SCL_PIN (21) 152 | 153 | #define SPI_HW_SS_PIN (53) //PB0 154 | #define SPI_HW_MOSI_PIN (51) //PB2 155 | #define SPI_HW_MISO_PIN (50) //PB3 156 | #define SPI_HW_SCK_PIN (52) //PB1 157 | 158 | #define __digitalPinToPortReg(P) \ 159 | (((P) >= 22 && (P) <= 29) ? &PORTA : \ 160 | ((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PORTB : \ 161 | (((P) >= 30 && (P) <= 37) ? &PORTC : \ 162 | ((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PORTD : \ 163 | ((((P) >= 0 && (P) <= 3) || (P) == 5) ? &PORTE : \ 164 | (((P) >= 54 && (P) <= 61) ? &PORTF : \ 165 | ((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PORTG : \ 166 | ((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PORTH : \ 167 | (((P) == 14 || (P) == 15) ? &PORTJ : \ 168 | (((P) >= 62 && (P) <= 69) ? &PORTK : &PORTL)))))))))) 169 | 170 | #define __digitalPinToDDRReg(P) \ 171 | (((P) >= 22 && (P) <= 29) ? &DDRA : \ 172 | ((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &DDRB : \ 173 | (((P) >= 30 && (P) <= 37) ? &DDRC : \ 174 | ((((P) >= 18 && (P) <= 21) || (P) == 38) ? &DDRD : \ 175 | ((((P) >= 0 && (P) <= 3) || (P) == 5) ? &DDRE : \ 176 | (((P) >= 54 && (P) <= 61) ? &DDRF : \ 177 | ((((P) >= 39 && (P) <= 41) || (P) == 4) ? &DDRG : \ 178 | ((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &DDRH : \ 179 | (((P) == 14 || (P) == 15) ? &DDRJ : \ 180 | (((P) >= 62 && (P) <= 69) ? &DDRK : &DDRL)))))))))) 181 | 182 | #define __digitalPinToPINReg(P) \ 183 | (((P) >= 22 && (P) <= 29) ? &PINA : \ 184 | ((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PINB : \ 185 | (((P) >= 30 && (P) <= 37) ? &PINC : \ 186 | ((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PIND : \ 187 | ((((P) >= 0 && (P) <= 3) || (P) == 5) ? &PINE : \ 188 | (((P) >= 54 && (P) <= 61) ? &PINF : \ 189 | ((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PING : \ 190 | ((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PINH : \ 191 | (((P) == 14 || (P) == 15) ? &PINJ : \ 192 | (((P) >= 62 && (P) <= 69) ? &PINK : &PINL)))))))))) 193 | 194 | #define __digitalPinToBit(P) \ 195 | (((P) >= 7 && (P) <= 9) ? (P) - 3 : \ 196 | (((P) >= 10 && (P) <= 13) ? (P) - 6 : \ 197 | (((P) >= 22 && (P) <= 29) ? (P) - 22 : \ 198 | (((P) >= 30 && (P) <= 37) ? 37 - (P) : \ 199 | (((P) >= 39 && (P) <= 41) ? 41 - (P) : \ 200 | (((P) >= 42 && (P) <= 49) ? 49 - (P) : \ 201 | (((P) >= 50 && (P) <= 53) ? 53 - (P) : \ 202 | (((P) >= 54 && (P) <= 61) ? (P) - 54 : \ 203 | (((P) >= 62 && (P) <= 69) ? (P) - 62 : \ 204 | (((P) == 0 || (P) == 15 || (P) == 17 || (P) == 21) ? 0 : \ 205 | (((P) == 1 || (P) == 14 || (P) == 16 || (P) == 20) ? 1 : \ 206 | (((P) == 19) ? 2 : \ 207 | (((P) == 5 || (P) == 6 || (P) == 18) ? 3 : \ 208 | (((P) == 2) ? 4 : \ 209 | (((P) == 3 || (P) == 4) ? 5 : 7))))))))))))))) 210 | 211 | 212 | // --- Arduino 644 --- 213 | #elif (defined(__AVR_ATmega644__) || \ 214 | defined(__AVR_ATmega644P__)) 215 | 216 | #define UART_RX_PIN (8) //PD0 217 | #define UART_TX_PIN (9) //PD1 218 | 219 | #define I2C_SDA_PIN (17) //PC1 220 | #define I2C_SCL_PIN (16) //PC0 221 | 222 | #define SPI_HW_SS_PIN (4) //PB4 223 | #define SPI_HW_MOSI_PIN (5) //PB5 224 | #define SPI_HW_MISO_PIN (6) //PB6 225 | #define SPI_HW_SCK_PIN (7) //PB7 226 | 227 | #define __digitalPinToPortReg(P) \ 228 | (((P) >= 0 && (P) <= 7) ? &PORTB : (((P) >= 8 && (P) <= 15) ? &PORTD : (((P) >= 16 && (P) <= 23) ? &PORTC : &PORTA))) 229 | #define __digitalPinToDDRReg(P) \ 230 | (((P) >= 0 && (P) <= 7) ? &DDRB : (((P) >= 8 && (P) <= 15) ? &DDRD : (((P) >= 8 && (P) <= 15) ? &DDRC : &DDRA))) 231 | #define __digitalPinToPINReg(P) \ 232 | (((P) >= 0 && (P) <= 7) ? &PINB : (((P) >= 8 && (P) <= 15) ? &PIND : (((P) >= 8 && (P) <= 15) ? &PINC : &PINA))) 233 | #define __digitalPinToBit(P) \ 234 | (((P) >= 0 && (P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (P) - 24))) 235 | 236 | 237 | // --- Arduino Leonardo --- 238 | #elif (defined(ARDUINO_AVR_LEONARDO) || \ 239 | defined(__AVR_ATmega16U4__) || \ 240 | defined(__AVR_ATmega32U4__)) 241 | 242 | #define UART_RX_PIN (0) //PD2 243 | #define UART_TX_PIN (1) //PD3 244 | 245 | #define I2C_SDA_PIN (2) //PD1 246 | #define I2C_SCL_PIN (3) //PD0 247 | 248 | #define SPI_HW_SS_PIN (17) //PB0 249 | #define SPI_HW_MOSI_PIN (16) //PB2 250 | #define SPI_HW_MISO_PIN (14) //PB3 251 | #define SPI_HW_SCK_PIN (15) //PB1 252 | 253 | #define __digitalPinToPortReg(P) \ 254 | ((((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))) 255 | #define __digitalPinToDDRReg(P) \ 256 | ((((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))) 257 | #define __digitalPinToPINReg(P) \ 258 | ((((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))) 259 | #define __digitalPinToBit(P) \ 260 | (((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 ))))))))))))))))))) 261 | 262 | 263 | // --- Arduino Uno --- 264 | #elif (defined(ARDUINO_AVR_UNO) || \ 265 | defined(ARDUINO_AVR_DUEMILANOVE) || \ 266 | defined(ARDUINO_ARCH_AVR) || \ 267 | defined(__AVR_ATmega328__) || \ 268 | defined(__AVR_ATmega328P__) || \ 269 | defined(__AVR__)) 270 | 271 | #define UART_RX_PIN (0) //PD0 272 | #define UART_TX_PIN (1) //PD1 273 | 274 | #define I2C_SDA_PIN (18) //A4 275 | #define I2C_SCL_PIN (19) //A5 276 | 277 | #define SPI_HW_SS_PIN (10) //PB0 278 | #define SPI_HW_MOSI_PIN (11) //PB2 279 | #define SPI_HW_MISO_PIN (12) //PB3 280 | #define SPI_HW_SCK_PIN (13) //PB1 281 | 282 | #define __digitalPinToPortReg(P) \ 283 | (((P) >= 0 && (P) <= 7) ? &PORTD : (((P) >= 8 && (P) <= 13) ? &PORTB : &PORTC)) 284 | #define __digitalPinToDDRReg(P) \ 285 | (((P) >= 0 && (P) <= 7) ? &DDRD : (((P) >= 8 && (P) <= 13) ? &DDRB : &DDRC)) 286 | #define __digitalPinToPINReg(P) \ 287 | (((P) >= 0 && (P) <= 7) ? &PIND : (((P) >= 8 && (P) <= 13) ? &PINB : &PINC)) 288 | #define __digitalPinToBit(P) \ 289 | (((P) >= 0 && (P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P) - 8 : (P) - 14)) 290 | 291 | 292 | // --- Other --- 293 | #else 294 | 295 | #define SPI_HW_SS_PIN SS 296 | #define SPI_HW_MOSI_PIN MOSI 297 | #define SPI_HW_MISO_PIN MISO 298 | #define SPI_HW_SCK_PIN SCK 299 | 300 | 301 | #endif 302 | //#endif //#ifndef digitalPinToPortReg 303 | 304 | 305 | //ref: http://forum.arduino.cc/index.php?topic=140409.msg1054868#msg1054868 306 | //void OutputsErrorIfCalled( void ) __attribute__ (( error( "Line: "__line__ "Variable used for digitalWriteFast") )); 307 | void NonConstantUsed( void ) __attribute__ (( error("") )); 308 | 309 | 310 | #ifndef digitalWriteFast 311 | #if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) 312 | #define digitalWriteFast(P, V) \ 313 | if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \ 314 | BIT_WRITE(*__digitalPinToPortReg(P), __digitalPinToBit(P), (V)); \ 315 | } else { \ 316 | NonConstantUsed(); \ 317 | } 318 | #else 319 | //#define digitalWriteFast digitalWrite 320 | #error Non-AVR device, unsupported. 321 | #endif 322 | #endif 323 | 324 | 325 | #ifndef pinModeFast 326 | #if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) 327 | #define pinModeFast(P, V) \ 328 | if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \ 329 | BIT_WRITE(*__digitalPinToDDRReg(P), __digitalPinToBit(P), (V)); \ 330 | } else { \ 331 | NonConstantUsed(); \ 332 | } 333 | #else 334 | //#define pinModeFast pinMode 335 | #error Non-AVR device, unsupported. 336 | #endif 337 | #endif 338 | 339 | 340 | #ifndef digitalReadFast 341 | #if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) 342 | #define digitalReadFast(P) ( (byte) __digitalReadFast((P)) ) 343 | #define __digitalReadFast(P ) \ 344 | (__builtin_constant_p(P) ) ? ( \ 345 | ( BIT_READ(*__digitalPinToPINReg(P), __digitalPinToBit(P))) ) : \ 346 | ERROR_SEQUENCE 347 | #else 348 | //#define digitalReadFast digitalRead 349 | #error Non-AVR device, unsupported. 350 | #endif 351 | #endif 352 | 353 | #endif //__digitalWriteFast_h_ 354 | --------------------------------------------------------------------------------