Adafruit Library
CP_Boards.h
1 /*
2  Boards.h - Hardware Abstraction Layer for Firmata library
3  Copyright (c) 2006-2008 Hans-Christoph Steiner. All rights reserved.
4  Copyright (C) 2009-2016 Jeff Hoefs. All rights reserved.
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either
9  version 2.1 of the License, or (at your option) any later version.
10 
11  See file LICENSE.txt for further informations on licensing terms.
12 
13  Last updated April 10th, 2016
14 */
15 
16 #ifndef Firmata_Boards_h
17 #define Firmata_Boards_h
18 
19 #include <inttypes.h>
20 
21 #if defined(ARDUINO) && ARDUINO >= 100
22 #include "Arduino.h" // for digitalRead, digitalWrite, etc
23 #else
24 #include "WProgram.h"
25 #endif
26 
27 // Normally Servo.h must be included before Firmata.h (which then includes
28 // this file). If Servo.h wasn't included, this allows the code to still
29 // compile, but without support for any Servos. Hopefully that's what the
30 // user intended by not including Servo.h
31 #ifndef MAX_SERVOS
32 #define MAX_SERVOS 0
33 #endif
34 
35 /*
36  Firmata Hardware Abstraction Layer
37 
38 Firmata is built on top of the hardware abstraction functions of Arduino,
39 specifically digitalWrite, digitalRead, analogWrite, analogRead, and
40 pinMode. While these functions offer simple integer pin numbers, Firmata
41 needs more information than is provided by Arduino. This file provides
42 all other hardware specific details. To make Firmata support a new board,
43 only this file should require editing.
44 
45 The key concept is every "pin" implemented by Firmata may be mapped to
46 any pin as implemented by Arduino. Usually a simple 1-to-1 mapping is
47 best, but such mapping should not be assumed. This hardware abstraction
48 layer allows Firmata to implement any number of pins which map onto the
49 Arduino implemented pins in almost any arbitrary way.
50 
51 
52 General Constants:
53 
54 These constants provide basic information Firmata requires.
55 
56 TOTAL_PINS: The total number of pins Firmata implemented by Firmata.
57  Usually this will match the number of pins the Arduino functions
58  implement, including any pins pins capable of analog or digital.
59  However, Firmata may implement any number of pins. For example,
60  on Arduino Mini with 8 analog inputs, 6 of these may be used
61  for digital functions, and 2 are analog only. On such boards,
62  Firmata can implement more pins than Arduino's pinMode()
63  function, in order to accommodate those special pins. The
64  Firmata protocol supports a maximum of 128 pins, so this
65  constant must not exceed 128.
66 
67 TOTAL_ANALOG_PINS: The total number of analog input pins implemented.
68  The Firmata protocol allows up to 16 analog inputs, accessed
69  using offsets 0 to 15. Because Firmata presents the analog
70  inputs using different offsets than the actual pin numbers
71  (a legacy of Arduino's analogRead function, and the way the
72  analog input capable pins are physically labeled on all
73  Arduino boards), the total number of analog input signals
74  must be specified. 16 is the maximum.
75 
76 VERSION_BLINK_PIN: When Firmata starts up, it will blink the version
77  number. This constant is the Arduino pin number where a
78  LED is connected.
79 
80 
81 Pin Mapping Macros:
82 
83 These macros provide the mapping between pins as implemented by
84 Firmata protocol and the actual pin numbers used by the Arduino
85 functions. Even though such mappings are often simple, pin
86 numbers received by Firmata protocol should always be used as
87 input to these macros, and the result of the macro should be
88 used with with any Arduino function.
89 
90 When Firmata is extended to support a new pin mode or feature,
91 a pair of macros should be added and used for all hardware
92 access. For simple 1:1 mapping, these macros add no actual
93 overhead, yet their consistent use allows source code which
94 uses them consistently to be easily adapted to all other boards
95 with different requirements.
96 
97 IS_PIN_XXXX(pin): The IS_PIN macros resolve to true or non-zero
98  if a pin as implemented by Firmata corresponds to a pin
99  that actually implements the named feature.
100 
101 PIN_TO_XXXX(pin): The PIN_TO macros translate pin numbers as
102  implemented by Firmata to the pin numbers needed as inputs
103  to the Arduino functions. The corresponding IS_PIN macro
104  should always be tested before using a PIN_TO macro, so
105  these macros only need to handle valid Firmata pin
106  numbers for the named feature.
107 
108 
109 Port Access Inline Funtions:
110 
111 For efficiency, Firmata protocol provides access to digital
112 input and output pins grouped by 8 bit ports. When these
113 groups of 8 correspond to actual 8 bit ports as implemented
114 by the hardware, these inline functions can provide high
115 speed direct port access. Otherwise, a default implementation
116 using 8 calls to digitalWrite or digitalRead is used.
117 
118 When porting Firmata to a new board, it is recommended to
119 use the default functions first and focus only on the constants
120 and macros above. When those are working, if optimized port
121 access is desired, these inline functions may be extended.
122 The recommended approach defines a symbol indicating which
123 optimization to use, and then conditional complication is
124 used within these functions.
125 
126 readPort(port, bitmask): Read an 8 bit port, returning the value.
127  port: The port number, Firmata pins port*8 to port*8+7
128  bitmask: The actual pins to read, indicated by 1 bits.
129 
130 writePort(port, value, bitmask): Write an 8 bit port.
131  port: The port number, Firmata pins port*8 to port*8+7
132  value: The 8 bit value to write
133  bitmask: The actual pins to write, indicated by 1 bits.
134 */
135 
136 /*==============================================================================
137  * Board Specific Configuration
138  *============================================================================*/
139 
140 #ifndef digitalPinHasPWM
141 #define digitalPinHasPWM(p) IS_PIN_DIGITAL(p)
142 #endif
143 
144 // Arduino Duemilanove, Diecimila, and NG
145 #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)
146 #if defined(NUM_ANALOG_INPUTS) && NUM_ANALOG_INPUTS == 6
147 #define TOTAL_ANALOG_PINS 6
148 #define TOTAL_PINS 20 // 14 digital + 6 analog
149 #else
150 #define TOTAL_ANALOG_PINS 8
151 #define TOTAL_PINS 22 // 14 digital + 8 analog
152 #endif
153 #define VERSION_BLINK_PIN 13
154 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19)
155 #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS)
156 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
157 #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS)
158 #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19)
159 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
160 #define PIN_TO_DIGITAL(p) (p)
161 #define PIN_TO_ANALOG(p) ((p) - 14)
162 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
163 #define PIN_TO_SERVO(p) ((p) - 2)
164 #define ARDUINO_PINOUT_OPTIMIZE 1
165 
166 
167 // Wiring (and board)
168 #elif defined(WIRING)
169 #define VERSION_BLINK_PIN WLED
170 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
171 #define IS_PIN_ANALOG(p) ((p) >= FIRST_ANALOG_PIN && (p) < (FIRST_ANALOG_PIN+TOTAL_ANALOG_PINS))
172 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
173 #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
174 #define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL)
175 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
176 #define PIN_TO_DIGITAL(p) (p)
177 #define PIN_TO_ANALOG(p) ((p) - FIRST_ANALOG_PIN)
178 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
179 #define PIN_TO_SERVO(p) (p)
180 
181 
182 // old Arduinos
183 #elif defined(__AVR_ATmega8__)
184 #define TOTAL_ANALOG_PINS 6
185 #define TOTAL_PINS 20 // 14 digital + 6 analog
186 #define VERSION_BLINK_PIN 13
187 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19)
188 #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 19)
189 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
190 #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS)
191 #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19)
192 #define PIN_TO_DIGITAL(p) (p)
193 #define PIN_TO_ANALOG(p) ((p) - 14)
194 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
195 #define PIN_TO_SERVO(p) ((p) - 2)
196 #define ARDUINO_PINOUT_OPTIMIZE 1
197 
198 
199 // Arduino Mega
200 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
201 #define TOTAL_ANALOG_PINS 16
202 #define TOTAL_PINS 70 // 54 digital + 16 analog
203 #define VERSION_BLINK_PIN 13
204 #define PIN_SERIAL1_RX 19
205 #define PIN_SERIAL1_TX 18
206 #define PIN_SERIAL2_RX 17
207 #define PIN_SERIAL2_TX 16
208 #define PIN_SERIAL3_RX 15
209 #define PIN_SERIAL3_TX 14
210 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
211 #define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS)
212 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
213 #define IS_PIN_SERVO(p) ((p) >= 2 && (p) - 2 < MAX_SERVOS)
214 #define IS_PIN_I2C(p) ((p) == 20 || (p) == 21)
215 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
216 #define IS_PIN_SERIAL(p) ((p) > 13 && (p) < 20)
217 #define PIN_TO_DIGITAL(p) (p)
218 #define PIN_TO_ANALOG(p) ((p) - 54)
219 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
220 #define PIN_TO_SERVO(p) ((p) - 2)
221 
222 
223 // Arduino DUE
224 #elif defined(__SAM3X8E__)
225 #define TOTAL_ANALOG_PINS 12
226 #define TOTAL_PINS 66 // 54 digital + 12 analog
227 #define VERSION_BLINK_PIN 13
228 #define PIN_SERIAL1_RX 19
229 #define PIN_SERIAL1_TX 18
230 #define PIN_SERIAL2_RX 17
231 #define PIN_SERIAL2_TX 16
232 #define PIN_SERIAL3_RX 15
233 #define PIN_SERIAL3_TX 14
234 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
235 #define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS)
236 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
237 #define IS_PIN_SERVO(p) ((p) >= 2 && (p) - 2 < MAX_SERVOS)
238 #define IS_PIN_I2C(p) ((p) == 20 || (p) == 21) // 70 71
239 #define IS_PIN_SERIAL(p) ((p) > 13 && (p) < 20)
240 #define PIN_TO_DIGITAL(p) (p)
241 #define PIN_TO_ANALOG(p) ((p) - 54)
242 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
243 #define PIN_TO_SERVO(p) ((p) - 2)
244 
245 
246 // Arduino/Genuino MKR1000
247 #elif defined(ARDUINO_SAMD_MKR1000)
248 #define TOTAL_ANALOG_PINS 7
249 #define TOTAL_PINS 22 // 8 digital + 3 spi + 2 i2c + 2 uart + 7 analog
250 #define IS_PIN_DIGITAL(p) (((p) >= 0 && (p) <= 21) && !IS_PIN_SERIAL(p))
251 #define IS_PIN_ANALOG(p) ((p) >= 15 && (p) < 15 + TOTAL_ANALOG_PINS)
252 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
253 #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4
254 #define IS_PIN_I2C(p) ((p) == 11 || (p) == 12) // SDA = 11, SCL = 12
255 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
256 #define IS_PIN_SERIAL(p) ((p) == PIN_SERIAL1_RX || (p) == PIN_SERIAL1_TX) //defined in variant.h RX = 13, TX = 14
257 #define PIN_TO_DIGITAL(p) (p)
258 #define PIN_TO_ANALOG(p) ((p) - 15)
259 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
260 #define PIN_TO_SERVO(p) (p) // deprecated since v2.4
261 
262 
263 // Arduino Zero
264 // Note this will work with an Arduino Zero Pro, but not with an Arduino M0 Pro
265 // Arduino M0 Pro does not properly map pins to the board labeled pin numbers
266 #elif defined(_VARIANT_ARDUINO_ZERO_)
267 #define TOTAL_ANALOG_PINS 6
268 #define TOTAL_PINS 25 // 14 digital + 6 analog + 2 i2c + 3 spi
269 #define TOTAL_PORTS 3 // set when TOTAL_PINS > num digitial I/O pins
270 #define VERSION_BLINK_PIN LED_BUILTIN
271 //#define PIN_SERIAL1_RX 0 // already defined in zero core variant.h
272 //#define PIN_SERIAL1_TX 1 // already defined in zero core variant.h
273 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) <= 19)
274 #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS)
275 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
276 #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4
277 #define IS_PIN_I2C(p) ((p) == 20 || (p) == 21) // SDA = 20, SCL = 21
278 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) // SS = A2
279 #define IS_PIN_SERIAL(p) ((p) == 0 || (p) == 1)
280 #define PIN_TO_DIGITAL(p) (p)
281 #define PIN_TO_ANALOG(p) ((p) - 14)
282 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
283 #define PIN_TO_SERVO(p) (p) // deprecated since v2.4
284 
285 
286 // Arduino 101
287 #elif defined(_VARIANT_ARDUINO_101_X_)
288 #define TOTAL_ANALOG_PINS NUM_ANALOG_INPUTS
289 #define TOTAL_PINS NUM_DIGITAL_PINS // 15 digital (including ATN pin) + 6 analog
290 #define VERSION_BLINK_PIN LED_BUILTIN
291 #define PIN_SERIAL1_RX 0
292 #define PIN_SERIAL1_TX 1
293 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) <= 20)
294 #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS)
295 #define IS_PIN_PWM(p) digitalPinHasPWM(p) // 3, 5, 6, 9
296 #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4
297 #define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL) // SDA = 18, SCL = 19
298 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
299 #define IS_PIN_SERIAL(p) ((p) == 0 || (p) == 1)
300 #define PIN_TO_DIGITAL(p) (p)
301 #define PIN_TO_ANALOG(p) ((p) - 14)
302 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
303 #define PIN_TO_SERVO(p) (p) // deprecated since v2.4
304 
305 
306 // Teensy 1.0
307 #elif defined(__AVR_AT90USB162__)
308 #define TOTAL_ANALOG_PINS 0
309 #define TOTAL_PINS 21 // 21 digital + no analog
310 #define VERSION_BLINK_PIN 6
311 #define PIN_SERIAL1_RX 2
312 #define PIN_SERIAL1_TX 3
313 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
314 #define IS_PIN_ANALOG(p) (0)
315 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
316 #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
317 #define IS_PIN_I2C(p) (0)
318 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
319 #define IS_PIN_SERIAL(p) ((p) == 2 || (p) == 3)
320 #define PIN_TO_DIGITAL(p) (p)
321 #define PIN_TO_ANALOG(p) (0)
322 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
323 #define PIN_TO_SERVO(p) (p)
324 
325 
326 // Teensy 2.0
327 #elif defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY)
328 #define TOTAL_ANALOG_PINS 12
329 #define TOTAL_PINS 25 // 11 digital + 12 analog
330 #define VERSION_BLINK_PIN 11
331 #define PIN_SERIAL1_RX 7
332 #define PIN_SERIAL1_TX 8
333 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
334 #define IS_PIN_ANALOG(p) ((p) >= 11 && (p) <= 22)
335 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
336 #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
337 #define IS_PIN_I2C(p) ((p) == 5 || (p) == 6)
338 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
339 #define IS_PIN_SERIAL(p) ((p) == 7 || (p) == 8)
340 #define PIN_TO_DIGITAL(p) (p)
341 #define PIN_TO_ANALOG(p) (((p) < 22) ? 21 - (p) : 11)
342 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
343 #define PIN_TO_SERVO(p) (p)
344 
345 
346 // Teensy 3.0, 3.1 and 3.2
347 #elif defined(__MK20DX128__) || defined(__MK20DX256__)
348 #define TOTAL_ANALOG_PINS 14
349 #define TOTAL_PINS 38 // 24 digital + 10 analog-digital + 4 analog
350 #define VERSION_BLINK_PIN 13
351 #define PIN_SERIAL1_RX 0
352 #define PIN_SERIAL1_TX 1
353 #define PIN_SERIAL2_RX 9
354 #define PIN_SERIAL2_TX 10
355 #define PIN_SERIAL3_RX 7
356 #define PIN_SERIAL3_TX 8
357 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) <= 33)
358 #define IS_PIN_ANALOG(p) (((p) >= 14 && (p) <= 23) || ((p) >= 34 && (p) <= 38))
359 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
360 #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
361 #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19)
362 #define IS_PIN_SERIAL(p) (((p) > 6 && (p) < 11) || ((p) == 0 || (p) == 1))
363 #define PIN_TO_DIGITAL(p) (p)
364 #define PIN_TO_ANALOG(p) (((p) <= 23) ? (p) - 14 : (p) - 24)
365 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
366 #define PIN_TO_SERVO(p) (p)
367 
368 
369 // Teensy-LC
370 #elif defined(__MKL26Z64__)
371 #define TOTAL_ANALOG_PINS 13
372 #define TOTAL_PINS 27 // 27 digital + 13 analog-digital
373 #define VERSION_BLINK_PIN 13
374 #define PIN_SERIAL1_RX 0
375 #define PIN_SERIAL1_TX 1
376 #define PIN_SERIAL2_RX 9
377 #define PIN_SERIAL2_TX 10
378 #define PIN_SERIAL3_RX 7
379 #define PIN_SERIAL3_TX 8
380 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) <= 26)
381 #define IS_PIN_ANALOG(p) ((p) >= 14)
382 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
383 #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
384 #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19)
385 #define IS_PIN_SERIAL(p) (((p) > 6 && (p) < 11) || ((p) == 0 || (p) == 1))
386 #define PIN_TO_DIGITAL(p) (p)
387 #define PIN_TO_ANALOG(p) ((p) - 14)
388 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
389 #define PIN_TO_SERVO(p) (p)
390 
391 
392 // Teensy++ 1.0 and 2.0
393 #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
394 #define TOTAL_ANALOG_PINS 8
395 #define TOTAL_PINS 46 // 38 digital + 8 analog
396 #define VERSION_BLINK_PIN 6
397 #define PIN_SERIAL1_RX 2
398 #define PIN_SERIAL1_TX 3
399 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
400 #define IS_PIN_ANALOG(p) ((p) >= 38 && (p) < TOTAL_PINS)
401 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
402 #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
403 #define IS_PIN_I2C(p) ((p) == 0 || (p) == 1)
404 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
405 #define IS_PIN_SERIAL(p) ((p) == 2 || (p) == 3)
406 #define PIN_TO_DIGITAL(p) (p)
407 #define PIN_TO_ANALOG(p) ((p) - 38)
408 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
409 #define PIN_TO_SERVO(p) (p)
410 
411 
412 // Leonardo
413 #elif defined(__AVR_ATmega32U4__)
414 #define TOTAL_ANALOG_PINS 12
415 #define TOTAL_PINS 30 // 14 digital + 12 analog + 4 SPI (D14-D17 on ISP header)
416 #define VERSION_BLINK_PIN 13
417 #define PIN_SERIAL1_RX 0
418 #define PIN_SERIAL1_TX 1
419 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
420 #define IS_PIN_ANALOG(p) ((p) >= 18 && (p) < TOTAL_PINS)
421 #define IS_PIN_PWM(p) ((p) == 3 || (p) == 5 || (p) == 6 || (p) == 9 || (p) == 10 || (p) == 11 || (p) == 13)
422 #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
423 #define IS_PIN_I2C(p) ((p) == 2 || (p) == 3)
424 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
425 #define IS_PIN_SERIAL(p) ((p) == 0 || (p) == 1)
426 #define PIN_TO_DIGITAL(p) (p)
427 #define PIN_TO_ANALOG(p) (p) - 18
428 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
429 #define PIN_TO_SERVO(p) (p)
430 
431 
432 // Intel Galileo Board (gen 1 and 2) and Intel Edison
433 #elif defined(ARDUINO_LINUX)
434 #define TOTAL_ANALOG_PINS 6
435 #define TOTAL_PINS 20 // 14 digital + 6 analog
436 #define VERSION_BLINK_PIN 13
437 #define PIN_SERIAL1_RX 0
438 #define PIN_SERIAL1_TX 1
439 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19)
440 #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 19)
441 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
442 #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS)
443 #define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL)
444 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
445 #define IS_PIN_SERIAL(p) ((p) == 0 || (p) == 1)
446 #define PIN_TO_DIGITAL(p) (p)
447 #define PIN_TO_ANALOG(p) ((p) - 14)
448 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
449 #define PIN_TO_SERVO(p) ((p) - 2)
450 
451 
452 // RedBearLab BLE Nano with factory switch settings (S1 - S10)
453 #elif defined(BLE_NANO)
454 #define TOTAL_ANALOG_PINS 6
455 #define TOTAL_PINS 15 // 9 digital + 3 analog
456 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 14)
457 #define IS_PIN_ANALOG(p) ((p) == 8 || (p) == 9 || (p) == 10 || (p) == 11 || (p) == 12 || (p) == 14) //A0~A5
458 #define IS_PIN_PWM(p) ((p) == 3 || (p) == 5 || (p) == 6)
459 #define IS_PIN_SERVO(p) ((p) >= 2 && (p) <= 7)
460 #define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL)
461 #define IS_PIN_SPI(p) ((p) == CS || (p) == MOSI || (p) == MISO || (p) == SCK)
462 #define PIN_TO_DIGITAL(p) (p)
463 #define PIN_TO_ANALOG(p) ((p) - 8)
464 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
465 #define PIN_TO_SERVO(p) (p)
466 
467 
468 // Sanguino
469 #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
470 #define TOTAL_ANALOG_PINS 8
471 #define TOTAL_PINS 32 // 24 digital + 8 analog
472 #define VERSION_BLINK_PIN 0
473 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
474 #define IS_PIN_ANALOG(p) ((p) >= 24 && (p) < TOTAL_PINS)
475 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
476 #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
477 #define IS_PIN_I2C(p) ((p) == 16 || (p) == 17)
478 #define PIN_TO_DIGITAL(p) (p)
479 #define PIN_TO_ANALOG(p) ((p) - 24)
480 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
481 #define PIN_TO_SERVO(p) ((p) - 2)
482 
483 
484 // Illuminato
485 #elif defined(__AVR_ATmega645__)
486 #define TOTAL_ANALOG_PINS 6
487 #define TOTAL_PINS 42 // 36 digital + 6 analog
488 #define VERSION_BLINK_PIN 13
489 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
490 #define IS_PIN_ANALOG(p) ((p) >= 36 && (p) < TOTAL_PINS)
491 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
492 #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
493 #define IS_PIN_I2C(p) ((p) == 4 || (p) == 5)
494 #define PIN_TO_DIGITAL(p) (p)
495 #define PIN_TO_ANALOG(p) ((p) - 36)
496 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
497 #define PIN_TO_SERVO(p) ((p) - 2)
498 
499 
500 // Pic32 chipKIT FubarinoSD
501 #elif defined(_BOARD_FUBARINO_SD_)
502 #define TOTAL_ANALOG_PINS NUM_ANALOG_PINS // 15
503 #define TOTAL_PINS NUM_DIGITAL_PINS // 45, All pins can be digital
504 #define MAX_SERVOS NUM_DIGITAL_PINS
505 #define VERSION_BLINK_PIN PIN_LED1
506 #define IS_PIN_DIGITAL(p) 1
507 #define IS_PIN_ANALOG(p) ((p) >= 30 && (p) <= 44)
508 #define IS_PIN_PWM(p) IS_PIN_DIGITAL(p)
509 #define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p)
510 #define IS_PIN_I2C(p) ((p) == 1 || (p) == 2)
511 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
512 #define PIN_TO_DIGITAL(p) (p)
513 #define PIN_TO_ANALOG(p) (14 - (p - 30))
514 #define PIN_TO_PWM(p) (p)
515 #define PIN_TO_SERVO(p) (p)
516 
517 
518 // Pic32 chipKIT FubarinoMini
519 // Note, FubarinoMini analog pin 20 will not function in Firmata as analog input due to limitation in analog mapping
520 #elif defined(_BOARD_FUBARINO_MINI_)
521 #define TOTAL_ANALOG_PINS 14 // We have to fake this because of the poor analog pin mapping planning in FubarinoMini
522 #define TOTAL_PINS NUM_DIGITAL_PINS // 33
523 #define MAX_SERVOS NUM_DIGITAL_PINS
524 #define VERSION_BLINK_PIN PIN_LED1
525 #define IS_PIN_DIGITAL(p) ((p) != 14 && (p) != 15 && (p) != 31 && (p) != 32)
526 #define IS_PIN_ANALOG(p) ((p) == 0 || ((p) >= 3 && (p) <= 13))
527 #define IS_PIN_PWM(p) IS_PIN_DIGITAL(p)
528 #define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p)
529 #define IS_PIN_I2C(p) ((p) == 25 || (p) == 26)
530 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
531 #define PIN_TO_DIGITAL(p) (p)
532 #define PIN_TO_ANALOG(p) (p)
533 #define PIN_TO_PWM(p) (p)
534 #define PIN_TO_SERVO(p) (p)
535 
536 
537 // Pic32 chipKIT UNO32
538 #elif defined(_BOARD_UNO_) && defined(__PIC32) // NOTE: no _BOARD_UNO32_ to use
539 #define TOTAL_ANALOG_PINS NUM_ANALOG_PINS // 12
540 #define TOTAL_PINS NUM_DIGITAL_PINS // 47 All pins can be digital
541 #define MAX_SERVOS NUM_DIGITAL_PINS // All pins can be servo with SoftPWMservo
542 #define VERSION_BLINK_PIN PIN_LED1
543 #define IS_PIN_DIGITAL(p) ((p) >= 2)
544 #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 25)
545 #define IS_PIN_PWM(p) IS_PIN_DIGITAL(p)
546 #define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p)
547 #define IS_PIN_I2C(p) ((p) == 45 || (p) == 46)
548 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
549 #define PIN_TO_DIGITAL(p) (p)
550 #define PIN_TO_ANALOG(p) ((p) - 14)
551 #define PIN_TO_PWM(p) (p)
552 #define PIN_TO_SERVO(p) (p)
553 
554 
555 // Pic32 chipKIT DP32
556 #elif defined(_BOARD_DP32_)
557 #define TOTAL_ANALOG_PINS 15 // Really only has 9, but have to override because of mistake in variant file
558 #define TOTAL_PINS NUM_DIGITAL_PINS // 19
559 #define MAX_SERVOS NUM_DIGITAL_PINS // All pins can be servo with SoftPWMservo
560 #define VERSION_BLINK_PIN PIN_LED1
561 #define IS_PIN_DIGITAL(p) (((p) != 1) && ((p) != 4) && ((p) != 5) && ((p) != 15) && ((p) != 16))
562 #define IS_PIN_ANALOG(p) ((p) >= 6 && (p) <= 14)
563 #define IS_PIN_PWM(p) IS_PIN_DIGITAL(p)
564 #define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p)
565 #define IS_PIN_I2C(p) ((p) == 2 || (p) == 3)
566 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
567 #define PIN_TO_DIGITAL(p) (p)
568 #define PIN_TO_ANALOG(p) (p)
569 #define PIN_TO_PWM(p) (p)
570 #define PIN_TO_SERVO(p) (p)
571 
572 
573 // Pic32 chipKIT uC32
574 #elif defined(_BOARD_UC32_)
575 #define TOTAL_ANALOG_PINS NUM_ANALOG_PINS // 12
576 #define TOTAL_PINS NUM_DIGITAL_PINS // 47 All pins can be digital
577 #define MAX_SERVOS NUM_DIGITAL_PINS // All pins can be servo with SoftPWMservo
578 #define VERSION_BLINK_PIN PIN_LED1
579 #define IS_PIN_DIGITAL(p) ((p) >= 2)
580 #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 25)
581 #define IS_PIN_PWM(p) IS_PIN_DIGITAL(p)
582 #define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p)
583 #define IS_PIN_I2C(p) ((p) == 45 || (p) == 46)
584 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
585 #define PIN_TO_DIGITAL(p) (p)
586 #define PIN_TO_ANALOG(p) ((p) - 14)
587 #define PIN_TO_PWM(p) (p)
588 #define PIN_TO_SERVO(p) (p)
589 
590 
591 // Pic32 chipKIT WF32
592 #elif defined(_BOARD_WF32_)
593 #define TOTAL_ANALOG_PINS NUM_ANALOG_PINS
594 #define TOTAL_PINS NUM_DIGITAL_PINS
595 #define MAX_SERVOS NUM_DIGITAL_PINS
596 #define VERSION_BLINK_PIN PIN_LED1
597 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 49) // Accounts for SD and WiFi dedicated pins
598 #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 25)
599 #define IS_PIN_PWM(p) IS_PIN_DIGITAL(p)
600 #define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p)
601 #define IS_PIN_I2C(p) ((p) == 34 || (p) == 35)
602 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
603 #define PIN_TO_DIGITAL(p) (p)
604 #define PIN_TO_ANALOG(p) ((p) - 14)
605 #define PIN_TO_PWM(p) (p)
606 #define PIN_TO_SERVO(p) (p)
607 
608 
609 // Pic32 chipKIT WiFire
610 #elif defined(_BOARD_WIFIRE_)
611 #define TOTAL_ANALOG_PINS NUM_ANALOG_PINS // 14
612 #define TOTAL_PINS NUM_DIGITAL_PINS // 71
613 #define MAX_SERVOS NUM_DIGITAL_PINS
614 #define VERSION_BLINK_PIN PIN_LED1
615 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 47) // Accounts for SD and WiFi dedicated pins
616 #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 25)
617 #define IS_PIN_PWM(p) IS_PIN_DIGITAL(p)
618 #define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p)
619 #define IS_PIN_I2C(p) ((p) == 34 || (p) == 35)
620 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
621 #define PIN_TO_DIGITAL(p) (p)
622 #define PIN_TO_ANALOG(p) ((p) <= 25 ? ((p) - 14) : (p) - 36)
623 #define PIN_TO_PWM(p) (p)
624 #define PIN_TO_SERVO(p) (p)
625 
626 
627 // Pic32 chipKIT MAX32
628 #elif defined(_BOARD_MEGA_) && defined(__PIC32) // NOTE: no _BOARD_MAX32_ to use
629 #define TOTAL_ANALOG_PINS NUM_ANALOG_PINS // 16
630 #define TOTAL_PINS NUM_DIGITAL_PINS // 87
631 #define MAX_SERVOS NUM_DIGITAL_PINS
632 #define VERSION_BLINK_PIN PIN_LED1
633 #define IS_PIN_DIGITAL(p) ((p) >= 2)
634 #define IS_PIN_ANALOG(p) ((p) >= 54 && (p) <= 69)
635 #define IS_PIN_PWM(p) IS_PIN_DIGITAL(p)
636 #define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p)
637 #define IS_PIN_I2C(p) ((p) == 34 || (p) == 35)
638 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
639 #define PIN_TO_DIGITAL(p) (p)
640 #define PIN_TO_ANALOG(p) ((p) - 54)
641 #define PIN_TO_PWM(p) (p)
642 #define PIN_TO_SERVO(p) (p)
643 
644 
645 // Pic32 chipKIT Pi
646 #elif defined(_BOARD_CHIPKIT_PI_)
647 #define TOTAL_ANALOG_PINS 16
648 #define TOTAL_PINS NUM_DIGITAL_PINS // 19
649 #define MAX_SERVOS NUM_DIGITAL_PINS
650 #define VERSION_BLINK_PIN PIN_LED1
651 #define IS_PIN_DIGITAL(p) (((p) >= 2) && ((p) <= 3) || (((p) >= 8) && ((p) <= 13)) || (((p) >= 14) && ((p) <= 17)))
652 #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 17)
653 #define IS_PIN_PWM(p) IS_PIN_DIGITAL(p)
654 #define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p)
655 #define IS_PIN_I2C(p) ((p) == 16 || (p) == 17)
656 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
657 #define PIN_TO_DIGITAL(p) (p)
658 #define PIN_TO_ANALOG(p) ((p) <= 15 ? (p) - 14 : (p) - 12)
659 //#define PIN_TO_ANALOG(p) (((p) <= 16) ? ((p) - 14) : ((p) - 16))
660 #define PIN_TO_PWM(p) (p)
661 #define PIN_TO_SERVO(p) (p)
662 
663 // Pinoccio Scout
664 // Note: digital pins 9-16 are usable but not labeled on the board numerically.
665 // SS=9, MOSI=10, MISO=11, SCK=12, RX1=13, TX1=14, SCL=15, SDA=16
666 #elif defined(ARDUINO_PINOCCIO)
667 #define TOTAL_ANALOG_PINS 8
668 #define TOTAL_PINS NUM_DIGITAL_PINS // 32
669 #define VERSION_BLINK_PIN 23
670 #define PIN_SERIAL1_RX 13
671 #define PIN_SERIAL1_TX 14
672 #define IS_PIN_DIGITAL(p) (((p) >= 2) && ((p) <= 16)) || (((p) >= 24) && ((p) <= 31))
673 #define IS_PIN_ANALOG(p) ((p) >= 24 && (p) <= 31)
674 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
675 #define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p)
676 #define IS_PIN_I2C(p) ((p) == SCL || (p) == SDA)
677 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
678 #define IS_PIN_SERIAL(p) ((p) == 13 || (p) == 14)
679 #define PIN_TO_DIGITAL(p) (p)
680 #define PIN_TO_ANALOG(p) ((p) - 24)
681 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
682 #define PIN_TO_SERVO(p) ((p) - 2)
683 
684 // ESP8266
685 // note: boot mode GPIOs 0, 2 and 15 can be used as outputs, GPIOs 6-11 are in use for flash IO
686 #elif defined(ESP8266)
687 #define TOTAL_ANALOG_PINS NUM_ANALOG_INPUTS
688 #define TOTAL_PINS A0 + NUM_ANALOG_INPUTS
689 #define PIN_SERIAL_RX 3
690 #define PIN_SERIAL_TX 1
691 #define IS_PIN_DIGITAL(p) (((p) >= 0 && (p) <= 5) || ((p) >= 12 && (p) < A0))
692 #define IS_PIN_ANALOG(p) ((p) >= A0 && (p) < A0 + NUM_ANALOG_INPUTS)
693 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
694 #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS)
695 #define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL)
696 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
697 #define IS_PIN_INTERRUPT(p) (digitalPinToInterrupt(p) > NOT_AN_INTERRUPT)
698 #define IS_PIN_SERIAL(p) ((p) == PIN_SERIAL_RX || (p) == PIN_SERIAL_TX)
699 #define PIN_TO_DIGITAL(p) (p)
700 #define PIN_TO_ANALOG(p) ((p) - A0)
701 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
702 #define PIN_TO_SERVO(p) (p)
703 #define DEFAULT_PWM_RESOLUTION 10
704 
705 // Circuit Playground Express
706 #elif defined(__SAMD21G18A__)
707 #define TOTAL_ANALOG_PINS 6
708 #define TOTAL_PINS 25 // 14 digital + 6 analog + 2 i2c + 3 spi
709 #define TOTAL_PORTS 3 // set when TOTAL_PINS > num digitial I/O pins
710 #define VERSION_BLINK_PIN LED_BUILTIN
711 //#define PIN_SERIAL1_RX 0 // already defined in zero core variant.h
712 //#define PIN_SERIAL1_TX 1 // already defined in zero core variant.h
713 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) <= 19)
714 #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS)
715 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
716 #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4
717 #define IS_PIN_I2C(p) ((p) == 20 || (p) == 21) // SDA = 20, SCL = 21
718 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) // SS = A2
719 #define IS_PIN_SERIAL(p) ((p) == 0 || (p) == 1)
720 #define PIN_TO_DIGITAL(p) (p)
721 #define PIN_TO_ANALOG(p) ((p) - 14)
722 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
723 
724 // Circuit Playground Bluefruit
725 #elif defined(ARDUINO_NRF52840_CIRCUITPLAY)
726 #define TOTAL_ANALOG_PINS 6
727 #define TOTAL_PINS 25 // 14 digital + 6 analog + 2 i2c + 3 spi
728 #define TOTAL_PORTS 3 // set when TOTAL_PINS > num digitial I/O pins
729 #define VERSION_BLINK_PIN LED_BUILTIN
730 //#define PIN_SERIAL1_RX 0 // already defined in zero core variant.h
731 //#define PIN_SERIAL1_TX 1 // already defined in zero core variant.h
732 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) <= 19)
733 #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS)
734 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
735 #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4
736 #define IS_PIN_I2C(p) ((p) == 20 || (p) == 21) // SDA = 20, SCL = 21
737 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) // SS = A2
738 #define IS_PIN_SERIAL(p) ((p) == 0 || (p) == 1)
739 #define PIN_TO_DIGITAL(p) (p)
740 #define PIN_TO_ANALOG(p) ((p) - 14)
741 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
742 
743 
744 // anything else
745 #else
746 #error "Please edit CP_Boards.h with a hardware abstraction for this board"
747 #endif
748 
749 // as long this is not defined for all boards:
750 #ifndef IS_PIN_SPI
751 #define IS_PIN_SPI(p) 0
752 #endif
753 
754 #ifndef IS_PIN_SERIAL
755 #define IS_PIN_SERIAL(p) 0
756 #endif
757 
758 #ifndef DEFAULT_PWM_RESOLUTION
759 #define DEFAULT_PWM_RESOLUTION 8
760 #endif
761 
762 /*==============================================================================
763  * readPort() - Read an 8 bit port
764  *============================================================================*/
765 
766 static inline unsigned char readPort(byte, byte) __attribute__((always_inline, unused));
767 static inline unsigned char readPort(byte port, byte bitmask)
768 {
769 #if defined(ARDUINO_PINOUT_OPTIMIZE)
770  if (port == 0) return (PIND & 0xFC) & bitmask; // ignore Rx/Tx 0/1
771  if (port == 1) return ((PINB & 0x3F) | ((PINC & 0x03) << 6)) & bitmask;
772  if (port == 2) return ((PINC & 0x3C) >> 2) & bitmask;
773  return 0;
774 #else
775  unsigned char out = 0, pin = port * 8;
776  if (IS_PIN_DIGITAL(pin + 0) && (bitmask & 0x01) && digitalRead(PIN_TO_DIGITAL(pin + 0))) out |= 0x01;
777  if (IS_PIN_DIGITAL(pin + 1) && (bitmask & 0x02) && digitalRead(PIN_TO_DIGITAL(pin + 1))) out |= 0x02;
778  if (IS_PIN_DIGITAL(pin + 2) && (bitmask & 0x04) && digitalRead(PIN_TO_DIGITAL(pin + 2))) out |= 0x04;
779  if (IS_PIN_DIGITAL(pin + 3) && (bitmask & 0x08) && digitalRead(PIN_TO_DIGITAL(pin + 3))) out |= 0x08;
780  if (IS_PIN_DIGITAL(pin + 4) && (bitmask & 0x10) && digitalRead(PIN_TO_DIGITAL(pin + 4))) out |= 0x10;
781  if (IS_PIN_DIGITAL(pin + 5) && (bitmask & 0x20) && digitalRead(PIN_TO_DIGITAL(pin + 5))) out |= 0x20;
782  if (IS_PIN_DIGITAL(pin + 6) && (bitmask & 0x40) && digitalRead(PIN_TO_DIGITAL(pin + 6))) out |= 0x40;
783  if (IS_PIN_DIGITAL(pin + 7) && (bitmask & 0x80) && digitalRead(PIN_TO_DIGITAL(pin + 7))) out |= 0x80;
784  return out;
785 #endif
786 }
787 
788 /*==============================================================================
789  * writePort() - Write an 8 bit port, only touch pins specified by a bitmask
790  *============================================================================*/
791 
792 static inline unsigned char writePort(byte, byte, byte) __attribute__((always_inline, unused));
793 static inline unsigned char writePort(byte port, byte value, byte bitmask)
794 {
795 #if defined(ARDUINO_PINOUT_OPTIMIZE)
796  if (port == 0) {
797  bitmask = bitmask & 0xFC; // do not touch Tx & Rx pins
798  byte valD = value & bitmask;
799  byte maskD = ~bitmask;
800  cli();
801  PORTD = (PORTD & maskD) | valD;
802  sei();
803  } else if (port == 1) {
804  byte valB = (value & bitmask) & 0x3F;
805  byte valC = (value & bitmask) >> 6;
806  byte maskB = ~(bitmask & 0x3F);
807  byte maskC = ~((bitmask & 0xC0) >> 6);
808  cli();
809  PORTB = (PORTB & maskB) | valB;
810  PORTC = (PORTC & maskC) | valC;
811  sei();
812  } else if (port == 2) {
813  bitmask = bitmask & 0x0F;
814  byte valC = (value & bitmask) << 2;
815  byte maskC = ~(bitmask << 2);
816  cli();
817  PORTC = (PORTC & maskC) | valC;
818  sei();
819  }
820  return 1;
821 #else
822  byte pin = port * 8;
823  if ((bitmask & 0x01)) digitalWrite(PIN_TO_DIGITAL(pin + 0), (value & 0x01));
824  if ((bitmask & 0x02)) digitalWrite(PIN_TO_DIGITAL(pin + 1), (value & 0x02));
825  if ((bitmask & 0x04)) digitalWrite(PIN_TO_DIGITAL(pin + 2), (value & 0x04));
826  if ((bitmask & 0x08)) digitalWrite(PIN_TO_DIGITAL(pin + 3), (value & 0x08));
827  if ((bitmask & 0x10)) digitalWrite(PIN_TO_DIGITAL(pin + 4), (value & 0x10));
828  if ((bitmask & 0x20)) digitalWrite(PIN_TO_DIGITAL(pin + 5), (value & 0x20));
829  if ((bitmask & 0x40)) digitalWrite(PIN_TO_DIGITAL(pin + 6), (value & 0x40));
830  if ((bitmask & 0x80)) digitalWrite(PIN_TO_DIGITAL(pin + 7), (value & 0x80));
831  return 1;
832 #endif
833 }
834 
835 
836 
837 
838 #ifndef TOTAL_PORTS
839 #define TOTAL_PORTS ((TOTAL_PINS + 7) / 8)
840 #endif
841 
842 
843 #endif /* Firmata_Boards_h */