Digital IO
|
00001 /* Arduino DigitalIO Library 00002 * Copyright (C) 2013 by William Greiman 00003 * 00004 * This file is part of the Arduino DigitalIO Library 00005 * 00006 * This Library is free software: you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation, either version 3 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This Library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with the Arduino DigitalIO Library. If not, see 00018 * <http://www.gnu.org/licenses/>. 00019 */ 00028 #ifndef DigitalPin_h 00029 #define DigitalPin_h 00030 #include <avr/io.h> 00031 #include <util/atomic.h> 00032 #include <Arduino.h> 00033 //------------------------------------------------------------------------------ 00038 struct pin_map_t { 00039 volatile uint8_t* ddr; 00040 volatile uint8_t* pin; 00041 volatile uint8_t* port; 00042 uint8_t bit; 00043 }; 00044 //------------------------------------------------------------------------------ 00045 #if defined(__AVR_ATmega168__)\ 00046 ||defined(__AVR_ATmega168P__)\ 00047 ||defined(__AVR_ATmega328P__) 00048 // 168 and 328 Arduinos 00049 const static pin_map_t pinMap[] = { 00050 {&DDRD, &PIND, &PORTD, 0}, // D0 0 00051 {&DDRD, &PIND, &PORTD, 1}, // D1 1 00052 {&DDRD, &PIND, &PORTD, 2}, // D2 2 00053 {&DDRD, &PIND, &PORTD, 3}, // D3 3 00054 {&DDRD, &PIND, &PORTD, 4}, // D4 4 00055 {&DDRD, &PIND, &PORTD, 5}, // D5 5 00056 {&DDRD, &PIND, &PORTD, 6}, // D6 6 00057 {&DDRD, &PIND, &PORTD, 7}, // D7 7 00058 {&DDRB, &PINB, &PORTB, 0}, // B0 8 00059 {&DDRB, &PINB, &PORTB, 1}, // B1 9 00060 {&DDRB, &PINB, &PORTB, 2}, // B2 10 00061 {&DDRB, &PINB, &PORTB, 3}, // B3 11 00062 {&DDRB, &PINB, &PORTB, 4}, // B4 12 00063 {&DDRB, &PINB, &PORTB, 5}, // B5 13 00064 {&DDRC, &PINC, &PORTC, 0}, // C0 14 00065 {&DDRC, &PINC, &PORTC, 1}, // C1 15 00066 {&DDRC, &PINC, &PORTC, 2}, // C2 16 00067 {&DDRC, &PINC, &PORTC, 3}, // C3 17 00068 {&DDRC, &PINC, &PORTC, 4}, // C4 18 00069 {&DDRC, &PINC, &PORTC, 5} // C5 19 00070 }; 00071 //------------------------------------------------------------------------------ 00072 #elif defined(__AVR_ATmega1280__)\ 00073 || defined(__AVR_ATmega2560__) 00074 // Mega 00075 static const pin_map_t pinMap[] = { 00076 {&DDRE, &PINE, &PORTE, 0}, // E0 0 00077 {&DDRE, &PINE, &PORTE, 1}, // E1 1 00078 {&DDRE, &PINE, &PORTE, 4}, // E4 2 00079 {&DDRE, &PINE, &PORTE, 5}, // E5 3 00080 {&DDRG, &PING, &PORTG, 5}, // G5 4 00081 {&DDRE, &PINE, &PORTE, 3}, // E3 5 00082 {&DDRH, &PINH, &PORTH, 3}, // H3 6 00083 {&DDRH, &PINH, &PORTH, 4}, // H4 7 00084 {&DDRH, &PINH, &PORTH, 5}, // H5 8 00085 {&DDRH, &PINH, &PORTH, 6}, // H6 9 00086 {&DDRB, &PINB, &PORTB, 4}, // B4 10 00087 {&DDRB, &PINB, &PORTB, 5}, // B5 11 00088 {&DDRB, &PINB, &PORTB, 6}, // B6 12 00089 {&DDRB, &PINB, &PORTB, 7}, // B7 13 00090 {&DDRJ, &PINJ, &PORTJ, 1}, // J1 14 00091 {&DDRJ, &PINJ, &PORTJ, 0}, // J0 15 00092 {&DDRH, &PINH, &PORTH, 1}, // H1 16 00093 {&DDRH, &PINH, &PORTH, 0}, // H0 17 00094 {&DDRD, &PIND, &PORTD, 3}, // D3 18 00095 {&DDRD, &PIND, &PORTD, 2}, // D2 19 00096 {&DDRD, &PIND, &PORTD, 1}, // D1 20 00097 {&DDRD, &PIND, &PORTD, 0}, // D0 21 00098 {&DDRA, &PINA, &PORTA, 0}, // A0 22 00099 {&DDRA, &PINA, &PORTA, 1}, // A1 23 00100 {&DDRA, &PINA, &PORTA, 2}, // A2 24 00101 {&DDRA, &PINA, &PORTA, 3}, // A3 25 00102 {&DDRA, &PINA, &PORTA, 4}, // A4 26 00103 {&DDRA, &PINA, &PORTA, 5}, // A5 27 00104 {&DDRA, &PINA, &PORTA, 6}, // A6 28 00105 {&DDRA, &PINA, &PORTA, 7}, // A7 29 00106 {&DDRC, &PINC, &PORTC, 7}, // C7 30 00107 {&DDRC, &PINC, &PORTC, 6}, // C6 31 00108 {&DDRC, &PINC, &PORTC, 5}, // C5 32 00109 {&DDRC, &PINC, &PORTC, 4}, // C4 33 00110 {&DDRC, &PINC, &PORTC, 3}, // C3 34 00111 {&DDRC, &PINC, &PORTC, 2}, // C2 35 00112 {&DDRC, &PINC, &PORTC, 1}, // C1 36 00113 {&DDRC, &PINC, &PORTC, 0}, // C0 37 00114 {&DDRD, &PIND, &PORTD, 7}, // D7 38 00115 {&DDRG, &PING, &PORTG, 2}, // G2 39 00116 {&DDRG, &PING, &PORTG, 1}, // G1 40 00117 {&DDRG, &PING, &PORTG, 0}, // G0 41 00118 {&DDRL, &PINL, &PORTL, 7}, // L7 42 00119 {&DDRL, &PINL, &PORTL, 6}, // L6 43 00120 {&DDRL, &PINL, &PORTL, 5}, // L5 44 00121 {&DDRL, &PINL, &PORTL, 4}, // L4 45 00122 {&DDRL, &PINL, &PORTL, 3}, // L3 46 00123 {&DDRL, &PINL, &PORTL, 2}, // L2 47 00124 {&DDRL, &PINL, &PORTL, 1}, // L1 48 00125 {&DDRL, &PINL, &PORTL, 0}, // L0 49 00126 {&DDRB, &PINB, &PORTB, 3}, // B3 50 00127 {&DDRB, &PINB, &PORTB, 2}, // B2 51 00128 {&DDRB, &PINB, &PORTB, 1}, // B1 52 00129 {&DDRB, &PINB, &PORTB, 0}, // B0 53 00130 {&DDRF, &PINF, &PORTF, 0}, // F0 54 00131 {&DDRF, &PINF, &PORTF, 1}, // F1 55 00132 {&DDRF, &PINF, &PORTF, 2}, // F2 56 00133 {&DDRF, &PINF, &PORTF, 3}, // F3 57 00134 {&DDRF, &PINF, &PORTF, 4}, // F4 58 00135 {&DDRF, &PINF, &PORTF, 5}, // F5 59 00136 {&DDRF, &PINF, &PORTF, 6}, // F6 60 00137 {&DDRF, &PINF, &PORTF, 7}, // F7 61 00138 {&DDRK, &PINK, &PORTK, 0}, // K0 62 00139 {&DDRK, &PINK, &PORTK, 1}, // K1 63 00140 {&DDRK, &PINK, &PORTK, 2}, // K2 64 00141 {&DDRK, &PINK, &PORTK, 3}, // K3 65 00142 {&DDRK, &PINK, &PORTK, 4}, // K4 66 00143 {&DDRK, &PINK, &PORTK, 5}, // K5 67 00144 {&DDRK, &PINK, &PORTK, 6}, // K6 68 00145 {&DDRK, &PINK, &PORTK, 7} // K7 69 00146 }; 00147 //------------------------------------------------------------------------------ 00148 #elif defined(__AVR_ATmega1284P__)\ 00149 || defined(__AVR_ATmega1284__)\ 00150 || defined(__AVR_ATmega644P__)\ 00151 || defined(__AVR_ATmega644__)\ 00152 || defined(__AVR_ATmega64__)\ 00153 || defined(__AVR_ATmega32__)\ 00154 || defined(__AVR_ATmega324__)\ 00155 || defined(__AVR_ATmega16__) 00156 00157 #ifdef defined(VARIANT_MIGHTY) 00158 // Mighty Layout 00159 static const pin_map_t pinMap[] = { 00160 {&DDRB, &PINB, &PORTB, 0}, // B0 0 00161 {&DDRB, &PINB, &PORTB, 1}, // B1 1 00162 {&DDRB, &PINB, &PORTB, 2}, // B2 2 00163 {&DDRB, &PINB, &PORTB, 3}, // B3 3 00164 {&DDRB, &PINB, &PORTB, 4}, // B4 4 00165 {&DDRB, &PINB, &PORTB, 5}, // B5 5 00166 {&DDRB, &PINB, &PORTB, 6}, // B6 6 00167 {&DDRB, &PINB, &PORTB, 7}, // B7 7 00168 {&DDRD, &PIND, &PORTD, 0}, // D0 8 00169 {&DDRD, &PIND, &PORTD, 1}, // D1 9 00170 {&DDRD, &PIND, &PORTD, 2}, // D2 10 00171 {&DDRD, &PIND, &PORTD, 3}, // D3 11 00172 {&DDRD, &PIND, &PORTD, 4}, // D4 12 00173 {&DDRD, &PIND, &PORTD, 5}, // D5 13 00174 {&DDRD, &PIND, &PORTD, 6}, // D6 14 00175 {&DDRD, &PIND, &PORTD, 7}, // D7 15 00176 {&DDRC, &PINC, &PORTC, 0}, // C0 16 00177 {&DDRC, &PINC, &PORTC, 1}, // C1 17 00178 {&DDRC, &PINC, &PORTC, 2}, // C2 18 00179 {&DDRC, &PINC, &PORTC, 3}, // C3 19 00180 {&DDRC, &PINC, &PORTC, 4}, // C4 20 00181 {&DDRC, &PINC, &PORTC, 5}, // C5 21 00182 {&DDRC, &PINC, &PORTC, 6}, // C6 22 00183 {&DDRC, &PINC, &PORTC, 7}, // C7 23 00184 {&DDRA, &PINA, &PORTA, 0}, // A0 24 00185 {&DDRA, &PINA, &PORTA, 1}, // A1 25 00186 {&DDRA, &PINA, &PORTA, 2}, // A2 26 00187 {&DDRA, &PINA, &PORTA, 3}, // A3 27 00188 {&DDRA, &PINA, &PORTA, 4}, // A4 28 00189 {&DDRA, &PINA, &PORTA, 5}, // A5 29 00190 {&DDRA, &PINA, &PORTA, 6}, // A6 30 00191 {&DDRA, &PINA, &PORTA, 7} // A7 31 00192 }; 00193 #elif defined(VARIANT_BOBUINO) 00194 // Bobuino Layout 00195 static const pin_map_t pinMap[] = { 00196 {&DDRD, &PIND, &PORTD, 0}, // D0 0 00197 {&DDRD, &PIND, &PORTD, 1}, // D1 1 00198 {&DDRD, &PIND, &PORTD, 2}, // D2 2 00199 {&DDRD, &PIND, &PORTD, 3}, // D3 3 00200 {&DDRB, &PINB, &PORTB, 0}, // B0 4 00201 {&DDRB, &PINB, &PORTB, 1}, // B1 5 00202 {&DDRB, &PINB, &PORTB, 2}, // B2 6 00203 {&DDRB, &PINB, &PORTB, 3}, // B3 7 00204 {&DDRD, &PIND, &PORTD, 5}, // D5 8 00205 {&DDRD, &PIND, &PORTD, 6}, // D6 9 00206 {&DDRB, &PINB, &PORTB, 4}, // B4 10 00207 {&DDRB, &PINB, &PORTB, 5}, // B5 11 00208 {&DDRB, &PINB, &PORTB, 6}, // B6 12 00209 {&DDRB, &PINB, &PORTB, 7}, // B7 13 00210 {&DDRA, &PINA, &PORTA, 7}, // A7 14 00211 {&DDRA, &PINA, &PORTA, 6}, // A6 15 00212 {&DDRA, &PINA, &PORTA, 5}, // A5 16 00213 {&DDRA, &PINA, &PORTA, 4}, // A4 17 00214 {&DDRA, &PINA, &PORTA, 3}, // A3 18 00215 {&DDRA, &PINA, &PORTA, 2}, // A2 19 00216 {&DDRA, &PINA, &PORTA, 1}, // A1 20 00217 {&DDRA, &PINA, &PORTA, 0}, // A0 21 00218 {&DDRC, &PINC, &PORTC, 0}, // C0 22 00219 {&DDRC, &PINC, &PORTC, 1}, // C1 23 00220 {&DDRC, &PINC, &PORTC, 2}, // C2 24 00221 {&DDRC, &PINC, &PORTC, 3}, // C3 25 00222 {&DDRC, &PINC, &PORTC, 4}, // C4 26 00223 {&DDRC, &PINC, &PORTC, 5}, // C5 27 00224 {&DDRC, &PINC, &PORTC, 6}, // C6 28 00225 {&DDRC, &PINC, &PORTC, 7}, // C7 29 00226 {&DDRD, &PIND, &PORTD, 4}, // D4 30 00227 {&DDRD, &PIND, &PORTD, 7} // D7 31 00228 }; 00229 #elif defined(VARIANT_STANDARD) 00230 // Standard Layout 00231 static const pin_map_t pinMap[] = { 00232 {&DDRB, &PINB, &PORTB, 0}, // B0 0 00233 {&DDRB, &PINB, &PORTB, 1}, // B1 1 00234 {&DDRB, &PINB, &PORTB, 2}, // B2 2 00235 {&DDRB, &PINB, &PORTB, 3}, // B3 3 00236 {&DDRB, &PINB, &PORTB, 4}, // B4 4 00237 {&DDRB, &PINB, &PORTB, 5}, // B5 5 00238 {&DDRB, &PINB, &PORTB, 6}, // B6 6 00239 {&DDRB, &PINB, &PORTB, 7}, // B7 7 00240 {&DDRD, &PIND, &PORTD, 0}, // D0 8 00241 {&DDRD, &PIND, &PORTD, 1}, // D1 9 00242 {&DDRD, &PIND, &PORTD, 2}, // D2 10 00243 {&DDRD, &PIND, &PORTD, 3}, // D3 11 00244 {&DDRD, &PIND, &PORTD, 4}, // D4 12 00245 {&DDRD, &PIND, &PORTD, 5}, // D5 13 00246 {&DDRD, &PIND, &PORTD, 6}, // D6 14 00247 {&DDRD, &PIND, &PORTD, 7}, // D7 15 00248 {&DDRC, &PINC, &PORTC, 0}, // C0 16 00249 {&DDRC, &PINC, &PORTC, 1}, // C1 17 00250 {&DDRC, &PINC, &PORTC, 2}, // C2 18 00251 {&DDRC, &PINC, &PORTC, 3}, // C3 19 00252 {&DDRC, &PINC, &PORTC, 4}, // C4 20 00253 {&DDRC, &PINC, &PORTC, 5}, // C5 21 00254 {&DDRC, &PINC, &PORTC, 6}, // C6 22 00255 {&DDRC, &PINC, &PORTC, 7}, // C7 23 00256 {&DDRA, &PINA, &PORTA, 7}, // A7 24 00257 {&DDRA, &PINA, &PORTA, 6}, // A6 25 00258 {&DDRA, &PINA, &PORTA, 5}, // A5 26 00259 {&DDRA, &PINA, &PORTA, 4}, // A4 27 00260 {&DDRA, &PINA, &PORTA, 3}, // A3 28 00261 {&DDRA, &PINA, &PORTA, 2}, // A2 29 00262 {&DDRA, &PINA, &PORTA, 1}, // A1 30 00263 {&DDRA, &PINA, &PORTA, 0} // A0 31 00264 }; 00265 #else // VARIANT_MIGHTY 00266 #error Undefined variant 1284, 644, 324, 64, 32 00267 #endif // VARIANT_MIGHTY 00268 //------------------------------------------------------------------------------ 00269 #elif defined(__AVR_ATmega32U4__) 00270 #ifdef CORE_TEENSY 00271 // Teensy 2.0 00272 static const pin_map_t pinMap[] = { 00273 {&DDRB, &PINB, &PORTB, 0}, // B0 0 00274 {&DDRB, &PINB, &PORTB, 1}, // B1 1 00275 {&DDRB, &PINB, &PORTB, 2}, // B2 2 00276 {&DDRB, &PINB, &PORTB, 3}, // B3 3 00277 {&DDRB, &PINB, &PORTB, 7}, // B7 4 00278 {&DDRD, &PIND, &PORTD, 0}, // D0 5 00279 {&DDRD, &PIND, &PORTD, 1}, // D1 6 00280 {&DDRD, &PIND, &PORTD, 2}, // D2 7 00281 {&DDRD, &PIND, &PORTD, 3}, // D3 8 00282 {&DDRC, &PINC, &PORTC, 6}, // C6 9 00283 {&DDRC, &PINC, &PORTC, 7}, // C7 10 00284 {&DDRD, &PIND, &PORTD, 6}, // D6 11 00285 {&DDRD, &PIND, &PORTD, 7}, // D7 12 00286 {&DDRB, &PINB, &PORTB, 4}, // B4 13 00287 {&DDRB, &PINB, &PORTB, 5}, // B5 14 00288 {&DDRB, &PINB, &PORTB, 6}, // B6 15 00289 {&DDRF, &PINF, &PORTF, 7}, // F7 16 00290 {&DDRF, &PINF, &PORTF, 6}, // F6 17 00291 {&DDRF, &PINF, &PORTF, 5}, // F5 18 00292 {&DDRF, &PINF, &PORTF, 4}, // F4 19 00293 {&DDRF, &PINF, &PORTF, 1}, // F1 20 00294 {&DDRF, &PINF, &PORTF, 0}, // F0 21 00295 {&DDRD, &PIND, &PORTD, 4}, // D4 22 00296 {&DDRD, &PIND, &PORTD, 5}, // D5 23 00297 {&DDRE, &PINE, &PORTE, 6} // E6 24 00298 }; 00299 //------------------------------------------------------------------------------ 00300 #else // CORE_TEENSY 00301 // Leonardo 00302 static const pin_map_t pinMap[] = { 00303 {&DDRD, &PIND, &PORTD, 2}, // D2 0 00304 {&DDRD, &PIND, &PORTD, 3}, // D3 1 00305 {&DDRD, &PIND, &PORTD, 1}, // D1 2 00306 {&DDRD, &PIND, &PORTD, 0}, // D0 3 00307 {&DDRD, &PIND, &PORTD, 4}, // D4 4 00308 {&DDRC, &PINC, &PORTC, 6}, // C6 5 00309 {&DDRD, &PIND, &PORTD, 7}, // D7 6 00310 {&DDRE, &PINE, &PORTE, 6}, // E6 7 00311 {&DDRB, &PINB, &PORTB, 4}, // B4 8 00312 {&DDRB, &PINB, &PORTB, 5}, // B5 9 00313 {&DDRB, &PINB, &PORTB, 6}, // B6 10 00314 {&DDRB, &PINB, &PORTB, 7}, // B7 11 00315 {&DDRD, &PIND, &PORTD, 6}, // D6 12 00316 {&DDRC, &PINC, &PORTC, 7}, // C7 13 00317 {&DDRB, &PINB, &PORTB, 3}, // B3 14 00318 {&DDRB, &PINB, &PORTB, 1}, // B1 15 00319 {&DDRB, &PINB, &PORTB, 2}, // B2 16 00320 {&DDRB, &PINB, &PORTB, 0}, // B0 17 00321 {&DDRF, &PINF, &PORTF, 7}, // F7 18 00322 {&DDRF, &PINF, &PORTF, 6}, // F6 19 00323 {&DDRF, &PINF, &PORTF, 5}, // F5 20 00324 {&DDRF, &PINF, &PORTF, 4}, // F4 21 00325 {&DDRF, &PINF, &PORTF, 1}, // F1 22 00326 {&DDRF, &PINF, &PORTF, 0}, // F0 23 00327 {&DDRD, &PIND, &PORTD, 4}, // D4 24 00328 {&DDRD, &PIND, &PORTD, 7}, // D7 25 00329 {&DDRB, &PINB, &PORTB, 4}, // B4 26 00330 {&DDRB, &PINB, &PORTB, 5}, // B5 27 00331 {&DDRB, &PINB, &PORTB, 6}, // B6 28 00332 {&DDRD, &PIND, &PORTD, 6} // D6 29 00333 }; 00334 #endif // CORE_TEENSY 00335 //------------------------------------------------------------------------------ 00336 #elif defined(__AVR_AT90USB646__)\ 00337 || defined(__AVR_AT90USB1286__) 00338 // Teensy++ 1.0 & 2.0 00339 static const pin_map_t pinMap[] = { 00340 {&DDRD, &PIND, &PORTD, 0}, // D0 0 00341 {&DDRD, &PIND, &PORTD, 1}, // D1 1 00342 {&DDRD, &PIND, &PORTD, 2}, // D2 2 00343 {&DDRD, &PIND, &PORTD, 3}, // D3 3 00344 {&DDRD, &PIND, &PORTD, 4}, // D4 4 00345 {&DDRD, &PIND, &PORTD, 5}, // D5 5 00346 {&DDRD, &PIND, &PORTD, 6}, // D6 6 00347 {&DDRD, &PIND, &PORTD, 7}, // D7 7 00348 {&DDRE, &PINE, &PORTE, 0}, // E0 8 00349 {&DDRE, &PINE, &PORTE, 1}, // E1 9 00350 {&DDRC, &PINC, &PORTC, 0}, // C0 10 00351 {&DDRC, &PINC, &PORTC, 1}, // C1 11 00352 {&DDRC, &PINC, &PORTC, 2}, // C2 12 00353 {&DDRC, &PINC, &PORTC, 3}, // C3 13 00354 {&DDRC, &PINC, &PORTC, 4}, // C4 14 00355 {&DDRC, &PINC, &PORTC, 5}, // C5 15 00356 {&DDRC, &PINC, &PORTC, 6}, // C6 16 00357 {&DDRC, &PINC, &PORTC, 7}, // C7 17 00358 {&DDRE, &PINE, &PORTE, 6}, // E6 18 00359 {&DDRE, &PINE, &PORTE, 7}, // E7 19 00360 {&DDRB, &PINB, &PORTB, 0}, // B0 20 00361 {&DDRB, &PINB, &PORTB, 1}, // B1 21 00362 {&DDRB, &PINB, &PORTB, 2}, // B2 22 00363 {&DDRB, &PINB, &PORTB, 3}, // B3 23 00364 {&DDRB, &PINB, &PORTB, 4}, // B4 24 00365 {&DDRB, &PINB, &PORTB, 5}, // B5 25 00366 {&DDRB, &PINB, &PORTB, 6}, // B6 26 00367 {&DDRB, &PINB, &PORTB, 7}, // B7 27 00368 {&DDRA, &PINA, &PORTA, 0}, // A0 28 00369 {&DDRA, &PINA, &PORTA, 1}, // A1 29 00370 {&DDRA, &PINA, &PORTA, 2}, // A2 30 00371 {&DDRA, &PINA, &PORTA, 3}, // A3 31 00372 {&DDRA, &PINA, &PORTA, 4}, // A4 32 00373 {&DDRA, &PINA, &PORTA, 5}, // A5 33 00374 {&DDRA, &PINA, &PORTA, 6}, // A6 34 00375 {&DDRA, &PINA, &PORTA, 7}, // A7 35 00376 {&DDRE, &PINE, &PORTE, 4}, // E4 36 00377 {&DDRE, &PINE, &PORTE, 5}, // E5 37 00378 {&DDRF, &PINF, &PORTF, 0}, // F0 38 00379 {&DDRF, &PINF, &PORTF, 1}, // F1 39 00380 {&DDRF, &PINF, &PORTF, 2}, // F2 40 00381 {&DDRF, &PINF, &PORTF, 3}, // F3 41 00382 {&DDRF, &PINF, &PORTF, 4}, // F4 42 00383 {&DDRF, &PINF, &PORTF, 5}, // F5 43 00384 {&DDRF, &PINF, &PORTF, 6}, // F6 44 00385 {&DDRF, &PINF, &PORTF, 7} // F7 45 00386 }; 00387 //------------------------------------------------------------------------------ 00388 #else // CPU type 00389 #error unknown CPU type 00390 #endif // CPU type 00391 //------------------------------------------------------------------------------ 00393 static const uint8_t digitalPinCount = sizeof(pinMap)/sizeof(pin_map_t); 00394 //============================================================================== 00396 void badPinNumber(void) 00397 __attribute__((error("Pin number is too large or not a constant"))); 00398 //------------------------------------------------------------------------------ 00402 static inline __attribute__((always_inline)) 00403 void badPinCheck(uint8_t pin) { 00404 if (!__builtin_constant_p(pin) || pin >= digitalPinCount) { 00405 badPinNumber(); 00406 } 00407 } 00408 //------------------------------------------------------------------------------ 00414 static inline __attribute__((always_inline)) 00415 void fastBitWriteSafe(volatile uint8_t* address, uint8_t bit, bool level) { 00416 uint8_t oldSREG; 00417 if (address > (uint8_t*)0X5F) { 00418 oldSREG = SREG; 00419 cli(); 00420 } 00421 if (level) { 00422 *address |= 1 << bit; 00423 } else { 00424 *address &= ~(1 << bit); 00425 } 00426 if (address > (uint8_t*)0X5F) { 00427 SREG = oldSREG; 00428 } 00429 } 00430 //------------------------------------------------------------------------------ 00435 static inline __attribute__((always_inline)) 00436 bool fastDigitalRead(uint8_t pin) { 00437 badPinCheck(pin); 00438 return (*pinMap[pin].pin >> pinMap[pin].bit) & 1; 00439 } 00440 //------------------------------------------------------------------------------ 00447 static inline __attribute__((always_inline)) 00448 void fastDigitalToggle(uint8_t pin) { 00449 badPinCheck(pin); 00450 if (pinMap[pin].pin > (uint8_t*)0X5F) { 00451 // must write bit to high address port 00452 *pinMap[pin].pin = 1 << pinMap[pin].bit; 00453 } else { 00454 // will compile to sbi and PIN register will not be read. 00455 *pinMap[pin].pin |= 1 << pinMap[pin].bit; 00456 } 00457 } 00458 //------------------------------------------------------------------------------ 00463 static inline __attribute__((always_inline)) 00464 void fastDigitalWrite(uint8_t pin, bool level) { 00465 badPinCheck(pin); 00466 fastBitWriteSafe(pinMap[pin].port, pinMap[pin].bit, level); 00467 } 00468 //------------------------------------------------------------------------------ 00475 static inline __attribute__((always_inline)) 00476 void fastPinMode(uint8_t pin, bool mode) { 00477 badPinCheck(pin); 00478 fastBitWriteSafe(pinMap[pin].ddr, pinMap[pin].bit, mode); 00479 } 00480 //------------------------------------------------------------------------------ 00487 static inline __attribute__((always_inline)) 00488 void fastPinConfig(uint8_t pin, bool mode, bool level) { 00489 fastPinMode(pin, mode); 00490 fastDigitalWrite(pin, level); 00491 } 00492 //============================================================================== 00497 template<uint8_t PinNumber> 00498 class DigitalPin { 00499 public: 00500 //---------------------------------------------------------------------------- 00502 DigitalPin() {} 00503 //---------------------------------------------------------------------------- 00507 explicit DigitalPin(bool pinMode) { 00508 mode(pinMode); 00509 } 00510 //---------------------------------------------------------------------------- 00516 DigitalPin(bool mode, bool level) { 00517 config(mode, level); 00518 } 00519 //---------------------------------------------------------------------------- 00526 inline DigitalPin & operator = (bool value) __attribute__((always_inline)) { 00527 write(value); 00528 return *this; 00529 } 00530 //---------------------------------------------------------------------------- 00534 inline operator bool () const __attribute__((always_inline)) { 00535 return read(); 00536 } 00537 //---------------------------------------------------------------------------- 00543 inline __attribute__((always_inline)) 00544 void config(bool mode, bool level) { 00545 fastPinConfig(PinNumber, mode, level); 00546 } 00547 //---------------------------------------------------------------------------- 00551 inline __attribute__((always_inline)) 00552 void high() {write(true);} 00553 //---------------------------------------------------------------------------- 00557 inline __attribute__((always_inline)) 00558 void low() {write(false);} 00559 //---------------------------------------------------------------------------- 00566 inline __attribute__((always_inline)) 00567 void mode(bool pinMode) { 00568 fastPinMode(PinNumber, pinMode); 00569 } 00570 //---------------------------------------------------------------------------- 00572 inline __attribute__((always_inline)) 00573 bool read() const { 00574 return fastDigitalRead(PinNumber); 00575 } 00576 //---------------------------------------------------------------------------- 00582 inline __attribute__((always_inline)) 00583 void toggle() { 00584 fastDigitalToggle(PinNumber); 00585 } 00586 //---------------------------------------------------------------------------- 00591 inline __attribute__((always_inline)) 00592 void write(bool value) { 00593 fastDigitalWrite(PinNumber, value); 00594 } 00595 }; 00596 #endif // DigitalPin_h 00597