|
| 1 | +/* |
| 2 | + Firmata.h - Firmata library v2.4.4 - 2015-8-9 |
| 3 | + Copyright (c) 2006-2008 Hans-Christoph Steiner. All rights reserved. |
| 4 | +
|
| 5 | + This library is free software; you can redistribute it and/or |
| 6 | + modify it under the terms of the GNU Lesser General Public |
| 7 | + License as published by the Free Software Foundation; either |
| 8 | + version 2.1 of the License, or (at your option) any later version. |
| 9 | +
|
| 10 | + See file LICENSE.txt for further informations on licensing terms. |
| 11 | +*/ |
| 12 | + |
| 13 | +#ifndef Firmata_h |
| 14 | +#define Firmata_h |
| 15 | + |
| 16 | +#include "Boards.h" /* Hardware Abstraction Layer + Wiring/Arduino */ |
| 17 | + |
| 18 | +/* Version numbers for the protocol. The protocol is still changing, so these |
| 19 | + * version numbers are important. This number can be queried so that host |
| 20 | + * software can test whether it will be compatible with the currently |
| 21 | + * installed firmware. */ |
| 22 | +#define FIRMATA_MAJOR_VERSION 2 // for non-compatible changes |
| 23 | +#define FIRMATA_MINOR_VERSION 4 // for backwards compatible changes |
| 24 | +#define FIRMATA_BUGFIX_VERSION 4 // for bugfix releases |
| 25 | + |
| 26 | +#define MAX_DATA_BYTES 64 // max number of data bytes in incoming messages |
| 27 | + |
| 28 | +// message command bytes (128-255/0x80-0xFF) |
| 29 | +#define DIGITAL_MESSAGE 0x90 // send data for a digital port (collection of 8 pins) |
| 30 | +#define ANALOG_MESSAGE 0xE0 // send data for an analog pin (or PWM) |
| 31 | +#define REPORT_ANALOG 0xC0 // enable analog input by pin # |
| 32 | +#define REPORT_DIGITAL 0xD0 // enable digital input by port pair |
| 33 | +// |
| 34 | +#define SET_PIN_MODE 0xF4 // set a pin to INPUT/OUTPUT/PWM/etc |
| 35 | +// |
| 36 | +#define REPORT_VERSION 0xF9 // report protocol version |
| 37 | +#define SYSTEM_RESET 0xFF // reset from MIDI |
| 38 | +// |
| 39 | +#define START_SYSEX 0xF0 // start a MIDI Sysex message |
| 40 | +#define END_SYSEX 0xF7 // end a MIDI Sysex message |
| 41 | + |
| 42 | +// extended command set using sysex (0-127/0x00-0x7F) |
| 43 | +/* 0x00-0x0F reserved for user-defined commands */ |
| 44 | +#define ENCODER_DATA 0x61 // reply with encoders current positions |
| 45 | +#define SERVO_CONFIG 0x70 // set max angle, minPulse, maxPulse, freq |
| 46 | +#define STRING_DATA 0x71 // a string message with 14-bits per char |
| 47 | +#define STEPPER_DATA 0x72 // control a stepper motor |
| 48 | +#define ONEWIRE_DATA 0x73 // send an OneWire read/write/reset/select/skip/search request |
| 49 | +#define SHIFT_DATA 0x75 // a bitstream to/from a shift register |
| 50 | +#define I2C_REQUEST 0x76 // send an I2C read/write request |
| 51 | +#define I2C_REPLY 0x77 // a reply to an I2C read request |
| 52 | +#define I2C_CONFIG 0x78 // config I2C settings such as delay times and power pins |
| 53 | +#define EXTENDED_ANALOG 0x6F // analog write (PWM, Servo, etc) to any pin |
| 54 | +#define PIN_STATE_QUERY 0x6D // ask for a pin's current mode and value |
| 55 | +#define PIN_STATE_RESPONSE 0x6E // reply with pin's current mode and value |
| 56 | +#define CAPABILITY_QUERY 0x6B // ask for supported modes and resolution of all pins |
| 57 | +#define CAPABILITY_RESPONSE 0x6C // reply with supported modes and resolution |
| 58 | +#define ANALOG_MAPPING_QUERY 0x69 // ask for mapping of analog to pin numbers |
| 59 | +#define ANALOG_MAPPING_RESPONSE 0x6A // reply with mapping info |
| 60 | +#define REPORT_FIRMWARE 0x79 // report name and version of the firmware |
| 61 | +#define SAMPLING_INTERVAL 0x7A // set the poll rate of the main loop |
| 62 | +#define SCHEDULER_DATA 0x7B // send a createtask/deletetask/addtotask/schedule/querytasks/querytask request to the scheduler |
| 63 | +#define SYSEX_NON_REALTIME 0x7E // MIDI Reserved for non-realtime messages |
| 64 | +#define SYSEX_REALTIME 0x7F // MIDI Reserved for realtime messages |
| 65 | +// these are DEPRECATED to make the naming more consistent |
| 66 | +#define FIRMATA_STRING 0x71 // same as STRING_DATA |
| 67 | +#define SYSEX_I2C_REQUEST 0x76 // same as I2C_REQUEST |
| 68 | +#define SYSEX_I2C_REPLY 0x77 // same as I2C_REPLY |
| 69 | +#define SYSEX_SAMPLING_INTERVAL 0x7A // same as SAMPLING_INTERVAL |
| 70 | + |
| 71 | +// pin modes |
| 72 | +//#define INPUT 0x00 // defined in Arduino.h |
| 73 | +//#define OUTPUT 0x01 // defined in Arduino.h |
| 74 | +#define ANALOG 0x02 // analog pin in analogInput mode |
| 75 | +#define PWM 0x03 // digital pin in PWM output mode |
| 76 | +#define SERVO 0x04 // digital pin in Servo output mode |
| 77 | +#define SHIFT 0x05 // shiftIn/shiftOut mode |
| 78 | +#define I2C 0x06 // pin included in I2C setup |
| 79 | +#define ONEWIRE 0x07 // pin configured for 1-wire |
| 80 | +#define STEPPER 0x08 // pin configured for stepper motor |
| 81 | +#define ENCODER 0x09 // pin configured for rotary encoders |
| 82 | +#define IGNORE 0x7F // pin configured to be ignored by digitalWrite and capabilityResponse |
| 83 | +#define TOTAL_PIN_MODES 11 |
| 84 | + |
| 85 | +extern "C" { |
| 86 | + // callback function types |
| 87 | + typedef void (*callbackFunction)(byte, int); |
| 88 | + typedef void (*systemResetCallbackFunction)(void); |
| 89 | + typedef void (*stringCallbackFunction)(char *); |
| 90 | + typedef void (*sysexCallbackFunction)(byte command, byte argc, byte *argv); |
| 91 | +} |
| 92 | + |
| 93 | + |
| 94 | +// TODO make it a subclass of a generic Serial/Stream base class |
| 95 | +class FirmataClass |
| 96 | +{ |
| 97 | + public: |
| 98 | + FirmataClass(); |
| 99 | + /* Arduino constructors */ |
| 100 | + void begin(); |
| 101 | + void begin(long); |
| 102 | + void begin(Stream &s); |
| 103 | + /* querying functions */ |
| 104 | + void printVersion(void); |
| 105 | + void blinkVersion(void); |
| 106 | + void printFirmwareVersion(void); |
| 107 | + //void setFirmwareVersion(byte major, byte minor); // see macro below |
| 108 | + void setFirmwareNameAndVersion(const char *name, byte major, byte minor); |
| 109 | + /* serial receive handling */ |
| 110 | + int available(void); |
| 111 | + void processInput(void); |
| 112 | + /* serial send handling */ |
| 113 | + void sendAnalog(byte pin, int value); |
| 114 | + void sendDigital(byte pin, int value); // TODO implement this |
| 115 | + void sendDigitalPort(byte portNumber, int portData); |
| 116 | + void sendString(const char *string); |
| 117 | + void sendString(byte command, const char *string); |
| 118 | + void sendSysex(byte command, byte bytec, byte *bytev); |
| 119 | + void write(byte c); |
| 120 | + /* attach & detach callback functions to messages */ |
| 121 | + void attach(byte command, callbackFunction newFunction); |
| 122 | + void attach(byte command, systemResetCallbackFunction newFunction); |
| 123 | + void attach(byte command, stringCallbackFunction newFunction); |
| 124 | + void attach(byte command, sysexCallbackFunction newFunction); |
| 125 | + void detach(byte command); |
| 126 | + |
| 127 | + /* utility methods */ |
| 128 | + void sendValueAsTwo7bitBytes(int value); |
| 129 | + void startSysex(void); |
| 130 | + void endSysex(void); |
| 131 | + |
| 132 | + private: |
| 133 | + Stream *FirmataStream; |
| 134 | + /* firmware name and version */ |
| 135 | + byte firmwareVersionCount; |
| 136 | + byte *firmwareVersionVector; |
| 137 | + /* input message handling */ |
| 138 | + byte waitForData; // this flag says the next serial input will be data |
| 139 | + byte executeMultiByteCommand; // execute this after getting multi-byte data |
| 140 | + byte multiByteChannel; // channel data for multiByteCommands |
| 141 | + byte storedInputData[MAX_DATA_BYTES]; // multi-byte data |
| 142 | + /* sysex */ |
| 143 | + boolean parsingSysex; |
| 144 | + int sysexBytesRead; |
| 145 | + /* callback functions */ |
| 146 | + callbackFunction currentAnalogCallback; |
| 147 | + callbackFunction currentDigitalCallback; |
| 148 | + callbackFunction currentReportAnalogCallback; |
| 149 | + callbackFunction currentReportDigitalCallback; |
| 150 | + callbackFunction currentPinModeCallback; |
| 151 | + systemResetCallbackFunction currentSystemResetCallback; |
| 152 | + stringCallbackFunction currentStringCallback; |
| 153 | + sysexCallbackFunction currentSysexCallback; |
| 154 | + |
| 155 | + /* private methods ------------------------------ */ |
| 156 | + void processSysexMessage(void); |
| 157 | + void systemReset(void); |
| 158 | + void strobeBlinkPin(int count, int onInterval, int offInterval); |
| 159 | +}; |
| 160 | + |
| 161 | +extern FirmataClass Firmata; |
| 162 | + |
| 163 | +/*============================================================================== |
| 164 | + * MACROS |
| 165 | + *============================================================================*/ |
| 166 | + |
| 167 | +/* shortcut for setFirmwareNameAndVersion() that uses __FILE__ to set the |
| 168 | + * firmware name. It needs to be a macro so that __FILE__ is included in the |
| 169 | + * firmware source file rather than the library source file. |
| 170 | + */ |
| 171 | +#define setFirmwareVersion(x, y) setFirmwareNameAndVersion(__FILE__, x, y) |
| 172 | + |
| 173 | +#endif /* Firmata_h */ |
0 commit comments