Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

697 lines
26KB

  1. /* Arduino DigitalIO Library
  2. * Copyright (C) 2013 by William Greiman
  3. *
  4. * This file is part of the Arduino DigitalIO Library
  5. *
  6. * This Library is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This Library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with the Arduino DigitalIO Library. If not, see
  18. * <http://www.gnu.org/licenses/>.
  19. */
  20. /**
  21. * @file
  22. * @brief Fast Digital Pin functions
  23. *
  24. * @defgroup digitalPin Fast Pin I/O
  25. * @details Fast Digital I/O functions and template class.
  26. * @{
  27. */
  28. #ifndef DigitalPin_h
  29. #define DigitalPin_h
  30. #include <Arduino.h>
  31. #ifdef __arm__
  32. #ifdef CORE_TEENSY
  33. //------------------------------------------------------------------------------
  34. /** read pin value
  35. * @param[in] pin Arduino pin number
  36. * @return value read
  37. */
  38. static inline __attribute__((always_inline))
  39. bool fastDigitalRead(uint8_t pin) {
  40. return *portInputRegister(pin);
  41. }
  42. //------------------------------------------------------------------------------
  43. /** Set pin value
  44. * @param[in] pin Arduino pin number
  45. * @param[in] level value to write
  46. */
  47. static inline __attribute__((always_inline))
  48. void fastDigitalWrite(uint8_t pin, bool value) {
  49. if (value) {
  50. *portSetRegister(pin) = 1;
  51. } else {
  52. *portClearRegister(pin) = 1;
  53. }
  54. }
  55. #else // CORE_TEENSY
  56. //------------------------------------------------------------------------------
  57. /** read pin value
  58. * @param[in] pin Arduino pin number
  59. * @return value read
  60. */
  61. static inline __attribute__((always_inline))
  62. bool fastDigitalRead(uint8_t pin) {
  63. return g_APinDescription[pin].pPort->PIO_PDSR & g_APinDescription[pin].ulPin;
  64. }
  65. //------------------------------------------------------------------------------
  66. /** Set pin value
  67. * @param[in] pin Arduino pin number
  68. * @param[in] level value to write
  69. */
  70. static inline __attribute__((always_inline))
  71. void fastDigitalWrite(uint8_t pin, bool value) {
  72. if (value) {
  73. g_APinDescription[pin].pPort->PIO_SODR = g_APinDescription[pin].ulPin;
  74. } else {
  75. g_APinDescription[pin].pPort->PIO_CODR = g_APinDescription[pin].ulPin;
  76. }
  77. }
  78. #endif // CORE_TEENSY
  79. //------------------------------------------------------------------------------
  80. inline void fastDigitalToggle(uint8_t pin) {
  81. fastDigitalWrite(pin, !fastDigitalRead(pin));
  82. }
  83. //------------------------------------------------------------------------------
  84. inline void fastPinMode(uint8_t pin, bool mode) {
  85. pinMode(pin, mode);
  86. }
  87. #else // __arm__
  88. #include <avr/io.h>
  89. #include <util/atomic.h>
  90. //------------------------------------------------------------------------------
  91. /**
  92. * @class pin_map_t
  93. * @brief struct for mapping digital pins
  94. */
  95. struct pin_map_t {
  96. volatile uint8_t* ddr; /**< address of DDR for this pin */
  97. volatile uint8_t* pin; /**< address of PIN for this pin */
  98. volatile uint8_t* port; /**< address of PORT for this pin */
  99. uint8_t bit; /**< bit number for this pin */
  100. };
  101. //------------------------------------------------------------------------------
  102. #if defined(__AVR_ATmega168__)\
  103. ||defined(__AVR_ATmega168P__)\
  104. ||defined(__AVR_ATmega328P__)
  105. // 168 and 328 Arduinos
  106. static const pin_map_t pinMap[] = {
  107. {&DDRD, &PIND, &PORTD, 0}, // D0 0
  108. {&DDRD, &PIND, &PORTD, 1}, // D1 1
  109. {&DDRD, &PIND, &PORTD, 2}, // D2 2
  110. {&DDRD, &PIND, &PORTD, 3}, // D3 3
  111. {&DDRD, &PIND, &PORTD, 4}, // D4 4
  112. {&DDRD, &PIND, &PORTD, 5}, // D5 5
  113. {&DDRD, &PIND, &PORTD, 6}, // D6 6
  114. {&DDRD, &PIND, &PORTD, 7}, // D7 7
  115. {&DDRB, &PINB, &PORTB, 0}, // B0 8
  116. {&DDRB, &PINB, &PORTB, 1}, // B1 9
  117. {&DDRB, &PINB, &PORTB, 2}, // B2 10
  118. {&DDRB, &PINB, &PORTB, 3}, // B3 11
  119. {&DDRB, &PINB, &PORTB, 4}, // B4 12
  120. {&DDRB, &PINB, &PORTB, 5}, // B5 13
  121. {&DDRC, &PINC, &PORTC, 0}, // C0 14
  122. {&DDRC, &PINC, &PORTC, 1}, // C1 15
  123. {&DDRC, &PINC, &PORTC, 2}, // C2 16
  124. {&DDRC, &PINC, &PORTC, 3}, // C3 17
  125. {&DDRC, &PINC, &PORTC, 4}, // C4 18
  126. {&DDRC, &PINC, &PORTC, 5} // C5 19
  127. };
  128. //------------------------------------------------------------------------------
  129. #elif defined(__AVR_ATmega1280__)\
  130. || defined(__AVR_ATmega2560__)
  131. // Mega
  132. static const pin_map_t pinMap[] = {
  133. {&DDRE, &PINE, &PORTE, 0}, // E0 0
  134. {&DDRE, &PINE, &PORTE, 1}, // E1 1
  135. {&DDRE, &PINE, &PORTE, 4}, // E4 2
  136. {&DDRE, &PINE, &PORTE, 5}, // E5 3
  137. {&DDRG, &PING, &PORTG, 5}, // G5 4
  138. {&DDRE, &PINE, &PORTE, 3}, // E3 5
  139. {&DDRH, &PINH, &PORTH, 3}, // H3 6
  140. {&DDRH, &PINH, &PORTH, 4}, // H4 7
  141. {&DDRH, &PINH, &PORTH, 5}, // H5 8
  142. {&DDRH, &PINH, &PORTH, 6}, // H6 9
  143. {&DDRB, &PINB, &PORTB, 4}, // B4 10
  144. {&DDRB, &PINB, &PORTB, 5}, // B5 11
  145. {&DDRB, &PINB, &PORTB, 6}, // B6 12
  146. {&DDRB, &PINB, &PORTB, 7}, // B7 13
  147. {&DDRJ, &PINJ, &PORTJ, 1}, // J1 14
  148. {&DDRJ, &PINJ, &PORTJ, 0}, // J0 15
  149. {&DDRH, &PINH, &PORTH, 1}, // H1 16
  150. {&DDRH, &PINH, &PORTH, 0}, // H0 17
  151. {&DDRD, &PIND, &PORTD, 3}, // D3 18
  152. {&DDRD, &PIND, &PORTD, 2}, // D2 19
  153. {&DDRD, &PIND, &PORTD, 1}, // D1 20
  154. {&DDRD, &PIND, &PORTD, 0}, // D0 21
  155. {&DDRA, &PINA, &PORTA, 0}, // A0 22
  156. {&DDRA, &PINA, &PORTA, 1}, // A1 23
  157. {&DDRA, &PINA, &PORTA, 2}, // A2 24
  158. {&DDRA, &PINA, &PORTA, 3}, // A3 25
  159. {&DDRA, &PINA, &PORTA, 4}, // A4 26
  160. {&DDRA, &PINA, &PORTA, 5}, // A5 27
  161. {&DDRA, &PINA, &PORTA, 6}, // A6 28
  162. {&DDRA, &PINA, &PORTA, 7}, // A7 29
  163. {&DDRC, &PINC, &PORTC, 7}, // C7 30
  164. {&DDRC, &PINC, &PORTC, 6}, // C6 31
  165. {&DDRC, &PINC, &PORTC, 5}, // C5 32
  166. {&DDRC, &PINC, &PORTC, 4}, // C4 33
  167. {&DDRC, &PINC, &PORTC, 3}, // C3 34
  168. {&DDRC, &PINC, &PORTC, 2}, // C2 35
  169. {&DDRC, &PINC, &PORTC, 1}, // C1 36
  170. {&DDRC, &PINC, &PORTC, 0}, // C0 37
  171. {&DDRD, &PIND, &PORTD, 7}, // D7 38
  172. {&DDRG, &PING, &PORTG, 2}, // G2 39
  173. {&DDRG, &PING, &PORTG, 1}, // G1 40
  174. {&DDRG, &PING, &PORTG, 0}, // G0 41
  175. {&DDRL, &PINL, &PORTL, 7}, // L7 42
  176. {&DDRL, &PINL, &PORTL, 6}, // L6 43
  177. {&DDRL, &PINL, &PORTL, 5}, // L5 44
  178. {&DDRL, &PINL, &PORTL, 4}, // L4 45
  179. {&DDRL, &PINL, &PORTL, 3}, // L3 46
  180. {&DDRL, &PINL, &PORTL, 2}, // L2 47
  181. {&DDRL, &PINL, &PORTL, 1}, // L1 48
  182. {&DDRL, &PINL, &PORTL, 0}, // L0 49
  183. {&DDRB, &PINB, &PORTB, 3}, // B3 50
  184. {&DDRB, &PINB, &PORTB, 2}, // B2 51
  185. {&DDRB, &PINB, &PORTB, 1}, // B1 52
  186. {&DDRB, &PINB, &PORTB, 0}, // B0 53
  187. {&DDRF, &PINF, &PORTF, 0}, // F0 54
  188. {&DDRF, &PINF, &PORTF, 1}, // F1 55
  189. {&DDRF, &PINF, &PORTF, 2}, // F2 56
  190. {&DDRF, &PINF, &PORTF, 3}, // F3 57
  191. {&DDRF, &PINF, &PORTF, 4}, // F4 58
  192. {&DDRF, &PINF, &PORTF, 5}, // F5 59
  193. {&DDRF, &PINF, &PORTF, 6}, // F6 60
  194. {&DDRF, &PINF, &PORTF, 7}, // F7 61
  195. {&DDRK, &PINK, &PORTK, 0}, // K0 62
  196. {&DDRK, &PINK, &PORTK, 1}, // K1 63
  197. {&DDRK, &PINK, &PORTK, 2}, // K2 64
  198. {&DDRK, &PINK, &PORTK, 3}, // K3 65
  199. {&DDRK, &PINK, &PORTK, 4}, // K4 66
  200. {&DDRK, &PINK, &PORTK, 5}, // K5 67
  201. {&DDRK, &PINK, &PORTK, 6}, // K6 68
  202. {&DDRK, &PINK, &PORTK, 7} // K7 69
  203. };
  204. //------------------------------------------------------------------------------
  205. #elif defined(__AVR_ATmega1284P__)\
  206. || defined(__AVR_ATmega1284__)\
  207. || defined(__AVR_ATmega644P__)\
  208. || defined(__AVR_ATmega644__)\
  209. || defined(__AVR_ATmega64__)\
  210. || defined(__AVR_ATmega32__)\
  211. || defined(__AVR_ATmega324__)\
  212. || defined(__AVR_ATmega16__)
  213. #ifdef PORT_D0
  214. // Newer version of 1284P
  215. static const pin_map_t pinMap[] = {
  216. {PORT_TO_MODE(PORT_D0), PORT_TO_INPUT(PORT_D0), PORT_TO_OUTPUT(PORT_D0), BIT_D0},
  217. {PORT_TO_MODE(PORT_D1), PORT_TO_INPUT(PORT_D1), PORT_TO_OUTPUT(PORT_D1), BIT_D1},
  218. {PORT_TO_MODE(PORT_D2), PORT_TO_INPUT(PORT_D2), PORT_TO_OUTPUT(PORT_D2), BIT_D2},
  219. {PORT_TO_MODE(PORT_D3), PORT_TO_INPUT(PORT_D3), PORT_TO_OUTPUT(PORT_D3), BIT_D3},
  220. {PORT_TO_MODE(PORT_D4), PORT_TO_INPUT(PORT_D4), PORT_TO_OUTPUT(PORT_D4), BIT_D4},
  221. {PORT_TO_MODE(PORT_D5), PORT_TO_INPUT(PORT_D5), PORT_TO_OUTPUT(PORT_D5), BIT_D5},
  222. {PORT_TO_MODE(PORT_D6), PORT_TO_INPUT(PORT_D6), PORT_TO_OUTPUT(PORT_D6), BIT_D6},
  223. {PORT_TO_MODE(PORT_D7), PORT_TO_INPUT(PORT_D7), PORT_TO_OUTPUT(PORT_D7), BIT_D7},
  224. {PORT_TO_MODE(PORT_D8), PORT_TO_INPUT(PORT_D8), PORT_TO_OUTPUT(PORT_D8), BIT_D8},
  225. {PORT_TO_MODE(PORT_D9), PORT_TO_INPUT(PORT_D9), PORT_TO_OUTPUT(PORT_D9), BIT_D9},
  226. {PORT_TO_MODE(PORT_D10), PORT_TO_INPUT(PORT_D10), PORT_TO_OUTPUT(PORT_D10), BIT_D10},
  227. {PORT_TO_MODE(PORT_D11), PORT_TO_INPUT(PORT_D11), PORT_TO_OUTPUT(PORT_D11), BIT_D11},
  228. {PORT_TO_MODE(PORT_D12), PORT_TO_INPUT(PORT_D12), PORT_TO_OUTPUT(PORT_D12), BIT_D12},
  229. {PORT_TO_MODE(PORT_D13), PORT_TO_INPUT(PORT_D13), PORT_TO_OUTPUT(PORT_D13), BIT_D13},
  230. {PORT_TO_MODE(PORT_D14), PORT_TO_INPUT(PORT_D14), PORT_TO_OUTPUT(PORT_D14), BIT_D14},
  231. {PORT_TO_MODE(PORT_D15), PORT_TO_INPUT(PORT_D15), PORT_TO_OUTPUT(PORT_D15), BIT_D15},
  232. {PORT_TO_MODE(PORT_D16), PORT_TO_INPUT(PORT_D16), PORT_TO_OUTPUT(PORT_D16), BIT_D16},
  233. {PORT_TO_MODE(PORT_D17), PORT_TO_INPUT(PORT_D17), PORT_TO_OUTPUT(PORT_D17), BIT_D17},
  234. {PORT_TO_MODE(PORT_D18), PORT_TO_INPUT(PORT_D18), PORT_TO_OUTPUT(PORT_D18), BIT_D18},
  235. {PORT_TO_MODE(PORT_D19), PORT_TO_INPUT(PORT_D19), PORT_TO_OUTPUT(PORT_D19), BIT_D19},
  236. {PORT_TO_MODE(PORT_D20), PORT_TO_INPUT(PORT_D20), PORT_TO_OUTPUT(PORT_D20), BIT_D20},
  237. {PORT_TO_MODE(PORT_D21), PORT_TO_INPUT(PORT_D21), PORT_TO_OUTPUT(PORT_D21), BIT_D21},
  238. {PORT_TO_MODE(PORT_D22), PORT_TO_INPUT(PORT_D22), PORT_TO_OUTPUT(PORT_D22), BIT_D22},
  239. {PORT_TO_MODE(PORT_D23), PORT_TO_INPUT(PORT_D23), PORT_TO_OUTPUT(PORT_D23), BIT_D23},
  240. {PORT_TO_MODE(PORT_D24), PORT_TO_INPUT(PORT_D24), PORT_TO_OUTPUT(PORT_D24), BIT_D24},
  241. {PORT_TO_MODE(PORT_D25), PORT_TO_INPUT(PORT_D25), PORT_TO_OUTPUT(PORT_D25), BIT_D25},
  242. {PORT_TO_MODE(PORT_D26), PORT_TO_INPUT(PORT_D26), PORT_TO_OUTPUT(PORT_D26), BIT_D26},
  243. {PORT_TO_MODE(PORT_D27), PORT_TO_INPUT(PORT_D27), PORT_TO_OUTPUT(PORT_D27), BIT_D27},
  244. {PORT_TO_MODE(PORT_D28), PORT_TO_INPUT(PORT_D28), PORT_TO_OUTPUT(PORT_D28), BIT_D28},
  245. {PORT_TO_MODE(PORT_D29), PORT_TO_INPUT(PORT_D29), PORT_TO_OUTPUT(PORT_D29), BIT_D29},
  246. {PORT_TO_MODE(PORT_D30), PORT_TO_INPUT(PORT_D30), PORT_TO_OUTPUT(PORT_D30), BIT_D30},
  247. {PORT_TO_MODE(PORT_D31), PORT_TO_INPUT(PORT_D31), PORT_TO_OUTPUT(PORT_D31), BIT_D31}
  248. };
  249. #elif analogInputToDigitalPin(0)==24
  250. // Mighty Layout
  251. static const pin_map_t pinMap[] = {
  252. {&DDRB, &PINB, &PORTB, 0}, // B0 0
  253. {&DDRB, &PINB, &PORTB, 1}, // B1 1
  254. {&DDRB, &PINB, &PORTB, 2}, // B2 2
  255. {&DDRB, &PINB, &PORTB, 3}, // B3 3
  256. {&DDRB, &PINB, &PORTB, 4}, // B4 4
  257. {&DDRB, &PINB, &PORTB, 5}, // B5 5
  258. {&DDRB, &PINB, &PORTB, 6}, // B6 6
  259. {&DDRB, &PINB, &PORTB, 7}, // B7 7
  260. {&DDRD, &PIND, &PORTD, 0}, // D0 8
  261. {&DDRD, &PIND, &PORTD, 1}, // D1 9
  262. {&DDRD, &PIND, &PORTD, 2}, // D2 10
  263. {&DDRD, &PIND, &PORTD, 3}, // D3 11
  264. {&DDRD, &PIND, &PORTD, 4}, // D4 12
  265. {&DDRD, &PIND, &PORTD, 5}, // D5 13
  266. {&DDRD, &PIND, &PORTD, 6}, // D6 14
  267. {&DDRD, &PIND, &PORTD, 7}, // D7 15
  268. {&DDRC, &PINC, &PORTC, 0}, // C0 16
  269. {&DDRC, &PINC, &PORTC, 1}, // C1 17
  270. {&DDRC, &PINC, &PORTC, 2}, // C2 18
  271. {&DDRC, &PINC, &PORTC, 3}, // C3 19
  272. {&DDRC, &PINC, &PORTC, 4}, // C4 20
  273. {&DDRC, &PINC, &PORTC, 5}, // C5 21
  274. {&DDRC, &PINC, &PORTC, 6}, // C6 22
  275. {&DDRC, &PINC, &PORTC, 7}, // C7 23
  276. {&DDRA, &PINA, &PORTA, 0}, // A0 24
  277. {&DDRA, &PINA, &PORTA, 1}, // A1 25
  278. {&DDRA, &PINA, &PORTA, 2}, // A2 26
  279. {&DDRA, &PINA, &PORTA, 3}, // A3 27
  280. {&DDRA, &PINA, &PORTA, 4}, // A4 28
  281. {&DDRA, &PINA, &PORTA, 5}, // A5 29
  282. {&DDRA, &PINA, &PORTA, 6}, // A6 30
  283. {&DDRA, &PINA, &PORTA, 7} // A7 31
  284. };
  285. #elif analogInputToDigitalPin(0)==21
  286. // Bobuino Layout
  287. static const pin_map_t pinMap[] = {
  288. {&DDRD, &PIND, &PORTD, 0}, // D0 0
  289. {&DDRD, &PIND, &PORTD, 1}, // D1 1
  290. {&DDRD, &PIND, &PORTD, 2}, // D2 2
  291. {&DDRD, &PIND, &PORTD, 3}, // D3 3
  292. {&DDRB, &PINB, &PORTB, 0}, // B0 4
  293. {&DDRB, &PINB, &PORTB, 1}, // B1 5
  294. {&DDRB, &PINB, &PORTB, 2}, // B2 6
  295. {&DDRB, &PINB, &PORTB, 3}, // B3 7
  296. {&DDRD, &PIND, &PORTD, 5}, // D5 8
  297. {&DDRD, &PIND, &PORTD, 6}, // D6 9
  298. {&DDRB, &PINB, &PORTB, 4}, // B4 10
  299. {&DDRB, &PINB, &PORTB, 5}, // B5 11
  300. {&DDRB, &PINB, &PORTB, 6}, // B6 12
  301. {&DDRB, &PINB, &PORTB, 7}, // B7 13
  302. {&DDRA, &PINA, &PORTA, 7}, // A7 14
  303. {&DDRA, &PINA, &PORTA, 6}, // A6 15
  304. {&DDRA, &PINA, &PORTA, 5}, // A5 16
  305. {&DDRA, &PINA, &PORTA, 4}, // A4 17
  306. {&DDRA, &PINA, &PORTA, 3}, // A3 18
  307. {&DDRA, &PINA, &PORTA, 2}, // A2 19
  308. {&DDRA, &PINA, &PORTA, 1}, // A1 20
  309. {&DDRA, &PINA, &PORTA, 0}, // A0 21
  310. {&DDRC, &PINC, &PORTC, 0}, // C0 22
  311. {&DDRC, &PINC, &PORTC, 1}, // C1 23
  312. {&DDRC, &PINC, &PORTC, 2}, // C2 24
  313. {&DDRC, &PINC, &PORTC, 3}, // C3 25
  314. {&DDRC, &PINC, &PORTC, 4}, // C4 26
  315. {&DDRC, &PINC, &PORTC, 5}, // C5 27
  316. {&DDRC, &PINC, &PORTC, 6}, // C6 28
  317. {&DDRC, &PINC, &PORTC, 7}, // C7 29
  318. {&DDRD, &PIND, &PORTD, 4}, // D4 30
  319. {&DDRD, &PIND, &PORTD, 7} // D7 31
  320. };
  321. #elif analogInputToDigitalPin(0)==31
  322. // Standard Layout
  323. static const pin_map_t pinMap[] = {
  324. {&DDRB, &PINB, &PORTB, 0}, // B0 0
  325. {&DDRB, &PINB, &PORTB, 1}, // B1 1
  326. {&DDRB, &PINB, &PORTB, 2}, // B2 2
  327. {&DDRB, &PINB, &PORTB, 3}, // B3 3
  328. {&DDRB, &PINB, &PORTB, 4}, // B4 4
  329. {&DDRB, &PINB, &PORTB, 5}, // B5 5
  330. {&DDRB, &PINB, &PORTB, 6}, // B6 6
  331. {&DDRB, &PINB, &PORTB, 7}, // B7 7
  332. {&DDRD, &PIND, &PORTD, 0}, // D0 8
  333. {&DDRD, &PIND, &PORTD, 1}, // D1 9
  334. {&DDRD, &PIND, &PORTD, 2}, // D2 10
  335. {&DDRD, &PIND, &PORTD, 3}, // D3 11
  336. {&DDRD, &PIND, &PORTD, 4}, // D4 12
  337. {&DDRD, &PIND, &PORTD, 5}, // D5 13
  338. {&DDRD, &PIND, &PORTD, 6}, // D6 14
  339. {&DDRD, &PIND, &PORTD, 7}, // D7 15
  340. {&DDRC, &PINC, &PORTC, 0}, // C0 16
  341. {&DDRC, &PINC, &PORTC, 1}, // C1 17
  342. {&DDRC, &PINC, &PORTC, 2}, // C2 18
  343. {&DDRC, &PINC, &PORTC, 3}, // C3 19
  344. {&DDRC, &PINC, &PORTC, 4}, // C4 20
  345. {&DDRC, &PINC, &PORTC, 5}, // C5 21
  346. {&DDRC, &PINC, &PORTC, 6}, // C6 22
  347. {&DDRC, &PINC, &PORTC, 7}, // C7 23
  348. {&DDRA, &PINA, &PORTA, 7}, // A7 24
  349. {&DDRA, &PINA, &PORTA, 6}, // A6 25
  350. {&DDRA, &PINA, &PORTA, 5}, // A5 26
  351. {&DDRA, &PINA, &PORTA, 4}, // A4 27
  352. {&DDRA, &PINA, &PORTA, 3}, // A3 28
  353. {&DDRA, &PINA, &PORTA, 2}, // A2 29
  354. {&DDRA, &PINA, &PORTA, 1}, // A1 30
  355. {&DDRA, &PINA, &PORTA, 0} // A0 31
  356. };
  357. #else // VARIANT_MIGHTY
  358. #error Undefined variant 1284, 644, 324, 64, 32
  359. #endif // VARIANT_MIGHTY
  360. //------------------------------------------------------------------------------
  361. #elif defined(__AVR_ATmega32U4__)
  362. #ifdef CORE_TEENSY
  363. // Teensy 2.0
  364. static const pin_map_t pinMap[] = {
  365. {&DDRB, &PINB, &PORTB, 0}, // B0 0
  366. {&DDRB, &PINB, &PORTB, 1}, // B1 1
  367. {&DDRB, &PINB, &PORTB, 2}, // B2 2
  368. {&DDRB, &PINB, &PORTB, 3}, // B3 3
  369. {&DDRB, &PINB, &PORTB, 7}, // B7 4
  370. {&DDRD, &PIND, &PORTD, 0}, // D0 5
  371. {&DDRD, &PIND, &PORTD, 1}, // D1 6
  372. {&DDRD, &PIND, &PORTD, 2}, // D2 7
  373. {&DDRD, &PIND, &PORTD, 3}, // D3 8
  374. {&DDRC, &PINC, &PORTC, 6}, // C6 9
  375. {&DDRC, &PINC, &PORTC, 7}, // C7 10
  376. {&DDRD, &PIND, &PORTD, 6}, // D6 11
  377. {&DDRD, &PIND, &PORTD, 7}, // D7 12
  378. {&DDRB, &PINB, &PORTB, 4}, // B4 13
  379. {&DDRB, &PINB, &PORTB, 5}, // B5 14
  380. {&DDRB, &PINB, &PORTB, 6}, // B6 15
  381. {&DDRF, &PINF, &PORTF, 7}, // F7 16
  382. {&DDRF, &PINF, &PORTF, 6}, // F6 17
  383. {&DDRF, &PINF, &PORTF, 5}, // F5 18
  384. {&DDRF, &PINF, &PORTF, 4}, // F4 19
  385. {&DDRF, &PINF, &PORTF, 1}, // F1 20
  386. {&DDRF, &PINF, &PORTF, 0}, // F0 21
  387. {&DDRD, &PIND, &PORTD, 4}, // D4 22
  388. {&DDRD, &PIND, &PORTD, 5}, // D5 23
  389. {&DDRE, &PINE, &PORTE, 6} // E6 24
  390. };
  391. //------------------------------------------------------------------------------
  392. #else // CORE_TEENSY
  393. // Leonardo
  394. static const pin_map_t pinMap[] = {
  395. {&DDRD, &PIND, &PORTD, 2}, // D2 0
  396. {&DDRD, &PIND, &PORTD, 3}, // D3 1
  397. {&DDRD, &PIND, &PORTD, 1}, // D1 2
  398. {&DDRD, &PIND, &PORTD, 0}, // D0 3
  399. {&DDRD, &PIND, &PORTD, 4}, // D4 4
  400. {&DDRC, &PINC, &PORTC, 6}, // C6 5
  401. {&DDRD, &PIND, &PORTD, 7}, // D7 6
  402. {&DDRE, &PINE, &PORTE, 6}, // E6 7
  403. {&DDRB, &PINB, &PORTB, 4}, // B4 8
  404. {&DDRB, &PINB, &PORTB, 5}, // B5 9
  405. {&DDRB, &PINB, &PORTB, 6}, // B6 10
  406. {&DDRB, &PINB, &PORTB, 7}, // B7 11
  407. {&DDRD, &PIND, &PORTD, 6}, // D6 12
  408. {&DDRC, &PINC, &PORTC, 7}, // C7 13
  409. {&DDRB, &PINB, &PORTB, 3}, // B3 14
  410. {&DDRB, &PINB, &PORTB, 1}, // B1 15
  411. {&DDRB, &PINB, &PORTB, 2}, // B2 16
  412. {&DDRB, &PINB, &PORTB, 0}, // B0 17
  413. {&DDRF, &PINF, &PORTF, 7}, // F7 18
  414. {&DDRF, &PINF, &PORTF, 6}, // F6 19
  415. {&DDRF, &PINF, &PORTF, 5}, // F5 20
  416. {&DDRF, &PINF, &PORTF, 4}, // F4 21
  417. {&DDRF, &PINF, &PORTF, 1}, // F1 22
  418. {&DDRF, &PINF, &PORTF, 0}, // F0 23
  419. {&DDRD, &PIND, &PORTD, 4}, // D4 24
  420. {&DDRD, &PIND, &PORTD, 7}, // D7 25
  421. {&DDRB, &PINB, &PORTB, 4}, // B4 26
  422. {&DDRB, &PINB, &PORTB, 5}, // B5 27
  423. {&DDRB, &PINB, &PORTB, 6}, // B6 28
  424. {&DDRD, &PIND, &PORTD, 6} // D6 29
  425. };
  426. #endif // CORE_TEENSY
  427. //------------------------------------------------------------------------------
  428. #elif defined(__AVR_AT90USB646__)\
  429. || defined(__AVR_AT90USB1286__)
  430. // Teensy++ 1.0 & 2.0
  431. static const pin_map_t pinMap[] = {
  432. {&DDRD, &PIND, &PORTD, 0}, // D0 0
  433. {&DDRD, &PIND, &PORTD, 1}, // D1 1
  434. {&DDRD, &PIND, &PORTD, 2}, // D2 2
  435. {&DDRD, &PIND, &PORTD, 3}, // D3 3
  436. {&DDRD, &PIND, &PORTD, 4}, // D4 4
  437. {&DDRD, &PIND, &PORTD, 5}, // D5 5
  438. {&DDRD, &PIND, &PORTD, 6}, // D6 6
  439. {&DDRD, &PIND, &PORTD, 7}, // D7 7
  440. {&DDRE, &PINE, &PORTE, 0}, // E0 8
  441. {&DDRE, &PINE, &PORTE, 1}, // E1 9
  442. {&DDRC, &PINC, &PORTC, 0}, // C0 10
  443. {&DDRC, &PINC, &PORTC, 1}, // C1 11
  444. {&DDRC, &PINC, &PORTC, 2}, // C2 12
  445. {&DDRC, &PINC, &PORTC, 3}, // C3 13
  446. {&DDRC, &PINC, &PORTC, 4}, // C4 14
  447. {&DDRC, &PINC, &PORTC, 5}, // C5 15
  448. {&DDRC, &PINC, &PORTC, 6}, // C6 16
  449. {&DDRC, &PINC, &PORTC, 7}, // C7 17
  450. {&DDRE, &PINE, &PORTE, 6}, // E6 18
  451. {&DDRE, &PINE, &PORTE, 7}, // E7 19
  452. {&DDRB, &PINB, &PORTB, 0}, // B0 20
  453. {&DDRB, &PINB, &PORTB, 1}, // B1 21
  454. {&DDRB, &PINB, &PORTB, 2}, // B2 22
  455. {&DDRB, &PINB, &PORTB, 3}, // B3 23
  456. {&DDRB, &PINB, &PORTB, 4}, // B4 24
  457. {&DDRB, &PINB, &PORTB, 5}, // B5 25
  458. {&DDRB, &PINB, &PORTB, 6}, // B6 26
  459. {&DDRB, &PINB, &PORTB, 7}, // B7 27
  460. {&DDRA, &PINA, &PORTA, 0}, // A0 28
  461. {&DDRA, &PINA, &PORTA, 1}, // A1 29
  462. {&DDRA, &PINA, &PORTA, 2}, // A2 30
  463. {&DDRA, &PINA, &PORTA, 3}, // A3 31
  464. {&DDRA, &PINA, &PORTA, 4}, // A4 32
  465. {&DDRA, &PINA, &PORTA, 5}, // A5 33
  466. {&DDRA, &PINA, &PORTA, 6}, // A6 34
  467. {&DDRA, &PINA, &PORTA, 7}, // A7 35
  468. {&DDRE, &PINE, &PORTE, 4}, // E4 36
  469. {&DDRE, &PINE, &PORTE, 5}, // E5 37
  470. {&DDRF, &PINF, &PORTF, 0}, // F0 38
  471. {&DDRF, &PINF, &PORTF, 1}, // F1 39
  472. {&DDRF, &PINF, &PORTF, 2}, // F2 40
  473. {&DDRF, &PINF, &PORTF, 3}, // F3 41
  474. {&DDRF, &PINF, &PORTF, 4}, // F4 42
  475. {&DDRF, &PINF, &PORTF, 5}, // F5 43
  476. {&DDRF, &PINF, &PORTF, 6}, // F6 44
  477. {&DDRF, &PINF, &PORTF, 7} // F7 45
  478. };
  479. //------------------------------------------------------------------------------
  480. #else // CPU type
  481. #error unknown CPU type
  482. #endif // CPU type
  483. //------------------------------------------------------------------------------
  484. /** count of pins */
  485. static const uint8_t digitalPinCount = sizeof(pinMap)/sizeof(pin_map_t);
  486. //==============================================================================
  487. /** generate bad pin number error */
  488. void badPinNumber(void)
  489. __attribute__((error("Pin number is too large or not a constant")));
  490. //------------------------------------------------------------------------------
  491. /** Check for valid pin number
  492. * @param[in] pin Number of pin to be checked.
  493. */
  494. static inline __attribute__((always_inline))
  495. void badPinCheck(uint8_t pin) {
  496. if (!__builtin_constant_p(pin) || pin >= digitalPinCount) {
  497. badPinNumber();
  498. }
  499. }
  500. //------------------------------------------------------------------------------
  501. /** fast write helper
  502. * @param[in] address I/O register address
  503. * @param[in] bit bit number to write
  504. * @param[in] level value for bit
  505. */
  506. static inline __attribute__((always_inline))
  507. void fastBitWriteSafe(volatile uint8_t* address, uint8_t bit, bool level) {
  508. uint8_t oldSREG;
  509. if (address > reinterpret_cast<uint8_t*>(0X5F)) {
  510. oldSREG = SREG;
  511. cli();
  512. }
  513. if (level) {
  514. *address |= 1 << bit;
  515. } else {
  516. *address &= ~(1 << bit);
  517. }
  518. if (address > reinterpret_cast<uint8_t*>(0X5F)) {
  519. SREG = oldSREG;
  520. }
  521. }
  522. //------------------------------------------------------------------------------
  523. /** read pin value
  524. * @param[in] pin Arduino pin number
  525. * @return value read
  526. */
  527. static inline __attribute__((always_inline))
  528. bool fastDigitalRead(uint8_t pin) {
  529. badPinCheck(pin);
  530. return (*pinMap[pin].pin >> pinMap[pin].bit) & 1;
  531. }
  532. //------------------------------------------------------------------------------
  533. /** toggle a pin
  534. * @param[in] pin Arduino pin number
  535. *
  536. * If the pin is in output mode toggle the pin level.
  537. * If the pin is in input mode toggle the state of the 20K pull-up.
  538. */
  539. static inline __attribute__((always_inline))
  540. void fastDigitalToggle(uint8_t pin) {
  541. badPinCheck(pin);
  542. if (pinMap[pin].pin > reinterpret_cast<uint8_t*>(0X5F)) {
  543. // must write bit to high address port
  544. *pinMap[pin].pin = 1 << pinMap[pin].bit;
  545. } else {
  546. // will compile to sbi and PIN register will not be read.
  547. *pinMap[pin].pin |= 1 << pinMap[pin].bit;
  548. }
  549. }
  550. //------------------------------------------------------------------------------
  551. /** Set pin value
  552. * @param[in] pin Arduino pin number
  553. * @param[in] level value to write
  554. */
  555. static inline __attribute__((always_inline))
  556. void fastDigitalWrite(uint8_t pin, bool level) {
  557. badPinCheck(pin);
  558. fastBitWriteSafe(pinMap[pin].port, pinMap[pin].bit, level);
  559. }
  560. //------------------------------------------------------------------------------
  561. /** set pin mode
  562. * @param[in] pin Arduino pin number
  563. * @param[in] mode if true set output mode else input mode
  564. *
  565. * fastPinMode does not enable or disable the 20K pull-up for input mode.
  566. */
  567. static inline __attribute__((always_inline))
  568. void fastPinMode(uint8_t pin, bool mode) {
  569. badPinCheck(pin);
  570. fastBitWriteSafe(pinMap[pin].ddr, pinMap[pin].bit, mode);
  571. }
  572. #endif // __arm__
  573. //------------------------------------------------------------------------------
  574. /** set pin configuration
  575. * @param[in] pin Arduino pin number
  576. * @param[in] mode If true set output mode else input mode
  577. * @param[in] level If mode is output, set level high/low.
  578. * If mode is input, enable or disable the pin's 20K pull-up.
  579. */
  580. static inline __attribute__((always_inline))
  581. void fastPinConfig(uint8_t pin, bool mode, bool level) {
  582. fastPinMode(pin, mode);
  583. fastDigitalWrite(pin, level);
  584. }
  585. //==============================================================================
  586. /**
  587. * @class DigitalPin
  588. * @brief Fast digital port I/O
  589. */
  590. template<uint8_t PinNumber>
  591. class DigitalPin {
  592. public:
  593. //----------------------------------------------------------------------------
  594. /** Constructor */
  595. DigitalPin() {}
  596. //----------------------------------------------------------------------------
  597. /** Constructor
  598. * @param[in] pinMode if true set output mode else input mode.
  599. */
  600. explicit DigitalPin(bool pinMode) {
  601. mode(pinMode);
  602. }
  603. //----------------------------------------------------------------------------
  604. /** Constructor
  605. * @param[in] mode If true set output mode else input mode
  606. * @param[in] level If mode is output, set level high/low.
  607. * If mode is input, enable or disable the pin's 20K pull-up.
  608. */
  609. DigitalPin(bool mode, bool level) {
  610. config(mode, level);
  611. }
  612. //----------------------------------------------------------------------------
  613. /** Asignment operator
  614. * @param[in] value If true set the pin's level high else set the
  615. * pin's level low.
  616. *
  617. * @return This DigitalPin instance.
  618. */
  619. inline DigitalPin & operator = (bool value) __attribute__((always_inline)) {
  620. write(value);
  621. return *this;
  622. }
  623. //----------------------------------------------------------------------------
  624. /** Parenthesis operator
  625. * @return Pin's level
  626. */
  627. inline operator bool() const __attribute__((always_inline)) {
  628. return read();
  629. }
  630. //----------------------------------------------------------------------------
  631. /** set pin configuration
  632. * @param[in] mode If true set output mode else input mode
  633. * @param[in] level If mode is output, set level high/low. If mode
  634. * is input, enable or disable the pin's 20K pull-up.
  635. */
  636. inline __attribute__((always_inline))
  637. void config(bool mode, bool level) {
  638. fastPinConfig(PinNumber, mode, level);
  639. }
  640. //----------------------------------------------------------------------------
  641. /**
  642. * Set pin level high if output mode or enable 20K pull-up if input mode.
  643. */
  644. inline __attribute__((always_inline))
  645. void high() {
  646. write(true);
  647. }
  648. //----------------------------------------------------------------------------
  649. /**
  650. * Set pin level low if output mode or disable 20K pull-up if input mode.
  651. */
  652. inline __attribute__((always_inline))
  653. void low() {
  654. write(false);
  655. }
  656. //----------------------------------------------------------------------------
  657. /**
  658. * Set pin mode
  659. * @param[in] pinMode if true set output mode else input mode.
  660. *
  661. * mode() does not enable or disable the 20K pull-up for input mode.
  662. */
  663. inline __attribute__((always_inline))
  664. void mode(bool pinMode) {
  665. fastPinMode(PinNumber, pinMode);
  666. }
  667. //----------------------------------------------------------------------------
  668. /** @return Pin's level */
  669. inline __attribute__((always_inline))
  670. bool read() const {
  671. return fastDigitalRead(PinNumber);
  672. }
  673. //----------------------------------------------------------------------------
  674. /** toggle a pin
  675. *
  676. * If the pin is in output mode toggle the pin's level.
  677. * If the pin is in input mode toggle the state of the 20K pull-up.
  678. */
  679. inline __attribute__((always_inline))
  680. void toggle() {
  681. fastDigitalToggle(PinNumber);
  682. }
  683. //----------------------------------------------------------------------------
  684. /** Write the pin's level.
  685. * @param[in] value If true set the pin's level high else set the
  686. * pin's level low.
  687. */
  688. inline __attribute__((always_inline))
  689. void write(bool value) {
  690. fastDigitalWrite(PinNumber, value);
  691. }
  692. };
  693. #endif // DigitalPin_h
  694. /** @} */