You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  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 defined(VARIANT_MIGHTY)
  214. // Mighty Layout
  215. static const pin_map_t pinMap[] = {
  216. {&DDRB, &PINB, &PORTB, 0}, // B0 0
  217. {&DDRB, &PINB, &PORTB, 1}, // B1 1
  218. {&DDRB, &PINB, &PORTB, 2}, // B2 2
  219. {&DDRB, &PINB, &PORTB, 3}, // B3 3
  220. {&DDRB, &PINB, &PORTB, 4}, // B4 4
  221. {&DDRB, &PINB, &PORTB, 5}, // B5 5
  222. {&DDRB, &PINB, &PORTB, 6}, // B6 6
  223. {&DDRB, &PINB, &PORTB, 7}, // B7 7
  224. {&DDRD, &PIND, &PORTD, 0}, // D0 8
  225. {&DDRD, &PIND, &PORTD, 1}, // D1 9
  226. {&DDRD, &PIND, &PORTD, 2}, // D2 10
  227. {&DDRD, &PIND, &PORTD, 3}, // D3 11
  228. {&DDRD, &PIND, &PORTD, 4}, // D4 12
  229. {&DDRD, &PIND, &PORTD, 5}, // D5 13
  230. {&DDRD, &PIND, &PORTD, 6}, // D6 14
  231. {&DDRD, &PIND, &PORTD, 7}, // D7 15
  232. {&DDRC, &PINC, &PORTC, 0}, // C0 16
  233. {&DDRC, &PINC, &PORTC, 1}, // C1 17
  234. {&DDRC, &PINC, &PORTC, 2}, // C2 18
  235. {&DDRC, &PINC, &PORTC, 3}, // C3 19
  236. {&DDRC, &PINC, &PORTC, 4}, // C4 20
  237. {&DDRC, &PINC, &PORTC, 5}, // C5 21
  238. {&DDRC, &PINC, &PORTC, 6}, // C6 22
  239. {&DDRC, &PINC, &PORTC, 7}, // C7 23
  240. {&DDRA, &PINA, &PORTA, 0}, // A0 24
  241. {&DDRA, &PINA, &PORTA, 1}, // A1 25
  242. {&DDRA, &PINA, &PORTA, 2}, // A2 26
  243. {&DDRA, &PINA, &PORTA, 3}, // A3 27
  244. {&DDRA, &PINA, &PORTA, 4}, // A4 28
  245. {&DDRA, &PINA, &PORTA, 5}, // A5 29
  246. {&DDRA, &PINA, &PORTA, 6}, // A6 30
  247. {&DDRA, &PINA, &PORTA, 7} // A7 31
  248. };
  249. #elif defined(VARIANT_BOBUINO)
  250. // Bobuino Layout
  251. static const pin_map_t pinMap[] = {
  252. {&DDRD, &PIND, &PORTD, 0}, // D0 0
  253. {&DDRD, &PIND, &PORTD, 1}, // D1 1
  254. {&DDRD, &PIND, &PORTD, 2}, // D2 2
  255. {&DDRD, &PIND, &PORTD, 3}, // D3 3
  256. {&DDRB, &PINB, &PORTB, 0}, // B0 4
  257. {&DDRB, &PINB, &PORTB, 1}, // B1 5
  258. {&DDRB, &PINB, &PORTB, 2}, // B2 6
  259. {&DDRB, &PINB, &PORTB, 3}, // B3 7
  260. {&DDRD, &PIND, &PORTD, 5}, // D5 8
  261. {&DDRD, &PIND, &PORTD, 6}, // D6 9
  262. {&DDRB, &PINB, &PORTB, 4}, // B4 10
  263. {&DDRB, &PINB, &PORTB, 5}, // B5 11
  264. {&DDRB, &PINB, &PORTB, 6}, // B6 12
  265. {&DDRB, &PINB, &PORTB, 7}, // B7 13
  266. {&DDRA, &PINA, &PORTA, 7}, // A7 14
  267. {&DDRA, &PINA, &PORTA, 6}, // A6 15
  268. {&DDRA, &PINA, &PORTA, 5}, // A5 16
  269. {&DDRA, &PINA, &PORTA, 4}, // A4 17
  270. {&DDRA, &PINA, &PORTA, 3}, // A3 18
  271. {&DDRA, &PINA, &PORTA, 2}, // A2 19
  272. {&DDRA, &PINA, &PORTA, 1}, // A1 20
  273. {&DDRA, &PINA, &PORTA, 0}, // A0 21
  274. {&DDRC, &PINC, &PORTC, 0}, // C0 22
  275. {&DDRC, &PINC, &PORTC, 1}, // C1 23
  276. {&DDRC, &PINC, &PORTC, 2}, // C2 24
  277. {&DDRC, &PINC, &PORTC, 3}, // C3 25
  278. {&DDRC, &PINC, &PORTC, 4}, // C4 26
  279. {&DDRC, &PINC, &PORTC, 5}, // C5 27
  280. {&DDRC, &PINC, &PORTC, 6}, // C6 28
  281. {&DDRC, &PINC, &PORTC, 7}, // C7 29
  282. {&DDRD, &PIND, &PORTD, 4}, // D4 30
  283. {&DDRD, &PIND, &PORTD, 7} // D7 31
  284. };
  285. #elif defined(VARIANT_STANDARD)
  286. // Standard Layout
  287. static const pin_map_t pinMap[] = {
  288. {&DDRB, &PINB, &PORTB, 0}, // B0 0
  289. {&DDRB, &PINB, &PORTB, 1}, // B1 1
  290. {&DDRB, &PINB, &PORTB, 2}, // B2 2
  291. {&DDRB, &PINB, &PORTB, 3}, // B3 3
  292. {&DDRB, &PINB, &PORTB, 4}, // B4 4
  293. {&DDRB, &PINB, &PORTB, 5}, // B5 5
  294. {&DDRB, &PINB, &PORTB, 6}, // B6 6
  295. {&DDRB, &PINB, &PORTB, 7}, // B7 7
  296. {&DDRD, &PIND, &PORTD, 0}, // D0 8
  297. {&DDRD, &PIND, &PORTD, 1}, // D1 9
  298. {&DDRD, &PIND, &PORTD, 2}, // D2 10
  299. {&DDRD, &PIND, &PORTD, 3}, // D3 11
  300. {&DDRD, &PIND, &PORTD, 4}, // D4 12
  301. {&DDRD, &PIND, &PORTD, 5}, // D5 13
  302. {&DDRD, &PIND, &PORTD, 6}, // D6 14
  303. {&DDRD, &PIND, &PORTD, 7}, // D7 15
  304. {&DDRC, &PINC, &PORTC, 0}, // C0 16
  305. {&DDRC, &PINC, &PORTC, 1}, // C1 17
  306. {&DDRC, &PINC, &PORTC, 2}, // C2 18
  307. {&DDRC, &PINC, &PORTC, 3}, // C3 19
  308. {&DDRC, &PINC, &PORTC, 4}, // C4 20
  309. {&DDRC, &PINC, &PORTC, 5}, // C5 21
  310. {&DDRC, &PINC, &PORTC, 6}, // C6 22
  311. {&DDRC, &PINC, &PORTC, 7}, // C7 23
  312. {&DDRA, &PINA, &PORTA, 7}, // A7 24
  313. {&DDRA, &PINA, &PORTA, 6}, // A6 25
  314. {&DDRA, &PINA, &PORTA, 5}, // A5 26
  315. {&DDRA, &PINA, &PORTA, 4}, // A4 27
  316. {&DDRA, &PINA, &PORTA, 3}, // A3 28
  317. {&DDRA, &PINA, &PORTA, 2}, // A2 29
  318. {&DDRA, &PINA, &PORTA, 1}, // A1 30
  319. {&DDRA, &PINA, &PORTA, 0} // A0 31
  320. };
  321. #else // VARIANT_MIGHTY
  322. #error Undefined variant 1284, 644, 324, 64, 32
  323. #endif // VARIANT_MIGHTY
  324. //------------------------------------------------------------------------------
  325. #elif defined(__AVR_ATmega32U4__)
  326. #ifdef CORE_TEENSY
  327. // Teensy 2.0
  328. static const pin_map_t pinMap[] = {
  329. {&DDRB, &PINB, &PORTB, 0}, // B0 0
  330. {&DDRB, &PINB, &PORTB, 1}, // B1 1
  331. {&DDRB, &PINB, &PORTB, 2}, // B2 2
  332. {&DDRB, &PINB, &PORTB, 3}, // B3 3
  333. {&DDRB, &PINB, &PORTB, 7}, // B7 4
  334. {&DDRD, &PIND, &PORTD, 0}, // D0 5
  335. {&DDRD, &PIND, &PORTD, 1}, // D1 6
  336. {&DDRD, &PIND, &PORTD, 2}, // D2 7
  337. {&DDRD, &PIND, &PORTD, 3}, // D3 8
  338. {&DDRC, &PINC, &PORTC, 6}, // C6 9
  339. {&DDRC, &PINC, &PORTC, 7}, // C7 10
  340. {&DDRD, &PIND, &PORTD, 6}, // D6 11
  341. {&DDRD, &PIND, &PORTD, 7}, // D7 12
  342. {&DDRB, &PINB, &PORTB, 4}, // B4 13
  343. {&DDRB, &PINB, &PORTB, 5}, // B5 14
  344. {&DDRB, &PINB, &PORTB, 6}, // B6 15
  345. {&DDRF, &PINF, &PORTF, 7}, // F7 16
  346. {&DDRF, &PINF, &PORTF, 6}, // F6 17
  347. {&DDRF, &PINF, &PORTF, 5}, // F5 18
  348. {&DDRF, &PINF, &PORTF, 4}, // F4 19
  349. {&DDRF, &PINF, &PORTF, 1}, // F1 20
  350. {&DDRF, &PINF, &PORTF, 0}, // F0 21
  351. {&DDRD, &PIND, &PORTD, 4}, // D4 22
  352. {&DDRD, &PIND, &PORTD, 5}, // D5 23
  353. {&DDRE, &PINE, &PORTE, 6} // E6 24
  354. };
  355. //------------------------------------------------------------------------------
  356. #else // CORE_TEENSY
  357. // Leonardo
  358. static const pin_map_t pinMap[] = {
  359. {&DDRD, &PIND, &PORTD, 2}, // D2 0
  360. {&DDRD, &PIND, &PORTD, 3}, // D3 1
  361. {&DDRD, &PIND, &PORTD, 1}, // D1 2
  362. {&DDRD, &PIND, &PORTD, 0}, // D0 3
  363. {&DDRD, &PIND, &PORTD, 4}, // D4 4
  364. {&DDRC, &PINC, &PORTC, 6}, // C6 5
  365. {&DDRD, &PIND, &PORTD, 7}, // D7 6
  366. {&DDRE, &PINE, &PORTE, 6}, // E6 7
  367. {&DDRB, &PINB, &PORTB, 4}, // B4 8
  368. {&DDRB, &PINB, &PORTB, 5}, // B5 9
  369. {&DDRB, &PINB, &PORTB, 6}, // B6 10
  370. {&DDRB, &PINB, &PORTB, 7}, // B7 11
  371. {&DDRD, &PIND, &PORTD, 6}, // D6 12
  372. {&DDRC, &PINC, &PORTC, 7}, // C7 13
  373. {&DDRB, &PINB, &PORTB, 3}, // B3 14
  374. {&DDRB, &PINB, &PORTB, 1}, // B1 15
  375. {&DDRB, &PINB, &PORTB, 2}, // B2 16
  376. {&DDRB, &PINB, &PORTB, 0}, // B0 17
  377. {&DDRF, &PINF, &PORTF, 7}, // F7 18
  378. {&DDRF, &PINF, &PORTF, 6}, // F6 19
  379. {&DDRF, &PINF, &PORTF, 5}, // F5 20
  380. {&DDRF, &PINF, &PORTF, 4}, // F4 21
  381. {&DDRF, &PINF, &PORTF, 1}, // F1 22
  382. {&DDRF, &PINF, &PORTF, 0}, // F0 23
  383. {&DDRD, &PIND, &PORTD, 4}, // D4 24
  384. {&DDRD, &PIND, &PORTD, 7}, // D7 25
  385. {&DDRB, &PINB, &PORTB, 4}, // B4 26
  386. {&DDRB, &PINB, &PORTB, 5}, // B5 27
  387. {&DDRB, &PINB, &PORTB, 6}, // B6 28
  388. {&DDRD, &PIND, &PORTD, 6} // D6 29
  389. };
  390. #endif // CORE_TEENSY
  391. //------------------------------------------------------------------------------
  392. #elif defined(__AVR_AT90USB646__)\
  393. || defined(__AVR_AT90USB1286__)
  394. // Teensy++ 1.0 & 2.0
  395. static const pin_map_t pinMap[] = {
  396. {&DDRD, &PIND, &PORTD, 0}, // D0 0
  397. {&DDRD, &PIND, &PORTD, 1}, // D1 1
  398. {&DDRD, &PIND, &PORTD, 2}, // D2 2
  399. {&DDRD, &PIND, &PORTD, 3}, // D3 3
  400. {&DDRD, &PIND, &PORTD, 4}, // D4 4
  401. {&DDRD, &PIND, &PORTD, 5}, // D5 5
  402. {&DDRD, &PIND, &PORTD, 6}, // D6 6
  403. {&DDRD, &PIND, &PORTD, 7}, // D7 7
  404. {&DDRE, &PINE, &PORTE, 0}, // E0 8
  405. {&DDRE, &PINE, &PORTE, 1}, // E1 9
  406. {&DDRC, &PINC, &PORTC, 0}, // C0 10
  407. {&DDRC, &PINC, &PORTC, 1}, // C1 11
  408. {&DDRC, &PINC, &PORTC, 2}, // C2 12
  409. {&DDRC, &PINC, &PORTC, 3}, // C3 13
  410. {&DDRC, &PINC, &PORTC, 4}, // C4 14
  411. {&DDRC, &PINC, &PORTC, 5}, // C5 15
  412. {&DDRC, &PINC, &PORTC, 6}, // C6 16
  413. {&DDRC, &PINC, &PORTC, 7}, // C7 17
  414. {&DDRE, &PINE, &PORTE, 6}, // E6 18
  415. {&DDRE, &PINE, &PORTE, 7}, // E7 19
  416. {&DDRB, &PINB, &PORTB, 0}, // B0 20
  417. {&DDRB, &PINB, &PORTB, 1}, // B1 21
  418. {&DDRB, &PINB, &PORTB, 2}, // B2 22
  419. {&DDRB, &PINB, &PORTB, 3}, // B3 23
  420. {&DDRB, &PINB, &PORTB, 4}, // B4 24
  421. {&DDRB, &PINB, &PORTB, 5}, // B5 25
  422. {&DDRB, &PINB, &PORTB, 6}, // B6 26
  423. {&DDRB, &PINB, &PORTB, 7}, // B7 27
  424. {&DDRA, &PINA, &PORTA, 0}, // A0 28
  425. {&DDRA, &PINA, &PORTA, 1}, // A1 29
  426. {&DDRA, &PINA, &PORTA, 2}, // A2 30
  427. {&DDRA, &PINA, &PORTA, 3}, // A3 31
  428. {&DDRA, &PINA, &PORTA, 4}, // A4 32
  429. {&DDRA, &PINA, &PORTA, 5}, // A5 33
  430. {&DDRA, &PINA, &PORTA, 6}, // A6 34
  431. {&DDRA, &PINA, &PORTA, 7}, // A7 35
  432. {&DDRE, &PINE, &PORTE, 4}, // E4 36
  433. {&DDRE, &PINE, &PORTE, 5}, // E5 37
  434. {&DDRF, &PINF, &PORTF, 0}, // F0 38
  435. {&DDRF, &PINF, &PORTF, 1}, // F1 39
  436. {&DDRF, &PINF, &PORTF, 2}, // F2 40
  437. {&DDRF, &PINF, &PORTF, 3}, // F3 41
  438. {&DDRF, &PINF, &PORTF, 4}, // F4 42
  439. {&DDRF, &PINF, &PORTF, 5}, // F5 43
  440. {&DDRF, &PINF, &PORTF, 6}, // F6 44
  441. {&DDRF, &PINF, &PORTF, 7} // F7 45
  442. };
  443. //------------------------------------------------------------------------------
  444. #else // CPU type
  445. #error unknown CPU type
  446. #endif // CPU type
  447. //------------------------------------------------------------------------------
  448. /** count of pins */
  449. static const uint8_t digitalPinCount = sizeof(pinMap)/sizeof(pin_map_t);
  450. //==============================================================================
  451. /** generate bad pin number error */
  452. void badPinNumber(void)
  453. __attribute__((error("Pin number is too large or not a constant")));
  454. //------------------------------------------------------------------------------
  455. /** Check for valid pin number
  456. * @param[in] pin Number of pin to be checked.
  457. */
  458. static inline __attribute__((always_inline))
  459. void badPinCheck(uint8_t pin) {
  460. if (!__builtin_constant_p(pin) || pin >= digitalPinCount) {
  461. badPinNumber();
  462. }
  463. }
  464. //------------------------------------------------------------------------------
  465. /** fast write helper
  466. * @param[in] address I/O register address
  467. * @param[in] bit bit number to write
  468. * @param[in] level value for bit
  469. */
  470. static inline __attribute__((always_inline))
  471. void fastBitWriteSafe(volatile uint8_t* address, uint8_t bit, bool level) {
  472. uint8_t oldSREG;
  473. if (address > reinterpret_cast<uint8_t*>(0X5F)) {
  474. oldSREG = SREG;
  475. cli();
  476. }
  477. if (level) {
  478. *address |= 1 << bit;
  479. } else {
  480. *address &= ~(1 << bit);
  481. }
  482. if (address > reinterpret_cast<uint8_t*>(0X5F)) {
  483. SREG = oldSREG;
  484. }
  485. }
  486. //------------------------------------------------------------------------------
  487. /** read pin value
  488. * @param[in] pin Arduino pin number
  489. * @return value read
  490. */
  491. static inline __attribute__((always_inline))
  492. bool fastDigitalRead(uint8_t pin) {
  493. badPinCheck(pin);
  494. return (*pinMap[pin].pin >> pinMap[pin].bit) & 1;
  495. }
  496. //------------------------------------------------------------------------------
  497. /** toggle a pin
  498. * @param[in] pin Arduino pin number
  499. *
  500. * If the pin is in output mode toggle the pin level.
  501. * If the pin is in input mode toggle the state of the 20K pull-up.
  502. */
  503. static inline __attribute__((always_inline))
  504. void fastDigitalToggle(uint8_t pin) {
  505. badPinCheck(pin);
  506. if (pinMap[pin].pin > reinterpret_cast<uint8_t*>(0X5F)) {
  507. // must write bit to high address port
  508. *pinMap[pin].pin = 1 << pinMap[pin].bit;
  509. } else {
  510. // will compile to sbi and PIN register will not be read.
  511. *pinMap[pin].pin |= 1 << pinMap[pin].bit;
  512. }
  513. }
  514. //------------------------------------------------------------------------------
  515. /** Set pin value
  516. * @param[in] pin Arduino pin number
  517. * @param[in] level value to write
  518. */
  519. static inline __attribute__((always_inline))
  520. void fastDigitalWrite(uint8_t pin, bool level) {
  521. badPinCheck(pin);
  522. fastBitWriteSafe(pinMap[pin].port, pinMap[pin].bit, level);
  523. }
  524. //------------------------------------------------------------------------------
  525. /** set pin mode
  526. * @param[in] pin Arduino pin number
  527. * @param[in] mode if true set output mode else input mode
  528. *
  529. * fastPinMode does not enable or disable the 20K pull-up for input mode.
  530. */
  531. static inline __attribute__((always_inline))
  532. void fastPinMode(uint8_t pin, bool mode) {
  533. badPinCheck(pin);
  534. fastBitWriteSafe(pinMap[pin].ddr, pinMap[pin].bit, mode);
  535. }
  536. #endif // __arm__
  537. //------------------------------------------------------------------------------
  538. /** set pin configuration
  539. * @param[in] pin Arduino pin number
  540. * @param[in] mode If true set output mode else input mode
  541. * @param[in] level If mode is output, set level high/low.
  542. * If mode is input, enable or disable the pin's 20K pull-up.
  543. */
  544. static inline __attribute__((always_inline))
  545. void fastPinConfig(uint8_t pin, bool mode, bool level) {
  546. fastPinMode(pin, mode);
  547. fastDigitalWrite(pin, level);
  548. }
  549. //==============================================================================
  550. /**
  551. * @class DigitalPin
  552. * @brief Fast digital port I/O
  553. */
  554. template<uint8_t PinNumber>
  555. class DigitalPin {
  556. public:
  557. //----------------------------------------------------------------------------
  558. /** Constructor */
  559. DigitalPin() {}
  560. //----------------------------------------------------------------------------
  561. /** Constructor
  562. * @param[in] pinMode if true set output mode else input mode.
  563. */
  564. explicit DigitalPin(bool pinMode) {
  565. mode(pinMode);
  566. }
  567. //----------------------------------------------------------------------------
  568. /** Constructor
  569. * @param[in] mode If true set output mode else input mode
  570. * @param[in] level If mode is output, set level high/low.
  571. * If mode is input, enable or disable the pin's 20K pull-up.
  572. */
  573. DigitalPin(bool mode, bool level) {
  574. config(mode, level);
  575. }
  576. //----------------------------------------------------------------------------
  577. /** Asignment operator
  578. * @param[in] value If true set the pin's level high else set the
  579. * pin's level low.
  580. *
  581. * @return This DigitalPin instance.
  582. */
  583. inline DigitalPin & operator = (bool value) __attribute__((always_inline)) {
  584. write(value);
  585. return *this;
  586. }
  587. //----------------------------------------------------------------------------
  588. /** Parenthesis operator
  589. * @return Pin's level
  590. */
  591. inline operator bool() const __attribute__((always_inline)) {
  592. return read();
  593. }
  594. //----------------------------------------------------------------------------
  595. /** set pin configuration
  596. * @param[in] mode If true set output mode else input mode
  597. * @param[in] level If mode is output, set level high/low. If mode
  598. * is input, enable or disable the pin's 20K pull-up.
  599. */
  600. inline __attribute__((always_inline))
  601. void config(bool mode, bool level) {
  602. fastPinConfig(PinNumber, mode, level);
  603. }
  604. //----------------------------------------------------------------------------
  605. /**
  606. * Set pin level high if output mode or enable 20K pull-up if input mode.
  607. */
  608. inline __attribute__((always_inline))
  609. void high() {
  610. write(true);
  611. }
  612. //----------------------------------------------------------------------------
  613. /**
  614. * Set pin level low if output mode or disable 20K pull-up if input mode.
  615. */
  616. inline __attribute__((always_inline))
  617. void low() {
  618. write(false);
  619. }
  620. //----------------------------------------------------------------------------
  621. /**
  622. * Set pin mode
  623. * @param[in] pinMode if true set output mode else input mode.
  624. *
  625. * mode() does not enable or disable the 20K pull-up for input mode.
  626. */
  627. inline __attribute__((always_inline))
  628. void mode(bool pinMode) {
  629. fastPinMode(PinNumber, pinMode);
  630. }
  631. //----------------------------------------------------------------------------
  632. /** @return Pin's level */
  633. inline __attribute__((always_inline))
  634. bool read() const {
  635. return fastDigitalRead(PinNumber);
  636. }
  637. //----------------------------------------------------------------------------
  638. /** toggle a pin
  639. *
  640. * If the pin is in output mode toggle the pin's level.
  641. * If the pin is in input mode toggle the state of the 20K pull-up.
  642. */
  643. inline __attribute__((always_inline))
  644. void toggle() {
  645. fastDigitalToggle(PinNumber);
  646. }
  647. //----------------------------------------------------------------------------
  648. /** Write the pin's level.
  649. * @param[in] value If true set the pin's level high else set the
  650. * pin's level low.
  651. */
  652. inline __attribute__((always_inline))
  653. void write(bool value) {
  654. fastDigitalWrite(PinNumber, value);
  655. }
  656. };
  657. #endif // DigitalPin_h
  658. /** @} */