digitalWriteFast.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  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. #ifndef __digitalWriteFast_h_
  7. #define __digitalWriteFast_h_ 1
  8. // general macros/defines
  9. #ifndef BIT_READ
  10. # define BIT_READ(value, bit) ((value) & (1UL << (bit)))
  11. #endif
  12. #ifndef BIT_SET
  13. # define BIT_SET(value, bit) ((value) |= (1UL << (bit)))
  14. #endif
  15. #ifndef BIT_CLEAR
  16. # define BIT_CLEAR(value, bit) ((value) &= ~(1UL << (bit)))
  17. #endif
  18. #ifndef BIT_WRITE
  19. # define BIT_WRITE(value, bit, bitvalue) (bitvalue ? BIT_SET(value, bit) : BIT_CLEAR(value, bit))
  20. #endif
  21. #ifndef SWAP
  22. #define SWAP(x,y) do{ (x)=(x)^(y); (y)=(x)^(y); (x)=(x)^(y); }while(0)
  23. #endif
  24. #ifndef DEC
  25. # define DEC (10)
  26. #endif
  27. #ifndef HEX
  28. # define HEX (16)
  29. #endif
  30. #ifndef OCT
  31. # define OCT (8)
  32. #endif
  33. #ifndef BIN
  34. # define BIN (2)
  35. #endif
  36. // workarounds for ARM microcontrollers
  37. #if (!defined(__AVR__) || defined(ARDUINO_ARCH_SAM))
  38. #ifndef PROGMEM
  39. # define PROGMEM
  40. #endif
  41. #ifndef PGM_P
  42. # define PGM_P const char *
  43. #endif
  44. #ifndef PSTR
  45. # define PSTR(str) (str)
  46. #endif
  47. #ifndef memcpy_P
  48. # define memcpy_P(dest, src, num) memcpy((dest), (src), (num))
  49. #endif
  50. #ifndef strcpy_P
  51. # define strcpy_P(dst, src) strcpy((dst), (src))
  52. #endif
  53. #ifndef strcat_P
  54. # define strcat_P(dst, src) strcat((dst), (src))
  55. #endif
  56. #ifndef strcmp_P
  57. # define strcmp_P(a, b) strcmp((a), (b))
  58. #endif
  59. #ifndef strcasecmp_P
  60. # define strcasecmp_P(a, b) strcasecmp((a), (b))
  61. #endif
  62. #ifndef strncmp_P
  63. # define strncmp_P(a, b, n) strncmp((a), (b), (n))
  64. #endif
  65. #ifndef strncasecmp_P
  66. # define strncasecmp_P(a, b, n) strncasecmp((a), (b), (n))
  67. #endif
  68. #ifndef strstr_P
  69. # define strstr_P(a, b) strstr((a), (b))
  70. #endif
  71. #ifndef strlen_P
  72. # define strlen_P(a) strlen((a))
  73. #endif
  74. #ifndef sprintf_P
  75. # define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__)
  76. #endif
  77. #ifndef pgm_read_byte
  78. # define pgm_read_byte(addr) (*(const unsigned char *)(addr))
  79. #endif
  80. #ifndef pgm_read_word
  81. # define pgm_read_word(addr) (*(const unsigned short *)(addr))
  82. #endif
  83. #ifndef pgm_read_dword
  84. # define pgm_read_dword(addr) (*(const unsigned long *)(addr))
  85. #endif
  86. #endif
  87. // digital functions
  88. //#ifndef digitalPinToPortReg
  89. #define SPI_SW_SS_PIN (10) //SS on Uno (for software SPI)
  90. #define SPI_SW_MOSI_PIN (11) //MOSI on Uno (for software SPI)
  91. #define SPI_SW_MISO_PIN (12) //MISO on Uno (for software SPI)
  92. #define SPI_SW_SCK_PIN (13) //SCK on Uno (for software SPI)
  93. // --- Arduino Due ---
  94. #if (defined(ARDUINO_SAM_DUE) || defined(__SAM3X8E__))
  95. #define UART_RX_PIN (0)
  96. #define UART_TX_PIN (1)
  97. #define I2C_SDA_PIN (20)
  98. #define I2C_SCL_PIN (21)
  99. #define SPI_HW_SS_PIN (78) //SS0:77, SS1:87, SS2:86, SS3:78
  100. #define SPI_HW_MOSI_PIN (75) //75
  101. #define SPI_HW_MISO_PIN (74) //74
  102. #define SPI_HW_SCK_PIN (76) //76
  103. // --- Arduino Zero ---
  104. #elif (defined(ARDUINO_SAM_ZERO) || defined(__SAMD21G18A__))
  105. #define UART_RX_PIN (0)
  106. #define UART_TX_PIN (1)
  107. #define I2C_SDA_PIN (16)
  108. #define I2C_SCL_PIN (17)
  109. #define SPI_HW_SS_PIN (14) //14
  110. #define SPI_HW_MOSI_PIN (21) //21
  111. #define SPI_HW_MISO_PIN (18) //18
  112. #define SPI_HW_SCK_PIN (20) //20
  113. // --- Arduino Mega ---
  114. #elif (defined(ARDUINO_AVR_MEGA) || \
  115. defined(ARDUINO_AVR_MEGA1280) || \
  116. defined(ARDUINO_AVR_MEGA2560) || \
  117. defined(__AVR_ATmega1280__) || \
  118. defined(__AVR_ATmega1281__) || \
  119. defined(__AVR_ATmega2560__) || \
  120. defined(__AVR_ATmega2561__))
  121. #define UART_RX_PIN (0) //PE0
  122. #define UART_TX_PIN (1) //PE1
  123. #define I2C_SDA_PIN (20)
  124. #define I2C_SCL_PIN (21)
  125. #define SPI_HW_SS_PIN (53) //PB0
  126. #define SPI_HW_MOSI_PIN (51) //PB2
  127. #define SPI_HW_MISO_PIN (50) //PB3
  128. #define SPI_HW_SCK_PIN (52) //PB1
  129. #define __digitalPinToPortReg(P) \
  130. (((P) >= 22 && (P) <= 29) ? &PORTA : \
  131. ((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PORTB : \
  132. (((P) >= 30 && (P) <= 37) ? &PORTC : \
  133. ((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PORTD : \
  134. ((((P) >= 0 && (P) <= 3) || (P) == 5) ? &PORTE : \
  135. (((P) >= 54 && (P) <= 61) ? &PORTF : \
  136. ((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PORTG : \
  137. ((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PORTH : \
  138. (((P) == 14 || (P) == 15) ? &PORTJ : \
  139. (((P) >= 62 && (P) <= 69) ? &PORTK : &PORTL))))))))))
  140. #define __digitalPinToDDRReg(P) \
  141. (((P) >= 22 && (P) <= 29) ? &DDRA : \
  142. ((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &DDRB : \
  143. (((P) >= 30 && (P) <= 37) ? &DDRC : \
  144. ((((P) >= 18 && (P) <= 21) || (P) == 38) ? &DDRD : \
  145. ((((P) >= 0 && (P) <= 3) || (P) == 5) ? &DDRE : \
  146. (((P) >= 54 && (P) <= 61) ? &DDRF : \
  147. ((((P) >= 39 && (P) <= 41) || (P) == 4) ? &DDRG : \
  148. ((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &DDRH : \
  149. (((P) == 14 || (P) == 15) ? &DDRJ : \
  150. (((P) >= 62 && (P) <= 69) ? &DDRK : &DDRL))))))))))
  151. #define __digitalPinToPINReg(P) \
  152. (((P) >= 22 && (P) <= 29) ? &PINA : \
  153. ((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PINB : \
  154. (((P) >= 30 && (P) <= 37) ? &PINC : \
  155. ((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PIND : \
  156. ((((P) >= 0 && (P) <= 3) || (P) == 5) ? &PINE : \
  157. (((P) >= 54 && (P) <= 61) ? &PINF : \
  158. ((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PING : \
  159. ((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PINH : \
  160. (((P) == 14 || (P) == 15) ? &PINJ : \
  161. (((P) >= 62 && (P) <= 69) ? &PINK : &PINL))))))))))
  162. #define __digitalPinToBit(P) \
  163. (((P) >= 7 && (P) <= 9) ? (P) - 3 : \
  164. (((P) >= 10 && (P) <= 13) ? (P) - 6 : \
  165. (((P) >= 22 && (P) <= 29) ? (P) - 22 : \
  166. (((P) >= 30 && (P) <= 37) ? 37 - (P) : \
  167. (((P) >= 39 && (P) <= 41) ? 41 - (P) : \
  168. (((P) >= 42 && (P) <= 49) ? 49 - (P) : \
  169. (((P) >= 50 && (P) <= 53) ? 53 - (P) : \
  170. (((P) >= 54 && (P) <= 61) ? (P) - 54 : \
  171. (((P) >= 62 && (P) <= 69) ? (P) - 62 : \
  172. (((P) == 0 || (P) == 15 || (P) == 17 || (P) == 21) ? 0 : \
  173. (((P) == 1 || (P) == 14 || (P) == 16 || (P) == 20) ? 1 : \
  174. (((P) == 19) ? 2 : \
  175. (((P) == 5 || (P) == 6 || (P) == 18) ? 3 : \
  176. (((P) == 2) ? 4 : \
  177. (((P) == 3 || (P) == 4) ? 5 : 7)))))))))))))))
  178. // --- Arduino 644 ---
  179. #elif (defined(__AVR_ATmega644__) || \
  180. defined(__AVR_ATmega644P__))
  181. #define UART_RX_PIN (8) //PD0
  182. #define UART_TX_PIN (9) //PD1
  183. #define I2C_SDA_PIN (17) //PC1
  184. #define I2C_SCL_PIN (16) //PC0
  185. #define SPI_HW_SS_PIN (4) //PB4
  186. #define SPI_HW_MOSI_PIN (5) //PB5
  187. #define SPI_HW_MISO_PIN (6) //PB6
  188. #define SPI_HW_SCK_PIN (7) //PB7
  189. #define __digitalPinToPortReg(P) \
  190. (((P) >= 0 && (P) <= 7) ? &PORTB : (((P) >= 8 && (P) <= 15) ? &PORTD : (((P) >= 16 && (P) <= 23) ? &PORTC : &PORTA)))
  191. #define __digitalPinToDDRReg(P) \
  192. (((P) >= 0 && (P) <= 7) ? &DDRB : (((P) >= 8 && (P) <= 15) ? &DDRD : (((P) >= 8 && (P) <= 15) ? &DDRC : &DDRA)))
  193. #define __digitalPinToPINReg(P) \
  194. (((P) >= 0 && (P) <= 7) ? &PINB : (((P) >= 8 && (P) <= 15) ? &PIND : (((P) >= 8 && (P) <= 15) ? &PINC : &PINA)))
  195. #define __digitalPinToBit(P) \
  196. (((P) >= 0 && (P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (P) - 24)))
  197. // --- Arduino Leonardo ---
  198. #elif (defined(ARDUINO_AVR_LEONARDO) || \
  199. defined(__AVR_ATmega16U4__) || \
  200. defined(__AVR_ATmega32U4__))
  201. #define UART_RX_PIN (0) //PD2
  202. #define UART_TX_PIN (1) //PD3
  203. #define I2C_SDA_PIN (2) //PD1
  204. #define I2C_SCL_PIN (3) //PD0
  205. #define SPI_HW_SS_PIN (17) //PB0
  206. #define SPI_HW_MOSI_PIN (16) //PB2
  207. #define SPI_HW_MISO_PIN (14) //PB3
  208. #define SPI_HW_SCK_PIN (15) //PB1
  209. #define __digitalPinToPortReg(P) \
  210. ((((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)))
  211. #define __digitalPinToDDRReg(P) \
  212. ((((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)))
  213. #define __digitalPinToPINReg(P) \
  214. ((((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)))
  215. #define __digitalPinToBit(P) \
  216. (((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 )))))))))))))))))))
  217. // --- Arduino Uno ---
  218. #elif (defined(ARDUINO_AVR_UNO) || \
  219. defined(ARDUINO_AVR_DUEMILANOVE) || \
  220. defined(__AVR_ATmega328__) || \
  221. defined(__AVR_ATmega328P__) || \
  222. defined(__AVR_ATmega328PB__))
  223. #define UART_RX_PIN (0) //PD0
  224. #define UART_TX_PIN (1) //PD1
  225. #define I2C_SDA_PIN (18) //A4
  226. #define I2C_SCL_PIN (19) //A5
  227. #define SPI_HW_SS_PIN (10) //PB0
  228. #define SPI_HW_MOSI_PIN (11) //PB2
  229. #define SPI_HW_MISO_PIN (12) //PB3
  230. #define SPI_HW_SCK_PIN (13) //PB1
  231. #if defined(__AVR_ATmega328PB__)
  232. #define __digitalPinToPortReg(P) \
  233. (((P) >= 0 && (P) <= 7) ? &PORTD : (((P) >= 8 && (P) <= 13) ? &PORTB : (((P) >= 14 && (P) <= 19) ? &PORTC : &PORTE)))
  234. #define __digitalPinToDDRReg(P) \
  235. (((P) >= 0 && (P) <= 7) ? &DDRD : (((P) >= 8 && (P) <= 13) ? &DDRB : (((P) >= 14 && (P) <= 19) ? &DDRC : &DDRE)))
  236. #define __digitalPinToPINReg(P) \
  237. (((P) >= 0 && (P) <= 7) ? &PIND : (((P) >= 8 && (P) <= 13) ? &PINB : (((P) >= 14 && (P) <= 19) ? &PINC : &PINE)))
  238. #define __digitalPinToBit(P) \
  239. (((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))))
  240. #else
  241. #define __digitalPinToPortReg(P) \
  242. (((P) >= 0 && (P) <= 7) ? &PORTD : (((P) >= 8 && (P) <= 13) ? &PORTB : &PORTC))
  243. #define __digitalPinToDDRReg(P) \
  244. (((P) >= 0 && (P) <= 7) ? &DDRD : (((P) >= 8 && (P) <= 13) ? &DDRB : &DDRC))
  245. #define __digitalPinToPINReg(P) \
  246. (((P) >= 0 && (P) <= 7) ? &PIND : (((P) >= 8 && (P) <= 13) ? &PINB : &PINC))
  247. #define __digitalPinToBit(P) \
  248. (((P) >= 0 && (P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P) - 8 : (P) - 14))
  249. #endif
  250. // --- Other ---
  251. #else
  252. #define I2C_SDA_PIN SDA
  253. #define I2C_SCL_PIN SCL
  254. #define SPI_HW_SS_PIN SS
  255. #define SPI_HW_MOSI_PIN MOSI
  256. #define SPI_HW_MISO_PIN MISO
  257. #define SPI_HW_SCK_PIN SCK
  258. #endif
  259. //#endif //#ifndef digitalPinToPortReg
  260. #ifndef digitalWriteFast
  261. #if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
  262. #define digitalWriteFast(P, V) \
  263. if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \
  264. BIT_WRITE(*__digitalPinToPortReg(P), __digitalPinToBit(P), (V)); \
  265. } else { \
  266. digitalWrite((P), (V)); \
  267. }
  268. #else
  269. #define digitalWriteFast digitalWrite
  270. #endif
  271. #endif
  272. #ifndef pinModeFast
  273. #if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
  274. #define pinModeFast(P, V) \
  275. if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \
  276. BIT_WRITE(*__digitalPinToDDRReg(P), __digitalPinToBit(P), (V)); \
  277. } else { \
  278. pinMode((P), (V)); \
  279. }
  280. #else
  281. #define pinModeFast pinMode
  282. #endif
  283. #endif
  284. #ifndef digitalReadFast
  285. #if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
  286. #define digitalReadFast(P) ( (int) __digitalReadFast((P)) )
  287. #define __digitalReadFast(P ) \
  288. (__builtin_constant_p(P) ) ? ( \
  289. ( BIT_READ(*__digitalPinToPINReg(P), __digitalPinToBit(P))) ) : \
  290. digitalRead((P))
  291. #else
  292. #define digitalReadFast digitalRead
  293. #endif
  294. #endif
  295. #endif //__digitalWriteFast_h_