00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "WProgram.h"
00018 #include "HardwareSerial.h"
00019 #include "Firmata.h"
00020
00021 extern "C" {
00022 #include <string.h>
00023 #include <stdlib.h>
00024 }
00025
00026
00027
00028
00029
00030 void sendValueAsTwo7bitBytes(int value)
00031 {
00032 Serial.print(value & B01111111, BYTE);
00033 Serial.print(value >> 7 & B01111111, BYTE);
00034 }
00035
00036 void startSysex(void)
00037 {
00038 Serial.print(START_SYSEX, BYTE);
00039 }
00040
00041 void endSysex(void)
00042 {
00043 Serial.print(END_SYSEX, BYTE);
00044 }
00045
00046
00047
00048
00049
00050 FirmataClass::FirmataClass(void)
00051 {
00052 firmwareVersionCount = 0;
00053 systemReset();
00054 }
00055
00056
00057
00058
00059
00060
00061 void FirmataClass::begin(void)
00062 {
00063 begin(57600);
00064 }
00065
00066
00067 void FirmataClass::begin(long speed)
00068 {
00069 #if defined(__AVR_ATmega128__) // Wiring
00070 Serial.begin((uint32_t)speed);
00071 #else
00072 Serial.begin(speed);
00073 #endif
00074 blinkVersion();
00075 delay(300);
00076 printVersion();
00077 printFirmwareVersion();
00078 }
00079
00080
00081 void FirmataClass::printVersion(void) {
00082 Serial.print(REPORT_VERSION, BYTE);
00083 Serial.print(FIRMATA_MAJOR_VERSION, BYTE);
00084 Serial.print(FIRMATA_MINOR_VERSION, BYTE);
00085 }
00086
00087 void FirmataClass::blinkVersion(void)
00088 {
00089
00090 pinMode(VERSION_BLINK_PIN,OUTPUT);
00091 pin13strobe(FIRMATA_MAJOR_VERSION, 200, 400);
00092 delay(300);
00093 pin13strobe(2,1,4);
00094 delay(300);
00095 pin13strobe(FIRMATA_MINOR_VERSION, 200, 400);
00096 }
00097
00098 void FirmataClass::printFirmwareVersion(void)
00099 {
00100 byte i;
00101
00102 if(firmwareVersionCount) {
00103 startSysex();
00104 Serial.print(REPORT_FIRMWARE, BYTE);
00105 Serial.print(firmwareVersionVector[0]);
00106 Serial.print(firmwareVersionVector[1]);
00107 for(i=2; i<firmwareVersionCount; ++i) {
00108 sendValueAsTwo7bitBytes(firmwareVersionVector[i]);
00109 }
00110 endSysex();
00111 }
00112 }
00113
00114 void FirmataClass::setFirmwareNameAndVersion(const char *name, byte major, byte minor)
00115 {
00116 const char *filename;
00117 char *extension;
00118
00119
00120 extension = strstr(name, ".cpp");
00121 filename = strrchr(name, '/') + 1;
00122
00123 if(extension && filename) {
00124 firmwareVersionCount = extension - filename + 2;
00125 } else {
00126 firmwareVersionCount = strlen(name) + 2;
00127 filename = name;
00128 }
00129 firmwareVersionVector = (byte *) malloc(firmwareVersionCount);
00130 firmwareVersionVector[firmwareVersionCount] = 0;
00131 firmwareVersionVector[0] = major;
00132 firmwareVersionVector[1] = minor;
00133 strncpy((char*)firmwareVersionVector + 2, filename, firmwareVersionCount - 2);
00134
00135
00136
00137 }
00138
00139
00140
00141
00142 int FirmataClass::available(void)
00143 {
00144 return Serial.available();
00145 }
00146
00147
00148 void FirmataClass::processSysexMessage(void)
00149 {
00150 switch(storedInputData[0]) {
00151 case REPORT_FIRMWARE:
00152 printFirmwareVersion();
00153 break;
00154 case STRING_DATA:
00155 if(currentStringCallback) {
00156 byte bufferLength = (sysexBytesRead - 1) / 2;
00157 char *buffer = (char*)malloc(bufferLength * sizeof(char));
00158 byte i = 1;
00159 byte j = 0;
00160 while(j < bufferLength) {
00161 buffer[j] = (char)storedInputData[i];
00162 i++;
00163 buffer[j] += (char)(storedInputData[i] << 7);
00164 i++;
00165 j++;
00166 }
00167 (*currentStringCallback)(buffer);
00168 }
00169 break;
00170 default:
00171 if(currentSysexCallback)
00172 (*currentSysexCallback)(storedInputData[0], sysexBytesRead - 1, storedInputData + 1);
00173 }
00174 }
00175
00176 void FirmataClass::processInput(void)
00177 {
00178 int inputData = Serial.read();
00179 int command;
00180
00181
00182
00183 if (parsingSysex) {
00184 if(inputData == END_SYSEX) {
00185
00186 parsingSysex = false;
00187
00188 processSysexMessage();
00189 } else {
00190
00191 storedInputData[sysexBytesRead] = inputData;
00192 sysexBytesRead++;
00193 }
00194 } else if( (waitForData > 0) && (inputData < 128) ) {
00195 waitForData--;
00196 storedInputData[waitForData] = inputData;
00197 if( (waitForData==0) && executeMultiByteCommand ) {
00198 switch(executeMultiByteCommand) {
00199 case ANALOG_MESSAGE:
00200 if(currentAnalogCallback) {
00201 (*currentAnalogCallback)(multiByteChannel,
00202 (storedInputData[0] << 7)
00203 + storedInputData[1]);
00204 }
00205 break;
00206 case DIGITAL_MESSAGE:
00207 if(currentDigitalCallback) {
00208 (*currentDigitalCallback)(multiByteChannel,
00209 (storedInputData[0] << 7)
00210 + storedInputData[1]);
00211 }
00212 break;
00213 case SET_PIN_MODE:
00214 if(currentPinModeCallback)
00215 (*currentPinModeCallback)(storedInputData[1], storedInputData[0]);
00216 break;
00217 case REPORT_ANALOG:
00218 if(currentReportAnalogCallback)
00219 (*currentReportAnalogCallback)(multiByteChannel,storedInputData[0]);
00220 break;
00221 case REPORT_DIGITAL:
00222 if(currentReportDigitalCallback)
00223 (*currentReportDigitalCallback)(multiByteChannel,storedInputData[0]);
00224 break;
00225 }
00226 executeMultiByteCommand = 0;
00227 }
00228 } else {
00229
00230 if(inputData < 0xF0) {
00231 command = inputData & 0xF0;
00232 multiByteChannel = inputData & 0x0F;
00233 } else {
00234 command = inputData;
00235
00236 }
00237 switch (command) {
00238 case ANALOG_MESSAGE:
00239 case DIGITAL_MESSAGE:
00240 case SET_PIN_MODE:
00241 waitForData = 2;
00242 executeMultiByteCommand = command;
00243 break;
00244 case REPORT_ANALOG:
00245 case REPORT_DIGITAL:
00246 waitForData = 1;
00247 executeMultiByteCommand = command;
00248 break;
00249 case START_SYSEX:
00250 parsingSysex = true;
00251 sysexBytesRead = 0;
00252 break;
00253 case SYSTEM_RESET:
00254 systemReset();
00255 break;
00256 case REPORT_VERSION:
00257 Firmata.printVersion();
00258 break;
00259 }
00260 }
00261 }
00262
00263
00264
00265
00266
00267 void FirmataClass::sendAnalog(byte pin, int value)
00268 {
00269
00270 Serial.print(ANALOG_MESSAGE | (pin & 0xF), BYTE);
00271 sendValueAsTwo7bitBytes(value);
00272 }
00273
00274
00275 void FirmataClass::sendDigital(byte pin, int value)
00276 {
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 }
00295
00296
00297
00298
00299 void FirmataClass::sendDigitalPort(byte portNumber, int portData)
00300 {
00301 Serial.print(DIGITAL_MESSAGE | (portNumber & 0xF),BYTE);
00302 Serial.print((byte)portData % 128, BYTE);
00303 Serial.print(portData >> 7, BYTE);
00304 }
00305
00306
00307 void FirmataClass::sendSysex(byte command, byte bytec, byte* bytev)
00308 {
00309 byte i;
00310 startSysex();
00311 Serial.print(command, BYTE);
00312 for(i=0; i<bytec; i++) {
00313 sendValueAsTwo7bitBytes(bytev[i]);
00314 }
00315 endSysex();
00316 }
00317
00318 void FirmataClass::sendString(byte command, const char* string)
00319 {
00320 sendSysex(command, strlen(string), (byte *)string);
00321 }
00322
00323
00324
00325 void FirmataClass::sendString(const char* string)
00326 {
00327 sendString(STRING_DATA, string);
00328 }
00329
00330
00331
00332
00333
00334 void FirmataClass::attach(byte command, callbackFunction newFunction)
00335 {
00336 switch(command) {
00337 case ANALOG_MESSAGE: currentAnalogCallback = newFunction; break;
00338 case DIGITAL_MESSAGE: currentDigitalCallback = newFunction; break;
00339 case REPORT_ANALOG: currentReportAnalogCallback = newFunction; break;
00340 case REPORT_DIGITAL: currentReportDigitalCallback = newFunction; break;
00341 case SET_PIN_MODE: currentPinModeCallback = newFunction; break;
00342 }
00343 }
00344
00345 void FirmataClass::attach(byte command, systemResetCallbackFunction newFunction)
00346 {
00347 switch(command) {
00348 case SYSTEM_RESET: currentSystemResetCallback = newFunction; break;
00349 }
00350 }
00351
00352 void FirmataClass::attach(byte command, stringCallbackFunction newFunction)
00353 {
00354 switch(command) {
00355 case STRING_DATA: currentStringCallback = newFunction; break;
00356 }
00357 }
00358
00359 void FirmataClass::attach(byte command, sysexCallbackFunction newFunction)
00360 {
00361 currentSysexCallback = newFunction;
00362 }
00363
00364 void FirmataClass::detach(byte command)
00365 {
00366 switch(command) {
00367 case SYSTEM_RESET: currentSystemResetCallback = NULL; break;
00368 case STRING_DATA: currentStringCallback = NULL; break;
00369 case START_SYSEX: currentSysexCallback = NULL; break;
00370 default:
00371 attach(command, (callbackFunction)NULL);
00372 }
00373 }
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 void FirmataClass::systemReset(void)
00401 {
00402 byte i;
00403
00404 waitForData = 0;
00405 executeMultiByteCommand = 0;
00406 multiByteChannel = 0;
00407
00408
00409 for(i=0; i<MAX_DATA_BYTES; i++) {
00410 storedInputData[i] = 0;
00411 }
00412
00413 parsingSysex = false;
00414 sysexBytesRead = 0;
00415
00416 if(currentSystemResetCallback)
00417 (*currentSystemResetCallback)();
00418
00419
00420 }
00421
00422
00423
00424
00425
00426 void FirmataClass::pin13strobe(int count, int onInterval, int offInterval)
00427 {
00428 byte i;
00429 pinMode(VERSION_BLINK_PIN, OUTPUT);
00430 for(i=0; i<count; i++) {
00431 delay(offInterval);
00432 digitalWrite(VERSION_BLINK_PIN, HIGH);
00433 delay(onInterval);
00434 digitalWrite(VERSION_BLINK_PIN, LOW);
00435 }
00436 }
00437
00438
00439
00440 FirmataClass Firmata;
00441
00442