D:/DRISSI/arduino-0022/arduino-0022/libraries/Firmata/Boards.h
00001 /* Boards.h - Hardware Abstraction Layer for Firmata library */
00002 
00003 #ifndef Firmata_Boards_h
00004 #define Firmata_Boards_h
00005 
00006 #include <WProgram.h>   // for digitalRead, digitalWrite, etc
00007 
00008 // Normally Servo.h must be included before Firmata.h (which then includes
00009 // this file).  If Servo.h wasn't included, this allows the code to still
00010 // compile, but without support for any Servos.  Hopefully that's what the
00011 // user intended by not including Servo.h
00012 #ifndef MAX_SERVOS
00013 #define MAX_SERVOS 0
00014 #endif
00015 
00016 /*
00017     Firmata Hardware Abstraction Layer
00018 
00019 Firmata is built on top of the hardware abstraction functions of Arduino,
00020 specifically digitalWrite, digitalRead, analogWrite, analogRead, and 
00021 pinMode.  While these functions offer simple integer pin numbers, Firmata
00022 needs more information than is provided by Arduino.  This file provides
00023 all other hardware specific details.  To make Firmata support a new board,
00024 only this file should require editing.
00025 
00026 The key concept is every "pin" implemented by Firmata may be mapped to
00027 any pin as implemented by Arduino.  Usually a simple 1-to-1 mapping is
00028 best, but such mapping should not be assumed.  This hardware abstraction
00029 layer allows Firmata to implement any number of pins which map onto the
00030 Arduino implemented pins in almost any arbitrary way.
00031 
00032 
00033 General Constants:
00034 
00035 These constants provide basic information Firmata requires.
00036 
00037 TOTAL_PINS: The total number of pins Firmata implemented by Firmata.
00038     Usually this will match the number of pins the Arduino functions
00039     implement, including any pins pins capable of analog or digital.
00040     However, Firmata may implement any number of pins.  For example,
00041     on Arduino Mini with 8 analog inputs, 6 of these may be used
00042     for digital functions, and 2 are analog only.  On such boards,
00043     Firmata can implement more pins than Arduino's pinMode()
00044     function, in order to accommodate those special pins.  The
00045     Firmata protocol supports a maximum of 128 pins, so this
00046     constant must not exceed 128.
00047 
00048 TOTAL_ANALOG_PINS: The total number of analog input pins implemented.
00049     The Firmata protocol allows up to 16 analog inputs, accessed
00050     using offsets 0 to 15.  Because Firmata presents the analog
00051     inputs using different offsets than the actual pin numbers
00052     (a legacy of Arduino's analogRead function, and the way the
00053     analog input capable pins are physically labeled on all
00054     Arduino boards), the total number of analog input signals
00055     must be specified.  16 is the maximum.
00056 
00057 VERSION_BLINK_PIN: When Firmata starts up, it will blink the version
00058     number.  This constant is the Arduino pin number where a
00059     LED is connected.
00060 
00061 
00062 Pin Mapping Macros:
00063 
00064 These macros provide the mapping between pins as implemented by
00065 Firmata protocol and the actual pin numbers used by the Arduino
00066 functions.  Even though such mappings are often simple, pin
00067 numbers received by Firmata protocol should always be used as
00068 input to these macros, and the result of the macro should be
00069 used with with any Arduino function.
00070 
00071 When Firmata is extended to support a new pin mode or feature,
00072 a pair of macros should be added and used for all hardware
00073 access.  For simple 1:1 mapping, these macros add no actual
00074 overhead, yet their consistent use allows source code which
00075 uses them consistently to be easily adapted to all other boards
00076 with different requirements.
00077 
00078 IS_PIN_XXXX(pin): The IS_PIN macros resolve to true or non-zero
00079     if a pin as implemented by Firmata corresponds to a pin
00080     that actually implements the named feature.
00081 
00082 PIN_TO_XXXX(pin): The PIN_TO macros translate pin numbers as
00083     implemented by Firmata to the pin numbers needed as inputs
00084     to the Arduino functions.  The corresponding IS_PIN macro
00085     should always be tested before using a PIN_TO macro, so
00086     these macros only need to handle valid Firmata pin
00087     numbers for the named feature.
00088 
00089 
00090 Port Access Inline Funtions:
00091 
00092 For efficiency, Firmata protocol provides access to digital
00093 input and output pins grouped by 8 bit ports.  When these
00094 groups of 8 correspond to actual 8 bit ports as implemented
00095 by the hardware, these inline functions can provide high
00096 speed direct port access.  Otherwise, a default implementation
00097 using 8 calls to digitalWrite or digitalRead is used.
00098 
00099 When porting Firmata to a new board, it is recommended to
00100 use the default functions first and focus only on the constants
00101 and macros above.  When those are working, if optimized port
00102 access is desired, these inline functions may be extended.
00103 The recommended approach defines a symbol indicating which
00104 optimization to use, and then conditional complication is
00105 used within these functions.
00106 
00107 readPort(port, bitmask):  Read an 8 bit port, returning the value.
00108    port:    The port number, Firmata pins port*8 to port*8+7
00109    bitmask: The actual pins to read, indicated by 1 bits.
00110 
00111 writePort(port, value, bitmask):  Write an 8 bit port.
00112    port:    The port number, Firmata pins port*8 to port*8+7
00113    value:   The 8 bit value to write
00114    bitmask: The actual pins to write, indicated by 1 bits.
00115 */
00116 
00117 /*==============================================================================
00118  * Board Specific Configuration
00119  *============================================================================*/
00120 
00121 // Arduino Duemilanove, Diecimila, and NG
00122 #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
00123 #define TOTAL_ANALOG_PINS       8
00124 #define TOTAL_PINS              24 // 14 digital + 2 unused + 8 analog
00125 #define VERSION_BLINK_PIN       13
00126 #define IS_PIN_DIGITAL(p)       (((p) >= 2 && (p) <= 13) || ((p) >= 16 && (p) <= 21))
00127 #define IS_PIN_ANALOG(p)        ((p) >= 16 && (p) <= 23)
00128 #define IS_PIN_PWM(p)           IS_PIN_DIGITAL(p)
00129 #define IS_PIN_SERVO(p)         ((p) >= 2 && (p) <= 13 && (p) - 2 < MAX_SERVOS)
00130 #define IS_PIN_I2C(p)           (0)
00131 #define PIN_TO_DIGITAL(p)       (((p) < 16) ? (p) : (p) - 2)
00132 #define PIN_TO_ANALOG(p)        ((p) - 16)
00133 #define PIN_TO_PWM(p)           PIN_TO_DIGITAL(p)
00134 #define PIN_TO_SERVO(p)         ((p) - 2)
00135 #define ARDUINO_PINOUT_OPTIMIZE 1
00136 
00137 
00138 // old Arduinos
00139 #elif defined(__AVR_ATmega8__)
00140 #define TOTAL_ANALOG_PINS       6
00141 #define TOTAL_PINS              22 // 14 digital + 2 unused + 6 analog
00142 #define VERSION_BLINK_PIN       13
00143 #define IS_PIN_DIGITAL(p)       (((p) >= 2 && (p) <= 13) || ((p) >= 16 && (p) <= 21))
00144 #define IS_PIN_ANALOG(p)        ((p) >= 16 && (p) <= 21)
00145 #define IS_PIN_PWM(p)           IS_PIN_DIGITAL(p)
00146 #define IS_PIN_SERVO(p)         ((p) >= 2 && (p) <= 13 && (p) - 2 < MAX_SERVOS)
00147 #define IS_PIN_I2C(p)           (0)
00148 #define PIN_TO_DIGITAL(p)       (((p) < 16) ? (p) : (p) - 2)
00149 #define PIN_TO_ANALOG(p)        ((p) - 16)
00150 #define PIN_TO_PWM(p)           PIN_TO_DIGITAL(p)
00151 #define PIN_TO_SERVO(p)         ((p) - 2)
00152 #define ARDUINO_PINOUT_OPTIMIZE 1
00153 
00154 
00155 // Arduino Mega
00156 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
00157 #define TOTAL_ANALOG_PINS       16
00158 #define TOTAL_PINS              70 // 54 digital + 16 analog
00159 #define VERSION_BLINK_PIN       13
00160 #define IS_PIN_DIGITAL(p)       ((p) >= 2 && (p) < TOTAL_PINS)
00161 #define IS_PIN_ANALOG(p)        ((p) >= 54 && (p) < TOTAL_PINS)
00162 #define IS_PIN_PWM(p)           IS_PIN_DIGITAL(p)
00163 #define IS_PIN_SERVO(p)         ((p) >= 2 && (p) - 2 < MAX_SERVOS)
00164 #define IS_PIN_I2C(p)           (0)
00165 #define PIN_TO_DIGITAL(p)       (p)
00166 #define PIN_TO_ANALOG(p)        ((p) - 54)
00167 #define PIN_TO_PWM(p)           PIN_TO_DIGITAL(p)
00168 #define PIN_TO_SERVO(p)         ((p) - 2)
00169 
00170 
00171 // Wiring
00172 #elif defined(__AVR_ATmega128__)
00173 #define TOTAL_ANALOG_PINS       8
00174 #define TOTAL_PINS              51
00175 #define VERSION_BLINK_PIN       48
00176 // TODO: hardware abstraction for wiring board
00177 
00178 
00179 // Teensy 1.0
00180 #elif defined(__AVR_AT90USB162__)
00181 #define TOTAL_ANALOG_PINS       0
00182 #define TOTAL_PINS              21 // 21 digital + no analog
00183 #define VERSION_BLINK_PIN       6
00184 #define IS_PIN_DIGITAL(p)       ((p) >= 0 && (p) < TOTAL_PINS)
00185 #define IS_PIN_ANALOG(p)        (0)
00186 #define IS_PIN_PWM(p)           IS_PIN_DIGITAL(p)
00187 #define IS_PIN_SERVO(p)         ((p) >= 0 && (p) < MAX_SERVOS)
00188 #define IS_PIN_I2C(p)           (0)
00189 #define PIN_TO_DIGITAL(p)       (p)
00190 #define PIN_TO_ANALOG(p)        (0)
00191 #define PIN_TO_PWM(p)           PIN_TO_DIGITAL(p)
00192 #define PIN_TO_SERVO(p)         (p)
00193 
00194 
00195 // Teensy 2.0
00196 #elif defined(__AVR_ATmega32U4__)
00197 #define TOTAL_ANALOG_PINS       12
00198 #define TOTAL_PINS              25 // 11 digital + 12 analog
00199 #define VERSION_BLINK_PIN       11
00200 #define IS_PIN_DIGITAL(p)       ((p) >= 0 && (p) < TOTAL_PINS)
00201 #define IS_PIN_ANALOG(p)        ((p) >= 11 && (p) <= 22)
00202 #define IS_PIN_PWM(p)           IS_PIN_DIGITAL(p)
00203 #define IS_PIN_SERVO(p)         ((p) >= 0 && (p) < MAX_SERVOS)
00204 #define IS_PIN_I2C(p)           (0)
00205 #define PIN_TO_DIGITAL(p)       (p)
00206 #define PIN_TO_ANALOG(p)        (((p)<22)?21-(p):11)
00207 #define PIN_TO_PWM(p)           PIN_TO_DIGITAL(p)
00208 #define PIN_TO_SERVO(p)         (p)
00209 
00210 
00211 // Teensy++ 1.0 and 2.0
00212 #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
00213 #define TOTAL_ANALOG_PINS       8
00214 #define TOTAL_PINS              46 // 38 digital + 8 analog
00215 #define VERSION_BLINK_PIN       6
00216 #define IS_PIN_DIGITAL(p)       ((p) >= 0 && (p) < TOTAL_PINS)
00217 #define IS_PIN_ANALOG(p)        ((p) >= 38 && (p) < TOTAL_PINS)
00218 #define IS_PIN_PWM(p)           IS_PIN_DIGITAL(p)
00219 #define IS_PIN_SERVO(p)         ((p) >= 0 && (p) < MAX_SERVOS)
00220 #define IS_PIN_I2C(p)           (0)
00221 #define PIN_TO_DIGITAL(p)       (p)
00222 #define PIN_TO_ANALOG(p)        ((p) - 38)
00223 #define PIN_TO_PWM(p)           PIN_TO_DIGITAL(p)
00224 #define PIN_TO_SERVO(p)         (p)
00225 
00226 
00227 // Sanguino
00228 #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
00229 #define TOTAL_ANALOG_PINS       8
00230 #define TOTAL_PINS              32 // 24 digital + 8 analog
00231 #define VERSION_BLINK_PIN       0
00232 #define IS_PIN_DIGITAL(p)       ((p) >= 2 && (p) < TOTAL_PINS)
00233 #define IS_PIN_ANALOG(p)        ((p) >= 24 && (p) < TOTAL_PINS)
00234 #define IS_PIN_PWM(p)           IS_PIN_DIGITAL(p)
00235 #define IS_PIN_SERVO(p)         ((p) >= 0 && (p) < MAX_SERVOS)
00236 #define IS_PIN_I2C(p)           (0)
00237 #define PIN_TO_DIGITAL(p)       (p)
00238 #define PIN_TO_ANALOG(p)        ((p) - 24)
00239 #define PIN_TO_PWM(p)           PIN_TO_DIGITAL(p)
00240 #define PIN_TO_SERVO(p)         ((p) - 2)
00241 
00242 
00243 // Illuminato
00244 #elif defined(__AVR_ATmega645__)
00245 #define TOTAL_ANALOG_PINS       6
00246 #define TOTAL_PINS              42 // 36 digital + 6 analog
00247 #define VERSION_BLINK_PIN       13
00248 #define IS_PIN_DIGITAL(p)       ((p) >= 2 && (p) < TOTAL_PINS)
00249 #define IS_PIN_ANALOG(p)        ((p) >= 36 && (p) < TOTAL_PINS)
00250 #define IS_PIN_PWM(p)           IS_PIN_DIGITAL(p)
00251 #define IS_PIN_SERVO(p)         ((p) >= 0 && (p) < MAX_SERVOS)
00252 #define IS_PIN_I2C(p)           (0)
00253 #define PIN_TO_DIGITAL(p)       (p)
00254 #define PIN_TO_ANALOG(p)        ((p) - 36)
00255 #define PIN_TO_PWM(p)           PIN_TO_DIGITAL(p)
00256 #define PIN_TO_SERVO(p)         ((p) - 2)
00257 
00258 
00259 // anything else
00260 #else
00261 #error "Please edit Boards.h with a hardware abstraction for this board"
00262 #endif
00263 
00264 
00265 /*==============================================================================
00266  * readPort() - Read an 8 bit port
00267  *============================================================================*/
00268 
00269 static inline unsigned char readPort(byte, byte) __attribute__((always_inline, unused));
00270 static inline unsigned char readPort(byte port, byte bitmask)
00271 {
00272 #if defined(ARDUINO_PINOUT_OPTIMIZE)
00273         if (port == 0) return PIND & B11111100 & bitmask; // ignore Rx/Tx 0/1
00274         if (port == 1) return PINB & B00111111 & bitmask; // pins 8-13 (14,15 are disabled for the crystal)
00275         if (port == 2) return PINC & bitmask;
00276         return 0;
00277 #else
00278         unsigned char out=0, pin=port*8;
00279         if (IS_PIN_DIGITAL(pin+0) && (bitmask & 0x01) && digitalRead(PIN_TO_DIGITAL(pin+0))) out |= 0x01;
00280         if (IS_PIN_DIGITAL(pin+1) && (bitmask & 0x02) && digitalRead(PIN_TO_DIGITAL(pin+1))) out |= 0x02;
00281         if (IS_PIN_DIGITAL(pin+2) && (bitmask & 0x04) && digitalRead(PIN_TO_DIGITAL(pin+2))) out |= 0x04;
00282         if (IS_PIN_DIGITAL(pin+3) && (bitmask & 0x08) && digitalRead(PIN_TO_DIGITAL(pin+3))) out |= 0x08;
00283         if (IS_PIN_DIGITAL(pin+4) && (bitmask & 0x10) && digitalRead(PIN_TO_DIGITAL(pin+4))) out |= 0x10;
00284         if (IS_PIN_DIGITAL(pin+5) && (bitmask & 0x20) && digitalRead(PIN_TO_DIGITAL(pin+5))) out |= 0x20;
00285         if (IS_PIN_DIGITAL(pin+6) && (bitmask & 0x40) && digitalRead(PIN_TO_DIGITAL(pin+6))) out |= 0x40;
00286         if (IS_PIN_DIGITAL(pin+7) && (bitmask & 0x80) && digitalRead(PIN_TO_DIGITAL(pin+7))) out |= 0x80;
00287         return out;
00288 #endif
00289 }
00290 
00291 /*==============================================================================
00292  * writePort() - Write an 8 bit port, only touch pins specified by a bitmask
00293  *============================================================================*/
00294 
00295 static inline unsigned char writePort(byte, byte, byte) __attribute__((always_inline, unused));
00296 static inline unsigned char writePort(byte port, byte value, byte bitmask)
00297 {
00298 #if defined(ARDUINO_PINOUT_OPTIMIZE)
00299         if (port == 0) {
00300                 bitmask = bitmask & 0xFC;  // Tx & Rx pins
00301                 cli();
00302                 PORTD = (PORTD & ~bitmask) | (bitmask & value);
00303                 sei();
00304         } else if (port == 1) {
00305                 cli();
00306                 PORTB = (PORTB & ~bitmask) | (bitmask & value);
00307                 sei();
00308         } else if (port == 2) {
00309                 cli();
00310                 PORTC = (PORTC & ~bitmask) | (bitmask & value);
00311                 sei();
00312         }
00313 #else
00314         byte pin=port*8;
00315         if ((bitmask & 0x01)) digitalWrite(PIN_TO_DIGITAL(pin+0), (value & 0x01));
00316         if ((bitmask & 0x02)) digitalWrite(PIN_TO_DIGITAL(pin+1), (value & 0x02));
00317         if ((bitmask & 0x04)) digitalWrite(PIN_TO_DIGITAL(pin+2), (value & 0x04));
00318         if ((bitmask & 0x08)) digitalWrite(PIN_TO_DIGITAL(pin+3), (value & 0x08));
00319         if ((bitmask & 0x10)) digitalWrite(PIN_TO_DIGITAL(pin+4), (value & 0x10));
00320         if ((bitmask & 0x20)) digitalWrite(PIN_TO_DIGITAL(pin+5), (value & 0x20));
00321         if ((bitmask & 0x40)) digitalWrite(PIN_TO_DIGITAL(pin+6), (value & 0x40));
00322         if ((bitmask & 0x80)) digitalWrite(PIN_TO_DIGITAL(pin+7), (value & 0x80));
00323 #endif
00324 }
00325 
00326 
00327 
00328 
00329 #ifndef TOTAL_PORTS
00330 #define TOTAL_PORTS             ((TOTAL_PINS + 7) / 8)
00331 #endif
00332 
00333 
00334 #endif /* Firmata_Boards_h */
00335