Digital IO
 All Classes Files Functions Variables Macros Groups Pages
DigitalPin.h
Go to the documentation of this file.
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  */
28 #ifndef DigitalPin_h
29 #define DigitalPin_h
30 #include <Arduino.h>
31 #ifdef __arm__
32 #ifdef CORE_TEENSY
33 //------------------------------------------------------------------------------
38 static inline __attribute__((always_inline))
39 bool fastDigitalRead(uint8_t pin) {
40  return *portInputRegister(pin);
41 }
42 //------------------------------------------------------------------------------
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 //------------------------------------------------------------------------------
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 //------------------------------------------------------------------------------
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) {
82  }
83 //------------------------------------------------------------------------------
84 inline void fastPinMode(uint8_t pin, bool mode) {pinMode(pin, mode);}
85 #else // __arm__
86 #include <avr/io.h>
87 #include <util/atomic.h>
88 //------------------------------------------------------------------------------
93 struct pin_map_t {
94  volatile uint8_t* ddr;
95  volatile uint8_t* pin;
96  volatile uint8_t* port;
97  uint8_t bit;
98 };
99 //------------------------------------------------------------------------------
100 #if defined(__AVR_ATmega168__)\
101 ||defined(__AVR_ATmega168P__)\
102 ||defined(__AVR_ATmega328P__)
103 // 168 and 328 Arduinos
104 const static pin_map_t pinMap[] = {
105  {&DDRD, &PIND, &PORTD, 0}, // D0 0
106  {&DDRD, &PIND, &PORTD, 1}, // D1 1
107  {&DDRD, &PIND, &PORTD, 2}, // D2 2
108  {&DDRD, &PIND, &PORTD, 3}, // D3 3
109  {&DDRD, &PIND, &PORTD, 4}, // D4 4
110  {&DDRD, &PIND, &PORTD, 5}, // D5 5
111  {&DDRD, &PIND, &PORTD, 6}, // D6 6
112  {&DDRD, &PIND, &PORTD, 7}, // D7 7
113  {&DDRB, &PINB, &PORTB, 0}, // B0 8
114  {&DDRB, &PINB, &PORTB, 1}, // B1 9
115  {&DDRB, &PINB, &PORTB, 2}, // B2 10
116  {&DDRB, &PINB, &PORTB, 3}, // B3 11
117  {&DDRB, &PINB, &PORTB, 4}, // B4 12
118  {&DDRB, &PINB, &PORTB, 5}, // B5 13
119  {&DDRC, &PINC, &PORTC, 0}, // C0 14
120  {&DDRC, &PINC, &PORTC, 1}, // C1 15
121  {&DDRC, &PINC, &PORTC, 2}, // C2 16
122  {&DDRC, &PINC, &PORTC, 3}, // C3 17
123  {&DDRC, &PINC, &PORTC, 4}, // C4 18
124  {&DDRC, &PINC, &PORTC, 5} // C5 19
125 };
126 //------------------------------------------------------------------------------
127 #elif defined(__AVR_ATmega1280__)\
128 || defined(__AVR_ATmega2560__)
129 // Mega
130 static const pin_map_t pinMap[] = {
131  {&DDRE, &PINE, &PORTE, 0}, // E0 0
132  {&DDRE, &PINE, &PORTE, 1}, // E1 1
133  {&DDRE, &PINE, &PORTE, 4}, // E4 2
134  {&DDRE, &PINE, &PORTE, 5}, // E5 3
135  {&DDRG, &PING, &PORTG, 5}, // G5 4
136  {&DDRE, &PINE, &PORTE, 3}, // E3 5
137  {&DDRH, &PINH, &PORTH, 3}, // H3 6
138  {&DDRH, &PINH, &PORTH, 4}, // H4 7
139  {&DDRH, &PINH, &PORTH, 5}, // H5 8
140  {&DDRH, &PINH, &PORTH, 6}, // H6 9
141  {&DDRB, &PINB, &PORTB, 4}, // B4 10
142  {&DDRB, &PINB, &PORTB, 5}, // B5 11
143  {&DDRB, &PINB, &PORTB, 6}, // B6 12
144  {&DDRB, &PINB, &PORTB, 7}, // B7 13
145  {&DDRJ, &PINJ, &PORTJ, 1}, // J1 14
146  {&DDRJ, &PINJ, &PORTJ, 0}, // J0 15
147  {&DDRH, &PINH, &PORTH, 1}, // H1 16
148  {&DDRH, &PINH, &PORTH, 0}, // H0 17
149  {&DDRD, &PIND, &PORTD, 3}, // D3 18
150  {&DDRD, &PIND, &PORTD, 2}, // D2 19
151  {&DDRD, &PIND, &PORTD, 1}, // D1 20
152  {&DDRD, &PIND, &PORTD, 0}, // D0 21
153  {&DDRA, &PINA, &PORTA, 0}, // A0 22
154  {&DDRA, &PINA, &PORTA, 1}, // A1 23
155  {&DDRA, &PINA, &PORTA, 2}, // A2 24
156  {&DDRA, &PINA, &PORTA, 3}, // A3 25
157  {&DDRA, &PINA, &PORTA, 4}, // A4 26
158  {&DDRA, &PINA, &PORTA, 5}, // A5 27
159  {&DDRA, &PINA, &PORTA, 6}, // A6 28
160  {&DDRA, &PINA, &PORTA, 7}, // A7 29
161  {&DDRC, &PINC, &PORTC, 7}, // C7 30
162  {&DDRC, &PINC, &PORTC, 6}, // C6 31
163  {&DDRC, &PINC, &PORTC, 5}, // C5 32
164  {&DDRC, &PINC, &PORTC, 4}, // C4 33
165  {&DDRC, &PINC, &PORTC, 3}, // C3 34
166  {&DDRC, &PINC, &PORTC, 2}, // C2 35
167  {&DDRC, &PINC, &PORTC, 1}, // C1 36
168  {&DDRC, &PINC, &PORTC, 0}, // C0 37
169  {&DDRD, &PIND, &PORTD, 7}, // D7 38
170  {&DDRG, &PING, &PORTG, 2}, // G2 39
171  {&DDRG, &PING, &PORTG, 1}, // G1 40
172  {&DDRG, &PING, &PORTG, 0}, // G0 41
173  {&DDRL, &PINL, &PORTL, 7}, // L7 42
174  {&DDRL, &PINL, &PORTL, 6}, // L6 43
175  {&DDRL, &PINL, &PORTL, 5}, // L5 44
176  {&DDRL, &PINL, &PORTL, 4}, // L4 45
177  {&DDRL, &PINL, &PORTL, 3}, // L3 46
178  {&DDRL, &PINL, &PORTL, 2}, // L2 47
179  {&DDRL, &PINL, &PORTL, 1}, // L1 48
180  {&DDRL, &PINL, &PORTL, 0}, // L0 49
181  {&DDRB, &PINB, &PORTB, 3}, // B3 50
182  {&DDRB, &PINB, &PORTB, 2}, // B2 51
183  {&DDRB, &PINB, &PORTB, 1}, // B1 52
184  {&DDRB, &PINB, &PORTB, 0}, // B0 53
185  {&DDRF, &PINF, &PORTF, 0}, // F0 54
186  {&DDRF, &PINF, &PORTF, 1}, // F1 55
187  {&DDRF, &PINF, &PORTF, 2}, // F2 56
188  {&DDRF, &PINF, &PORTF, 3}, // F3 57
189  {&DDRF, &PINF, &PORTF, 4}, // F4 58
190  {&DDRF, &PINF, &PORTF, 5}, // F5 59
191  {&DDRF, &PINF, &PORTF, 6}, // F6 60
192  {&DDRF, &PINF, &PORTF, 7}, // F7 61
193  {&DDRK, &PINK, &PORTK, 0}, // K0 62
194  {&DDRK, &PINK, &PORTK, 1}, // K1 63
195  {&DDRK, &PINK, &PORTK, 2}, // K2 64
196  {&DDRK, &PINK, &PORTK, 3}, // K3 65
197  {&DDRK, &PINK, &PORTK, 4}, // K4 66
198  {&DDRK, &PINK, &PORTK, 5}, // K5 67
199  {&DDRK, &PINK, &PORTK, 6}, // K6 68
200  {&DDRK, &PINK, &PORTK, 7} // K7 69
201 };
202 //------------------------------------------------------------------------------
203 #elif defined(__AVR_ATmega1284P__)\
204 || defined(__AVR_ATmega1284__)\
205 || defined(__AVR_ATmega644P__)\
206 || defined(__AVR_ATmega644__)\
207 || defined(__AVR_ATmega64__)\
208 || defined(__AVR_ATmega32__)\
209 || defined(__AVR_ATmega324__)\
210 || defined(__AVR_ATmega16__)
211 
212 #ifdef defined(VARIANT_MIGHTY)
213 // Mighty Layout
214 static const pin_map_t pinMap[] = {
215  {&DDRB, &PINB, &PORTB, 0}, // B0 0
216  {&DDRB, &PINB, &PORTB, 1}, // B1 1
217  {&DDRB, &PINB, &PORTB, 2}, // B2 2
218  {&DDRB, &PINB, &PORTB, 3}, // B3 3
219  {&DDRB, &PINB, &PORTB, 4}, // B4 4
220  {&DDRB, &PINB, &PORTB, 5}, // B5 5
221  {&DDRB, &PINB, &PORTB, 6}, // B6 6
222  {&DDRB, &PINB, &PORTB, 7}, // B7 7
223  {&DDRD, &PIND, &PORTD, 0}, // D0 8
224  {&DDRD, &PIND, &PORTD, 1}, // D1 9
225  {&DDRD, &PIND, &PORTD, 2}, // D2 10
226  {&DDRD, &PIND, &PORTD, 3}, // D3 11
227  {&DDRD, &PIND, &PORTD, 4}, // D4 12
228  {&DDRD, &PIND, &PORTD, 5}, // D5 13
229  {&DDRD, &PIND, &PORTD, 6}, // D6 14
230  {&DDRD, &PIND, &PORTD, 7}, // D7 15
231  {&DDRC, &PINC, &PORTC, 0}, // C0 16
232  {&DDRC, &PINC, &PORTC, 1}, // C1 17
233  {&DDRC, &PINC, &PORTC, 2}, // C2 18
234  {&DDRC, &PINC, &PORTC, 3}, // C3 19
235  {&DDRC, &PINC, &PORTC, 4}, // C4 20
236  {&DDRC, &PINC, &PORTC, 5}, // C5 21
237  {&DDRC, &PINC, &PORTC, 6}, // C6 22
238  {&DDRC, &PINC, &PORTC, 7}, // C7 23
239  {&DDRA, &PINA, &PORTA, 0}, // A0 24
240  {&DDRA, &PINA, &PORTA, 1}, // A1 25
241  {&DDRA, &PINA, &PORTA, 2}, // A2 26
242  {&DDRA, &PINA, &PORTA, 3}, // A3 27
243  {&DDRA, &PINA, &PORTA, 4}, // A4 28
244  {&DDRA, &PINA, &PORTA, 5}, // A5 29
245  {&DDRA, &PINA, &PORTA, 6}, // A6 30
246  {&DDRA, &PINA, &PORTA, 7} // A7 31
247 };
248 #elif defined(VARIANT_BOBUINO)
249 // Bobuino Layout
250 static const pin_map_t pinMap[] = {
251  {&DDRD, &PIND, &PORTD, 0}, // D0 0
252  {&DDRD, &PIND, &PORTD, 1}, // D1 1
253  {&DDRD, &PIND, &PORTD, 2}, // D2 2
254  {&DDRD, &PIND, &PORTD, 3}, // D3 3
255  {&DDRB, &PINB, &PORTB, 0}, // B0 4
256  {&DDRB, &PINB, &PORTB, 1}, // B1 5
257  {&DDRB, &PINB, &PORTB, 2}, // B2 6
258  {&DDRB, &PINB, &PORTB, 3}, // B3 7
259  {&DDRD, &PIND, &PORTD, 5}, // D5 8
260  {&DDRD, &PIND, &PORTD, 6}, // D6 9
261  {&DDRB, &PINB, &PORTB, 4}, // B4 10
262  {&DDRB, &PINB, &PORTB, 5}, // B5 11
263  {&DDRB, &PINB, &PORTB, 6}, // B6 12
264  {&DDRB, &PINB, &PORTB, 7}, // B7 13
265  {&DDRA, &PINA, &PORTA, 7}, // A7 14
266  {&DDRA, &PINA, &PORTA, 6}, // A6 15
267  {&DDRA, &PINA, &PORTA, 5}, // A5 16
268  {&DDRA, &PINA, &PORTA, 4}, // A4 17
269  {&DDRA, &PINA, &PORTA, 3}, // A3 18
270  {&DDRA, &PINA, &PORTA, 2}, // A2 19
271  {&DDRA, &PINA, &PORTA, 1}, // A1 20
272  {&DDRA, &PINA, &PORTA, 0}, // A0 21
273  {&DDRC, &PINC, &PORTC, 0}, // C0 22
274  {&DDRC, &PINC, &PORTC, 1}, // C1 23
275  {&DDRC, &PINC, &PORTC, 2}, // C2 24
276  {&DDRC, &PINC, &PORTC, 3}, // C3 25
277  {&DDRC, &PINC, &PORTC, 4}, // C4 26
278  {&DDRC, &PINC, &PORTC, 5}, // C5 27
279  {&DDRC, &PINC, &PORTC, 6}, // C6 28
280  {&DDRC, &PINC, &PORTC, 7}, // C7 29
281  {&DDRD, &PIND, &PORTD, 4}, // D4 30
282  {&DDRD, &PIND, &PORTD, 7} // D7 31
283 };
284 #elif defined(VARIANT_STANDARD)
285 // Standard Layout
286 static const pin_map_t pinMap[] = {
287  {&DDRB, &PINB, &PORTB, 0}, // B0 0
288  {&DDRB, &PINB, &PORTB, 1}, // B1 1
289  {&DDRB, &PINB, &PORTB, 2}, // B2 2
290  {&DDRB, &PINB, &PORTB, 3}, // B3 3
291  {&DDRB, &PINB, &PORTB, 4}, // B4 4
292  {&DDRB, &PINB, &PORTB, 5}, // B5 5
293  {&DDRB, &PINB, &PORTB, 6}, // B6 6
294  {&DDRB, &PINB, &PORTB, 7}, // B7 7
295  {&DDRD, &PIND, &PORTD, 0}, // D0 8
296  {&DDRD, &PIND, &PORTD, 1}, // D1 9
297  {&DDRD, &PIND, &PORTD, 2}, // D2 10
298  {&DDRD, &PIND, &PORTD, 3}, // D3 11
299  {&DDRD, &PIND, &PORTD, 4}, // D4 12
300  {&DDRD, &PIND, &PORTD, 5}, // D5 13
301  {&DDRD, &PIND, &PORTD, 6}, // D6 14
302  {&DDRD, &PIND, &PORTD, 7}, // D7 15
303  {&DDRC, &PINC, &PORTC, 0}, // C0 16
304  {&DDRC, &PINC, &PORTC, 1}, // C1 17
305  {&DDRC, &PINC, &PORTC, 2}, // C2 18
306  {&DDRC, &PINC, &PORTC, 3}, // C3 19
307  {&DDRC, &PINC, &PORTC, 4}, // C4 20
308  {&DDRC, &PINC, &PORTC, 5}, // C5 21
309  {&DDRC, &PINC, &PORTC, 6}, // C6 22
310  {&DDRC, &PINC, &PORTC, 7}, // C7 23
311  {&DDRA, &PINA, &PORTA, 7}, // A7 24
312  {&DDRA, &PINA, &PORTA, 6}, // A6 25
313  {&DDRA, &PINA, &PORTA, 5}, // A5 26
314  {&DDRA, &PINA, &PORTA, 4}, // A4 27
315  {&DDRA, &PINA, &PORTA, 3}, // A3 28
316  {&DDRA, &PINA, &PORTA, 2}, // A2 29
317  {&DDRA, &PINA, &PORTA, 1}, // A1 30
318  {&DDRA, &PINA, &PORTA, 0} // A0 31
319 };
320 #else // VARIANT_MIGHTY
321 #error Undefined variant 1284, 644, 324, 64, 32
322 #endif // VARIANT_MIGHTY
323 //------------------------------------------------------------------------------
324 #elif defined(__AVR_ATmega32U4__)
325 #ifdef CORE_TEENSY
326 // Teensy 2.0
327 static const pin_map_t pinMap[] = {
328  {&DDRB, &PINB, &PORTB, 0}, // B0 0
329  {&DDRB, &PINB, &PORTB, 1}, // B1 1
330  {&DDRB, &PINB, &PORTB, 2}, // B2 2
331  {&DDRB, &PINB, &PORTB, 3}, // B3 3
332  {&DDRB, &PINB, &PORTB, 7}, // B7 4
333  {&DDRD, &PIND, &PORTD, 0}, // D0 5
334  {&DDRD, &PIND, &PORTD, 1}, // D1 6
335  {&DDRD, &PIND, &PORTD, 2}, // D2 7
336  {&DDRD, &PIND, &PORTD, 3}, // D3 8
337  {&DDRC, &PINC, &PORTC, 6}, // C6 9
338  {&DDRC, &PINC, &PORTC, 7}, // C7 10
339  {&DDRD, &PIND, &PORTD, 6}, // D6 11
340  {&DDRD, &PIND, &PORTD, 7}, // D7 12
341  {&DDRB, &PINB, &PORTB, 4}, // B4 13
342  {&DDRB, &PINB, &PORTB, 5}, // B5 14
343  {&DDRB, &PINB, &PORTB, 6}, // B6 15
344  {&DDRF, &PINF, &PORTF, 7}, // F7 16
345  {&DDRF, &PINF, &PORTF, 6}, // F6 17
346  {&DDRF, &PINF, &PORTF, 5}, // F5 18
347  {&DDRF, &PINF, &PORTF, 4}, // F4 19
348  {&DDRF, &PINF, &PORTF, 1}, // F1 20
349  {&DDRF, &PINF, &PORTF, 0}, // F0 21
350  {&DDRD, &PIND, &PORTD, 4}, // D4 22
351  {&DDRD, &PIND, &PORTD, 5}, // D5 23
352  {&DDRE, &PINE, &PORTE, 6} // E6 24
353 };
354 //------------------------------------------------------------------------------
355 #else // CORE_TEENSY
356 // Leonardo
357 static const pin_map_t pinMap[] = {
358  {&DDRD, &PIND, &PORTD, 2}, // D2 0
359  {&DDRD, &PIND, &PORTD, 3}, // D3 1
360  {&DDRD, &PIND, &PORTD, 1}, // D1 2
361  {&DDRD, &PIND, &PORTD, 0}, // D0 3
362  {&DDRD, &PIND, &PORTD, 4}, // D4 4
363  {&DDRC, &PINC, &PORTC, 6}, // C6 5
364  {&DDRD, &PIND, &PORTD, 7}, // D7 6
365  {&DDRE, &PINE, &PORTE, 6}, // E6 7
366  {&DDRB, &PINB, &PORTB, 4}, // B4 8
367  {&DDRB, &PINB, &PORTB, 5}, // B5 9
368  {&DDRB, &PINB, &PORTB, 6}, // B6 10
369  {&DDRB, &PINB, &PORTB, 7}, // B7 11
370  {&DDRD, &PIND, &PORTD, 6}, // D6 12
371  {&DDRC, &PINC, &PORTC, 7}, // C7 13
372  {&DDRB, &PINB, &PORTB, 3}, // B3 14
373  {&DDRB, &PINB, &PORTB, 1}, // B1 15
374  {&DDRB, &PINB, &PORTB, 2}, // B2 16
375  {&DDRB, &PINB, &PORTB, 0}, // B0 17
376  {&DDRF, &PINF, &PORTF, 7}, // F7 18
377  {&DDRF, &PINF, &PORTF, 6}, // F6 19
378  {&DDRF, &PINF, &PORTF, 5}, // F5 20
379  {&DDRF, &PINF, &PORTF, 4}, // F4 21
380  {&DDRF, &PINF, &PORTF, 1}, // F1 22
381  {&DDRF, &PINF, &PORTF, 0}, // F0 23
382  {&DDRD, &PIND, &PORTD, 4}, // D4 24
383  {&DDRD, &PIND, &PORTD, 7}, // D7 25
384  {&DDRB, &PINB, &PORTB, 4}, // B4 26
385  {&DDRB, &PINB, &PORTB, 5}, // B5 27
386  {&DDRB, &PINB, &PORTB, 6}, // B6 28
387  {&DDRD, &PIND, &PORTD, 6} // D6 29
388 };
389 #endif // CORE_TEENSY
390 //------------------------------------------------------------------------------
391 #elif defined(__AVR_AT90USB646__)\
392 || defined(__AVR_AT90USB1286__)
393 // Teensy++ 1.0 & 2.0
394 static const pin_map_t pinMap[] = {
395  {&DDRD, &PIND, &PORTD, 0}, // D0 0
396  {&DDRD, &PIND, &PORTD, 1}, // D1 1
397  {&DDRD, &PIND, &PORTD, 2}, // D2 2
398  {&DDRD, &PIND, &PORTD, 3}, // D3 3
399  {&DDRD, &PIND, &PORTD, 4}, // D4 4
400  {&DDRD, &PIND, &PORTD, 5}, // D5 5
401  {&DDRD, &PIND, &PORTD, 6}, // D6 6
402  {&DDRD, &PIND, &PORTD, 7}, // D7 7
403  {&DDRE, &PINE, &PORTE, 0}, // E0 8
404  {&DDRE, &PINE, &PORTE, 1}, // E1 9
405  {&DDRC, &PINC, &PORTC, 0}, // C0 10
406  {&DDRC, &PINC, &PORTC, 1}, // C1 11
407  {&DDRC, &PINC, &PORTC, 2}, // C2 12
408  {&DDRC, &PINC, &PORTC, 3}, // C3 13
409  {&DDRC, &PINC, &PORTC, 4}, // C4 14
410  {&DDRC, &PINC, &PORTC, 5}, // C5 15
411  {&DDRC, &PINC, &PORTC, 6}, // C6 16
412  {&DDRC, &PINC, &PORTC, 7}, // C7 17
413  {&DDRE, &PINE, &PORTE, 6}, // E6 18
414  {&DDRE, &PINE, &PORTE, 7}, // E7 19
415  {&DDRB, &PINB, &PORTB, 0}, // B0 20
416  {&DDRB, &PINB, &PORTB, 1}, // B1 21
417  {&DDRB, &PINB, &PORTB, 2}, // B2 22
418  {&DDRB, &PINB, &PORTB, 3}, // B3 23
419  {&DDRB, &PINB, &PORTB, 4}, // B4 24
420  {&DDRB, &PINB, &PORTB, 5}, // B5 25
421  {&DDRB, &PINB, &PORTB, 6}, // B6 26
422  {&DDRB, &PINB, &PORTB, 7}, // B7 27
423  {&DDRA, &PINA, &PORTA, 0}, // A0 28
424  {&DDRA, &PINA, &PORTA, 1}, // A1 29
425  {&DDRA, &PINA, &PORTA, 2}, // A2 30
426  {&DDRA, &PINA, &PORTA, 3}, // A3 31
427  {&DDRA, &PINA, &PORTA, 4}, // A4 32
428  {&DDRA, &PINA, &PORTA, 5}, // A5 33
429  {&DDRA, &PINA, &PORTA, 6}, // A6 34
430  {&DDRA, &PINA, &PORTA, 7}, // A7 35
431  {&DDRE, &PINE, &PORTE, 4}, // E4 36
432  {&DDRE, &PINE, &PORTE, 5}, // E5 37
433  {&DDRF, &PINF, &PORTF, 0}, // F0 38
434  {&DDRF, &PINF, &PORTF, 1}, // F1 39
435  {&DDRF, &PINF, &PORTF, 2}, // F2 40
436  {&DDRF, &PINF, &PORTF, 3}, // F3 41
437  {&DDRF, &PINF, &PORTF, 4}, // F4 42
438  {&DDRF, &PINF, &PORTF, 5}, // F5 43
439  {&DDRF, &PINF, &PORTF, 6}, // F6 44
440  {&DDRF, &PINF, &PORTF, 7} // F7 45
441 };
442 //------------------------------------------------------------------------------
443 #else // CPU type
444 #error unknown CPU type
445 #endif // CPU type
446 //------------------------------------------------------------------------------
448 static const uint8_t digitalPinCount = sizeof(pinMap)/sizeof(pin_map_t);
449 //==============================================================================
451 void badPinNumber(void)
452  __attribute__((error("Pin number is too large or not a constant")));
453 //------------------------------------------------------------------------------
457 static inline __attribute__((always_inline))
458 void badPinCheck(uint8_t pin) {
459  if (!__builtin_constant_p(pin) || pin >= digitalPinCount) {
460  badPinNumber();
461  }
462 }
463 //------------------------------------------------------------------------------
469 static inline __attribute__((always_inline))
470 void fastBitWriteSafe(volatile uint8_t* address, uint8_t bit, bool level) {
471  uint8_t oldSREG;
472  if (address > (uint8_t*)0X5F) {
473  oldSREG = SREG;
474  cli();
475  }
476  if (level) {
477  *address |= 1 << bit;
478  } else {
479  *address &= ~(1 << bit);
480  }
481  if (address > (uint8_t*)0X5F) {
482  SREG = oldSREG;
483  }
484 }
485 //------------------------------------------------------------------------------
490 static inline __attribute__((always_inline))
491 bool fastDigitalRead(uint8_t pin) {
492  badPinCheck(pin);
493  return (*pinMap[pin].pin >> pinMap[pin].bit) & 1;
494 }
495 //------------------------------------------------------------------------------
502 static inline __attribute__((always_inline))
503 void fastDigitalToggle(uint8_t pin) {
504  badPinCheck(pin);
505  if (pinMap[pin].pin > (uint8_t*)0X5F) {
506  // must write bit to high address port
507  *pinMap[pin].pin = 1 << pinMap[pin].bit;
508  } else {
509  // will compile to sbi and PIN register will not be read.
510  *pinMap[pin].pin |= 1 << pinMap[pin].bit;
511  }
512 }
513 //------------------------------------------------------------------------------
518 static inline __attribute__((always_inline))
519 void fastDigitalWrite(uint8_t pin, bool level) {
520  badPinCheck(pin);
521  fastBitWriteSafe(pinMap[pin].port, pinMap[pin].bit, level);
522 }
523 //------------------------------------------------------------------------------
530 static inline __attribute__((always_inline))
531 void fastPinMode(uint8_t pin, bool mode) {
532  badPinCheck(pin);
533  fastBitWriteSafe(pinMap[pin].ddr, pinMap[pin].bit, mode);
534 }
535 
536 #endif // __arm__
537 //------------------------------------------------------------------------------
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 //==============================================================================
554 template<uint8_t PinNumber>
555 class DigitalPin {
556  public:
557  //----------------------------------------------------------------------------
560  //----------------------------------------------------------------------------
564  explicit DigitalPin(bool pinMode) {
565  mode(pinMode);
566  }
567  //----------------------------------------------------------------------------
573  DigitalPin(bool mode, bool level) {
574  config(mode, level);
575  }
576  //----------------------------------------------------------------------------
583  inline DigitalPin & operator = (bool value) __attribute__((always_inline)) {
584  write(value);
585  return *this;
586  }
587  //----------------------------------------------------------------------------
591  inline operator bool () const __attribute__((always_inline)) {
592  return read();
593  }
594  //----------------------------------------------------------------------------
600  inline __attribute__((always_inline))
601  void config(bool mode, bool level) {
602  fastPinConfig(PinNumber, mode, level);
603  }
604  //----------------------------------------------------------------------------
608  inline __attribute__((always_inline))
609  void high() {write(true);}
610  //----------------------------------------------------------------------------
614  inline __attribute__((always_inline))
615  void low() {write(false);}
616  //----------------------------------------------------------------------------
623  inline __attribute__((always_inline))
624  void mode(bool pinMode) {
625  fastPinMode(PinNumber, pinMode);
626  }
627  //----------------------------------------------------------------------------
629  inline __attribute__((always_inline))
630  bool read() const {
631  return fastDigitalRead(PinNumber);
632  }
633  //----------------------------------------------------------------------------
639  inline __attribute__((always_inline))
640  void toggle() {
641  fastDigitalToggle(PinNumber);
642  }
643  //----------------------------------------------------------------------------
648  inline __attribute__((always_inline))
649  void write(bool value) {
650  fastDigitalWrite(PinNumber, value);
651  }
652 };
653 #endif // DigitalPin_h
static const uint8_t digitalPinCount
Definition: DigitalPin.h:448
volatile uint8_t * ddr
Definition: DigitalPin.h:94
volatile uint8_t * port
Definition: DigitalPin.h:96
void write(bool value)
Definition: DigitalPin.h:649
void low()
Definition: DigitalPin.h:615
bool read() const
Definition: DigitalPin.h:630
DigitalPin & operator=(bool value)
Definition: DigitalPin.h:583
static void fastBitWriteSafe(volatile uint8_t *address, uint8_t bit, bool level)
Definition: DigitalPin.h:470
void config(bool mode, bool level)
Definition: DigitalPin.h:601
uint8_t bit
Definition: DigitalPin.h:97
static void fastPinMode(uint8_t pin, bool mode)
Definition: DigitalPin.h:531
DigitalPin(bool mode, bool level)
Definition: DigitalPin.h:573
Fast digital port I/O.
Definition: DigitalPin.h:555
static void fastDigitalWrite(uint8_t pin, bool level)
Definition: DigitalPin.h:519
DigitalPin(bool pinMode)
Definition: DigitalPin.h:564
static bool fastDigitalRead(uint8_t pin)
Definition: DigitalPin.h:491
void high()
Definition: DigitalPin.h:609
void badPinNumber(void)
static void fastDigitalToggle(uint8_t pin)
Definition: DigitalPin.h:503
void mode(bool pinMode)
Definition: DigitalPin.h:624
static void badPinCheck(uint8_t pin)
Definition: DigitalPin.h:458
static void fastPinConfig(uint8_t pin, bool mode, bool level)
Definition: DigitalPin.h:545
volatile uint8_t * pin
Definition: DigitalPin.h:95
void toggle()
Definition: DigitalPin.h:640
struct for mapping digital pins
Definition: DigitalPin.h:93