source: rtos_arduino/trunk/arduino_lib/libraries/Firmata/src/Boards.h@ 136

Last change on this file since 136 was 136, checked in by ertl-honda, 8 years ago

ライブラリとOS及びベーシックなサンプルの追加.

File size: 17.3 KB
Line 
1/* Boards.h - Hardware Abstraction Layer for Firmata library */
2
3#ifndef Firmata_Boards_h
4#define Firmata_Boards_h
5
6#include <inttypes.h>
7
8#if defined(ARDUINO) && ARDUINO >= 100
9#include "Arduino.h" // for digitalRead, digitalWrite, etc
10#else
11#include "WProgram.h"
12#endif
13
14// Normally Servo.h must be included before Firmata.h (which then includes
15// this file). If Servo.h wasn't included, this allows the code to still
16// compile, but without support for any Servos. Hopefully that's what the
17// user intended by not including Servo.h
18#ifndef MAX_SERVOS
19#define MAX_SERVOS 0
20#endif
21
22/*
23 Firmata Hardware Abstraction Layer
24
25Firmata is built on top of the hardware abstraction functions of Arduino,
26specifically digitalWrite, digitalRead, analogWrite, analogRead, and
27pinMode. While these functions offer simple integer pin numbers, Firmata
28needs more information than is provided by Arduino. This file provides
29all other hardware specific details. To make Firmata support a new board,
30only this file should require editing.
31
32The key concept is every "pin" implemented by Firmata may be mapped to
33any pin as implemented by Arduino. Usually a simple 1-to-1 mapping is
34best, but such mapping should not be assumed. This hardware abstraction
35layer allows Firmata to implement any number of pins which map onto the
36Arduino implemented pins in almost any arbitrary way.
37
38
39General Constants:
40
41These constants provide basic information Firmata requires.
42
43TOTAL_PINS: The total number of pins Firmata implemented by Firmata.
44 Usually this will match the number of pins the Arduino functions
45 implement, including any pins pins capable of analog or digital.
46 However, Firmata may implement any number of pins. For example,
47 on Arduino Mini with 8 analog inputs, 6 of these may be used
48 for digital functions, and 2 are analog only. On such boards,
49 Firmata can implement more pins than Arduino's pinMode()
50 function, in order to accommodate those special pins. The
51 Firmata protocol supports a maximum of 128 pins, so this
52 constant must not exceed 128.
53
54TOTAL_ANALOG_PINS: The total number of analog input pins implemented.
55 The Firmata protocol allows up to 16 analog inputs, accessed
56 using offsets 0 to 15. Because Firmata presents the analog
57 inputs using different offsets than the actual pin numbers
58 (a legacy of Arduino's analogRead function, and the way the
59 analog input capable pins are physically labeled on all
60 Arduino boards), the total number of analog input signals
61 must be specified. 16 is the maximum.
62
63VERSION_BLINK_PIN: When Firmata starts up, it will blink the version
64 number. This constant is the Arduino pin number where a
65 LED is connected.
66
67
68Pin Mapping Macros:
69
70These macros provide the mapping between pins as implemented by
71Firmata protocol and the actual pin numbers used by the Arduino
72functions. Even though such mappings are often simple, pin
73numbers received by Firmata protocol should always be used as
74input to these macros, and the result of the macro should be
75used with with any Arduino function.
76
77When Firmata is extended to support a new pin mode or feature,
78a pair of macros should be added and used for all hardware
79access. For simple 1:1 mapping, these macros add no actual
80overhead, yet their consistent use allows source code which
81uses them consistently to be easily adapted to all other boards
82with different requirements.
83
84IS_PIN_XXXX(pin): The IS_PIN macros resolve to true or non-zero
85 if a pin as implemented by Firmata corresponds to a pin
86 that actually implements the named feature.
87
88PIN_TO_XXXX(pin): The PIN_TO macros translate pin numbers as
89 implemented by Firmata to the pin numbers needed as inputs
90 to the Arduino functions. The corresponding IS_PIN macro
91 should always be tested before using a PIN_TO macro, so
92 these macros only need to handle valid Firmata pin
93 numbers for the named feature.
94
95
96Port Access Inline Funtions:
97
98For efficiency, Firmata protocol provides access to digital
99input and output pins grouped by 8 bit ports. When these
100groups of 8 correspond to actual 8 bit ports as implemented
101by the hardware, these inline functions can provide high
102speed direct port access. Otherwise, a default implementation
103using 8 calls to digitalWrite or digitalRead is used.
104
105When porting Firmata to a new board, it is recommended to
106use the default functions first and focus only on the constants
107and macros above. When those are working, if optimized port
108access is desired, these inline functions may be extended.
109The recommended approach defines a symbol indicating which
110optimization to use, and then conditional complication is
111used within these functions.
112
113readPort(port, bitmask): Read an 8 bit port, returning the value.
114 port: The port number, Firmata pins port*8 to port*8+7
115 bitmask: The actual pins to read, indicated by 1 bits.
116
117writePort(port, value, bitmask): Write an 8 bit port.
118 port: The port number, Firmata pins port*8 to port*8+7
119 value: The 8 bit value to write
120 bitmask: The actual pins to write, indicated by 1 bits.
121*/
122
123/*==============================================================================
124 * Board Specific Configuration
125 *============================================================================*/
126
127#ifndef digitalPinHasPWM
128#define digitalPinHasPWM(p) IS_PIN_DIGITAL(p)
129#endif
130
131// Arduino Duemilanove, Diecimila, and NG
132#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
133#if defined(NUM_ANALOG_INPUTS) && NUM_ANALOG_INPUTS == 6
134#define TOTAL_ANALOG_PINS 6
135#define TOTAL_PINS 20 // 14 digital + 6 analog
136#else
137#define TOTAL_ANALOG_PINS 8
138#define TOTAL_PINS 22 // 14 digital + 8 analog
139#endif
140#define VERSION_BLINK_PIN 13
141#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19)
142#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS)
143#define IS_PIN_PWM(p) digitalPinHasPWM(p)
144#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS)
145#define IS_PIN_I2C(p) ((p) == 18 || (p) == 19)
146#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
147#define PIN_TO_DIGITAL(p) (p)
148#define PIN_TO_ANALOG(p) ((p) - 14)
149#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
150#define PIN_TO_SERVO(p) ((p) - 2)
151#define ARDUINO_PINOUT_OPTIMIZE 1
152
153
154// Wiring (and board)
155#elif defined(WIRING)
156#define VERSION_BLINK_PIN WLED
157#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
158#define IS_PIN_ANALOG(p) ((p) >= FIRST_ANALOG_PIN && (p) < (FIRST_ANALOG_PIN+TOTAL_ANALOG_PINS))
159#define IS_PIN_PWM(p) digitalPinHasPWM(p)
160#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
161#define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL)
162#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
163#define PIN_TO_DIGITAL(p) (p)
164#define PIN_TO_ANALOG(p) ((p) - FIRST_ANALOG_PIN)
165#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
166#define PIN_TO_SERVO(p) (p)
167
168
169// old Arduinos
170#elif defined(__AVR_ATmega8__)
171#define TOTAL_ANALOG_PINS 6
172#define TOTAL_PINS 20 // 14 digital + 6 analog
173#define VERSION_BLINK_PIN 13
174#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19)
175#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 19)
176#define IS_PIN_PWM(p) digitalPinHasPWM(p)
177#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS)
178#define IS_PIN_I2C(p) ((p) == 18 || (p) == 19)
179#define PIN_TO_DIGITAL(p) (p)
180#define PIN_TO_ANALOG(p) ((p) - 14)
181#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
182#define PIN_TO_SERVO(p) ((p) - 2)
183#define ARDUINO_PINOUT_OPTIMIZE 1
184
185
186// Arduino Mega
187#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
188#define TOTAL_ANALOG_PINS 16
189#define TOTAL_PINS 70 // 54 digital + 16 analog
190#define VERSION_BLINK_PIN 13
191#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
192#define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS)
193#define IS_PIN_PWM(p) digitalPinHasPWM(p)
194#define IS_PIN_SERVO(p) ((p) >= 2 && (p) - 2 < MAX_SERVOS)
195#define IS_PIN_I2C(p) ((p) == 20 || (p) == 21)
196#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
197#define PIN_TO_DIGITAL(p) (p)
198#define PIN_TO_ANALOG(p) ((p) - 54)
199#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
200#define PIN_TO_SERVO(p) ((p) - 2)
201
202
203// Arduino DUE
204#elif defined(__SAM3X8E__)
205#define TOTAL_ANALOG_PINS 12
206#define TOTAL_PINS 66 // 54 digital + 12 analog
207#define VERSION_BLINK_PIN 13
208#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
209#define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS)
210#define IS_PIN_PWM(p) digitalPinHasPWM(p)
211#define IS_PIN_SERVO(p) ((p) >= 2 && (p) - 2 < MAX_SERVOS)
212#define IS_PIN_I2C(p) ((p) == 20 || (p) == 21) // 70 71
213#define PIN_TO_DIGITAL(p) (p)
214#define PIN_TO_ANALOG(p) ((p) - 54)
215#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
216#define PIN_TO_SERVO(p) ((p) - 2)
217
218
219// Teensy 1.0
220#elif defined(__AVR_AT90USB162__)
221#define TOTAL_ANALOG_PINS 0
222#define TOTAL_PINS 21 // 21 digital + no analog
223#define VERSION_BLINK_PIN 6
224#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
225#define IS_PIN_ANALOG(p) (0)
226#define IS_PIN_PWM(p) digitalPinHasPWM(p)
227#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
228#define IS_PIN_I2C(p) (0)
229#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
230#define PIN_TO_DIGITAL(p) (p)
231#define PIN_TO_ANALOG(p) (0)
232#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
233#define PIN_TO_SERVO(p) (p)
234
235
236// Teensy 2.0
237#elif defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY)
238#define TOTAL_ANALOG_PINS 12
239#define TOTAL_PINS 25 // 11 digital + 12 analog
240#define VERSION_BLINK_PIN 11
241#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
242#define IS_PIN_ANALOG(p) ((p) >= 11 && (p) <= 22)
243#define IS_PIN_PWM(p) digitalPinHasPWM(p)
244#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
245#define IS_PIN_I2C(p) ((p) == 5 || (p) == 6)
246#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
247#define PIN_TO_DIGITAL(p) (p)
248#define PIN_TO_ANALOG(p) (((p)<22)?21-(p):11)
249#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
250#define PIN_TO_SERVO(p) (p)
251
252
253// Teensy 3.0
254#elif defined(__MK20DX128__)
255#define TOTAL_ANALOG_PINS 14
256#define TOTAL_PINS 38 // 24 digital + 10 analog-digital + 4 analog
257#define VERSION_BLINK_PIN 13
258#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) <= 34)
259#define IS_PIN_ANALOG(p) (((p) >= 14 && (p) <= 23) || ((p) >= 34 && (p) <= 38))
260#define IS_PIN_PWM(p) digitalPinHasPWM(p)
261#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
262#define IS_PIN_I2C(p) ((p) == 18 || (p) == 19)
263#define PIN_TO_DIGITAL(p) (p)
264#define PIN_TO_ANALOG(p) (((p)<=23)?(p)-14:(p)-24)
265#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
266#define PIN_TO_SERVO(p) (p)
267
268
269// Teensy++ 1.0 and 2.0
270#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
271#define TOTAL_ANALOG_PINS 8
272#define TOTAL_PINS 46 // 38 digital + 8 analog
273#define VERSION_BLINK_PIN 6
274#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
275#define IS_PIN_ANALOG(p) ((p) >= 38 && (p) < TOTAL_PINS)
276#define IS_PIN_PWM(p) digitalPinHasPWM(p)
277#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
278#define IS_PIN_I2C(p) ((p) == 0 || (p) == 1)
279#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
280#define PIN_TO_DIGITAL(p) (p)
281#define PIN_TO_ANALOG(p) ((p) - 38)
282#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
283#define PIN_TO_SERVO(p) (p)
284
285
286// Leonardo
287#elif defined(__AVR_ATmega32U4__)
288#define TOTAL_ANALOG_PINS 12
289#define TOTAL_PINS 30 // 14 digital + 12 analog + 4 SPI (D14-D17 on ISP header)
290#define VERSION_BLINK_PIN 13
291#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
292#define IS_PIN_ANALOG(p) ((p) >= 18 && (p) < TOTAL_PINS)
293#define IS_PIN_PWM(p) ((p) == 3 || (p) == 5 || (p) == 6 || (p) == 9 || (p) == 10 || (p) == 11 || (p) == 13)
294#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
295#define IS_PIN_I2C(p) ((p) == 2 || (p) == 3)
296#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
297#define PIN_TO_DIGITAL(p) (p)
298#define PIN_TO_ANALOG(p) (p) - 18
299#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
300#define PIN_TO_SERVO(p) (p)
301
302
303// Sanguino
304#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
305#define TOTAL_ANALOG_PINS 8
306#define TOTAL_PINS 32 // 24 digital + 8 analog
307#define VERSION_BLINK_PIN 0
308#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
309#define IS_PIN_ANALOG(p) ((p) >= 24 && (p) < TOTAL_PINS)
310#define IS_PIN_PWM(p) digitalPinHasPWM(p)
311#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
312#define IS_PIN_I2C(p) ((p) == 16 || (p) == 17)
313#define PIN_TO_DIGITAL(p) (p)
314#define PIN_TO_ANALOG(p) ((p) - 24)
315#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
316#define PIN_TO_SERVO(p) ((p) - 2)
317
318
319// Illuminato
320#elif defined(__AVR_ATmega645__)
321#define TOTAL_ANALOG_PINS 6
322#define TOTAL_PINS 42 // 36 digital + 6 analog
323#define VERSION_BLINK_PIN 13
324#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
325#define IS_PIN_ANALOG(p) ((p) >= 36 && (p) < TOTAL_PINS)
326#define IS_PIN_PWM(p) digitalPinHasPWM(p)
327#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
328#define IS_PIN_I2C(p) ((p) == 4 || (p) == 5)
329#define PIN_TO_DIGITAL(p) (p)
330#define PIN_TO_ANALOG(p) ((p) - 36)
331#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
332#define PIN_TO_SERVO(p) ((p) - 2)
333
334
335// anything else
336#else
337#error "Please edit Boards.h with a hardware abstraction for this board"
338#endif
339
340// as long this is not defined for all boards:
341#ifndef IS_PIN_SPI(p)
342#define IS_PIN_SPI(p) 0
343#endif
344
345/*==============================================================================
346 * readPort() - Read an 8 bit port
347 *============================================================================*/
348
349static inline unsigned char readPort(byte, byte) __attribute__((always_inline, unused));
350static inline unsigned char readPort(byte port, byte bitmask)
351{
352#if defined(ARDUINO_PINOUT_OPTIMIZE)
353 if (port == 0) return (PIND & 0xFC) & bitmask; // ignore Rx/Tx 0/1
354 if (port == 1) return ((PINB & 0x3F) | ((PINC & 0x03) << 6)) & bitmask;
355 if (port == 2) return ((PINC & 0x3C) >> 2) & bitmask;
356 return 0;
357#else
358 unsigned char out=0, pin=port*8;
359 if (IS_PIN_DIGITAL(pin+0) && (bitmask & 0x01) && digitalRead(PIN_TO_DIGITAL(pin+0))) out |= 0x01;
360 if (IS_PIN_DIGITAL(pin+1) && (bitmask & 0x02) && digitalRead(PIN_TO_DIGITAL(pin+1))) out |= 0x02;
361 if (IS_PIN_DIGITAL(pin+2) && (bitmask & 0x04) && digitalRead(PIN_TO_DIGITAL(pin+2))) out |= 0x04;
362 if (IS_PIN_DIGITAL(pin+3) && (bitmask & 0x08) && digitalRead(PIN_TO_DIGITAL(pin+3))) out |= 0x08;
363 if (IS_PIN_DIGITAL(pin+4) && (bitmask & 0x10) && digitalRead(PIN_TO_DIGITAL(pin+4))) out |= 0x10;
364 if (IS_PIN_DIGITAL(pin+5) && (bitmask & 0x20) && digitalRead(PIN_TO_DIGITAL(pin+5))) out |= 0x20;
365 if (IS_PIN_DIGITAL(pin+6) && (bitmask & 0x40) && digitalRead(PIN_TO_DIGITAL(pin+6))) out |= 0x40;
366 if (IS_PIN_DIGITAL(pin+7) && (bitmask & 0x80) && digitalRead(PIN_TO_DIGITAL(pin+7))) out |= 0x80;
367 return out;
368#endif
369}
370
371/*==============================================================================
372 * writePort() - Write an 8 bit port, only touch pins specified by a bitmask
373 *============================================================================*/
374
375static inline unsigned char writePort(byte, byte, byte) __attribute__((always_inline, unused));
376static inline unsigned char writePort(byte port, byte value, byte bitmask)
377{
378#if defined(ARDUINO_PINOUT_OPTIMIZE)
379 if (port == 0) {
380 bitmask = bitmask & 0xFC; // do not touch Tx & Rx pins
381 byte valD = value & bitmask;
382 byte maskD = ~bitmask;
383 cli();
384 PORTD = (PORTD & maskD) | valD;
385 sei();
386 } else if (port == 1) {
387 byte valB = (value & bitmask) & 0x3F;
388 byte valC = (value & bitmask) >> 6;
389 byte maskB = ~(bitmask & 0x3F);
390 byte maskC = ~((bitmask & 0xC0) >> 6);
391 cli();
392 PORTB = (PORTB & maskB) | valB;
393 PORTC = (PORTC & maskC) | valC;
394 sei();
395 } else if (port == 2) {
396 bitmask = bitmask & 0x0F;
397 byte valC = (value & bitmask) << 2;
398 byte maskC = ~(bitmask << 2);
399 cli();
400 PORTC = (PORTC & maskC) | valC;
401 sei();
402 }
403#else
404 byte pin=port*8;
405 if ((bitmask & 0x01)) digitalWrite(PIN_TO_DIGITAL(pin+0), (value & 0x01));
406 if ((bitmask & 0x02)) digitalWrite(PIN_TO_DIGITAL(pin+1), (value & 0x02));
407 if ((bitmask & 0x04)) digitalWrite(PIN_TO_DIGITAL(pin+2), (value & 0x04));
408 if ((bitmask & 0x08)) digitalWrite(PIN_TO_DIGITAL(pin+3), (value & 0x08));
409 if ((bitmask & 0x10)) digitalWrite(PIN_TO_DIGITAL(pin+4), (value & 0x10));
410 if ((bitmask & 0x20)) digitalWrite(PIN_TO_DIGITAL(pin+5), (value & 0x20));
411 if ((bitmask & 0x40)) digitalWrite(PIN_TO_DIGITAL(pin+6), (value & 0x40));
412 if ((bitmask & 0x80)) digitalWrite(PIN_TO_DIGITAL(pin+7), (value & 0x80));
413#endif
414}
415
416
417
418
419#ifndef TOTAL_PORTS
420#define TOTAL_PORTS ((TOTAL_PINS + 7) / 8)
421#endif
422
423
424#endif /* Firmata_Boards_h */
425
Note: See TracBrowser for help on using the repository browser.