From fd76083dad2dedd18ae058f3657e3645c8b39bde Mon Sep 17 00:00:00 2001 From: "Zachary J. Fields" Date: Mon, 13 Mar 2017 00:07:37 -0700 Subject: [PATCH 01/81] firmware callbacks --- Firmata.cpp | 2 +- Firmata.h | 4 ++-- FirmataParser.cpp | 43 ++++++++++++++++++++++++++++++++++--------- FirmataParser.h | 8 +++++--- 4 files changed, 42 insertions(+), 15 deletions(-) diff --git a/Firmata.cpp b/Firmata.cpp index 250d5f12..6134ebfa 100644 --- a/Firmata.cpp +++ b/Firmata.cpp @@ -94,7 +94,7 @@ FirmataClass::FirmataClass() parser.attach(SET_DIGITAL_PIN_VALUE, (FirmataParser::callbackFunction)staticPinValueCallback, (void *)NULL); parser.attach(STRING_DATA, (FirmataParser::stringCallbackFunction)staticStringCallback, (void *)NULL); parser.attach(START_SYSEX, (FirmataParser::sysexCallbackFunction)staticSysexCallback, (void *)NULL); - parser.attach(REPORT_FIRMWARE, (FirmataParser::systemCallbackFunction)staticReportFirmwareCallback, this); + parser.attach(REPORT_FIRMWARE, (FirmataParser::versionCallbackFunction)staticReportFirmwareCallback, this); parser.attach(REPORT_VERSION, (FirmataParser::systemCallbackFunction)staticReportVersionCallback, this); parser.attach(SYSTEM_RESET, (FirmataParser::systemCallbackFunction)staticSystemResetCallback, (void *)NULL); } diff --git a/Firmata.h b/Firmata.h index 60eef9eb..cda11a6e 100644 --- a/Firmata.h +++ b/Firmata.h @@ -148,9 +148,9 @@ class FirmataClass inline static void staticPinValueCallback (void *, uint8_t command, uint16_t value) { if ( currentPinValueCallback ) { currentPinValueCallback(command, (int)value); } } inline static void staticReportAnalogCallback (void *, uint8_t command, uint16_t value) { if ( currentReportAnalogCallback ) { currentReportAnalogCallback(command, (int)value); } } inline static void staticReportDigitalCallback (void *, uint8_t command, uint16_t value) { if ( currentReportDigitalCallback ) { currentReportDigitalCallback(command, (int)value); } } - inline static void staticStringCallback (void *, char * c_str) { if ( currentStringCallback ) { currentStringCallback(c_str); } } + inline static void staticStringCallback (void *, const char * c_str) { if ( currentStringCallback ) { currentStringCallback((char *)c_str); } } inline static void staticSysexCallback (void *, uint8_t command, size_t argc, uint8_t *argv) { if ( currentSysexCallback ) { currentSysexCallback(command, (uint8_t)argc, argv); } } - inline static void staticReportFirmwareCallback (void * context) { if ( context ) { ((FirmataClass *)context)->printFirmwareVersion(); } } + inline static void staticReportFirmwareCallback (void * context, size_t, size_t, const char *) { if ( context ) { ((FirmataClass *)context)->printFirmwareVersion(); } } inline static void staticReportVersionCallback (void * context) { if ( context ) { ((FirmataClass *)context)->printVersion(); } } inline static void staticSystemResetCallback (void *) { if ( currentSystemResetCallback ) { currentSystemResetCallback(); } } }; diff --git a/FirmataParser.cpp b/FirmataParser.cpp index e446078d..415e6e07 100644 --- a/FirmataParser.cpp +++ b/FirmataParser.cpp @@ -60,7 +60,7 @@ FirmataParser::FirmataParser(uint8_t * const dataBuffer, size_t dataBufferSize) currentDataBufferOverflowCallback((dataBufferOverflowCallbackFunction)NULL), currentStringCallback((stringCallbackFunction)NULL), currentSysexCallback((sysexCallbackFunction)NULL), - currentReportFirmwareCallback((systemCallbackFunction)NULL), + currentReportFirmwareCallback((versionCallbackFunction)NULL), currentReportVersionCallback((systemCallbackFunction)NULL), currentSystemResetCallback((systemCallbackFunction)NULL) { @@ -244,21 +244,34 @@ void FirmataParser::attach(uint8_t command, callbackFunction newFunction, void * } /** - * Attach a system callback function (options are: REPORT_FIRMWARE, REPORT_VERSION - * and SYSTEM_RESET). + * Attach a version callback function (supported option: REPORT_FIRMWARE). * @param command The ID of the command to attach a callback function to. * @param newFunction A reference to the callback function to attach. * @param context An optional context to be provided to the callback function (NULL by default). * @note The context parameter is provided so you can pass a parameter, by reference, to * your callback function. */ -void FirmataParser::attach(uint8_t command, systemCallbackFunction newFunction, void * context) +void FirmataParser::attach(uint8_t command, versionCallbackFunction newFunction, void * context) { switch (command) { case REPORT_FIRMWARE: currentReportFirmwareCallback = newFunction; currentReportFirmwareCallbackContext = context; break; + } +} + +/** + * Attach a system callback function (supported options are: SYSTEM_RESET, REPORT_VERSION). + * @param command The ID of the command to attach a callback function to. + * @param newFunction A reference to the callback function to attach. + * @param context An optional context to be provided to the callback function (NULL by default). + * @note The context parameter is provided so you can pass a parameter, by reference, to + * your callback function. + */ +void FirmataParser::attach(uint8_t command, systemCallbackFunction newFunction, void * context) +{ + switch (command) { case REPORT_VERSION: currentReportVersionCallback = newFunction; currentReportVersionCallbackContext = context; @@ -325,6 +338,8 @@ void FirmataParser::detach(uint8_t command) { switch (command) { case REPORT_FIRMWARE: + attach(command, (versionCallbackFunction)NULL, NULL); + break; case REPORT_VERSION: case SYSTEM_RESET: attach(command, (systemCallbackFunction)NULL, NULL); @@ -394,14 +409,24 @@ void FirmataParser::processSysexMessage(void) { switch (dataBuffer[0]) { //first byte in buffer is command case REPORT_FIRMWARE: - if (currentReportFirmwareCallback) - (*currentReportFirmwareCallback)(currentReportFirmwareCallbackContext); + if (currentReportFirmwareCallback) { + size_t sv_major = dataBuffer[1], sv_minor = dataBuffer[2]; + size_t i = 0, j = 3; + while (j < sysexBytesRead) { + // The string length will only be at most half the size of the + // stored input buffer so we can decode the string within the buffer. + bufferDataAtPosition(dataBuffer[j], i); + ++i; + ++j; + } + bufferDataAtPosition('\0', i); // Terminate the string + (*currentReportFirmwareCallback)(currentReportFirmwareCallbackContext, sv_major, sv_minor, (const char *)&dataBuffer[0]); + } break; case STRING_DATA: if (currentStringCallback) { size_t bufferLength = (sysexBytesRead - 1) / 2; - size_t i = 1; - size_t j = 0; + size_t i = 1, j = 0; while (j < bufferLength) { // The string length will only be at most half the size of the // stored input buffer so we can decode the string within the buffer. @@ -417,7 +442,7 @@ void FirmataParser::processSysexMessage(void) if (dataBuffer[j - 1] != '\0') { bufferDataAtPosition('\0', j); } - (*currentStringCallback)(currentStringCallbackContext, (char *)&dataBuffer[0]); + (*currentStringCallback)(currentStringCallbackContext, (const char *)&dataBuffer[0]); } break; default: diff --git a/FirmataParser.h b/FirmataParser.h index a9516dae..1790b521 100644 --- a/FirmataParser.h +++ b/FirmataParser.h @@ -30,9 +30,10 @@ class FirmataParser /* callback function types */ typedef void (*callbackFunction)(void * context, uint8_t command, uint16_t value); typedef void (*dataBufferOverflowCallbackFunction)(void * context); - typedef void (*stringCallbackFunction)(void * context, char * c_str); + typedef void (*stringCallbackFunction)(void * context, const char * c_str); typedef void (*sysexCallbackFunction)(void * context, uint8_t command, size_t argc, uint8_t * argv); typedef void (*systemCallbackFunction)(void * context); + typedef void (*versionCallbackFunction)(void * context, size_t sv_major, size_t sv_minor, const char * firmware); FirmataParser(uint8_t * dataBuffer = (uint8_t *)NULL, size_t dataBufferSize = 0); @@ -47,6 +48,7 @@ class FirmataParser void attach(uint8_t command, stringCallbackFunction newFunction, void * context = NULL); void attach(uint8_t command, sysexCallbackFunction newFunction, void * context = NULL); void attach(uint8_t command, systemCallbackFunction newFunction, void * context = NULL); + void attach(uint8_t command, versionCallbackFunction newFunction, void * context = NULL); void detach(uint8_t command); void detach(dataBufferOverflowCallbackFunction); @@ -87,14 +89,14 @@ class FirmataParser dataBufferOverflowCallbackFunction currentDataBufferOverflowCallback; stringCallbackFunction currentStringCallback; sysexCallbackFunction currentSysexCallback; - systemCallbackFunction currentReportFirmwareCallback; + versionCallbackFunction currentReportFirmwareCallback; systemCallbackFunction currentReportVersionCallback; systemCallbackFunction currentSystemResetCallback; /* private methods ------------------------------ */ + bool bufferDataAtPosition(const uint8_t data, const size_t pos); void processSysexMessage(void); void systemReset(void); - bool bufferDataAtPosition(const uint8_t data, const size_t pos); }; } // firmata From d96a110dcc529ced004ba1462d3cdd6fb8763e3e Mon Sep 17 00:00:00 2001 From: chiararuggeri Date: Thu, 16 Mar 2017 10:01:52 +0100 Subject: [PATCH 02/81] Add support for Arduino Primo board --- Boards.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Boards.h b/Boards.h index 9e9ffdac..f2b61da2 100644 --- a/Boards.h +++ b/Boards.h @@ -299,6 +299,21 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) #define PIN_TO_SERVO(p) (p) // deprecated since v2.4 +// Arduino Primo +#elif defined(ARDUINO_PRIMO) +#define TOTAL_ANALOG_PINS 6 +#define TOTAL_PINS 22 //14 digital + 6 analog + 2 i2c +#define VERSION_BLINK_PIN LED_BUILTIN +#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < 20) +#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 20) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS+2) +#define IS_PIN_I2C(p) ((p) == PIN_WIRE_SDA || (p) == PIN_WIRE_SCL) // SDA = 20, SCL = 21 +#define IS_PIN_SPI(p) ((p) == SS || (p)== MOSI || (p) == MISO || (p == SCK)) // 10, 11, 12, 13 +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) ((p) - 14) +#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) +#define PIN_TO_SERVO(p) (p) // Arduino 101 #elif defined(_VARIANT_ARDUINO_101_X_) From eb5e7cdf08878a823e91fcfeab98bee130fdf0cc Mon Sep 17 00:00:00 2001 From: "Zachary J. Fields" Date: Wed, 15 Mar 2017 22:15:52 -0700 Subject: [PATCH 03/81] Improve decoding algorithm --- FirmataParser.cpp | 61 +++++++++++++++++++++++++---------------------- FirmataParser.h | 1 + 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/FirmataParser.cpp b/FirmataParser.cpp index 415e6e07..d402fdf0 100644 --- a/FirmataParser.cpp +++ b/FirmataParser.cpp @@ -400,6 +400,25 @@ bool FirmataParser::bufferDataAtPosition(const uint8_t data, const size_t pos) return bufferOverflow; } +/** + * Transform 7-bit firmata message into 8-bit stream + * @param bytec The encoded data byte length of the message (max: 16383). + * @param bytev A pointer to the encoded array of data bytes. + * @return The length of the decoded data. + * @note The conversion will be done in place on the provided buffer. + * @private + */ +size_t FirmataParser::decodeByteStream(size_t bytec, uint8_t * bytev) { + size_t decoded_bytes, i; + + for ( i = 0, decoded_bytes = 0 ; i < bytec ; ++decoded_bytes, ++i ) { + bytev[decoded_bytes] = bytev[i]; + bytev[decoded_bytes] |= (uint8_t)(bytev[++i] << 7); + } + + return decoded_bytes; +} + /** * Process incoming sysex messages. Handles REPORT_FIRMWARE and STRING_DATA internally. * Calls callback function for STRING_DATA and all other sysex messages. @@ -410,39 +429,25 @@ void FirmataParser::processSysexMessage(void) switch (dataBuffer[0]) { //first byte in buffer is command case REPORT_FIRMWARE: if (currentReportFirmwareCallback) { - size_t sv_major = dataBuffer[1], sv_minor = dataBuffer[2]; - size_t i = 0, j = 3; - while (j < sysexBytesRead) { - // The string length will only be at most half the size of the - // stored input buffer so we can decode the string within the buffer. - bufferDataAtPosition(dataBuffer[j], i); - ++i; - ++j; + const size_t major_version_offset = 1; + const size_t minor_version_offset = 2; + const size_t string_offset = 3; + // Test for malformed REPORT_FIRMWARE message (used to query firmware prior to Firmata v3.0.0) + if ( 3 > sysexBytesRead ) { + (*currentReportFirmwareCallback)(currentReportFirmwareCallbackContext, 0, 0, (const char *)NULL); + } else { + const size_t end_of_string = (string_offset + decodeByteStream((sysexBytesRead - string_offset), &dataBuffer[string_offset])); + bufferDataAtPosition('\0', end_of_string); // NULL terminate the string + (*currentReportFirmwareCallback)(currentReportFirmwareCallbackContext, (size_t)dataBuffer[major_version_offset], (size_t)dataBuffer[minor_version_offset], (const char *)&dataBuffer[string_offset]); } - bufferDataAtPosition('\0', i); // Terminate the string - (*currentReportFirmwareCallback)(currentReportFirmwareCallbackContext, sv_major, sv_minor, (const char *)&dataBuffer[0]); } break; case STRING_DATA: if (currentStringCallback) { - size_t bufferLength = (sysexBytesRead - 1) / 2; - size_t i = 1, j = 0; - while (j < bufferLength) { - // The string length will only be at most half the size of the - // stored input buffer so we can decode the string within the buffer. - bufferDataAtPosition(dataBuffer[i], j); - ++i; - bufferDataAtPosition((dataBuffer[j] + (dataBuffer[i] << 7)), j); - ++i; - ++j; - } - // Make sure string is null terminated. This may be the case for data - // coming from client libraries in languages that don't null terminate - // strings. - if (dataBuffer[j - 1] != '\0') { - bufferDataAtPosition('\0', j); - } - (*currentStringCallback)(currentStringCallbackContext, (const char *)&dataBuffer[0]); + const size_t string_offset = 1; + const size_t end_of_string = (string_offset + decodeByteStream((sysexBytesRead - string_offset), &dataBuffer[string_offset])); + bufferDataAtPosition('\0', end_of_string); // NULL terminate the string + (*currentStringCallback)(currentStringCallbackContext, (const char *)&dataBuffer[string_offset]); } break; default: diff --git a/FirmataParser.h b/FirmataParser.h index 1790b521..bb0c8be8 100644 --- a/FirmataParser.h +++ b/FirmataParser.h @@ -95,6 +95,7 @@ class FirmataParser /* private methods ------------------------------ */ bool bufferDataAtPosition(const uint8_t data, const size_t pos); + size_t decodeByteStream(size_t bytec, uint8_t * bytev); void processSysexMessage(void); void systemReset(void); }; From 8f834594fd1d3eb86b89b77b52f9fc3546791bed Mon Sep 17 00:00:00 2001 From: "Zachary J. Fields" Date: Sat, 18 Mar 2017 11:25:15 -0700 Subject: [PATCH 04/81] Fix bug #363 - string encoding --- Firmata.cpp | 2 +- Firmata.h | 2 +- FirmataMarshaller.cpp | 12 ++++++------ FirmataMarshaller.h | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Firmata.cpp b/Firmata.cpp index 6134ebfa..bd229ac9 100644 --- a/Firmata.cpp +++ b/Firmata.cpp @@ -50,7 +50,7 @@ systemCallbackFunction FirmataClass::currentSystemResetCallback = (systemCallbac */ void FirmataClass::sendValueAsTwo7bitBytes(int value) { - marshaller.transformByteStreamToMessageBytes(sizeof(value), reinterpret_cast(&value), sizeof(value)); + marshaller.encodeByteStream(sizeof(value), reinterpret_cast(&value), sizeof(value)); } /** diff --git a/Firmata.h b/Firmata.h index cda11a6e..90c1932d 100644 --- a/Firmata.h +++ b/Firmata.h @@ -128,7 +128,7 @@ class FirmataClass /* private methods ------------------------------ */ void strobeBlinkPin(byte pin, int count, int onInterval, int offInterval); - friend void FirmataMarshaller::transformByteStreamToMessageBytes (size_t bytec, uint8_t * bytev, size_t max_bytes = 0) const; + friend void FirmataMarshaller::encodeByteStream (size_t bytec, uint8_t * bytev, size_t max_bytes = 0) const; /* callback functions */ static callbackFunction currentAnalogCallback; diff --git a/FirmataMarshaller.cpp b/FirmataMarshaller.cpp index 2b1f45a9..6cb52002 100644 --- a/FirmataMarshaller.cpp +++ b/FirmataMarshaller.cpp @@ -79,7 +79,7 @@ const FirmataStream->write(START_SYSEX); FirmataStream->write(EXTENDED_ANALOG); FirmataStream->write(pin); - transformByteStreamToMessageBytes(bytec, bytev, bytec); + encodeByteStream(bytec, bytev, bytec); FirmataStream->write(END_SYSEX); } @@ -89,7 +89,7 @@ const * @param bytev A pointer to the array of data bytes to send in the message. * @param max_bytes Force message to be n bytes, regardless of data bits. */ -void FirmataMarshaller::transformByteStreamToMessageBytes (size_t bytec, uint8_t * bytev, size_t max_bytes) +void FirmataMarshaller::encodeByteStream (size_t bytec, uint8_t * bytev, size_t max_bytes) const { static const size_t transmit_bits = 7; @@ -248,7 +248,7 @@ const if ( (Stream *)NULL == FirmataStream ) { return; } if ( (0xF >= pin) && (0x3FFF >= value) ) { FirmataStream->write(ANALOG_MESSAGE|pin); - transformByteStreamToMessageBytes(sizeof(value), reinterpret_cast(&value), sizeof(value)); + encodeByteStream(sizeof(value), reinterpret_cast(&value), sizeof(value)); } else { sendExtendedAnalog(pin, sizeof(value), reinterpret_cast(&value)); } @@ -306,7 +306,7 @@ const FirmataStream->write(DIGITAL_MESSAGE | (portNumber & 0xF)); // Tx bits 0-6 (protocol v1 and higher) // Tx bits 7-13 (bit 7 only for protocol v2 and higher) - transformByteStreamToMessageBytes(sizeof(portData), reinterpret_cast(&portData), sizeof(portData)); + encodeByteStream(sizeof(portData), reinterpret_cast(&portData), sizeof(portData)); } /** @@ -326,7 +326,7 @@ const FirmataStream->write(major); FirmataStream->write(minor); for (i = 0; i < bytec; ++i) { - transformByteStreamToMessageBytes(sizeof(bytev[i]), reinterpret_cast(&bytev[i]), sizeof(bytev[i])); + encodeByteStream(sizeof(bytev[i]), reinterpret_cast(&bytev[i])); } FirmataStream->write(END_SYSEX); } @@ -393,7 +393,7 @@ const FirmataStream->write(START_SYSEX); FirmataStream->write(command); for (i = 0; i < bytec; ++i) { - transformByteStreamToMessageBytes(sizeof(bytev[i]), reinterpret_cast(&bytev[i]), sizeof(bytev[i])); + encodeByteStream(sizeof(bytev[i]), reinterpret_cast(&bytev[i])); } FirmataStream->write(END_SYSEX); } diff --git a/FirmataMarshaller.h b/FirmataMarshaller.h index 2a8650c7..3fa83f6a 100644 --- a/FirmataMarshaller.h +++ b/FirmataMarshaller.h @@ -64,7 +64,7 @@ class FirmataMarshaller void reportAnalog(uint8_t pin, bool stream_enable) const; void reportDigitalPort(uint8_t portNumber, bool stream_enable) const; void sendExtendedAnalog(uint8_t pin, size_t bytec, uint8_t * bytev) const; - void transformByteStreamToMessageBytes (size_t bytec, uint8_t * bytev, size_t max_bytes = 0) const; + void encodeByteStream (size_t bytec, uint8_t * bytev, size_t max_bytes = 0) const; Stream * FirmataStream; }; From f1bd40f3d977b3e93323cc541ef336f580601029 Mon Sep 17 00:00:00 2001 From: Jeff Hoefs Date: Sat, 18 Mar 2017 16:28:59 -0700 Subject: [PATCH 05/81] add tests for sending and receiving strings --- test/firmata_test/firmata_test.ino | 36 ++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/test/firmata_test/firmata_test.ino b/test/firmata_test/firmata_test.ino index ce40afa5..db058535 100644 --- a/test/firmata_test/firmata_test.ino +++ b/test/firmata_test/firmata_test.ino @@ -58,6 +58,12 @@ void setupDigitalPort() _digitalPortValue = 0; } +char * _receivedString; +void handleStringCallback(char *str) +{ + _receivedString = str; +} + test(processWriteDigital_0) { setupDigitalPort(); @@ -134,3 +140,33 @@ test(setFirmwareVersionDoesNotLeakMemory) assertEqual(0, initialMemory - freeMemory()); } + +test(sendStringShouldEncode2BytesPerChar) +{ + FakeStream stream; + Firmata.begin(stream); + // reset the buffer because the firmware name string will be sent on Firmata.begin + stream.reset(); + + char testString[] = "hi!"; + Firmata.sendString(testString); + + byte expected[] = { START_SYSEX, STRING_DATA, 'h', 0, 'i', 0, '!', 0, END_SYSEX }; + + int len = stream.bytesWritten().length(); + assertEqual(sizeof(expected), len); + for (byte i = 0; i < len; i++) { + assertEqual(expected[i], (byte)stream.bytesWritten().charAt(i)); + } +} + +test(receivedStringShouldDecodeFrom2BytesPerChar) +{ + Firmata.attach(STRING_DATA, handleStringCallback); + + byte message[] = { START_SYSEX, STRING_DATA, 'b', 0, 'y', 0, 'e', 0, '!', 0, END_SYSEX }; + processMessage(message, 11); + + assertEqual("bye!", _receivedString); +} + From f13a61bce62406fc182083cf0c527f25b3ef38c1 Mon Sep 17 00:00:00 2001 From: Jeff Hoefs Date: Sat, 18 Mar 2017 16:47:46 -0700 Subject: [PATCH 06/81] bugfix release --- Boards.h | 4 ++-- Firmata.cpp | 4 ++-- Firmata.h | 4 ++-- FirmataConstants.h | 4 ++-- extras/revisions.txt | 7 +++++++ library.properties | 2 +- readme.md | 8 ++++---- release.sh | 4 ++-- 8 files changed, 22 insertions(+), 15 deletions(-) diff --git a/Boards.h b/Boards.h index f2b61da2..7003565e 100644 --- a/Boards.h +++ b/Boards.h @@ -1,7 +1,7 @@ /* Boards.h - Hardware Abstraction Layer for Firmata library Copyright (c) 2006-2008 Hans-Christoph Steiner. All rights reserved. - Copyright (C) 2009-2016 Jeff Hoefs. All rights reserved. + Copyright (C) 2009-2017 Jeff Hoefs. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -10,7 +10,7 @@ See file LICENSE.txt for further informations on licensing terms. - Last updated October 16th, 2016 + Last updated March 16th, 2017 */ #ifndef Firmata_Boards_h diff --git a/Firmata.cpp b/Firmata.cpp index bd229ac9..8e48bc79 100644 --- a/Firmata.cpp +++ b/Firmata.cpp @@ -1,7 +1,7 @@ /* - Firmata.cpp - Firmata library v2.5.5 - 2017-03-06 + Firmata.cpp - Firmata library v2.5.6 - 2017-03-18 Copyright (c) 2006-2008 Hans-Christoph Steiner. All rights reserved. - Copyright (C) 2009-2016 Jeff Hoefs. All rights reserved. + Copyright (C) 2009-2017 Jeff Hoefs. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/Firmata.h b/Firmata.h index 90c1932d..ec951657 100644 --- a/Firmata.h +++ b/Firmata.h @@ -1,7 +1,7 @@ /* - Firmata.h - Firmata library v2.5.5 - 2017-03-06 + Firmata.h - Firmata library v2.5.6 - 2017-03-18 Copyright (c) 2006-2008 Hans-Christoph Steiner. All rights reserved. - Copyright (C) 2009-2016 Jeff Hoefs. All rights reserved. + Copyright (C) 2009-2017 Jeff Hoefs. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/FirmataConstants.h b/FirmataConstants.h index de84ceda..e8d21812 100644 --- a/FirmataConstants.h +++ b/FirmataConstants.h @@ -1,7 +1,7 @@ /* FirmataConstants.h Copyright (c) 2006-2008 Hans-Christoph Steiner. All rights reserved. - Copyright (C) 2009-2016 Jeff Hoefs. All rights reserved. + Copyright (C) 2009-2017 Jeff Hoefs. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -21,7 +21,7 @@ namespace firmata { */ static const int FIRMWARE_MAJOR_VERSION = 2; static const int FIRMWARE_MINOR_VERSION = 5; -static const int FIRMWARE_BUGFIX_VERSION = 5; +static const int FIRMWARE_BUGFIX_VERSION = 6; /* Version numbers for the protocol. The protocol is still changing, so these * version numbers are important. diff --git a/extras/revisions.txt b/extras/revisions.txt index 689dc0c4..3acc700f 100644 --- a/extras/revisions.txt +++ b/extras/revisions.txt @@ -1,3 +1,10 @@ +FIRMATA 2.5.6 - Mar 18, 2017 + +[core library] +* Fixed string encoder/decoder bug that also affected I2C (Zak Fields) +* Added support for Arduino Primo (chiararuggeri) +* Added unit tests for Firmata string message encoding/decoding + FIRMATA 2.5.5 - Mar 6, 2017 [core library] diff --git a/library.properties b/library.properties index 4d8df5ae..791ce146 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Firmata -version=2.5.5 +version=2.5.6 author=Firmata Developers maintainer=https://github.com/firmata/arduino sentence=Enables the communication with computer apps using a standard serial protocol. For all Arduino/Genuino boards. diff --git a/readme.md b/readme.md index 8b370815..7138c4a9 100644 --- a/readme.md +++ b/readme.md @@ -94,7 +94,7 @@ $ git clone git@github.com:firmata/arduino.git ~/Documents/Arduino/libraries/Fir ##Updating Firmata in the Arduino IDE - older versions (<= 1.6.3 or 1.0.x) -Download the latest [release](https://github.com/firmata/arduino/releases/tag/2.5.5) (for Arduino 1.0.x or Arduino 1.5.6 or higher) and replace the existing Firmata folder in your Arduino application. See the instructions below for your platform. +Download the latest [release](https://github.com/firmata/arduino/releases/tag/2.5.6) (for Arduino 1.0.x or Arduino 1.5.6 or higher) and replace the existing Firmata folder in your Arduino application. See the instructions below for your platform. *Note that Arduino 1.5.0 - 1.5.5 are not supported. Please use Arduino 1.5.6 or higher (or Arduino 1.0.5 or 1.0.6).* @@ -105,7 +105,7 @@ The Firmata library is contained within the Arduino package. 1. Navigate to the Arduino application 2. Right click on the application icon and select `Show Package Contents` 3. Navigate to: `/Contents/Resources/Java/libraries/` and replace the existing -`Firmata` folder with latest [Firmata release](https://github.com/firmata/arduino/releases/tag/2.5.5) (note there is a different download +`Firmata` folder with latest [Firmata release](https://github.com/firmata/arduino/releases/tag/2.5.6) (note there is a different download for Arduino 1.0.x vs 1.6.x) 4. Restart the Arduino application and the latest version of Firmata will be available. @@ -115,7 +115,7 @@ will differ slightly: `Contents/Java/libraries/Firmata` (no Resources directory) ###Windows: 1. Navigate to `c:/Program\ Files/arduino-1.x/libraries/` and replace the existing -`Firmata` folder with the latest [Firmata release](https://github.com/firmata/arduino/releases/tag/2.5.5) (note there is a different download +`Firmata` folder with the latest [Firmata release](https://github.com/firmata/arduino/releases/tag/2.5.6) (note there is a different download for Arduino 1.0.x vs 1.6.x). 2. Restart the Arduino application and the latest version of Firmata will be available. @@ -124,7 +124,7 @@ for Arduino 1.0.x vs 1.6.x). ###Linux: 1. Navigate to `~/arduino-1.x/libraries/` and replace the existing -`Firmata` folder with the latest [Firmata release](https://github.com/firmata/arduino/releases/tag/2.5.5) (note there is a different download +`Firmata` folder with the latest [Firmata release](https://github.com/firmata/arduino/releases/tag/2.5.6) (note there is a different download for Arduino 1.0.x vs 1.6.x). 2. Restart the Arduino application and the latest version of Firmata will be available. diff --git a/release.sh b/release.sh index 7fc12d1c..11a9b725 100644 --- a/release.sh +++ b/release.sh @@ -15,7 +15,7 @@ cd temp find . -name "*.DS_Store" -type f -delete zip -r Firmata.zip ./Firmata/ cd .. -mv ./temp/Firmata.zip Firmata-2.5.5.zip +mv ./temp/Firmata.zip Firmata-2.5.6.zip #package for Arduino 1.6.x cp library.properties temp/Firmata @@ -29,5 +29,5 @@ cd .. find . -name "*.DS_Store" -type f -delete zip -r Firmata.zip ./Firmata/ cd .. -mv ./temp/Firmata.zip Arduino-1.6.x-Firmata-2.5.5.zip +mv ./temp/Firmata.zip Arduino-1.6.x-Firmata-2.5.6.zip rm -r ./temp From 182673a52783dcd7862afeff7cc14b9d067e350e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?FRANCE=20Fr=C3=A9d=C3=A9ric?= Date: Sun, 9 Apr 2017 10:28:52 +0200 Subject: [PATCH 07/81] Adapt markdown --- readme.md | 108 +++++++++++++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 49 deletions(-) diff --git a/readme.md b/readme.md index 7138c4a9..a97a035b 100644 --- a/readme.md +++ b/readme.md @@ -1,78 +1,88 @@ -#Firmata +# Firmata -[![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/firmata/arduino?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/firmata/arduino?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) Firmata is a protocol for communicating with microcontrollers from software on a host computer. The [protocol](https://github.com/firmata/protocol) can be implemented in firmware on any microcontroller architecture as well as software on any host computer software package. The Arduino repository described here is a Firmata library for Arduino and Arduino-compatible devices. If you would like to contribute to Firmata, please see the [Contributing](#contributing) section below. -##Usage +# Contents + +- [Usage](#usage) +- [Firmata Client Libraries](#firmata-client-libraries) +- [Updating Firmata in the Arduino IDE - Arduino 1.6.4 and higher](#updating-firmata-in-the-arduino-ide---arduino-1.6.4-and-higher) + - [Mac OSX:](#mac-osx:) + - [Windows](#windows:) + - [Linux](#linux:) +- [Using the Source code rather than release archive (only for versions older than Arduino 1.6.3)](#using-the-source-code-rather-than-release-archive-only-for-versions-older-than-arduino-1.6.3) + +## Usage There are two main models of usage of Firmata. In one model, the author of the Arduino sketch uses the various methods provided by the Firmata library to selectively send and receive data between the Arduino device and the software running on the host computer. For example, a user can send analog data to the host using ``` Firmata.sendAnalog(analogPin, analogRead(analogPin)) ``` or send data packed in a string using ``` Firmata.sendString(stringToSend) ```. See File -> Examples -> Firmata -> AnalogFirmata & EchoString respectively for examples. The second and more common model is to load a general purpose sketch called StandardFirmata (or one of the variants such as StandardFirmataPlus or StandardFirmataEthernet depending on your needs) on the Arduino board and then use the host computer exclusively to interact with the Arduino board. StandardFirmata is located in the Arduino IDE in File -> Examples -> Firmata. -##Firmata Client Libraries +## Firmata Client Libraries Most of the time you will be interacting with Arduino with a client library on the host computers. Several Firmata client libraries have been implemented in a variety of popular programming languages: * processing - * [https://github.com/firmata/processing] - * [http://funnel.cc] + * [https://github.com/firmata/processing](https://github.com/firmata/processing) + * [http://funnel.cc](http://funnel.cc) * python - * [https://github.com/MrYsLab/pymata-aio] - * [https://github.com/MrYsLab/PyMata] - * [https://github.com/tino/pyFirmata] - * [https://github.com/lupeke/python-firmata] - * [https://github.com/firmata/pyduino] + * [https://github.com/MrYsLab/pymata-aio](https://github.com/MrYsLab/pymata-aio) + * [https://github.com/MrYsLab/PyMata]([https://github.com/MrYsLab/PyMata) + * [https://github.com/tino/pyFirmata](https://github.com/tino/pyFirmata) + * [https://github.com/lupeke/python-firmata](https://github.com/lupeke/python-firmata) + * [https://github.com/firmata/pyduino](https://github.com/firmata/pyduino) * perl - * [https://github.com/ntruchsess/perl-firmata] - * [https://github.com/rcaputo/rx-firmata] + * [https://github.com/ntruchsess/perl-firmata](https://github.com/ntruchsess/perl-firmata) + * [https://github.com/rcaputo/rx-firmata](https://github.com/rcaputo/rx-firmata) * ruby - * [https://github.com/hardbap/firmata] - * [https://github.com/PlasticLizard/rufinol] - * [http://funnel.cc] + * [https://github.com/hardbap/firmata](https://github.com/hardbap/firmata) + * [https://github.com/PlasticLizard/rufinol](https://github.com/PlasticLizard/rufinol) + * [http://funnel.cc](http://funnel.cc) * clojure - * [https://github.com/nakkaya/clodiuno] - * [https://github.com/peterschwarz/clj-firmata] + * [https://github.com/nakkaya/clodiuno](https://github.com/nakkaya/clodiuno) + * [https://github.com/peterschwarz/clj-firmata](https://github.com/peterschwarz/clj-firmata) * javascript - * [https://github.com/jgautier/firmata] - * [https://github.com/rwldrn/johnny-five] - * [http://breakoutjs.com] + * [https://github.com/jgautier/firmata](https://github.com/jgautier/firmata) + * [https://github.com/rwldrn/johnny-five](https://github.com/rwldrn/johnny-five) + * [http://breakoutjs.com](http://breakoutjs.com) * java - * [https://github.com/kurbatov/firmata4j] - * [https://github.com/4ntoine/Firmata] - * [https://github.com/reapzor/FiloFirmata] + * [https://github.com/kurbatov/firmata4j](https://github.com/kurbatov/firmata4j) + * [https://github.com/4ntoine/Firmata](https://github.com/4ntoine/Firmata) + * [https://github.com/reapzor/FiloFirmata](https://github.com/reapzor/FiloFirmata) * .NET - * [https://github.com/SolidSoils/Arduino] - * [http://www.acraigie.com/programming/firmatavb/default.html] + * [https://github.com/SolidSoils/Arduino](https://github.com/SolidSoils/Arduino) + * [http://www.acraigie.com/programming/firmatavb/default.html](http://www.acraigie.com/programming/firmatavb/default.html) * Flash/AS3 - * [http://funnel.cc] - * [http://code.google.com/p/as3glue/] + * [http://funnel.cc](http://funnel.cc) + * [http://code.google.com/p/as3glue/](http://code.google.com/p/as3glue/) * PHP - * [https://github.com/ThomasWeinert/carica-firmata] - * [https://github.com/oasynnoum/phpmake_firmata] + * [https://github.com/ThomasWeinert/carica-firmata]() + * [https://github.com/oasynnoum/phpmake_firmata](https://github.com/oasynnoum/phpmake_firmata) * Haskell - * [http://hackage.haskell.org/package/hArduino] + * [http://hackage.haskell.org/package/hArduino](http://hackage.haskell.org/package/hArduino) * iOS - * [https://github.com/jacobrosenthal/iosfirmata] + * [https://github.com/jacobrosenthal/iosfirmata](https://github.com/jacobrosenthal/iosfirmata) * Dart - * [https://github.com/nfrancois/firmata] + * [https://github.com/nfrancois/firmata](https://github.com/nfrancois/firmata) * Max/MSP - * [http://www.maxuino.org/] + * [http://www.maxuino.org/](http://www.maxuino.org/) * Elixir - * [https://github.com/kfatehi/firmata] + * [https://github.com/kfatehi/firmata](https://github.com/kfatehi/firmata) * Modelica - * [https://www.wolfram.com/system-modeler/libraries/model-plug/] + * [https://www.wolfram.com/system-modeler/libraries/model-plug/](https://www.wolfram.com/system-modeler/libraries/model-plug/) * Go - * [https://github.com/kraman/go-firmata] + * [https://github.com/kraman/go-firmata](https://github.com/kraman/go-firmata) * vvvv - * [https://vvvv.org/blog/arduino-second-service] + * [https://vvvv.org/blog/arduino-second-service](https://vvvv.org/blog/arduino-second-service) * openFrameworks - * [http://openframeworks.cc/documentation/communication/ofArduino/] + * [http://openframeworks.cc/documentation/communication/ofArduino/](http://openframeworks.cc/documentation/communication/ofArduino/) * Rust - * [https://github.com/zankich/rust-firmata] + * [https://github.com/zankich/rust-firmata](https://github.com/zankich/rust-firmata) Note: The above libraries may support various versions of the Firmata protocol and therefore may not support all features of the latest Firmata spec nor all Arduino and Arduino-compatible boards. Refer to the respective projects for details. -##Updating Firmata in the Arduino IDE - Arduino 1.6.4 and higher +## Updating Firmata in the Arduino IDE - Arduino 1.6.4 and higher If you want to update to the latest stable version: @@ -81,7 +91,7 @@ If you want to update to the latest stable version: 3. Click the `Select version` dropdown and select the most recent version (note you can also install previous versions) 4. Click `Install`. -###Cloning Firmata +### Cloning Firmata If you are contributing to Firmata or otherwise need a version newer than the latest tagged release, you can clone Firmata directly to your Arduino/libraries/ directory (where 3rd party libraries are installed). This only works for Arduino 1.6.4 and higher, for older versions you need to clone into the Arduino application directory (see section below titled "Using the Source code rather than release archive"). Be sure to change the name to Firmata as follows: @@ -92,13 +102,13 @@ $ git clone git@github.com:firmata/arduino.git ~/Documents/Arduino/libraries/Fir *Update path above if you're using Windows or Linux or changed the default Arduino directory on OS X* -##Updating Firmata in the Arduino IDE - older versions (<= 1.6.3 or 1.0.x) +## Updating Firmata in the Arduino IDE - older versions (<= 1.6.3 or 1.0.x) Download the latest [release](https://github.com/firmata/arduino/releases/tag/2.5.6) (for Arduino 1.0.x or Arduino 1.5.6 or higher) and replace the existing Firmata folder in your Arduino application. See the instructions below for your platform. *Note that Arduino 1.5.0 - 1.5.5 are not supported. Please use Arduino 1.5.6 or higher (or Arduino 1.0.5 or 1.0.6).* -###Mac OSX: +### Mac OSX: The Firmata library is contained within the Arduino package. @@ -112,7 +122,7 @@ for Arduino 1.0.x vs 1.6.x) *If you are using the Java 7 version of Arduino 1.5.7 or higher, the file path will differ slightly: `Contents/Java/libraries/Firmata` (no Resources directory).* -###Windows: +### Windows: 1. Navigate to `c:/Program\ Files/arduino-1.x/libraries/` and replace the existing `Firmata` folder with the latest [Firmata release](https://github.com/firmata/arduino/releases/tag/2.5.6) (note there is a different download @@ -121,7 +131,7 @@ for Arduino 1.0.x vs 1.6.x). *Update the path and Arduino version as necessary* -###Linux: +### Linux: 1. Navigate to `~/arduino-1.x/libraries/` and replace the existing `Firmata` folder with the latest [Firmata release](https://github.com/firmata/arduino/releases/tag/2.5.6) (note there is a different download @@ -130,7 +140,7 @@ for Arduino 1.0.x vs 1.6.x). *Update the path and Arduino version as necessary* -###Using the Source code rather than release archive (only for versions older than Arduino 1.6.3) +### Using the Source code rather than release archive (only for versions older than Arduino 1.6.3) *It is recommended you update to Arduino 1.6.4 or higher if possible, that way you can clone directly into the external Arduino/libraries/ directory which persists between Arduino application updates. Otherwise you will need to move your clone each time you update to a newer version of the Arduino IDE.* @@ -155,8 +165,8 @@ To generate properly formatted versions of Firmata (for Arduino 1.0.x and Arduin `release.sh` script. - -##Contributing + +## Contributing If you discover a bug or would like to propose a new feature, please open a new [issue](https://github.com/firmata/arduino/issues?sort=created&state=open). Due to the limited memory of standard Arduino boards we cannot add every requested feature to StandardFirmata. Requests to add new features to StandardFirmata will be evaluated by the Firmata developers. However it is still possible to add new features to other Firmata implementations (Firmata is a protocol whereas StandardFirmata is just one of many possible implementations). From 4a13241563c53c52d051713267e1c090ce25b56a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?FRANCE=20Fr=C3=A9d=C3=A9ric?= Date: Sun, 9 Apr 2017 10:35:44 +0200 Subject: [PATCH 08/81] Adapt markdown Content table --- readme.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/readme.md b/readme.md index a97a035b..2b00f9c6 100644 --- a/readme.md +++ b/readme.md @@ -8,11 +8,14 @@ Firmata is a protocol for communicating with microcontrollers from software on a - [Usage](#usage) - [Firmata Client Libraries](#firmata-client-libraries) -- [Updating Firmata in the Arduino IDE - Arduino 1.6.4 and higher](#updating-firmata-in-the-arduino-ide---arduino-1.6.4-and-higher) - - [Mac OSX:](#mac-osx:) - - [Windows](#windows:) - - [Linux](#linux:) -- [Using the Source code rather than release archive (only for versions older than Arduino 1.6.3)](#using-the-source-code-rather-than-release-archive-only-for-versions-older-than-arduino-1.6.3) +- [Updating Firmata in the Arduino IDE - Arduino 1.6.4 and higher](#updating-firmata-in-the-arduino-ide---arduino-164-and-higher) +- [Cloning Firmata](#cloning-firmata) +- [Updating Firmata in the Arduino IDE - older versions (<= 1.6.3 or 1.0.x)](#updating-firmata-in-the-arduino-ide---older-versions---163-or-10x) + - [Mac OSX:](#mac-osx) + - [Windows](#windows) + - [Linux](#linux) +- [Using the Source code rather than release archive (only for versions older than Arduino 1.6.3)](#using-the-source-code-rather-than-release-archive-only-for-versions-older-than-arduino-163) +- [Contributing](#contributing) ## Usage From 4cfb2bc062b2660e745f76900ef0be6a737491e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?FRANCE=20Fr=C3=A9d=C3=A9ric?= Date: Sun, 9 Apr 2017 10:41:27 +0200 Subject: [PATCH 09/81] Adapt markdown Content table --- readme.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/readme.md b/readme.md index 2b00f9c6..88e6c508 100644 --- a/readme.md +++ b/readme.md @@ -10,10 +10,10 @@ Firmata is a protocol for communicating with microcontrollers from software on a - [Firmata Client Libraries](#firmata-client-libraries) - [Updating Firmata in the Arduino IDE - Arduino 1.6.4 and higher](#updating-firmata-in-the-arduino-ide---arduino-164-and-higher) - [Cloning Firmata](#cloning-firmata) -- [Updating Firmata in the Arduino IDE - older versions (<= 1.6.3 or 1.0.x)](#updating-firmata-in-the-arduino-ide---older-versions---163-or-10x) - - [Mac OSX:](#mac-osx) - - [Windows](#windows) - - [Linux](#linux) +- [Updating Firmata in the Arduino IDE - older versions (<= 1.6.3 or 1.0.x)](#updating-firmata-in-the-arduino-ide---older-versions--163-or-10x) + - [Mac OSX:](#mac-osx) + - [Windows](#windows) + - [Linux](#linux) - [Using the Source code rather than release archive (only for versions older than Arduino 1.6.3)](#using-the-source-code-rather-than-release-archive-only-for-versions-older-than-arduino-163) - [Contributing](#contributing) From c63a34ef9a08d398d5e6ab83d056d71d430270a2 Mon Sep 17 00:00:00 2001 From: Santiago Castro Date: Tue, 18 Apr 2017 02:37:00 -0300 Subject: [PATCH 10/81] Fix broken Markdown headings --- test/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/readme.md b/test/readme.md index 726cbcba..ab8f8c3d 100644 --- a/test/readme.md +++ b/test/readme.md @@ -1,4 +1,4 @@ -#Testing Firmata +# Testing Firmata Tests tests are written using the [ArduinoUnit](https://github.com/mmurdoch/arduinounit) library (version 2.0). From 7507bb9cac70959e59392bc0bbbb7e4be97580fb Mon Sep 17 00:00:00 2001 From: Sandeep Mistry Date: Wed, 19 Apr 2017 09:38:08 -0400 Subject: [PATCH 11/81] Add support for Arduino MKRFox1200 --- Boards.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Boards.h b/Boards.h index 7003565e..7efb9be4 100644 --- a/Boards.h +++ b/Boards.h @@ -276,6 +276,22 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) #define PIN_TO_SERVO(p) (p) // deprecated since v2.4 +// Arduino MKRFox1200 +#elif defined(ARDUINO_SAMD_MKRFox1200) +#define TOTAL_ANALOG_PINS 7 +#define TOTAL_PINS 33 // 8 digital + 3 spi + 2 i2c + 2 uart + 7 analog + 3 usb + 1 aref + 5 sd + 1 bottom pad + 1 battery adc +#define IS_PIN_DIGITAL(p) ((((p) >= 0 && (p) <= 21)) && !IS_PIN_SERIAL(p)) +#define IS_PIN_ANALOG(p) (((p) >= 15 && (p) < 15 + TOTAL_ANALOG_PINS) || (p) == 32) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4 +#define IS_PIN_I2C(p) ((p) == 11 || (p) == 12) // SDA = 11, SCL = 12 +#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) +#define IS_PIN_SERIAL(p) ((p) == PIN_SERIAL1_RX || (p) == PIN_SERIAL1_TX) //defined in variant.h RX = 13, TX = 14 +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) ((p) - 15) +#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) +#define PIN_TO_SERVO(p) (p) // deprecated since v2.4 + // Arduino Zero // Note this will work with an Arduino Zero Pro, but not with an Arduino M0 Pro From d4a9ba96706bb1a979049bc63c0bf824e390a218 Mon Sep 17 00:00:00 2001 From: Sandeep Mistry Date: Wed, 19 Apr 2017 13:05:18 -0400 Subject: [PATCH 12/81] MKRZero, MKR1000, MKRFox1200: remove !IS_PIN_SERIAL check in IS_PIN_DIGITAL --- Boards.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Boards.h b/Boards.h index 7efb9be4..8b18cff5 100644 --- a/Boards.h +++ b/Boards.h @@ -247,7 +247,7 @@ writePort(port, value, bitmask): Write an 8 bit port. #elif defined(ARDUINO_SAMD_MKR1000) #define TOTAL_ANALOG_PINS 7 #define TOTAL_PINS 22 // 8 digital + 3 spi + 2 i2c + 2 uart + 7 analog -#define IS_PIN_DIGITAL(p) (((p) >= 0 && (p) <= 21) && !IS_PIN_SERIAL(p)) +#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) <= 21) #define IS_PIN_ANALOG(p) ((p) >= 15 && (p) < 15 + TOTAL_ANALOG_PINS) #define IS_PIN_PWM(p) digitalPinHasPWM(p) #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4 @@ -264,7 +264,7 @@ writePort(port, value, bitmask): Write an 8 bit port. #elif defined(ARDUINO_SAMD_MKRZERO) #define TOTAL_ANALOG_PINS 7 #define TOTAL_PINS 34 // 8 digital + 3 spi + 2 i2c + 2 uart + 7 analog + 3 usb + 1 aref + 5 sd + 1 bottom pad + 1 led + 1 battery adc -#define IS_PIN_DIGITAL(p) ((((p) >= 0 && (p) <= 21) || (p) == 32) && !IS_PIN_SERIAL(p)) +#define IS_PIN_DIGITAL(p) (((p) >= 0 && (p) <= 21) || (p) == 32) #define IS_PIN_ANALOG(p) (((p) >= 15 && (p) < 15 + TOTAL_ANALOG_PINS) || (p) == 33) #define IS_PIN_PWM(p) digitalPinHasPWM(p) #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4 @@ -280,7 +280,7 @@ writePort(port, value, bitmask): Write an 8 bit port. #elif defined(ARDUINO_SAMD_MKRFox1200) #define TOTAL_ANALOG_PINS 7 #define TOTAL_PINS 33 // 8 digital + 3 spi + 2 i2c + 2 uart + 7 analog + 3 usb + 1 aref + 5 sd + 1 bottom pad + 1 battery adc -#define IS_PIN_DIGITAL(p) ((((p) >= 0 && (p) <= 21)) && !IS_PIN_SERIAL(p)) +#define IS_PIN_DIGITAL(p) (((p) >= 0 && (p) <= 21)) #define IS_PIN_ANALOG(p) (((p) >= 15 && (p) < 15 + TOTAL_ANALOG_PINS) || (p) == 32) #define IS_PIN_PWM(p) digitalPinHasPWM(p) #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4 From 138a39fcc201b620986248d1140610f643b53d3a Mon Sep 17 00:00:00 2001 From: "Frederic.Pillon" Date: Tue, 1 Aug 2017 08:49:26 +0200 Subject: [PATCH 13/81] Add support for STM32 MCU based boards Signed-off-by: Frederic.Pillon --- Boards.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Boards.h b/Boards.h index 8b18cff5..3fba60c6 100644 --- a/Boards.h +++ b/Boards.h @@ -780,6 +780,26 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_SERVO(p) (p) #define DEFAULT_PWM_RESOLUTION 10 +// STM32 based boards +#elif defined(ARDUINO_ARCH_STM32) +#define TOTAL_ANALOG_PINS NUM_ANALOG_INPUTS +#define TOTAL_PINS NUM_DIGITAL_PINS +#define TOTAL_PORTS MAX_NB_PORT +#define VERSION_BLINK_PIN LED_BUILTIN +// PIN_SERIALY_RX/TX defined in the variant.h +#define IS_PIN_DIGITAL(p) (digitalPinIsValid(p) && !pinIsSerial(p)) +#define IS_PIN_ANALOG(p) ((p >= A0) && (p < AEND) && !pinIsSerial(p)) +#define IS_PIN_PWM(p) (IS_PIN_DIGITAL(p) && digitalPinHasPWM(p)) +#define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p) +#define IS_PIN_I2C(p) (IS_PIN_DIGITAL(p) && digitalPinHasI2C(p)) +#define IS_PIN_SPI(p) (IS_PIN_DIGITAL(p) && digitalPinHasSPI(p)) +#define IS_PIN_INTERRUPT(p) (IS_PIN_DIGITAL(p) && (digitalPinToInterrupt(p) > NOT_AN_INTERRUPT))) +#define IS_PIN_SERIAL(p) (digitalPinHasSerial(p) && !pinIsSerial(p)) +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) (p-A0) +#define PIN_TO_PWM(p) (p) +#define PIN_TO_SERVO(p) (p) +#define DEFAULT_PWM_RESOLUTION PWM_RESOLUTION // anything else #else From d1848c18ea5392ba38794efd23940246491affa4 Mon Sep 17 00:00:00 2001 From: MJPees Date: Sun, 9 Jul 2017 13:49:52 +0200 Subject: [PATCH 14/81] added server mode server mode implemented. --- .../StandardFirmataEthernet.ino | 25 ++- .../StandardFirmataEthernet/ethernetConfig.h | 16 +- utility/EthernetServerStream.cpp | 3 + utility/EthernetServerStream.h | 146 ++++++++++++++++++ 4 files changed, 178 insertions(+), 12 deletions(-) create mode 100644 utility/EthernetServerStream.cpp create mode 100644 utility/EthernetServerStream.h diff --git a/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino b/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino index f5c86bcd..07f7a89d 100644 --- a/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino +++ b/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino @@ -26,8 +26,8 @@ /* README - StandardFirmataEthernet is a TCP client implementation. You will need a Firmata client library - with a network transport that can act as a TCP server in order to establish a connection between + StandardFirmataEthernet is a TCP client/server implementation. You will need a Firmata client library + with a network transport that can act as a TCP server or client in order to establish a connection between StandardFirmataEthernet and the Firmata client application. To use StandardFirmataEthernet you will need to have one of the following @@ -68,6 +68,7 @@ // follow the instructions in ethernetConfig.h to configure your particular hardware #include "ethernetConfig.h" #include "utility/EthernetClientStream.h" +#include "utility/EthernetServerStream.h" /* * Uncomment the following include to enable interfacing with Serial devices via hardware or @@ -103,17 +104,25 @@ #if defined remote_ip && !defined remote_host #ifdef local_ip -EthernetClientStream stream(client, local_ip, remote_ip, NULL, remote_port); +EthernetClientStream stream(client, local_ip, remote_ip, NULL, network_port); #else -EthernetClientStream stream(client, IPAddress(0, 0, 0, 0), remote_ip, NULL, remote_port); +EthernetClientStream stream(client, IPAddress(0, 0, 0, 0), remote_ip, NULL, network_port); #endif #endif #if !defined remote_ip && defined remote_host #ifdef local_ip -EthernetClientStream stream(client, local_ip, IPAddress(0, 0, 0, 0), remote_host, remote_port); +EthernetClientStream stream(client, local_ip, IPAddress(0, 0, 0, 0), remote_host, network_port ); #else -EthernetClientStream stream(client, IPAddress(0, 0, 0, 0), IPAddress(0, 0, 0, 0), remote_host, remote_port); +EthernetClientStream stream(client, IPAddress(0, 0, 0, 0), IPAddress(0, 0, 0, 0), remote_host, network_port); +#endif +#endif + +#if !defined remote_ip && !defined remote_host +#ifdef local_ip +EthernetServerStream stream(local_ip, network_port); +#else +EthernetServerStream stream(IPAddress(0, 0, 0, 0), network_port); #endif #endif @@ -864,6 +873,10 @@ void initTransport() #endif DEBUG_PRINTLN("connecting..."); + + DEBUG_PRINT("IP Address: "); + IPAddress ip = Ethernet.localIP(); + DEBUG_PRINTLN(ip); } void initFirmata() diff --git a/examples/StandardFirmataEthernet/ethernetConfig.h b/examples/StandardFirmataEthernet/ethernetConfig.h index 345eafc6..baf3465a 100644 --- a/examples/StandardFirmataEthernet/ethernetConfig.h +++ b/examples/StandardFirmataEthernet/ethernetConfig.h @@ -3,8 +3,8 @@ * * You must configure your particular hardware. Follow the steps below. * - * Currently StandardFirmataEthernet is configured as a TCP client. An - * option to configure as a server may be added in the future. + * By default, StandardFirmataEthernet is configured as a TCP client. + * To configure as a TCP server, see STEP 2 *============================================================================*/ // STEP 1 [REQUIRED] @@ -46,16 +46,20 @@ EthernetClient client; YunClient client; #endif -// STEP 2[REQUIRED for all boards and shields] -// replace with IP of the server you want to connect to, comment out if using 'remote_host' +// STEP 2 [REQUIRED for all boards and shields] +// TCP Client configuration: +// To configure your board as a TCP client, set the IP address of the server you want to connect to. +// TCP Server configuration: +// To configure your board as a TCP server, comment out the following line and also ensure that +// remote_host is also commented out. #define remote_ip IPAddress(10, 0, 0, 3) // *** REMOTE HOST IS NOT YET WORKING *** // replace with hostname of server you want to connect to, comment out if using 'remote_ip' // #define remote_host "server.local" // STEP 3 [REQUIRED] -// Replace with the port that your server is listening on -#define remote_port 3030 +// Replace with the port that your client or server is listening on. +#define network_port 3030 // STEP 4 [REQUIRED unless using DHCP] // Replace with your board or ethernet shield's IP address diff --git a/utility/EthernetServerStream.cpp b/utility/EthernetServerStream.cpp new file mode 100644 index 00000000..de466f54 --- /dev/null +++ b/utility/EthernetServerStream.cpp @@ -0,0 +1,3 @@ +/* + * Implementation is in EthernetServerStream.h to avoid linker issues. + */ diff --git a/utility/EthernetServerStream.h b/utility/EthernetServerStream.h new file mode 100644 index 00000000..e80c799c --- /dev/null +++ b/utility/EthernetServerStream.h @@ -0,0 +1,146 @@ +/* + EthernetServerStream.h + + Copyright (C) 2017 Marc Josef Pees. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + See file LICENSE.txt for further informations on licensing terms. + + Last updated July 10th, 2017 + */ + +#ifndef ETHERNETSERVERSTREAM_H +#define ETHERNETSERVERSTREAM_H + +#include +#include +#include + +//#define SERIAL_DEBUG +#include "firmataDebug.h" + +class EthernetServerStream : public Stream +{ + public: + EthernetServerStream(IPAddress localip, uint16_t port); + int available(); + int read(); + int peek(); + void flush(); + size_t write(uint8_t); + void maintain(IPAddress localip); + + private: + EthernetClient client; + IPAddress localip; + uint16_t port; + bool connected; + bool maintain(); + void stop(); + + protected: + EthernetServer server = EthernetServer(3030); + bool listening = false; + bool connect_client(); +}; + + +/* + * EthernetServerStream.cpp + * Copied here as a hack to linker issues with 3rd party board packages that don't properly + * implement the Arduino network APIs. + */ +EthernetServerStream::EthernetServerStream(IPAddress localip, uint16_t port) + : localip(localip), + port(port), + connected(false) +{ +} + +bool EthernetServerStream::connect_client() + { + if ( connected ) + { + if ( client && client.connected() ) return true; + stop(); + } + + EthernetClient newClient = server.available(); + if ( !newClient ) return false; + client = newClient; + connected = true; + return true; + } + +int +EthernetServerStream::available() +{ + return maintain() ? client.available() : 0; +} + +int +EthernetServerStream::read() +{ + return maintain() ? client.read() : -1; +} + +int +EthernetServerStream::peek() +{ + return maintain() ? client.peek() : -1; +} + +void EthernetServerStream::flush() +{ + if (maintain()) + client.flush(); +} + +size_t +EthernetServerStream::write(uint8_t c) +{ + return maintain() ? client.write(c) : 0; +} + +void +EthernetServerStream::maintain(IPAddress localip) +{ + // ensure the local IP is updated in the case that it is changed by the DHCP server + if (this->localip != localip) { + this->localip = localip; + if (connected) + stop(); + } +} + +void +EthernetServerStream::stop() +{ + if(client) + { + client.stop(); + } + connected = false; +} + +bool +EthernetServerStream::maintain() +{ + if (connect_client()) return true; + + stop(); + + if(!listening) + { + server = EthernetServer(port); + server.begin(); + listening = true; + } + return false; +} + +#endif /* ETHERNETSERVERSTREAM_H */ From 0651617e541bfbcf7b5bb1c5d5378a649652ff12 Mon Sep 17 00:00:00 2001 From: Jeff Hoefs Date: Sun, 13 Aug 2017 21:40:51 -0700 Subject: [PATCH 15/81] Improve StandardFirmataEthernet logging --- .../StandardFirmataEthernet.ino | 30 ++++++++++++------- utility/EthernetClientStream.h | 4 +-- utility/EthernetServerStream.h | 1 + 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino b/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino index 07f7a89d..ca3a3e3e 100644 --- a/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino +++ b/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino @@ -11,7 +11,7 @@ Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved. Copyright (C) 2010-2011 Paul Stoffregen. All rights reserved. Copyright (C) 2009 Shigeru Kobayashi. All rights reserved. - Copyright (C) 2009-2016 Jeff Hoefs. All rights reserved. + Copyright (C) 2009-2017 Jeff Hoefs. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ See file LICENSE.txt for further informations on licensing terms. - Last updated October 16th, 2016 + Last updated August 13th, 2017 */ /* @@ -832,6 +832,17 @@ void systemResetCallback() isResetting = false; } +void printEthernetStatus() +{ + DEBUG_PRINT("Local IP Address: "); + IPAddress ip = Ethernet.localIP(); + DEBUG_PRINTLN(ip); +#ifdef remote_ip + DEBUG_PRINT("Connecting to server at: "); + DEBUG_PRINTLN(remote_ip); +#endif +} + /* * StandardFirmataEthernet communicates with Ethernet shields over SPI. Therefore all * SPI pins must be set to IGNORE. Otherwise Firmata would break SPI communication. @@ -868,15 +879,14 @@ void initTransport() #ifdef local_ip Ethernet.begin((uint8_t *)mac, local_ip); //start ethernet #else - Ethernet.begin((uint8_t *)mac); //start ethernet using dhcp + DEBUG_PRINTLN("Local IP will be requested from DHCP..."); + //start ethernet using dhcp + if (Ethernet.begin((uint8_t *)mac) == 0) { + DEBUG_PRINTLN("Failed to configure Ethernet using DHCP"); + } #endif #endif - - DEBUG_PRINTLN("connecting..."); - - DEBUG_PRINT("IP Address: "); - IPAddress ip = Ethernet.localIP(); - DEBUG_PRINTLN(ip); + printEthernetStatus(); } void initFirmata() @@ -895,7 +905,7 @@ void initFirmata() // start up Network Firmata: Firmata.begin(stream); - systemResetCallback(); // reset to default config + systemResetCallback(); // Initialize default configuration } void setup() diff --git a/utility/EthernetClientStream.h b/utility/EthernetClientStream.h index 6b024983..1b7d2e29 100644 --- a/utility/EthernetClientStream.h +++ b/utility/EthernetClientStream.h @@ -130,9 +130,9 @@ EthernetClientStream::maintain() connected = host ? client.connect(host, port) : client.connect(ip, port); if (!connected) { time_connect = millis(); - DEBUG_PRINTLN("connection failed. attempting to reconnect..."); + DEBUG_PRINTLN("Connection failed. Attempting to reconnect..."); } else { - DEBUG_PRINTLN("connected"); + DEBUG_PRINTLN("Connected"); } } return connected; diff --git a/utility/EthernetServerStream.h b/utility/EthernetServerStream.h index e80c799c..56f541e9 100644 --- a/utility/EthernetServerStream.h +++ b/utility/EthernetServerStream.h @@ -73,6 +73,7 @@ bool EthernetServerStream::connect_client() if ( !newClient ) return false; client = newClient; connected = true; + DEBUG_PRINTLN("Connected"); return true; } From ac32d18e44bde5e27f3300f002d0e4b558b62763 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 15 Aug 2017 12:05:48 +0700 Subject: [PATCH 16/81] add Adafruit nrf52 boards --- Boards.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Boards.h b/Boards.h index 3fba60c6..942b2ffc 100644 --- a/Boards.h +++ b/Boards.h @@ -801,6 +801,24 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_SERVO(p) (p) #define DEFAULT_PWM_RESOLUTION PWM_RESOLUTION +// Adafruit Bluefruit nRF52 boards +#elif defined(ARDUINO_NRF52_ADAFRUIT) +#define TOTAL_ANALOG_PINS NUM_ANALOG_INPUTS +#define TOTAL_PINS 32 +#define VERSION_BLINK_PIN LED_BUILTIN +#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS) +#define IS_PIN_ANALOG(p) ((p) == PIN_A0 || (p) == PIN_A1 || (p) == PIN_A2 || (p) == PIN_A3 || \ + (p) == PIN_A4 || (p) == PIN_A5 || (p) == PIN_A6 || (p) == PIN_A7) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p) +#define IS_PIN_I2C(p) ((p) == PIN_WIRE_SDA || (p) == PIN_WIRE_SCL) +#define IS_PIN_SPI(p) ((p) == SS || (p)== MOSI || (p) == MISO || (p == SCK)) +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) ( ((p) == PIN_A0) ? 0 : ((p) == PIN_A1) ? 1 : ((p) == PIN_A2) ? 2 : ((p) == PIN_A3) ? 3 : \ + ((p) == PIN_A4) ? 4 : ((p) == PIN_A5) ? 5 : ((p) == PIN_A6) ? 6 : ((p) == PIN_A7) ? 7 : (127)) +#define PIN_TO_PWM(p) (p) +#define PIN_TO_SERVO(p) (p) + // anything else #else #error "Please edit Boards.h with a hardware abstraction for this board" From 4fce1f33b6b7c81e262f8a20d7c85cca42df8e91 Mon Sep 17 00:00:00 2001 From: "Zachary J. Fields" Date: Fri, 18 Aug 2017 01:06:01 -0700 Subject: [PATCH 17/81] Fix I2C config parameter interpretation The current implementation pulls bytes out of the sysex buffer, regardless of whether or not the user specified such bytes. --- examples/StandardFirmata/StandardFirmata.ino | 2 +- examples/StandardFirmataBLE/StandardFirmataBLE.ino | 2 +- examples/StandardFirmataChipKIT/StandardFirmataChipKIT.ino | 2 +- examples/StandardFirmataEthernet/StandardFirmataEthernet.ino | 2 +- examples/StandardFirmataPlus/StandardFirmataPlus.ino | 2 +- examples/StandardFirmataWiFi/StandardFirmataWiFi.ino | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/StandardFirmata/StandardFirmata.ino b/examples/StandardFirmata/StandardFirmata.ino index c32639df..8439ee91 100755 --- a/examples/StandardFirmata/StandardFirmata.ino +++ b/examples/StandardFirmata/StandardFirmata.ino @@ -586,7 +586,7 @@ void sysexCallback(byte command, byte argc, byte *argv) case I2C_CONFIG: delayTime = (argv[0] + (argv[1] << 7)); - if (delayTime > 0) { + if (argc > 1 && delayTime > 0) { i2cReadDelayTime = delayTime; } diff --git a/examples/StandardFirmataBLE/StandardFirmataBLE.ino b/examples/StandardFirmataBLE/StandardFirmataBLE.ino index 6ccf7d1b..e962ed3e 100755 --- a/examples/StandardFirmataBLE/StandardFirmataBLE.ino +++ b/examples/StandardFirmataBLE/StandardFirmataBLE.ino @@ -603,7 +603,7 @@ void sysexCallback(byte command, byte argc, byte *argv) case I2C_CONFIG: delayTime = (argv[0] + (argv[1] << 7)); - if (delayTime > 0) { + if (argc > 1 && delayTime > 0) { i2cReadDelayTime = delayTime; } diff --git a/examples/StandardFirmataChipKIT/StandardFirmataChipKIT.ino b/examples/StandardFirmataChipKIT/StandardFirmataChipKIT.ino index 87942c70..42e7857e 100644 --- a/examples/StandardFirmataChipKIT/StandardFirmataChipKIT.ino +++ b/examples/StandardFirmataChipKIT/StandardFirmataChipKIT.ino @@ -588,7 +588,7 @@ void sysexCallback(byte command, byte argc, byte *argv) case I2C_CONFIG: delayTime = (argv[0] + (argv[1] << 7)); - if (delayTime > 0) { + if (argc > 1 && delayTime > 0) { i2cReadDelayTime = delayTime; } diff --git a/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino b/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino index ca3a3e3e..376cf23a 100644 --- a/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino +++ b/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino @@ -666,7 +666,7 @@ void sysexCallback(byte command, byte argc, byte *argv) case I2C_CONFIG: delayTime = (argv[0] + (argv[1] << 7)); - if (delayTime > 0) { + if (argc > 1 && delayTime > 0) { i2cReadDelayTime = delayTime; } diff --git a/examples/StandardFirmataPlus/StandardFirmataPlus.ino b/examples/StandardFirmataPlus/StandardFirmataPlus.ino index 49a1969c..52885ac0 100644 --- a/examples/StandardFirmataPlus/StandardFirmataPlus.ino +++ b/examples/StandardFirmataPlus/StandardFirmataPlus.ino @@ -611,7 +611,7 @@ void sysexCallback(byte command, byte argc, byte *argv) case I2C_CONFIG: delayTime = (argv[0] + (argv[1] << 7)); - if (delayTime > 0) { + if (argc > 1 && delayTime > 0) { i2cReadDelayTime = delayTime; } diff --git a/examples/StandardFirmataWiFi/StandardFirmataWiFi.ino b/examples/StandardFirmataWiFi/StandardFirmataWiFi.ino index d4cbfab8..307d764e 100644 --- a/examples/StandardFirmataWiFi/StandardFirmataWiFi.ino +++ b/examples/StandardFirmataWiFi/StandardFirmataWiFi.ino @@ -675,7 +675,7 @@ void sysexCallback(byte command, byte argc, byte *argv) case I2C_CONFIG: delayTime = (argv[0] + (argv[1] << 7)); - if (delayTime > 0) { + if (argc > 1 && delayTime > 0) { i2cReadDelayTime = delayTime; } From a939ca10352eedcea4b6250b997495e2cb205868 Mon Sep 17 00:00:00 2001 From: Jeff Hoefs Date: Sat, 19 Aug 2017 14:01:44 -0700 Subject: [PATCH 18/81] bugfix release --- Boards.h | 2 +- Firmata.cpp | 2 +- Firmata.h | 2 +- FirmataConstants.h | 2 +- examples/StandardFirmata/StandardFirmata.ino | 2 +- examples/StandardFirmataBLE/StandardFirmataBLE.ino | 2 +- .../StandardFirmataChipKIT.ino | 2 +- .../StandardFirmataEthernet.ino | 2 +- examples/StandardFirmataPlus/StandardFirmataPlus.ino | 2 +- examples/StandardFirmataWiFi/StandardFirmataWiFi.ino | 2 +- extras/revisions.txt | 12 ++++++++++++ library.properties | 2 +- readme.md | 10 ++++------ release.sh | 6 +++--- 14 files changed, 30 insertions(+), 20 deletions(-) diff --git a/Boards.h b/Boards.h index 942b2ffc..69bd3db0 100644 --- a/Boards.h +++ b/Boards.h @@ -10,7 +10,7 @@ See file LICENSE.txt for further informations on licensing terms. - Last updated March 16th, 2017 + Last updated August 14th, 2017 */ #ifndef Firmata_Boards_h diff --git a/Firmata.cpp b/Firmata.cpp index 8e48bc79..e35c3dcb 100644 --- a/Firmata.cpp +++ b/Firmata.cpp @@ -1,5 +1,5 @@ /* - Firmata.cpp - Firmata library v2.5.6 - 2017-03-18 + Firmata.cpp - Firmata library v2.5.7 - 2017-08-19 Copyright (c) 2006-2008 Hans-Christoph Steiner. All rights reserved. Copyright (C) 2009-2017 Jeff Hoefs. All rights reserved. diff --git a/Firmata.h b/Firmata.h index ec951657..c07b38d3 100644 --- a/Firmata.h +++ b/Firmata.h @@ -1,5 +1,5 @@ /* - Firmata.h - Firmata library v2.5.6 - 2017-03-18 + Firmata.h - Firmata library v2.5.7 - 2017-08-19 Copyright (c) 2006-2008 Hans-Christoph Steiner. All rights reserved. Copyright (C) 2009-2017 Jeff Hoefs. All rights reserved. diff --git a/FirmataConstants.h b/FirmataConstants.h index e8d21812..dee84079 100644 --- a/FirmataConstants.h +++ b/FirmataConstants.h @@ -21,7 +21,7 @@ namespace firmata { */ static const int FIRMWARE_MAJOR_VERSION = 2; static const int FIRMWARE_MINOR_VERSION = 5; -static const int FIRMWARE_BUGFIX_VERSION = 6; +static const int FIRMWARE_BUGFIX_VERSION = 7; /* Version numbers for the protocol. The protocol is still changing, so these * version numbers are important. diff --git a/examples/StandardFirmata/StandardFirmata.ino b/examples/StandardFirmata/StandardFirmata.ino index 8439ee91..b043c11e 100755 --- a/examples/StandardFirmata/StandardFirmata.ino +++ b/examples/StandardFirmata/StandardFirmata.ino @@ -20,7 +20,7 @@ See file LICENSE.txt for further informations on licensing terms. - Last updated October 16th, 2016 + Last updated August 17th, 2017 */ #include diff --git a/examples/StandardFirmataBLE/StandardFirmataBLE.ino b/examples/StandardFirmataBLE/StandardFirmataBLE.ino index e962ed3e..57756587 100755 --- a/examples/StandardFirmataBLE/StandardFirmataBLE.ino +++ b/examples/StandardFirmataBLE/StandardFirmataBLE.ino @@ -20,7 +20,7 @@ See file LICENSE.txt for further informations on licensing terms. - Last updated October 16th, 2016 + Last updated August 17th, 2017 */ #include diff --git a/examples/StandardFirmataChipKIT/StandardFirmataChipKIT.ino b/examples/StandardFirmataChipKIT/StandardFirmataChipKIT.ino index 42e7857e..e13d166d 100644 --- a/examples/StandardFirmataChipKIT/StandardFirmataChipKIT.ino +++ b/examples/StandardFirmataChipKIT/StandardFirmataChipKIT.ino @@ -21,7 +21,7 @@ See file LICENSE.txt for further informations on licensing terms. - Last updated October 16th, 2016 + Last updated August 17th, 2017 */ #include // Gives us PWM and Servo on every pin diff --git a/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino b/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino index 376cf23a..f512ccea 100644 --- a/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino +++ b/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino @@ -20,7 +20,7 @@ See file LICENSE.txt for further informations on licensing terms. - Last updated August 13th, 2017 + Last updated August 17th, 2017 */ /* diff --git a/examples/StandardFirmataPlus/StandardFirmataPlus.ino b/examples/StandardFirmataPlus/StandardFirmataPlus.ino index 52885ac0..8fb51ebe 100644 --- a/examples/StandardFirmataPlus/StandardFirmataPlus.ino +++ b/examples/StandardFirmataPlus/StandardFirmataPlus.ino @@ -20,7 +20,7 @@ See file LICENSE.txt for further informations on licensing terms. - Last updated October 16th, 2016 + Last updated August 17th, 2017 */ /* diff --git a/examples/StandardFirmataWiFi/StandardFirmataWiFi.ino b/examples/StandardFirmataWiFi/StandardFirmataWiFi.ino index 307d764e..4f7e4163 100644 --- a/examples/StandardFirmataWiFi/StandardFirmataWiFi.ino +++ b/examples/StandardFirmataWiFi/StandardFirmataWiFi.ino @@ -22,7 +22,7 @@ See file LICENSE.txt for further informations on licensing terms. - Last updated October 16th, 2016 + Last updated August 17th, 2017 */ /* diff --git a/extras/revisions.txt b/extras/revisions.txt index 3acc700f..6290a72e 100644 --- a/extras/revisions.txt +++ b/extras/revisions.txt @@ -1,3 +1,15 @@ +FIRMATA 2.5.7 - Aug 19, 2017 + +[core library] +* Added support for Adafruit nrf52 boards (hathach) +* Added TCP server option to StandardFirmataEthernet (MJPees) +* Added support for STM32-based boards (fpistm) +* Added support for MKRFox1200 (sandeepmistry) + +[StandardFirmata & variants] +* Fixed I2C config parameter interpretation (zfields) +* Improve debug output in StandardFirmataEthernet + FIRMATA 2.5.6 - Mar 18, 2017 [core library] diff --git a/library.properties b/library.properties index 791ce146..83431fc9 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Firmata -version=2.5.6 +version=2.5.7 author=Firmata Developers maintainer=https://github.com/firmata/arduino sentence=Enables the communication with computer apps using a standard serial protocol. For all Arduino/Genuino boards. diff --git a/readme.md b/readme.md index 88e6c508..f9f8c15a 100644 --- a/readme.md +++ b/readme.md @@ -107,7 +107,7 @@ $ git clone git@github.com:firmata/arduino.git ~/Documents/Arduino/libraries/Fir ## Updating Firmata in the Arduino IDE - older versions (<= 1.6.3 or 1.0.x) -Download the latest [release](https://github.com/firmata/arduino/releases/tag/2.5.6) (for Arduino 1.0.x or Arduino 1.5.6 or higher) and replace the existing Firmata folder in your Arduino application. See the instructions below for your platform. +Download the latest [release](https://github.com/firmata/arduino/releases/tag/2.5.7) (for Arduino 1.0.x or Arduino 1.5.6 or higher) and replace the existing Firmata folder in your Arduino application. See the instructions below for your platform. *Note that Arduino 1.5.0 - 1.5.5 are not supported. Please use Arduino 1.5.6 or higher (or Arduino 1.0.5 or 1.0.6).* @@ -118,7 +118,7 @@ The Firmata library is contained within the Arduino package. 1. Navigate to the Arduino application 2. Right click on the application icon and select `Show Package Contents` 3. Navigate to: `/Contents/Resources/Java/libraries/` and replace the existing -`Firmata` folder with latest [Firmata release](https://github.com/firmata/arduino/releases/tag/2.5.6) (note there is a different download +`Firmata` folder with latest [Firmata release](https://github.com/firmata/arduino/releases/tag/2.5.7) (note there is a different download for Arduino 1.0.x vs 1.6.x) 4. Restart the Arduino application and the latest version of Firmata will be available. @@ -128,7 +128,7 @@ will differ slightly: `Contents/Java/libraries/Firmata` (no Resources directory) ### Windows: 1. Navigate to `c:/Program\ Files/arduino-1.x/libraries/` and replace the existing -`Firmata` folder with the latest [Firmata release](https://github.com/firmata/arduino/releases/tag/2.5.6) (note there is a different download +`Firmata` folder with the latest [Firmata release](https://github.com/firmata/arduino/releases/tag/2.5.7) (note there is a different download for Arduino 1.0.x vs 1.6.x). 2. Restart the Arduino application and the latest version of Firmata will be available. @@ -137,7 +137,7 @@ for Arduino 1.0.x vs 1.6.x). ### Linux: 1. Navigate to `~/arduino-1.x/libraries/` and replace the existing -`Firmata` folder with the latest [Firmata release](https://github.com/firmata/arduino/releases/tag/2.5.6) (note there is a different download +`Firmata` folder with the latest [Firmata release](https://github.com/firmata/arduino/releases/tag/2.5.7) (note there is a different download for Arduino 1.0.x vs 1.6.x). 2. Restart the Arduino application and the latest version of Firmata will be available. @@ -167,8 +167,6 @@ $ git clone git@github.com:firmata/arduino.git /Applications/Arduino.app/Content To generate properly formatted versions of Firmata (for Arduino 1.0.x and Arduino 1.6.x), run the `release.sh` script. - - ## Contributing If you discover a bug or would like to propose a new feature, please open a new [issue](https://github.com/firmata/arduino/issues?sort=created&state=open). Due to the limited memory of standard Arduino boards we cannot add every requested feature to StandardFirmata. Requests to add new features to StandardFirmata will be evaluated by the Firmata developers. However it is still possible to add new features to other Firmata implementations (Firmata is a protocol whereas StandardFirmata is just one of many possible implementations). diff --git a/release.sh b/release.sh index 11a9b725..05cb74e4 100644 --- a/release.sh +++ b/release.sh @@ -15,9 +15,9 @@ cd temp find . -name "*.DS_Store" -type f -delete zip -r Firmata.zip ./Firmata/ cd .. -mv ./temp/Firmata.zip Firmata-2.5.6.zip +mv ./temp/Firmata.zip Arduino-1.0.x-Firmata-2.5.7.zip -#package for Arduino 1.6.x +#package for Arduino 1.6.x and 1.8.x cp library.properties temp/Firmata cd temp/Firmata mv readme.md ./extras/ @@ -29,5 +29,5 @@ cd .. find . -name "*.DS_Store" -type f -delete zip -r Firmata.zip ./Firmata/ cd .. -mv ./temp/Firmata.zip Arduino-1.6.x-Firmata-2.5.6.zip +mv ./temp/Firmata.zip Firmata-2.5.7.zip rm -r ./temp From defa0ea92b524b4473b81428fe3c7dfc91c520bc Mon Sep 17 00:00:00 2001 From: Sandeep Mistry Date: Fri, 1 Dec 2017 09:54:19 -0500 Subject: [PATCH 19/81] Add support for Arduino MKR WAN 1300 and MKR GSM 1400 --- Boards.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/Boards.h b/Boards.h index 69bd3db0..ae3e0639 100644 --- a/Boards.h +++ b/Boards.h @@ -292,6 +292,37 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) #define PIN_TO_SERVO(p) (p) // deprecated since v2.4 +// Arduino MKR WAN 1300 +#elif defined(ARDUINO_SAMD_MKRWAN1300) +#define TOTAL_ANALOG_PINS 7 +#define TOTAL_PINS 33 +#define IS_PIN_DIGITAL(p) (((p) >= 0 && (p) <= 21)) +#define IS_PIN_ANALOG(p) (((p) >= 15 && (p) < 15 + TOTAL_ANALOG_PINS) || (p) == 32) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4 +#define IS_PIN_I2C(p) ((p) == 11 || (p) == 12) // SDA = 11, SCL = 12 +#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) +#define IS_PIN_SERIAL(p) ((p) == PIN_SERIAL1_RX || (p) == PIN_SERIAL1_TX) //defined in variant.h RX = 13, TX = 14 +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) ((p) - 15) +#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) +#define PIN_TO_SERVO(p) (p) // deprecated since v2.4 + +// Arduino MKR GSM 1400 +#elif defined(ARDUINO_SAMD_MKRGSM1400) +#define TOTAL_ANALOG_PINS 7 +#define TOTAL_PINS 33 +#define IS_PIN_DIGITAL(p) (((p) >= 0 && (p) <= 21)) +#define IS_PIN_ANALOG(p) (((p) >= 15 && (p) < 15 + TOTAL_ANALOG_PINS) || (p) == 32) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4 +#define IS_PIN_I2C(p) ((p) == 11 || (p) == 12) // SDA = 11, SCL = 12 +#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) +#define IS_PIN_SERIAL(p) ((p) == PIN_SERIAL1_RX || (p) == PIN_SERIAL1_TX) //defined in variant.h RX = 13, TX = 14 +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) ((p) - 15) +#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) +#define PIN_TO_SERVO(p) (p) // deprecated since v2.4 // Arduino Zero // Note this will work with an Arduino Zero Pro, but not with an Arduino M0 Pro From e0594d44263c561e0809e8950ee3f9d91fd7e0a1 Mon Sep 17 00:00:00 2001 From: "Frederic.Pillon" Date: Mon, 29 Jan 2018 10:28:36 +0100 Subject: [PATCH 20/81] [STM32] Avoid using non standard constant AEND is an internal STM32 core constant and should not be used. Replaced by (A0 + TOTAL_ANALOG_PINS) Signed-off-by: Frederic.Pillon --- Boards.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Boards.h b/Boards.h index 69bd3db0..69c12481 100644 --- a/Boards.h +++ b/Boards.h @@ -788,7 +788,7 @@ writePort(port, value, bitmask): Write an 8 bit port. #define VERSION_BLINK_PIN LED_BUILTIN // PIN_SERIALY_RX/TX defined in the variant.h #define IS_PIN_DIGITAL(p) (digitalPinIsValid(p) && !pinIsSerial(p)) -#define IS_PIN_ANALOG(p) ((p >= A0) && (p < AEND) && !pinIsSerial(p)) +#define IS_PIN_ANALOG(p) ((p >= A0) && (p < (A0 + TOTAL_ANALOG_PINS)) && !pinIsSerial(p)) #define IS_PIN_PWM(p) (IS_PIN_DIGITAL(p) && digitalPinHasPWM(p)) #define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p) #define IS_PIN_I2C(p) (IS_PIN_DIGITAL(p) && digitalPinHasI2C(p)) From 73a73631338f2849d2083ed7b7320ea89204cd11 Mon Sep 17 00:00:00 2001 From: Jeff Hoefs Date: Sat, 3 Mar 2018 12:26:57 -0800 Subject: [PATCH 21/81] update link to list of host software packages --- examples/AllInputsFirmata/AllInputsFirmata.ino | 4 ++-- examples/AnalogFirmata/AnalogFirmata.ino | 4 ++-- examples/EchoString/EchoString.ino | 4 ++-- examples/OldStandardFirmata/OldStandardFirmata.ino | 4 ++-- examples/ServoFirmata/ServoFirmata.ino | 4 ++-- examples/SimpleAnalogFirmata/SimpleAnalogFirmata.ino | 4 ++-- examples/SimpleDigitalFirmata/SimpleDigitalFirmata.ino | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/examples/AllInputsFirmata/AllInputsFirmata.ino b/examples/AllInputsFirmata/AllInputsFirmata.ino index 9a1439aa..fb9b0fdc 100644 --- a/examples/AllInputsFirmata/AllInputsFirmata.ino +++ b/examples/AllInputsFirmata/AllInputsFirmata.ino @@ -4,9 +4,9 @@ * any host computer software package. * * To download a host software package, please click on the following link - * to open the download page in your default browser. + * to open the list of Firmata client libraries in your default browser. * - * http://firmata.org/wiki/Download + * https://github.com/firmata/arduino#firmata-client-libraries */ /* diff --git a/examples/AnalogFirmata/AnalogFirmata.ino b/examples/AnalogFirmata/AnalogFirmata.ino index 7890bcfa..689c6851 100644 --- a/examples/AnalogFirmata/AnalogFirmata.ino +++ b/examples/AnalogFirmata/AnalogFirmata.ino @@ -4,9 +4,9 @@ * any host computer software package. * * To download a host software package, please click on the following link - * to open the download page in your default browser. + * to open the list of Firmata client libraries in your default browser. * - * http://firmata.org/wiki/Download + * https://github.com/firmata/arduino#firmata-client-libraries */ /* This firmware supports as many analog ports as possible, all analog inputs, diff --git a/examples/EchoString/EchoString.ino b/examples/EchoString/EchoString.ino index 3e794b3d..e1651d50 100644 --- a/examples/EchoString/EchoString.ino +++ b/examples/EchoString/EchoString.ino @@ -4,9 +4,9 @@ * any host computer software package. * * To download a host software package, please click on the following link - * to open the download page in your default browser. + * to open the list of Firmata client libraries in your default browser. * - * http://firmata.org/wiki/Download + * https://github.com/firmata/arduino#firmata-client-libraries */ /* This sketch accepts strings and raw sysex messages and echos them back. diff --git a/examples/OldStandardFirmata/OldStandardFirmata.ino b/examples/OldStandardFirmata/OldStandardFirmata.ino index 2c63c2ab..5b79de57 100644 --- a/examples/OldStandardFirmata/OldStandardFirmata.ino +++ b/examples/OldStandardFirmata/OldStandardFirmata.ino @@ -4,9 +4,9 @@ * any host computer software package. * * To download a host software package, please click on the following link - * to open the download page in your default browser. + * to open the list of Firmata client libraries in your default browser. * - * http://firmata.org/wiki/Download + * https://github.com/firmata/arduino#firmata-client-libraries */ /* diff --git a/examples/ServoFirmata/ServoFirmata.ino b/examples/ServoFirmata/ServoFirmata.ino index a2f92e31..52b1f1bb 100644 --- a/examples/ServoFirmata/ServoFirmata.ino +++ b/examples/ServoFirmata/ServoFirmata.ino @@ -4,9 +4,9 @@ * any host computer software package. * * To download a host software package, please click on the following link - * to open the download page in your default browser. + * to open the list of Firmata client libraries in your default browser. * - * http://firmata.org/wiki/Download + * https://github.com/firmata/arduino#firmata-client-libraries */ /* This firmware supports as many servos as possible using the Servo library diff --git a/examples/SimpleAnalogFirmata/SimpleAnalogFirmata.ino b/examples/SimpleAnalogFirmata/SimpleAnalogFirmata.ino index d7f3a8bd..98a6adf8 100644 --- a/examples/SimpleAnalogFirmata/SimpleAnalogFirmata.ino +++ b/examples/SimpleAnalogFirmata/SimpleAnalogFirmata.ino @@ -4,9 +4,9 @@ * any host computer software package. * * To download a host software package, please click on the following link - * to open the download page in your default browser. + * to open the list of Firmata client libraries in your default browser. * - * http://firmata.org/wiki/Download + * https://github.com/firmata/arduino#firmata-client-libraries */ /* Supports as many analog inputs and analog PWM outputs as possible. diff --git a/examples/SimpleDigitalFirmata/SimpleDigitalFirmata.ino b/examples/SimpleDigitalFirmata/SimpleDigitalFirmata.ino index d935be1b..91db3337 100644 --- a/examples/SimpleDigitalFirmata/SimpleDigitalFirmata.ino +++ b/examples/SimpleDigitalFirmata/SimpleDigitalFirmata.ino @@ -4,9 +4,9 @@ * any host computer software package. * * To download a host software package, please click on the following link - * to open the download page in your default browser. + * to open the list of Firmata client libraries in your default browser. * - * http://firmata.org/wiki/Download + * https://github.com/firmata/arduino#firmata-client-libraries */ /* Supports as many digital inputs and outputs as possible. From a1a306757a1746b1ad1697bf0e64f5c880a98c8c Mon Sep 17 00:00:00 2001 From: Jeff Hoefs Date: Sat, 3 Mar 2018 12:28:33 -0800 Subject: [PATCH 22/81] update firmata.js url --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index f9f8c15a..46692a5b 100644 --- a/readme.md +++ b/readme.md @@ -46,7 +46,7 @@ Most of the time you will be interacting with Arduino with a client library on t * [https://github.com/nakkaya/clodiuno](https://github.com/nakkaya/clodiuno) * [https://github.com/peterschwarz/clj-firmata](https://github.com/peterschwarz/clj-firmata) * javascript - * [https://github.com/jgautier/firmata](https://github.com/jgautier/firmata) + * [https://github.com/firmata/firmata.js](https://github.com/firmata/firmata.js) * [https://github.com/rwldrn/johnny-five](https://github.com/rwldrn/johnny-five) * [http://breakoutjs.com](http://breakoutjs.com) * java From e3a29322d8c00220970a84074c683ea6ba479e61 Mon Sep 17 00:00:00 2001 From: Christopher Stawarz Date: Mon, 19 Mar 2018 13:54:22 -0400 Subject: [PATCH 23/81] Moved configuration of BLE connection and flush intervals to bleConfig.h These are hardware-specific settings, so they don't belong with the hardware-agnostic code in StandardFirmataBLE.ino. For Arduino 101, specify connection intervals in milliseconds, as expected by BLEPeripheral::setConnectionInterval in Intel Curie Boards package v2.0.2. --- .../StandardFirmataBLE/StandardFirmataBLE.ino | 11 ---- examples/StandardFirmataBLE/bleConfig.h | 58 +++++++++++++------ utility/BLEStream.h | 17 +----- 3 files changed, 44 insertions(+), 42 deletions(-) diff --git a/examples/StandardFirmataBLE/StandardFirmataBLE.ino b/examples/StandardFirmataBLE/StandardFirmataBLE.ino index 57756587..97cfb73f 100755 --- a/examples/StandardFirmataBLE/StandardFirmataBLE.ino +++ b/examples/StandardFirmataBLE/StandardFirmataBLE.ino @@ -56,10 +56,6 @@ // the minimum interval for sampling analog input #define MINIMUM_SAMPLING_INTERVAL 1 -// min cannot be < 0x0006. Adjust max if necessary -#define FIRMATA_BLE_MIN_INTERVAL 0x0006 // 7.5ms (7.5 / 1.25) -#define FIRMATA_BLE_MAX_INTERVAL 0x0018 // 30ms (30 / 1.25) - /*============================================================================== * GLOBAL VARIABLES *============================================================================*/ @@ -772,13 +768,6 @@ void setup() Firmata.attach(START_SYSEX, sysexCallback); Firmata.attach(SYSTEM_RESET, systemResetCallback); - stream.setLocalName(FIRMATA_BLE_LOCAL_NAME); - - // set the BLE connection interval - this is the fastest interval you can read inputs - stream.setConnectionInterval(FIRMATA_BLE_MIN_INTERVAL, FIRMATA_BLE_MAX_INTERVAL); - // set how often the BLE TX buffer is flushed (if not full) - stream.setFlushInterval(FIRMATA_BLE_MAX_INTERVAL); - #ifdef BLE_REQ for (byte i = 0; i < TOTAL_PINS; i++) { if (IS_IGNORE_BLE_PINS(i)) { diff --git a/examples/StandardFirmataBLE/bleConfig.h b/examples/StandardFirmataBLE/bleConfig.h index da5a5f20..5fd20ce3 100644 --- a/examples/StandardFirmataBLE/bleConfig.h +++ b/examples/StandardFirmataBLE/bleConfig.h @@ -5,7 +5,7 @@ * need a unique ble local name (see below). If you are using another supported BLE board or shield, * follow the instructions for the specific board or shield below. * - * Make sure you have the Intel Curie Boards package v1.0.6 or higher installed via the Arduino + * Make sure you have the Intel Curie Boards package v2.0.2 or higher installed via the Arduino * Boards Manager. * * Supported boards and shields: @@ -19,6 +19,22 @@ // within the same physical space #define FIRMATA_BLE_LOCAL_NAME "FIRMATA" +/* + * Arduino 101 + * + * Make sure you have the Intel Curie Boards package v2.0.2 or higher installed via the Arduino + * Boards Manager. + * + * Test script: https://gist.github.com/soundanalogous/927360b797574ed50e27 + */ +#ifdef _VARIANT_ARDUINO_101_X_ +// After conversion to units of 1.25ms, both values must be between +// 0x0006 (7.5ms) and 0x0c80 (4s) +#define FIRMATA_BLE_MIN_INTERVAL 8 // ( 8 * 1000) / 1250 == 0x06 -> 7.5ms +#define FIRMATA_BLE_MAX_INTERVAL 30 // (30 * 1000) / 1250 == 0x18 -> 30ms +#endif + + /* * RedBearLab BLE Shield * @@ -36,15 +52,27 @@ //#define REDBEAR_BLE_SHIELD #ifdef REDBEAR_BLE_SHIELD -#include -#include -#include "utility/BLEStream.h" - #define BLE_REQ 9 #define BLE_RDY 8 #define BLE_RST 4 // 4 or 7 via jumper on shield +#endif -BLEStream stream(BLE_REQ, BLE_RDY, BLE_RST); + +/* + * Generic settings + */ +#if !defined(FIRMATA_BLE_MIN_INTERVAL) && !defined(FIRMATA_BLE_MAX_INTERVAL) +// BLE connection interval - this is the fastest interval you can read inputs. +// These values apply to all devices using the Arduino BLEPeripheral library +// with a Nordic nRF8001 or nRF51822. Both values must be between +// 0x0006 (7.5ms) and 0x0c80 (4s). +#define FIRMATA_BLE_MIN_INTERVAL 0x0006 // 7.5ms (7.5 / 1.25) +#define FIRMATA_BLE_MAX_INTERVAL 0x0018 // 30ms (30 / 1.25) +#endif + +#if !defined(FIRMATA_BLE_TXBUFFER_FLUSH_INTERVAL) +// How often the BLE TX buffer is flushed (if not full) +#define FIRMATA_BLE_TXBUFFER_FLUSH_INTERVAL 30 // 30ms #endif @@ -52,21 +80,19 @@ BLEStream stream(BLE_REQ, BLE_RDY, BLE_RST); * END BLE CONFIGURATION - you should not need to change anything below this line *================================================================================================*/ -/* - * Arduino 101 - * - * Make sure you have the Intel Curie Boards package v1.0.6 or higher installed via the Arduino - * Boards Manager. - * - * Test script: https://gist.github.com/soundanalogous/927360b797574ed50e27 - */ #ifdef _VARIANT_ARDUINO_101_X_ -#include #include "utility/BLEStream.h" BLEStream stream; #endif +#ifdef REDBEAR_BLE_SHIELD +#include +#include "utility/BLEStream.h" +BLEStream stream(BLE_REQ, BLE_RDY, BLE_RST); +#endif + + /* * RedBearLab BLE Nano (with default switch settings) * @@ -81,7 +107,6 @@ BLEStream stream; * the pins are currently mapped in Firmata only for the default (factory) jumper settings. */ // #ifdef BLE_NANO -// #include // #include "utility/BLEStream.h" // BLEStream stream; // #endif @@ -96,7 +121,6 @@ BLEStream stream; */ // #if defined(BLEND_MICRO) || defined(BLEND) // #include -// #include // #include "utility/BLEStream.h" // #define BLE_REQ 6 diff --git a/utility/BLEStream.h b/utility/BLEStream.h index 56b36488..9a0d61fd 100644 --- a/utility/BLEStream.h +++ b/utility/BLEStream.h @@ -19,9 +19,6 @@ #define _MAX_ATTR_DATA_LEN_ BLE_ATTRIBUTE_MAX_VALUE_LENGTH #endif -#define BLESTREAM_TXBUFFER_FLUSH_INTERVAL 80 -#define BLESTREAM_MIN_FLUSH_INTERVAL 8 // minimum interval for flushing the TX buffer - // #define BLE_SERIAL_DEBUG class BLEStream : public BLEPeripheral, public Stream @@ -32,7 +29,6 @@ class BLEStream : public BLEPeripheral, public Stream void begin(...); bool poll(); void end(); - void setFlushInterval(int); virtual int available(void); virtual int peek(void); @@ -45,7 +41,6 @@ class BLEStream : public BLEPeripheral, public Stream private: bool _connected; unsigned long _flushed; - int _flushInterval; static BLEStream* _instance; size_t _rxHead; @@ -85,7 +80,6 @@ BLEStream::BLEStream(unsigned char req, unsigned char rdy, unsigned char rst) : this->_txCount = 0; this->_rxHead = this->_rxTail = 0; this->_flushed = 0; - this->_flushInterval = BLESTREAM_TXBUFFER_FLUSH_INTERVAL; BLEStream::_instance = this; addAttribute(this->_uartService); @@ -100,6 +94,8 @@ BLEStream::BLEStream(unsigned char req, unsigned char rdy, unsigned char rst) : void BLEStream::begin(...) { + BLEPeripheral::setLocalName(FIRMATA_BLE_LOCAL_NAME); + BLEPeripheral::setConnectionInterval(FIRMATA_BLE_MIN_INTERVAL, FIRMATA_BLE_MAX_INTERVAL); BLEPeripheral::begin(); #ifdef BLE_SERIAL_DEBUG Serial.println(F("BLEStream::begin()")); @@ -110,7 +106,7 @@ bool BLEStream::poll() { // BLEPeripheral::poll is called each time connected() is called this->_connected = BLEPeripheral::connected(); - if (millis() > this->_flushed + this->_flushInterval) { + if (millis() > this->_flushed + FIRMATA_BLE_TXBUFFER_FLUSH_INTERVAL) { flush(); } return this->_connected; @@ -214,13 +210,6 @@ BLEStream::operator bool() return retval; } -void BLEStream::setFlushInterval(int interval) -{ - if (interval > BLESTREAM_MIN_FLUSH_INTERVAL) { - this->_flushInterval = interval; - } -} - void BLEStream::_received(const unsigned char* data, size_t size) { for (size_t i = 0; i < size; i++) { From c2e8da390e59f1093227cb9549c720f3290d7f8c Mon Sep 17 00:00:00 2001 From: Christopher Stawarz Date: Mon, 19 Mar 2018 14:08:34 -0400 Subject: [PATCH 24/81] Added support for the Adafruit Feather M0 Bluefruit LE (and potentially other Bluefruit LE boards/modules that communicate with the nRF51822 via SPI) to StandardFirmataBLE --- .../StandardFirmataBLE/StandardFirmataBLE.ino | 2 +- examples/StandardFirmataBLE/bleConfig.h | 34 +++++ utility/BluefruitLE_SPI_Stream.cpp | 3 + utility/BluefruitLE_SPI_Stream.h | 127 ++++++++++++++++++ 4 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 utility/BluefruitLE_SPI_Stream.cpp create mode 100644 utility/BluefruitLE_SPI_Stream.h diff --git a/examples/StandardFirmataBLE/StandardFirmataBLE.ino b/examples/StandardFirmataBLE/StandardFirmataBLE.ino index 97cfb73f..7fa3a749 100755 --- a/examples/StandardFirmataBLE/StandardFirmataBLE.ino +++ b/examples/StandardFirmataBLE/StandardFirmataBLE.ino @@ -768,7 +768,7 @@ void setup() Firmata.attach(START_SYSEX, sysexCallback); Firmata.attach(SYSTEM_RESET, systemResetCallback); -#ifdef BLE_REQ +#ifdef IS_IGNORE_BLE_PINS for (byte i = 0; i < TOTAL_PINS; i++) { if (IS_IGNORE_BLE_PINS(i)) { Firmata.setPinMode(i, PIN_MODE_IGNORE); diff --git a/examples/StandardFirmataBLE/bleConfig.h b/examples/StandardFirmataBLE/bleConfig.h index 5fd20ce3..906bf77a 100644 --- a/examples/StandardFirmataBLE/bleConfig.h +++ b/examples/StandardFirmataBLE/bleConfig.h @@ -12,6 +12,7 @@ * - Arduino 101 (recommended) * - RedBearLab BLE Shield (v2) ** to be verified ** * - RedBearLab BLE Nano ** works with modifications ** + * - Adafruit Feather M0 Bluefruit LE * *================================================================================================*/ @@ -58,6 +59,31 @@ #endif +/* + * Adafruit Feather M0 Bluefruit LE + * + * If you are using an Adafruit Feather M0 Bluefruit LE, uncomment the define below. + * This configuration should also work with other Bluefruit LE boards/modules that communicate + * with the nRF51822 via SPI (e.g. Bluefruit LE SPI Friend, Bluefruit LE Shield), although + * you may need to change the values of BLE_SPI_CS, BLE_SPI_IRQ, and/or BLE_SPI_RST below. + * + * You will need to install a lightly-modified version of the Adafruit BluefruitLE nRF51 + * package, available at: + * https://github.com/cstawarz/Adafruit_BluefruitLE_nRF51/archive/firmata_fixes.zip + */ +//#define BLUEFRUIT_LE_SPI + +#ifdef BLUEFRUIT_LE_SPI +// Both values must be between 10ms and 4s +#define FIRMATA_BLE_MIN_INTERVAL 10 // 10ms +#define FIRMATA_BLE_MAX_INTERVAL 20 // 20ms + +#define BLE_SPI_CS 8 +#define BLE_SPI_IRQ 7 +#define BLE_SPI_RST 4 +#endif + + /* * Generic settings */ @@ -93,6 +119,12 @@ BLEStream stream(BLE_REQ, BLE_RDY, BLE_RST); #endif +#ifdef BLUEFRUIT_LE_SPI +#include "utility/BluefruitLE_SPI_Stream.h" +BluefruitLE_SPI_Stream stream(BLE_SPI_CS, BLE_SPI_IRQ, BLE_SPI_RST); +#endif + + /* * RedBearLab BLE Nano (with default switch settings) * @@ -133,4 +165,6 @@ BLEStream stream(BLE_REQ, BLE_RDY, BLE_RST); #if defined(BLE_REQ) && defined(BLE_RDY) && defined(BLE_RST) #define IS_IGNORE_BLE_PINS(p) ((p) == BLE_REQ || (p) == BLE_RDY || (p) == BLE_RST) +#elif defined(BLE_SPI_CS) && defined(BLE_SPI_IRQ) && defined(BLE_SPI_RST) +#define IS_IGNORE_BLE_PINS(p) ((p) == BLE_SPI_CS || (p) == BLE_SPI_IRQ || (p) == BLE_SPI_RST) #endif diff --git a/utility/BluefruitLE_SPI_Stream.cpp b/utility/BluefruitLE_SPI_Stream.cpp new file mode 100644 index 00000000..93953e96 --- /dev/null +++ b/utility/BluefruitLE_SPI_Stream.cpp @@ -0,0 +1,3 @@ +/* + * Implementation is in BluefruitLE_SPI_Stream.h to avoid linker issues. + */ diff --git a/utility/BluefruitLE_SPI_Stream.h b/utility/BluefruitLE_SPI_Stream.h new file mode 100644 index 00000000..43f8f929 --- /dev/null +++ b/utility/BluefruitLE_SPI_Stream.h @@ -0,0 +1,127 @@ +/* + BluefruitLE_SPI_Stream.h + + Documentation for the various AT commands used below is available at + https://learn.adafruit.com/adafruit-feather-m0-bluefruit-le/at-commands + */ + +#ifndef _BLUEFRUIT_LE_SPI_STREAM_H_ +#define _BLUEFRUIT_LE_SPI_STREAM_H_ + +#include + + +class BluefruitLE_SPI_Stream : public Stream +{ + public: + BluefruitLE_SPI_Stream(int8_t csPin, int8_t irqPin, int8_t rstPin); + + void begin(); + bool poll(); + void end(); + + // Print overrides + size_t write(uint8_t byte); + using Print::write; // Expose other write variants + + // Stream overrides + int available(); + int read(); + int peek(); + void flush(); + + private: + Adafruit_BluefruitLE_SPI ble; + + uint8_t txBuffer[SDEP_MAX_PACKETSIZE]; + size_t txCount; +}; + + +BluefruitLE_SPI_Stream::BluefruitLE_SPI_Stream(int8_t csPin, int8_t irqPin, int8_t rstPin) : + ble(csPin, irqPin, rstPin), + txCount(0) +{ } + +void BluefruitLE_SPI_Stream::begin() +{ + // Initialize the SPI interface + ble.begin(); + + // Perform a factory reset to make sure everything is in a known state + ble.factoryReset(); + + // Disable command echo from Bluefruit + ble.echo(false); + + // Change the MODE LED to indicate BLE UART activity + ble.println("AT+HWMODELED=BLEUART"); + + // Set local name + ble.print("AT+GAPDEVNAME="); + ble.println(FIRMATA_BLE_LOCAL_NAME); + + // Set connection interval + ble.print("AT+GAPINTERVALS="); + ble.print(FIRMATA_BLE_MIN_INTERVAL); + ble.print(","); + ble.print(FIRMATA_BLE_MAX_INTERVAL); + ble.println(",,,"); + + // Disable real and simulated mode switch (i.e. "+++") command + ble.println("AT+MODESWITCHEN=local,0"); + ble.enableModeSwitchCommand(false); + + // Switch to data mode + ble.setMode(BLUEFRUIT_MODE_DATA); +} + +bool BluefruitLE_SPI_Stream::poll() +{ + // If there's outgoing data in the buffer, just send it. The firmware on + // the nRF51822 will decide when to transmit the data in its TX FIFO. + if (txCount) flush(); + + // In order to check for a connection, we would need to switch from data to + // command mode and back again. However, due to the internal workings of + // Adafruit_BluefruitLE_SPI, this can lead to unread incoming data being + // lost. Therefore, we always return true. + return true; +} + +void BluefruitLE_SPI_Stream::end() +{ + flush(); + ble.end(); +} + +size_t BluefruitLE_SPI_Stream::write(uint8_t byte) +{ + txBuffer[txCount++] = byte; + if (txCount == sizeof(txBuffer)) flush(); + return 1; +} + +int BluefruitLE_SPI_Stream::available() +{ + return ble.available(); +} + +int BluefruitLE_SPI_Stream::read() +{ + return ble.read(); +} + +int BluefruitLE_SPI_Stream::peek() +{ + return ble.peek(); +} + +void BluefruitLE_SPI_Stream::flush() +{ + ble.write(txBuffer, txCount); + txCount = 0; +} + + +#endif // _BLUEFRUIT_LE_SPI_STREAM_H_ From 5b8b9f0060f645cda5c28b41a2ed7d89f19b48d9 Mon Sep 17 00:00:00 2001 From: Christopher Stawarz Date: Wed, 4 Apr 2018 13:34:58 -0400 Subject: [PATCH 25/81] Restored use of setter methods for BLE configuration --- .../StandardFirmataBLE/StandardFirmataBLE.ino | 7 +++ examples/StandardFirmataBLE/bleConfig.h | 2 - utility/BLEStream.h | 17 +++++-- utility/BluefruitLE_SPI_Stream.h | 44 ++++++++++++++++--- 4 files changed, 58 insertions(+), 12 deletions(-) diff --git a/examples/StandardFirmataBLE/StandardFirmataBLE.ino b/examples/StandardFirmataBLE/StandardFirmataBLE.ino index 7fa3a749..65cf3cbd 100755 --- a/examples/StandardFirmataBLE/StandardFirmataBLE.ino +++ b/examples/StandardFirmataBLE/StandardFirmataBLE.ino @@ -768,6 +768,13 @@ void setup() Firmata.attach(START_SYSEX, sysexCallback); Firmata.attach(SYSTEM_RESET, systemResetCallback); + stream.setLocalName(FIRMATA_BLE_LOCAL_NAME); + + // set the BLE connection interval - this is the fastest interval you can read inputs + stream.setConnectionInterval(FIRMATA_BLE_MIN_INTERVAL, FIRMATA_BLE_MAX_INTERVAL); + // set how often the BLE TX buffer is flushed (if not full) + stream.setFlushInterval(FIRMATA_BLE_TXBUFFER_FLUSH_INTERVAL); + #ifdef IS_IGNORE_BLE_PINS for (byte i = 0; i < TOTAL_PINS; i++) { if (IS_IGNORE_BLE_PINS(i)) { diff --git a/examples/StandardFirmataBLE/bleConfig.h b/examples/StandardFirmataBLE/bleConfig.h index 906bf77a..412bb849 100644 --- a/examples/StandardFirmataBLE/bleConfig.h +++ b/examples/StandardFirmataBLE/bleConfig.h @@ -88,7 +88,6 @@ * Generic settings */ #if !defined(FIRMATA_BLE_MIN_INTERVAL) && !defined(FIRMATA_BLE_MAX_INTERVAL) -// BLE connection interval - this is the fastest interval you can read inputs. // These values apply to all devices using the Arduino BLEPeripheral library // with a Nordic nRF8001 or nRF51822. Both values must be between // 0x0006 (7.5ms) and 0x0c80 (4s). @@ -97,7 +96,6 @@ #endif #if !defined(FIRMATA_BLE_TXBUFFER_FLUSH_INTERVAL) -// How often the BLE TX buffer is flushed (if not full) #define FIRMATA_BLE_TXBUFFER_FLUSH_INTERVAL 30 // 30ms #endif diff --git a/utility/BLEStream.h b/utility/BLEStream.h index 9a0d61fd..56b36488 100644 --- a/utility/BLEStream.h +++ b/utility/BLEStream.h @@ -19,6 +19,9 @@ #define _MAX_ATTR_DATA_LEN_ BLE_ATTRIBUTE_MAX_VALUE_LENGTH #endif +#define BLESTREAM_TXBUFFER_FLUSH_INTERVAL 80 +#define BLESTREAM_MIN_FLUSH_INTERVAL 8 // minimum interval for flushing the TX buffer + // #define BLE_SERIAL_DEBUG class BLEStream : public BLEPeripheral, public Stream @@ -29,6 +32,7 @@ class BLEStream : public BLEPeripheral, public Stream void begin(...); bool poll(); void end(); + void setFlushInterval(int); virtual int available(void); virtual int peek(void); @@ -41,6 +45,7 @@ class BLEStream : public BLEPeripheral, public Stream private: bool _connected; unsigned long _flushed; + int _flushInterval; static BLEStream* _instance; size_t _rxHead; @@ -80,6 +85,7 @@ BLEStream::BLEStream(unsigned char req, unsigned char rdy, unsigned char rst) : this->_txCount = 0; this->_rxHead = this->_rxTail = 0; this->_flushed = 0; + this->_flushInterval = BLESTREAM_TXBUFFER_FLUSH_INTERVAL; BLEStream::_instance = this; addAttribute(this->_uartService); @@ -94,8 +100,6 @@ BLEStream::BLEStream(unsigned char req, unsigned char rdy, unsigned char rst) : void BLEStream::begin(...) { - BLEPeripheral::setLocalName(FIRMATA_BLE_LOCAL_NAME); - BLEPeripheral::setConnectionInterval(FIRMATA_BLE_MIN_INTERVAL, FIRMATA_BLE_MAX_INTERVAL); BLEPeripheral::begin(); #ifdef BLE_SERIAL_DEBUG Serial.println(F("BLEStream::begin()")); @@ -106,7 +110,7 @@ bool BLEStream::poll() { // BLEPeripheral::poll is called each time connected() is called this->_connected = BLEPeripheral::connected(); - if (millis() > this->_flushed + FIRMATA_BLE_TXBUFFER_FLUSH_INTERVAL) { + if (millis() > this->_flushed + this->_flushInterval) { flush(); } return this->_connected; @@ -210,6 +214,13 @@ BLEStream::operator bool() return retval; } +void BLEStream::setFlushInterval(int interval) +{ + if (interval > BLESTREAM_MIN_FLUSH_INTERVAL) { + this->_flushInterval = interval; + } +} + void BLEStream::_received(const unsigned char* data, size_t size) { for (size_t i = 0; i < size; i++) { diff --git a/utility/BluefruitLE_SPI_Stream.h b/utility/BluefruitLE_SPI_Stream.h index 43f8f929..372e5aa9 100644 --- a/utility/BluefruitLE_SPI_Stream.h +++ b/utility/BluefruitLE_SPI_Stream.h @@ -16,6 +16,10 @@ class BluefruitLE_SPI_Stream : public Stream public: BluefruitLE_SPI_Stream(int8_t csPin, int8_t irqPin, int8_t rstPin); + void setLocalName(const char *localName); + void setConnectionInterval(unsigned short minConnInterval, unsigned short maxConnInterval); + void setFlushInterval(int flushInterval); + void begin(); bool poll(); void end(); @@ -33,6 +37,10 @@ class BluefruitLE_SPI_Stream : public Stream private: Adafruit_BluefruitLE_SPI ble; + String localName; + unsigned short minConnInterval; + unsigned short maxConnInterval; + uint8_t txBuffer[SDEP_MAX_PACKETSIZE]; size_t txCount; }; @@ -40,9 +48,27 @@ class BluefruitLE_SPI_Stream : public Stream BluefruitLE_SPI_Stream::BluefruitLE_SPI_Stream(int8_t csPin, int8_t irqPin, int8_t rstPin) : ble(csPin, irqPin, rstPin), + minConnInterval(0), + maxConnInterval(0), txCount(0) { } +void BluefruitLE_SPI_Stream::setLocalName(const char *localName) +{ + this->localName = localName; +} + +void BluefruitLE_SPI_Stream::setConnectionInterval(unsigned short minConnInterval, unsigned short maxConnInterval) +{ + this->minConnInterval = minConnInterval; + this->maxConnInterval = maxConnInterval; +} + +void BluefruitLE_SPI_Stream::setFlushInterval(int flushInterval) +{ + // Not used +} + void BluefruitLE_SPI_Stream::begin() { // Initialize the SPI interface @@ -58,15 +84,19 @@ void BluefruitLE_SPI_Stream::begin() ble.println("AT+HWMODELED=BLEUART"); // Set local name - ble.print("AT+GAPDEVNAME="); - ble.println(FIRMATA_BLE_LOCAL_NAME); + if (localName.length() > 0) { + ble.print("AT+GAPDEVNAME="); + ble.println(localName); + } // Set connection interval - ble.print("AT+GAPINTERVALS="); - ble.print(FIRMATA_BLE_MIN_INTERVAL); - ble.print(","); - ble.print(FIRMATA_BLE_MAX_INTERVAL); - ble.println(",,,"); + if (minConnInterval > 0 && maxConnInterval > 0) { + ble.print("AT+GAPINTERVALS="); + ble.print(minConnInterval); + ble.print(","); + ble.print(maxConnInterval); + ble.println(",,,"); + } // Disable real and simulated mode switch (i.e. "+++") command ble.println("AT+MODESWITCHEN=local,0"); From 00587f8756bca8f279d5914cc556827c63242925 Mon Sep 17 00:00:00 2001 From: Petros Angelatos Date: Fri, 13 Apr 2018 16:48:22 +0300 Subject: [PATCH 26/81] extend number of supported hardware serial ports to 6 Signed-off-by: Petros Angelatos --- utility/SerialFirmata.cpp | 12 ++++++++++++ utility/SerialFirmata.h | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/utility/SerialFirmata.cpp b/utility/SerialFirmata.cpp index b934f166..8b703e13 100644 --- a/utility/SerialFirmata.cpp +++ b/utility/SerialFirmata.cpp @@ -252,6 +252,18 @@ Stream* SerialFirmata::getPortFromId(byte portId) case HW_SERIAL3: return &Serial3; #endif +#if defined(PIN_SERIAL4_RX) + case HW_SERIAL4: + return &Serial4; +#endif +#if defined(PIN_SERIAL5_RX) + case HW_SERIAL5: + return &Serial5; +#endif +#if defined(PIN_SERIAL6_RX) + case HW_SERIAL6: + return &Serial6; +#endif #if defined(SoftwareSerial_h) case SW_SERIAL0: if (swSerial0 != NULL) { diff --git a/utility/SerialFirmata.h b/utility/SerialFirmata.h index 79915aaf..2319951b 100644 --- a/utility/SerialFirmata.h +++ b/utility/SerialFirmata.h @@ -37,6 +37,9 @@ #define HW_SERIAL1 0x01 #define HW_SERIAL2 0x02 #define HW_SERIAL3 0x03 +#define HW_SERIAL4 0x04 +#define HW_SERIAL5 0x05 +#define HW_SERIAL6 0x06 // extensible up to 0x07 #define SW_SERIAL0 0x08 @@ -56,6 +59,12 @@ #define RES_TX2 0x05 #define RES_RX3 0x06 #define RES_TX3 0x07 +#define RES_RX4 0x08 +#define RES_TX4 0x09 +#define RES_RX5 0x0a +#define RES_TX5 0x0b +#define RES_RX6 0x0c +#define RES_TX6 0x0d // Serial command bytes #define SERIAL_CONFIG 0x10 @@ -96,6 +105,18 @@ namespace { #if defined(PIN_SERIAL3_RX) if (pin == PIN_SERIAL3_RX) return RES_RX3; if (pin == PIN_SERIAL3_TX) return RES_TX3; + #endif + #if defined(PIN_SERIAL4_RX) + if (pin == PIN_SERIAL4_RX) return RES_RX4; + if (pin == PIN_SERIAL4_TX) return RES_TX4; + #endif + #if defined(PIN_SERIAL5_RX) + if (pin == PIN_SERIAL5_RX) return RES_RX5; + if (pin == PIN_SERIAL5_TX) return RES_TX5; + #endif + #if defined(PIN_SERIAL6_RX) + if (pin == PIN_SERIAL6_RX) return RES_RX6; + if (pin == PIN_SERIAL6_TX) return RES_TX6; #endif return 0; } @@ -128,6 +149,24 @@ namespace { pins.rx = PIN_SERIAL3_RX; pins.tx = PIN_SERIAL3_TX; break; + #endif + #if defined(PIN_SERIAL4_RX) + case HW_SERIAL4: + pins.rx = PIN_SERIAL4_RX; + pins.tx = PIN_SERIAL4_TX; + break; + #endif + #if defined(PIN_SERIAL5_RX) + case HW_SERIAL5: + pins.rx = PIN_SERIAL5_RX; + pins.tx = PIN_SERIAL5_TX; + break; + #endif + #if defined(PIN_SERIAL6_RX) + case HW_SERIAL6: + pins.rx = PIN_SERIAL6_RX; + pins.tx = PIN_SERIAL6_TX; + break; #endif default: pins.rx = 0; From 47fa25d51efb841ff8d8b85ed7ffc4945c5e1174 Mon Sep 17 00:00:00 2001 From: Petros Angelatos Date: Fri, 13 Apr 2018 16:50:08 +0300 Subject: [PATCH 27/81] boards: fix pin mapping for Teensy 3.5 and 3.6 Reference: https://www.pjrc.com/teensy/td_uart.html Signed-off-by: Petros Angelatos --- Boards.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Boards.h b/Boards.h index 69c12481..d8ef528f 100644 --- a/Boards.h +++ b/Boards.h @@ -403,11 +403,12 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_SERIAL2_TX 10 #define PIN_SERIAL3_RX 7 #define PIN_SERIAL3_TX 8 -// The following 2 UARTs are not yet available via SerialFirmata #define PIN_SERIAL4_RX 31 -#define PIN_SERIAL5_TX 32 -#define PIN_SERIAL6_RX 34 -#define PIN_SERIAL6_TX 33 +#define PIN_SERIAL4_TX 32 +#define PIN_SERIAL5_RX 34 +#define PIN_SERIAL5_TX 33 +#define PIN_SERIAL6_RX 47 +#define PIN_SERIAL6_TX 48 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) <= 63) #define IS_PIN_ANALOG(p) (((p) >= 14 && (p) <= 23) || ((p) >= 31 && (p) <= 39) || ((p) >= 49 && (p) <= 50) || ((p) >= 64 && (p) <= 69)) #define IS_PIN_PWM(p) digitalPinHasPWM(p) From c669cc369c876803e05d7e174649d68b37f97b56 Mon Sep 17 00:00:00 2001 From: Petros Angelatos Date: Sun, 15 Apr 2018 20:08:16 +0300 Subject: [PATCH 28/81] boards: update IS_PIN_SERIAL for Teensy 3.5 & 3.6 Signed-off-by: Petros Angelatos --- Boards.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Boards.h b/Boards.h index d8ef528f..3ae0e2ff 100644 --- a/Boards.h +++ b/Boards.h @@ -414,7 +414,7 @@ writePort(port, value, bitmask): Write an 8 bit port. #define IS_PIN_PWM(p) digitalPinHasPWM(p) #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19) -#define IS_PIN_SERIAL(p) (((p) > 6 && (p) < 11) || ((p) == 0 || (p) == 1)) +#define IS_PIN_SERIAL(p) (((p) > 6 && (p) < 11) || ((p) == 0 || (p) == 1) || ((p) > 30 && (p) < 35) || ((p) == 47 || (p) == 48)) #define PIN_TO_DIGITAL(p) (p) // A0-A9 = D14-D23; A12-A20 = D31-D39; A23-A24 = D49-D50; A10-A11 = D64-D65; A21-A22 = D66-D67; A25-A26 = D68-D69 #define PIN_TO_ANALOG(p) (((p) <= 23) ? (p) - 14 : (((p) <= 39) ? (p) - 19 : (((p) <= 50) ? (p) - 26 : (((p) <= 65) ? (p) - 55 : (((p) <= 67) ? (p) - 45 : (p) - 43))))) From d78cd6c4ab67c61ebf19da718b83cbdd8719db0a Mon Sep 17 00:00:00 2001 From: Jeff Hoefs Date: Sun, 15 Apr 2018 10:24:34 -0700 Subject: [PATCH 29/81] change last updated date --- Boards.h | 2 +- examples/StandardFirmataBLE/StandardFirmataBLE.ino | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Boards.h b/Boards.h index ae07eff5..ace8d975 100644 --- a/Boards.h +++ b/Boards.h @@ -10,7 +10,7 @@ See file LICENSE.txt for further informations on licensing terms. - Last updated August 14th, 2017 + Last updated April 15th, 2018 */ #ifndef Firmata_Boards_h diff --git a/examples/StandardFirmataBLE/StandardFirmataBLE.ino b/examples/StandardFirmataBLE/StandardFirmataBLE.ino index 65cf3cbd..7b17b891 100755 --- a/examples/StandardFirmataBLE/StandardFirmataBLE.ino +++ b/examples/StandardFirmataBLE/StandardFirmataBLE.ino @@ -20,7 +20,7 @@ See file LICENSE.txt for further informations on licensing terms. - Last updated August 17th, 2017 + Last updated April 15th, 2018 */ #include From 8cbe99be5890296d330b990f3ec078a4fba3a980 Mon Sep 17 00:00:00 2001 From: Jeff Hoefs Date: Sun, 15 Apr 2018 10:29:02 -0700 Subject: [PATCH 30/81] bump bugfix version --- Firmata.cpp | 2 +- Firmata.h | 2 +- library.properties | 2 +- readme.md | 8 ++++---- release.sh | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Firmata.cpp b/Firmata.cpp index e35c3dcb..ee01f8f5 100644 --- a/Firmata.cpp +++ b/Firmata.cpp @@ -1,5 +1,5 @@ /* - Firmata.cpp - Firmata library v2.5.7 - 2017-08-19 + Firmata.cpp - Firmata library v2.5.8 - 2018-04-15 Copyright (c) 2006-2008 Hans-Christoph Steiner. All rights reserved. Copyright (C) 2009-2017 Jeff Hoefs. All rights reserved. diff --git a/Firmata.h b/Firmata.h index c07b38d3..fa0fa6c2 100644 --- a/Firmata.h +++ b/Firmata.h @@ -1,5 +1,5 @@ /* - Firmata.h - Firmata library v2.5.7 - 2017-08-19 + Firmata.h - Firmata library v2.5.8 - 2018-04-15 Copyright (c) 2006-2008 Hans-Christoph Steiner. All rights reserved. Copyright (C) 2009-2017 Jeff Hoefs. All rights reserved. diff --git a/library.properties b/library.properties index 83431fc9..0dc9a348 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Firmata -version=2.5.7 +version=2.5.8 author=Firmata Developers maintainer=https://github.com/firmata/arduino sentence=Enables the communication with computer apps using a standard serial protocol. For all Arduino/Genuino boards. diff --git a/readme.md b/readme.md index 46692a5b..988edfd7 100644 --- a/readme.md +++ b/readme.md @@ -107,7 +107,7 @@ $ git clone git@github.com:firmata/arduino.git ~/Documents/Arduino/libraries/Fir ## Updating Firmata in the Arduino IDE - older versions (<= 1.6.3 or 1.0.x) -Download the latest [release](https://github.com/firmata/arduino/releases/tag/2.5.7) (for Arduino 1.0.x or Arduino 1.5.6 or higher) and replace the existing Firmata folder in your Arduino application. See the instructions below for your platform. +Download the latest [release](https://github.com/firmata/arduino/releases/tag/2.5.8) (for Arduino 1.0.x or Arduino 1.5.6 or higher) and replace the existing Firmata folder in your Arduino application. See the instructions below for your platform. *Note that Arduino 1.5.0 - 1.5.5 are not supported. Please use Arduino 1.5.6 or higher (or Arduino 1.0.5 or 1.0.6).* @@ -118,7 +118,7 @@ The Firmata library is contained within the Arduino package. 1. Navigate to the Arduino application 2. Right click on the application icon and select `Show Package Contents` 3. Navigate to: `/Contents/Resources/Java/libraries/` and replace the existing -`Firmata` folder with latest [Firmata release](https://github.com/firmata/arduino/releases/tag/2.5.7) (note there is a different download +`Firmata` folder with latest [Firmata release](https://github.com/firmata/arduino/releases/tag/2.5.8) (note there is a different download for Arduino 1.0.x vs 1.6.x) 4. Restart the Arduino application and the latest version of Firmata will be available. @@ -128,7 +128,7 @@ will differ slightly: `Contents/Java/libraries/Firmata` (no Resources directory) ### Windows: 1. Navigate to `c:/Program\ Files/arduino-1.x/libraries/` and replace the existing -`Firmata` folder with the latest [Firmata release](https://github.com/firmata/arduino/releases/tag/2.5.7) (note there is a different download +`Firmata` folder with the latest [Firmata release](https://github.com/firmata/arduino/releases/tag/2.5.8) (note there is a different download for Arduino 1.0.x vs 1.6.x). 2. Restart the Arduino application and the latest version of Firmata will be available. @@ -137,7 +137,7 @@ for Arduino 1.0.x vs 1.6.x). ### Linux: 1. Navigate to `~/arduino-1.x/libraries/` and replace the existing -`Firmata` folder with the latest [Firmata release](https://github.com/firmata/arduino/releases/tag/2.5.7) (note there is a different download +`Firmata` folder with the latest [Firmata release](https://github.com/firmata/arduino/releases/tag/2.5.8) (note there is a different download for Arduino 1.0.x vs 1.6.x). 2. Restart the Arduino application and the latest version of Firmata will be available. diff --git a/release.sh b/release.sh index 05cb74e4..0c47db8d 100644 --- a/release.sh +++ b/release.sh @@ -15,7 +15,7 @@ cd temp find . -name "*.DS_Store" -type f -delete zip -r Firmata.zip ./Firmata/ cd .. -mv ./temp/Firmata.zip Arduino-1.0.x-Firmata-2.5.7.zip +mv ./temp/Firmata.zip Arduino-1.0.x-Firmata-2.5.8.zip #package for Arduino 1.6.x and 1.8.x cp library.properties temp/Firmata @@ -29,5 +29,5 @@ cd .. find . -name "*.DS_Store" -type f -delete zip -r Firmata.zip ./Firmata/ cd .. -mv ./temp/Firmata.zip Firmata-2.5.7.zip +mv ./temp/Firmata.zip Firmata-2.5.8.zip rm -r ./temp From f9d9ec420c659eed4ce251cd58b1cdc6ff9c508e Mon Sep 17 00:00:00 2001 From: Serge Stinckwich Date: Fri, 11 May 2018 18:50:01 +0700 Subject: [PATCH 31/81] Add Pharo support --- readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/readme.md b/readme.md index 988edfd7..042c28d2 100644 --- a/readme.md +++ b/readme.md @@ -59,6 +59,8 @@ Most of the time you will be interacting with Arduino with a client library on t * Flash/AS3 * [http://funnel.cc](http://funnel.cc) * [http://code.google.com/p/as3glue/](http://code.google.com/p/as3glue/) +* Pharo + * [https://github.com/pharo-iot/Firmata](https://github.com/pharo-iot/Firmata) * PHP * [https://github.com/ThomasWeinert/carica-firmata]() * [https://github.com/oasynnoum/phpmake_firmata](https://github.com/oasynnoum/phpmake_firmata) From b1428e2ecb363fe733803419ecf74ca938db2274 Mon Sep 17 00:00:00 2001 From: per1234 Date: Sun, 15 Jul 2018 01:54:07 -0700 Subject: [PATCH 32/81] Use a single tab field separator in keywords.txt Each field of keywords.txt is separated by a single true tab. When you use multiple tabs it causes the field to be interpreted as empty. On Arduino IDE 1.6.5 and newer an empty KEYWORD_TOKENTYPE causes the default editor.function.style coloration to be used (as with KEYWORD2, KEYWORD3, LITERAL2). On Arduino IDE 1.6.4 and older it causes the keyword to not be recognized for any special coloration. Reference: https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Library-specification#keywords --- keywords.txt | 110 +++++++++++++++++++++++++-------------------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/keywords.txt b/keywords.txt index 5ab13d05..d11a5072 100644 --- a/keywords.txt +++ b/keywords.txt @@ -6,44 +6,44 @@ # Datatypes (KEYWORD1) ####################################### -Firmata KEYWORD1 Firmata -callbackFunction KEYWORD1 callbackFunction +Firmata KEYWORD1 Firmata +callbackFunction KEYWORD1 callbackFunction systemResetCallbackFunction KEYWORD1 systemResetCallbackFunction -stringCallbackFunction KEYWORD1 stringCallbackFunction -sysexCallbackFunction KEYWORD1 sysexCallbackFunction +stringCallbackFunction KEYWORD1 stringCallbackFunction +sysexCallbackFunction KEYWORD1 sysexCallbackFunction ####################################### # Methods and Functions (KEYWORD2) ####################################### -begin KEYWORD2 -printVersion KEYWORD2 -blinkVersion KEYWORD2 -printFirmwareVersion KEYWORD2 -setFirmwareVersion KEYWORD2 +begin KEYWORD2 +printVersion KEYWORD2 +blinkVersion KEYWORD2 +printFirmwareVersion KEYWORD2 +setFirmwareVersion KEYWORD2 setFirmwareNameAndVersion KEYWORD2 -available KEYWORD2 -processInput KEYWORD2 -isParsingMessage KEYWORD2 -parse KEYWORD2 -sendAnalog KEYWORD2 -sendDigital KEYWORD2 -sendDigitalPort KEYWORD2 -sendString KEYWORD2 -sendSysex KEYWORD2 -getPinMode KEYWORD2 -setPinMode KEYWORD2 -getPinState KEYWORD2 -setPinState KEYWORD2 -attach KEYWORD2 -detach KEYWORD2 -write KEYWORD2 +available KEYWORD2 +processInput KEYWORD2 +isParsingMessage KEYWORD2 +parse KEYWORD2 +sendAnalog KEYWORD2 +sendDigital KEYWORD2 +sendDigitalPort KEYWORD2 +sendString KEYWORD2 +sendSysex KEYWORD2 +getPinMode KEYWORD2 +setPinMode KEYWORD2 +getPinState KEYWORD2 +setPinState KEYWORD2 +attach KEYWORD2 +detach KEYWORD2 +write KEYWORD2 sendValueAsTwo7bitBytes KEYWORD2 -startSysex KEYWORD2 -endSysex KEYWORD2 -writePort KEYWORD2 -readPort KEYWORD2 -disableBlinkVersion KEYWORD2 +startSysex KEYWORD2 +endSysex KEYWORD2 +writePort KEYWORD2 +readPort KEYWORD2 +disableBlinkVersion KEYWORD2 ####################################### @@ -54,37 +54,37 @@ FIRMATA_MAJOR_VERSION LITERAL1 FIRMATA_MINOR_VERSION LITERAL1 FIRMATA_BUGFIX_VERSION LITERAL1 -MAX_DATA_BYTES LITERAL1 +MAX_DATA_BYTES LITERAL1 -DIGITAL_MESSAGE LITERAL1 -ANALOG_MESSAGE LITERAL1 -REPORT_ANALOG LITERAL1 -REPORT_DIGITAL LITERAL1 -REPORT_VERSION LITERAL1 -SET_PIN_MODE LITERAL1 +DIGITAL_MESSAGE LITERAL1 +ANALOG_MESSAGE LITERAL1 +REPORT_ANALOG LITERAL1 +REPORT_DIGITAL LITERAL1 +REPORT_VERSION LITERAL1 +SET_PIN_MODE LITERAL1 SET_DIGITAL_PIN_VALUE LITERAL1 -SYSTEM_RESET LITERAL1 -START_SYSEX LITERAL1 -END_SYSEX LITERAL1 -REPORT_FIRMWARE LITERAL1 -STRING_DATA LITERAL1 +SYSTEM_RESET LITERAL1 +START_SYSEX LITERAL1 +END_SYSEX LITERAL1 +REPORT_FIRMWARE LITERAL1 +STRING_DATA LITERAL1 -PIN_MODE_ANALOG LITERAL1 -PIN_MODE_PWM LITERAL1 -PIN_MODE_SERVO LITERAL1 -PIN_MODE_SHIFT LITERAL1 -PIN_MODE_I2C LITERAL1 +PIN_MODE_ANALOG LITERAL1 +PIN_MODE_PWM LITERAL1 +PIN_MODE_SERVO LITERAL1 +PIN_MODE_SHIFT LITERAL1 +PIN_MODE_I2C LITERAL1 PIN_MODE_ONEWIRE LITERAL1 PIN_MODE_STEPPER LITERAL1 PIN_MODE_ENCODER LITERAL1 -PIN_MODE_SERIAL LITERAL1 -PIN_MODE_PULLUP LITERAL1 -PIN_MODE_IGNORE LITERAL1 +PIN_MODE_SERIAL LITERAL1 +PIN_MODE_PULLUP LITERAL1 +PIN_MODE_IGNORE LITERAL1 -TOTAL_PINS LITERAL1 +TOTAL_PINS LITERAL1 TOTAL_ANALOG_PINS LITERAL1 TOTAL_DIGITAL_PINS LITERAL1 -TOTAL_PIN_MODES LITERAL1 -TOTAL_PORTS LITERAL1 -ANALOG_PORT LITERAL1 -MAX_SERVOS LITERAL1 +TOTAL_PIN_MODES LITERAL1 +TOTAL_PORTS LITERAL1 +ANALOG_PORT LITERAL1 +MAX_SERVOS LITERAL1 From 3d786388ad329fadacd52894e1faacd480d23800 Mon Sep 17 00:00:00 2001 From: per1234 Date: Sun, 9 Sep 2018 03:00:55 -0700 Subject: [PATCH 33/81] Remove invalid reference link from keywords.txt The third field of keywords.txt is used to provide Arduino Language/Libraries Reference links, which are accessed from the Arduino IDE by highlighting the keyword and then selecting "Find in Reference" from the Help or right click menu. Adding values to this field that do not match any existing reference pages results in a "Could not open the URL" error. Reference: https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Library-specification#keywordstxt-format --- keywords.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/keywords.txt b/keywords.txt index d11a5072..1e6dbc66 100644 --- a/keywords.txt +++ b/keywords.txt @@ -7,10 +7,10 @@ ####################################### Firmata KEYWORD1 Firmata -callbackFunction KEYWORD1 callbackFunction -systemResetCallbackFunction KEYWORD1 systemResetCallbackFunction -stringCallbackFunction KEYWORD1 stringCallbackFunction -sysexCallbackFunction KEYWORD1 sysexCallbackFunction +callbackFunction KEYWORD1 +systemResetCallbackFunction KEYWORD1 +stringCallbackFunction KEYWORD1 +sysexCallbackFunction KEYWORD1 ####################################### # Methods and Functions (KEYWORD2) From f3fef2bc81f31c8fdb9041f7e3bb0fd9373bc060 Mon Sep 17 00:00:00 2001 From: Hannes Brandstaetter-Mueller Date: Tue, 30 Oct 2018 22:37:15 +0100 Subject: [PATCH 34/81] Support for Sanguino/Melzi, e.g. Creality Ender-3 --- Boards.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Boards.h b/Boards.h index ace8d975..997093b9 100644 --- a/Boards.h +++ b/Boards.h @@ -590,6 +590,25 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) #define PIN_TO_SERVO(p) ((p) - 2) +// Sanguino/Melzi, e.g. Creality Ender-3 +#elif defined(__AVR_ATmega1284P__) +#define TOTAL_ANALOG_PINS 8 +#define TOTAL_PINS 32 +#define VERSION_BLINK_PIN 13 +#define PIN_SERIAL1_RX 8 //PD0 +#define PIN_SERIAL1_TX 9 //PD1 +#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) +#define IS_PIN_ANALOG(p) ((p) >= 24 && (p) < TOTAL_PINS) +#define IS_PIN_PWM(p) ((p) == 3 || (p) == 4 || (p) == 6 || (p) == 7 || (p) == 12 || (p) == 13 || (p) == 14 || (p) == 15) +#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) +#define IS_PIN_I2C(p) ((p) == 16 || (p) == 17) +#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) +#define IS_PIN_SERIAL(p) ((p) == 8 || (p) == 9) +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) (p) - 24 +#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) +#define PIN_TO_SERVO(p) (p) + // Illuminato #elif defined(__AVR_ATmega645__) From 521bdc93d6fe53cf68cf01e428f23147c7ee7d0b Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Tue, 30 Oct 2018 10:22:06 +0100 Subject: [PATCH 35/81] Add support for UNO WiFi Rev2 (ATMega4809) --- Boards.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Boards.h b/Boards.h index ace8d975..3df81370 100644 --- a/Boards.h +++ b/Boards.h @@ -219,6 +219,24 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) #define PIN_TO_SERVO(p) ((p) - 2) +// Arduino UNO WiFi rev2 (ATMega 4809) +#elif defined(__AVR_ATmega4809__) +#define TOTAL_ANALOG_PINS 6 +#define TOTAL_PINS 20 // 14 digital + 6 analog + /* 3 SPI (unexported, on ISP header) */ +#define VERSION_BLINK_PIN 25 +#define PIN_SERIAL1_RX 0 +#define PIN_SERIAL1_TX 1 +#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) +#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < TOTAL_PINS) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_SERVO(p) (p) +#define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL) +#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) +#define IS_PIN_SERIAL(p) ((p) == 0 || (p) == 1) +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) (p) - 14 +#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) +#define PIN_TO_SERVO(p) (p) // Arduino DUE #elif defined(__SAM3X8E__) From f9c978d279ca01283121c6bf6b9b1db257fd6b23 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 8 Nov 2018 21:00:54 +0700 Subject: [PATCH 36/81] update TOTAL_PINS for nrf52840 (64 pins max) --- Boards.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Boards.h b/Boards.h index 4af8b405..d790205b 100644 --- a/Boards.h +++ b/Boards.h @@ -873,7 +873,7 @@ writePort(port, value, bitmask): Write an 8 bit port. // Adafruit Bluefruit nRF52 boards #elif defined(ARDUINO_NRF52_ADAFRUIT) #define TOTAL_ANALOG_PINS NUM_ANALOG_INPUTS -#define TOTAL_PINS 32 +#define TOTAL_PINS NUM_DIGITAL_PINS #define VERSION_BLINK_PIN LED_BUILTIN #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS) #define IS_PIN_ANALOG(p) ((p) == PIN_A0 || (p) == PIN_A1 || (p) == PIN_A2 || (p) == PIN_A3 || \ From b28dd5dcd494d37dd705f827f04a49beed37ae10 Mon Sep 17 00:00:00 2001 From: gdsports Date: Thu, 4 Apr 2019 02:53:42 -0700 Subject: [PATCH 37/81] Add support for Arduino MKR WiFi 1010 The board uses the U-Blox WiFi NINA chip which has an ESP32 inside running NINA firmware. The SAMD21 is connected to the U-Blox chip via SPI. The WiFININA library is used to communicate between the U-Blox chip and the SAMD21. Other boards use the same U-Blox chip such as the MKR Vidor 4000 and the Uno WiFi Rev2. Additional changes will be required to support those boards. --- Boards.h | 4 +-- .../StandardFirmataWiFi.ino | 3 ++ examples/StandardFirmataWiFi/wifiConfig.h | 35 +++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/Boards.h b/Boards.h index d790205b..730826f6 100644 --- a/Boards.h +++ b/Boards.h @@ -261,8 +261,8 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_SERVO(p) ((p) - 2) -// Arduino/Genuino MKR1000 -#elif defined(ARDUINO_SAMD_MKR1000) +// Arduino/Genuino MKR1000 or MKR1010 +#elif defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRWIFI1010) #define TOTAL_ANALOG_PINS 7 #define TOTAL_PINS 22 // 8 digital + 3 spi + 2 i2c + 2 uart + 7 analog #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) <= 21) diff --git a/examples/StandardFirmataWiFi/StandardFirmataWiFi.ino b/examples/StandardFirmataWiFi/StandardFirmataWiFi.ino index 4f7e4163..032357d5 100644 --- a/examples/StandardFirmataWiFi/StandardFirmataWiFi.ino +++ b/examples/StandardFirmataWiFi/StandardFirmataWiFi.ino @@ -37,6 +37,7 @@ - Arduino WiFi Shield (or clone) - Arduino WiFi Shield 101 - Arduino MKR1000 board + - Arduino MKRWIFI1010 board - ESP8266 WiFi board compatible with ESP8266 Arduino core Follow the instructions in the wifiConfig.h file (wifiConfig.h tab in Arduino IDE) to @@ -929,6 +930,8 @@ void initTransport() DEBUG_PRINTLN( "using the ESP8266 WiFi library." ); #elif defined(HUZZAH_WIFI) DEBUG_PRINTLN( "using the HUZZAH WiFi library." ); +#elif defined(WIFI_NINA) + DEBUG_PRINTLN( "using the WiFi NINA library." ); //else should never happen here as error-checking in wifiConfig.h will catch this #endif //defined(WIFI_101) diff --git a/examples/StandardFirmataWiFi/wifiConfig.h b/examples/StandardFirmataWiFi/wifiConfig.h index bedc7447..6cdebc84 100644 --- a/examples/StandardFirmataWiFi/wifiConfig.h +++ b/examples/StandardFirmataWiFi/wifiConfig.h @@ -102,6 +102,41 @@ * For HUZZAH with ESP8266 use ESP8266_WIFI. */ +/* + * OPTION E: Configure for Arduino MKR WiFi 1010 and maybe other WiFiNINA boards. + * + * This will configure StandardFirmataWiFi to use the WiFiNINA library, which works with the + * boards that have the U-Blox NINA chip built in (such as the MKR1010). + * It is compatible with 802.11 2.4GHz B/G/N networks. + * + * If you are using the MKR1010 board, continue on to STEP 2. If you are using WiFiNINA add-on + * boards, follow the instructions below. + * + * To enable for WiFiNINA add-on boards, uncomment the #define WIFI_NINA below. + * TBD: Adafruit AirLyft boards are based on the WiFiNINA firmware so may work here. + * + * IMPORTANT: You must have the WiFI NINA library installed. To easily install this library, open + * the library manager via: Arduino IDE Menus: Sketch > Include Library > Manage Libraries > filter + * search for "WiFiNINA" > Select the result and click 'install' + */ +//#define WIFI_NINA + +//do not modify the following 15 lines +#if defined(ARDUINO_SAMD_MKRWIFI1010) && !defined(WIFI_NINA) +// automatically include if compiling for MRKWIFI1010 +#define WIFI_NINA +#endif +#ifdef WIFI_NINA +#include +#include "utility/WiFiClientStream.h" +#include "utility/WiFiServerStream.h" + #ifdef WIFI_LIB_INCLUDED + #define MULTIPLE_WIFI_LIB_INCLUDES + #else + #define WIFI_LIB_INCLUDED + #endif +#endif + //------------------------------ // TODO //------------------------------ From f22fe5403b59272ba528aaa8d06af643ec33a05a Mon Sep 17 00:00:00 2001 From: Christopher Stawarz Date: Wed, 24 Apr 2019 15:59:10 -0400 Subject: [PATCH 38/81] Adjusted Bluefruit LE connection intervals for better compatibility with Apple devices --- examples/StandardFirmataBLE/bleConfig.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/StandardFirmataBLE/bleConfig.h b/examples/StandardFirmataBLE/bleConfig.h index 412bb849..39b0b24d 100644 --- a/examples/StandardFirmataBLE/bleConfig.h +++ b/examples/StandardFirmataBLE/bleConfig.h @@ -67,16 +67,16 @@ * with the nRF51822 via SPI (e.g. Bluefruit LE SPI Friend, Bluefruit LE Shield), although * you may need to change the values of BLE_SPI_CS, BLE_SPI_IRQ, and/or BLE_SPI_RST below. * - * You will need to install a lightly-modified version of the Adafruit BluefruitLE nRF51 - * package, available at: - * https://github.com/cstawarz/Adafruit_BluefruitLE_nRF51/archive/firmata_fixes.zip + * You will need to install the latest version of the Adafruit BluefruitLE nRF51 package, + * available at: + * https://github.com/adafruit/Adafruit_BluefruitLE_nRF51/archive/master.zip */ //#define BLUEFRUIT_LE_SPI #ifdef BLUEFRUIT_LE_SPI // Both values must be between 10ms and 4s -#define FIRMATA_BLE_MIN_INTERVAL 10 // 10ms -#define FIRMATA_BLE_MAX_INTERVAL 20 // 20ms +#define FIRMATA_BLE_MIN_INTERVAL 15 // 15ms +#define FIRMATA_BLE_MAX_INTERVAL 30 // 30ms #define BLE_SPI_CS 8 #define BLE_SPI_IRQ 7 From ad2fd4ff97bd7170177072f1265b3272878db448 Mon Sep 17 00:00:00 2001 From: Timothy Claassens Date: Sat, 27 Apr 2019 21:12:49 +1200 Subject: [PATCH 39/81] Added a condition that adds the SoftwareSerial library for the ESP8266. --- utility/SerialFirmata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utility/SerialFirmata.h b/utility/SerialFirmata.h index 2319951b..365fde48 100644 --- a/utility/SerialFirmata.h +++ b/utility/SerialFirmata.h @@ -26,7 +26,7 @@ // SoftwareSerial is currently only supported for AVR-based boards and the Arduino 101. // Limited to Arduino 1.6.6 or higher because Arduino builder cannot find SoftwareSerial // prior to this release. -#if (ARDUINO > 10605) && (defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_ARC32)) +#if (ARDUINO > 10605) && (defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_ARC32) || defined(ESP8266)) #include #endif From 5f211573eda74786220c790066b3ac58edaf7965 Mon Sep 17 00:00:00 2001 From: Christopher Stawarz Date: Fri, 3 May 2019 16:01:41 -0400 Subject: [PATCH 40/81] Set Bluefruit LE advertising interval --- .../StandardFirmataBLE/StandardFirmataBLE.ino | 4 +++ examples/StandardFirmataBLE/bleConfig.h | 3 +++ utility/BluefruitLE_SPI_Stream.h | 26 +++++++++++++------ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/examples/StandardFirmataBLE/StandardFirmataBLE.ino b/examples/StandardFirmataBLE/StandardFirmataBLE.ino index 7b17b891..ebbe2efc 100755 --- a/examples/StandardFirmataBLE/StandardFirmataBLE.ino +++ b/examples/StandardFirmataBLE/StandardFirmataBLE.ino @@ -770,6 +770,10 @@ void setup() stream.setLocalName(FIRMATA_BLE_LOCAL_NAME); +#ifdef FIRMATA_BLE_ADVERTISING_INTERVAL + // set the BLE advertising interval + stream.setAdvertisingInterval(FIRMATA_BLE_ADVERTISING_INTERVAL); +#endif // set the BLE connection interval - this is the fastest interval you can read inputs stream.setConnectionInterval(FIRMATA_BLE_MIN_INTERVAL, FIRMATA_BLE_MAX_INTERVAL); // set how often the BLE TX buffer is flushed (if not full) diff --git a/examples/StandardFirmataBLE/bleConfig.h b/examples/StandardFirmataBLE/bleConfig.h index 39b0b24d..a783ce9b 100644 --- a/examples/StandardFirmataBLE/bleConfig.h +++ b/examples/StandardFirmataBLE/bleConfig.h @@ -74,6 +74,9 @@ //#define BLUEFRUIT_LE_SPI #ifdef BLUEFRUIT_LE_SPI +// Value must be between 20ms and 10.24s +#define FIRMATA_BLE_ADVERTISING_INTERVAL 20 // 20ms + // Both values must be between 10ms and 4s #define FIRMATA_BLE_MIN_INTERVAL 15 // 15ms #define FIRMATA_BLE_MAX_INTERVAL 30 // 30ms diff --git a/utility/BluefruitLE_SPI_Stream.h b/utility/BluefruitLE_SPI_Stream.h index 372e5aa9..42e982b2 100644 --- a/utility/BluefruitLE_SPI_Stream.h +++ b/utility/BluefruitLE_SPI_Stream.h @@ -17,6 +17,7 @@ class BluefruitLE_SPI_Stream : public Stream BluefruitLE_SPI_Stream(int8_t csPin, int8_t irqPin, int8_t rstPin); void setLocalName(const char *localName); + void setAdvertisingInterval(unsigned short advertisingInterval); void setConnectionInterval(unsigned short minConnInterval, unsigned short maxConnInterval); void setFlushInterval(int flushInterval); @@ -38,6 +39,7 @@ class BluefruitLE_SPI_Stream : public Stream Adafruit_BluefruitLE_SPI ble; String localName; + unsigned short advertisingInterval; unsigned short minConnInterval; unsigned short maxConnInterval; @@ -48,6 +50,7 @@ class BluefruitLE_SPI_Stream : public Stream BluefruitLE_SPI_Stream::BluefruitLE_SPI_Stream(int8_t csPin, int8_t irqPin, int8_t rstPin) : ble(csPin, irqPin, rstPin), + advertisingInterval(0), minConnInterval(0), maxConnInterval(0), txCount(0) @@ -58,6 +61,11 @@ void BluefruitLE_SPI_Stream::setLocalName(const char *localName) this->localName = localName; } +void BluefruitLE_SPI_Stream::setAdvertisingInterval(unsigned short advertisingInterval) +{ + this->advertisingInterval = advertisingInterval; +} + void BluefruitLE_SPI_Stream::setConnectionInterval(unsigned short minConnInterval, unsigned short maxConnInterval) { this->minConnInterval = minConnInterval; @@ -89,14 +97,16 @@ void BluefruitLE_SPI_Stream::begin() ble.println(localName); } - // Set connection interval - if (minConnInterval > 0 && maxConnInterval > 0) { - ble.print("AT+GAPINTERVALS="); - ble.print(minConnInterval); - ble.print(","); - ble.print(maxConnInterval); - ble.println(",,,"); - } + // Set connection and advertising intervals + ble.print("AT+GAPINTERVALS="); + if (minConnInterval > 0) ble.print(minConnInterval); + ble.print(","); + if (maxConnInterval > 0) ble.print(maxConnInterval); + ble.print(","); + if (advertisingInterval > 0) ble.print(advertisingInterval); + ble.print(",,"); // Always omit fast advertising timeout, hence two commas + if (advertisingInterval > 0) ble.print(advertisingInterval); + ble.println(); // Disable real and simulated mode switch (i.e. "+++") command ble.println("AT+MODESWITCHEN=local,0"); From 3f417c124e525aae1b5222b524e952a994671243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Jorge?= Date: Wed, 9 Oct 2019 22:24:30 -0500 Subject: [PATCH 41/81] Set up API docs using Doxygen --- docs/.nojekyll | 0 docs/Doxyfile | 2539 +++++++++++++++++ docs/html/_boards_8h_source.html | 1067 +++++++ docs/html/_firmata_8h_source.html | 284 ++ docs/html/_firmata_constants_8h_source.html | 174 ++ docs/html/_firmata_defines_8h_source.html | 360 +++ docs/html/_firmata_marshaller_8h_source.html | 176 ++ docs/html/_firmata_parser_8h_source.html | 189 ++ docs/html/annotated.html | 85 + docs/html/bc_s.png | Bin 0 -> 676 bytes docs/html/bdwn.png | Bin 0 -> 147 bytes docs/html/classes.html | 90 + ...lassfirmata_1_1_firmata_class-members.html | 121 + docs/html/classfirmata_1_1_firmata_class.html | 972 +++++++ ...irmata_1_1_firmata_marshaller-members.html | 107 + .../classfirmata_1_1_firmata_marshaller.html | 738 +++++ ...assfirmata_1_1_firmata_parser-members.html | 102 + .../html/classfirmata_1_1_firmata_parser.html | 552 ++++ docs/html/closed.png | Bin 0 -> 132 bytes docs/html/doc.png | Bin 0 -> 746 bytes docs/html/doxygen.css | 1766 ++++++++++++ docs/html/doxygen.png | Bin 0 -> 3779 bytes docs/html/dynsections.js | 120 + docs/html/files.html | 87 + docs/html/folderclosed.png | Bin 0 -> 616 bytes docs/html/folderopen.png | Bin 0 -> 597 bytes docs/html/functions.html | 262 ++ docs/html/functions_func.html | 262 ++ docs/html/index.html | 275 ++ docs/html/jquery.js | 35 + docs/html/md_readme.html | 275 ++ docs/html/menu.js | 50 + docs/html/menudata.js | 56 + docs/html/nav_f.png | Bin 0 -> 153 bytes docs/html/nav_g.png | Bin 0 -> 95 bytes docs/html/nav_h.png | Bin 0 -> 98 bytes docs/html/open.png | Bin 0 -> 123 bytes docs/html/pages.html | 82 + docs/html/search/all_0.html | 30 + docs/html/search/all_0.js | 5 + docs/html/search/all_1.html | 30 + docs/html/search/all_1.js | 5 + docs/html/search/all_2.html | 30 + docs/html/search/all_2.js | 5 + docs/html/search/all_3.html | 30 + docs/html/search/all_3.js | 5 + docs/html/search/all_4.html | 30 + docs/html/search/all_4.js | 7 + docs/html/search/all_5.html | 30 + docs/html/search/all_5.js | 5 + docs/html/search/all_6.html | 30 + docs/html/search/all_6.js | 4 + docs/html/search/all_7.html | 30 + docs/html/search/all_7.js | 7 + docs/html/search/all_8.html | 30 + docs/html/search/all_8.js | 5 + docs/html/search/all_9.html | 30 + docs/html/search/all_9.js | 7 + docs/html/search/all_a.html | 30 + docs/html/search/all_a.js | 22 + docs/html/search/all_b.html | 30 + docs/html/search/all_b.js | 4 + docs/html/search/classes_0.html | 30 + docs/html/search/classes_0.js | 6 + docs/html/search/close.png | Bin 0 -> 273 bytes docs/html/search/functions_0.html | 30 + docs/html/search/functions_0.js | 5 + docs/html/search/functions_1.html | 30 + docs/html/search/functions_1.js | 5 + docs/html/search/functions_2.html | 30 + docs/html/search/functions_2.js | 5 + docs/html/search/functions_3.html | 30 + docs/html/search/functions_3.js | 5 + docs/html/search/functions_4.html | 30 + docs/html/search/functions_4.js | 6 + docs/html/search/functions_5.html | 30 + docs/html/search/functions_5.js | 5 + docs/html/search/functions_6.html | 30 + docs/html/search/functions_6.js | 4 + docs/html/search/functions_7.html | 30 + docs/html/search/functions_7.js | 7 + docs/html/search/functions_8.html | 30 + docs/html/search/functions_8.js | 5 + docs/html/search/functions_9.html | 30 + docs/html/search/functions_9.js | 7 + docs/html/search/functions_a.html | 30 + docs/html/search/functions_a.js | 22 + docs/html/search/functions_b.html | 30 + docs/html/search/functions_b.js | 4 + docs/html/search/mag_sel.png | Bin 0 -> 465 bytes docs/html/search/nomatches.html | 12 + docs/html/search/pages_0.html | 30 + docs/html/search/pages_0.js | 4 + docs/html/search/search.css | 271 ++ docs/html/search/search.js | 814 ++++++ docs/html/search/search_l.png | Bin 0 -> 567 bytes docs/html/search/search_m.png | Bin 0 -> 158 bytes docs/html/search/search_r.png | Bin 0 -> 553 bytes docs/html/search/searchdata.js | 24 + docs/html/splitbar.png | Bin 0 -> 314 bytes docs/html/sync_off.png | Bin 0 -> 853 bytes docs/html/sync_on.png | Bin 0 -> 845 bytes docs/html/tab_a.png | Bin 0 -> 142 bytes docs/html/tab_b.png | Bin 0 -> 169 bytes docs/html/tab_h.png | Bin 0 -> 177 bytes docs/html/tab_s.png | Bin 0 -> 184 bytes docs/html/tabs.css | 1 + docs/index.html | 2 + 108 files changed, 12901 insertions(+) create mode 100644 docs/.nojekyll create mode 100644 docs/Doxyfile create mode 100644 docs/html/_boards_8h_source.html create mode 100644 docs/html/_firmata_8h_source.html create mode 100644 docs/html/_firmata_constants_8h_source.html create mode 100644 docs/html/_firmata_defines_8h_source.html create mode 100644 docs/html/_firmata_marshaller_8h_source.html create mode 100644 docs/html/_firmata_parser_8h_source.html create mode 100644 docs/html/annotated.html create mode 100644 docs/html/bc_s.png create mode 100644 docs/html/bdwn.png create mode 100644 docs/html/classes.html create mode 100644 docs/html/classfirmata_1_1_firmata_class-members.html create mode 100644 docs/html/classfirmata_1_1_firmata_class.html create mode 100644 docs/html/classfirmata_1_1_firmata_marshaller-members.html create mode 100644 docs/html/classfirmata_1_1_firmata_marshaller.html create mode 100644 docs/html/classfirmata_1_1_firmata_parser-members.html create mode 100644 docs/html/classfirmata_1_1_firmata_parser.html create mode 100644 docs/html/closed.png create mode 100644 docs/html/doc.png create mode 100644 docs/html/doxygen.css create mode 100644 docs/html/doxygen.png create mode 100644 docs/html/dynsections.js create mode 100644 docs/html/files.html create mode 100644 docs/html/folderclosed.png create mode 100644 docs/html/folderopen.png create mode 100644 docs/html/functions.html create mode 100644 docs/html/functions_func.html create mode 100644 docs/html/index.html create mode 100644 docs/html/jquery.js create mode 100644 docs/html/md_readme.html create mode 100644 docs/html/menu.js create mode 100644 docs/html/menudata.js create mode 100644 docs/html/nav_f.png create mode 100644 docs/html/nav_g.png create mode 100644 docs/html/nav_h.png create mode 100644 docs/html/open.png create mode 100644 docs/html/pages.html create mode 100644 docs/html/search/all_0.html create mode 100644 docs/html/search/all_0.js create mode 100644 docs/html/search/all_1.html create mode 100644 docs/html/search/all_1.js create mode 100644 docs/html/search/all_2.html create mode 100644 docs/html/search/all_2.js create mode 100644 docs/html/search/all_3.html create mode 100644 docs/html/search/all_3.js create mode 100644 docs/html/search/all_4.html create mode 100644 docs/html/search/all_4.js create mode 100644 docs/html/search/all_5.html create mode 100644 docs/html/search/all_5.js create mode 100644 docs/html/search/all_6.html create mode 100644 docs/html/search/all_6.js create mode 100644 docs/html/search/all_7.html create mode 100644 docs/html/search/all_7.js create mode 100644 docs/html/search/all_8.html create mode 100644 docs/html/search/all_8.js create mode 100644 docs/html/search/all_9.html create mode 100644 docs/html/search/all_9.js create mode 100644 docs/html/search/all_a.html create mode 100644 docs/html/search/all_a.js create mode 100644 docs/html/search/all_b.html create mode 100644 docs/html/search/all_b.js create mode 100644 docs/html/search/classes_0.html create mode 100644 docs/html/search/classes_0.js create mode 100644 docs/html/search/close.png create mode 100644 docs/html/search/functions_0.html create mode 100644 docs/html/search/functions_0.js create mode 100644 docs/html/search/functions_1.html create mode 100644 docs/html/search/functions_1.js create mode 100644 docs/html/search/functions_2.html create mode 100644 docs/html/search/functions_2.js create mode 100644 docs/html/search/functions_3.html create mode 100644 docs/html/search/functions_3.js create mode 100644 docs/html/search/functions_4.html create mode 100644 docs/html/search/functions_4.js create mode 100644 docs/html/search/functions_5.html create mode 100644 docs/html/search/functions_5.js create mode 100644 docs/html/search/functions_6.html create mode 100644 docs/html/search/functions_6.js create mode 100644 docs/html/search/functions_7.html create mode 100644 docs/html/search/functions_7.js create mode 100644 docs/html/search/functions_8.html create mode 100644 docs/html/search/functions_8.js create mode 100644 docs/html/search/functions_9.html create mode 100644 docs/html/search/functions_9.js create mode 100644 docs/html/search/functions_a.html create mode 100644 docs/html/search/functions_a.js create mode 100644 docs/html/search/functions_b.html create mode 100644 docs/html/search/functions_b.js create mode 100644 docs/html/search/mag_sel.png create mode 100644 docs/html/search/nomatches.html create mode 100644 docs/html/search/pages_0.html create mode 100644 docs/html/search/pages_0.js create mode 100644 docs/html/search/search.css create mode 100644 docs/html/search/search.js create mode 100644 docs/html/search/search_l.png create mode 100644 docs/html/search/search_m.png create mode 100644 docs/html/search/search_r.png create mode 100644 docs/html/search/searchdata.js create mode 100644 docs/html/splitbar.png create mode 100644 docs/html/sync_off.png create mode 100644 docs/html/sync_on.png create mode 100644 docs/html/tab_a.png create mode 100644 docs/html/tab_b.png create mode 100644 docs/html/tab_h.png create mode 100644 docs/html/tab_s.png create mode 100644 docs/html/tabs.css create mode 100644 docs/index.html diff --git a/docs/.nojekyll b/docs/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/docs/Doxyfile b/docs/Doxyfile new file mode 100644 index 00000000..a420115e --- /dev/null +++ b/docs/Doxyfile @@ -0,0 +1,2539 @@ +# Doxyfile 1.8.16 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "Firmata firmware for Arduino" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "Firmata is a protocol for communicating with microcontrollers from software on a host computer" + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = . + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all generated output in the proper direction. +# Possible values are: None, LTR, RTL and Context. +# The default value is: None. + +OUTPUT_TEXT_DIRECTION = None + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = ../ + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines (in the resulting output). You can put ^^ in the value part of an +# alias to insert a newline as if a physical newline was in the original file. +# When you need a literal { or } or , in the value part of an alias you have to +# escape them by means of a backslash (\), this can lead to conflicts with the +# commands \{ and \} for these it is advised to use the version @{ and @} or use +# a double escape (\\{ and \\}) + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, +# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat +# .inc files as Fortran files (default is PHP), and .f files as C (default is +# Fortran), use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See https://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 5. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 5 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO, these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# (including Cygwin) ands Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. If +# EXTRACT_ALL is set to YES then this flag will automatically be disabled. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = ../ \ + ../readme.md + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: https://www.gnu.org/software/libiconv/) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice. + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.pyw \ + *.f90 \ + *.f95 \ + *.f03 \ + *.f08 \ + *.f \ + *.for \ + *.tcl \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf \ + *.ice + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = readme.md + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# entity all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via Javascript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have Javascript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: https://developer.apple.com/xcode/), introduced with OSX +# 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANSPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. +# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/ + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /
+
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-2017 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 15th, 2018
+
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 // Arduino UNO WiFi rev2 (ATMega 4809)
+
223 #elif defined(__AVR_ATmega4809__)
+
224 #define TOTAL_ANALOG_PINS 6
+
225 #define TOTAL_PINS 20 // 14 digital + 6 analog + /* 3 SPI (unexported, on ISP header) */
+
226 #define VERSION_BLINK_PIN 25
+
227 #define PIN_SERIAL1_RX 0
+
228 #define PIN_SERIAL1_TX 1
+
229 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
+
230 #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < TOTAL_PINS)
+
231 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
+
232 #define IS_PIN_SERVO(p) (p)
+
233 #define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL)
+
234 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
235 #define IS_PIN_SERIAL(p) ((p) == 0 || (p) == 1)
+
236 #define PIN_TO_DIGITAL(p) (p)
+
237 #define PIN_TO_ANALOG(p) (p) - 14
+
238 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
+
239 #define PIN_TO_SERVO(p) (p)
+
240 
+
241 // Arduino DUE
+
242 #elif defined(__SAM3X8E__)
+
243 #define TOTAL_ANALOG_PINS 12
+
244 #define TOTAL_PINS 66 // 54 digital + 12 analog
+
245 #define VERSION_BLINK_PIN 13
+
246 #define PIN_SERIAL1_RX 19
+
247 #define PIN_SERIAL1_TX 18
+
248 #define PIN_SERIAL2_RX 17
+
249 #define PIN_SERIAL2_TX 16
+
250 #define PIN_SERIAL3_RX 15
+
251 #define PIN_SERIAL3_TX 14
+
252 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
+
253 #define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS)
+
254 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
+
255 #define IS_PIN_SERVO(p) ((p) >= 2 && (p) - 2 < MAX_SERVOS)
+
256 #define IS_PIN_I2C(p) ((p) == 20 || (p) == 21) // 70 71
+
257 #define IS_PIN_SERIAL(p) ((p) > 13 && (p) < 20)
+
258 #define PIN_TO_DIGITAL(p) (p)
+
259 #define PIN_TO_ANALOG(p) ((p) - 54)
+
260 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
+
261 #define PIN_TO_SERVO(p) ((p) - 2)
+
262 
+
263 
+
264 // Arduino/Genuino MKR1000 or MKR1010
+
265 #elif defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRWIFI1010)
+
266 #define TOTAL_ANALOG_PINS 7
+
267 #define TOTAL_PINS 22 // 8 digital + 3 spi + 2 i2c + 2 uart + 7 analog
+
268 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) <= 21)
+
269 #define IS_PIN_ANALOG(p) ((p) >= 15 && (p) < 15 + TOTAL_ANALOG_PINS)
+
270 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
+
271 #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4
+
272 #define IS_PIN_I2C(p) ((p) == 11 || (p) == 12) // SDA = 11, SCL = 12
+
273 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
274 #define IS_PIN_SERIAL(p) ((p) == PIN_SERIAL1_RX || (p) == PIN_SERIAL1_TX) //defined in variant.h RX = 13, TX = 14
+
275 #define PIN_TO_DIGITAL(p) (p)
+
276 #define PIN_TO_ANALOG(p) ((p) - 15)
+
277 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
+
278 #define PIN_TO_SERVO(p) (p) // deprecated since v2.4
+
279 
+
280 
+
281 // Arduino MKRZero
+
282 #elif defined(ARDUINO_SAMD_MKRZERO)
+
283 #define TOTAL_ANALOG_PINS 7
+
284 #define TOTAL_PINS 34 // 8 digital + 3 spi + 2 i2c + 2 uart + 7 analog + 3 usb + 1 aref + 5 sd + 1 bottom pad + 1 led + 1 battery adc
+
285 #define IS_PIN_DIGITAL(p) (((p) >= 0 && (p) <= 21) || (p) == 32)
+
286 #define IS_PIN_ANALOG(p) (((p) >= 15 && (p) < 15 + TOTAL_ANALOG_PINS) || (p) == 33)
+
287 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
+
288 #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4
+
289 #define IS_PIN_I2C(p) ((p) == 11 || (p) == 12) // SDA = 11, SCL = 12
+
290 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
291 #define IS_PIN_SERIAL(p) ((p) == PIN_SERIAL1_RX || (p) == PIN_SERIAL1_TX) //defined in variant.h RX = 13, TX = 14
+
292 #define PIN_TO_DIGITAL(p) (p)
+
293 #define PIN_TO_ANALOG(p) ((p) - 15)
+
294 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
+
295 #define PIN_TO_SERVO(p) (p) // deprecated since v2.4
+
296 
+
297 // Arduino MKRFox1200
+
298 #elif defined(ARDUINO_SAMD_MKRFox1200)
+
299 #define TOTAL_ANALOG_PINS 7
+
300 #define TOTAL_PINS 33 // 8 digital + 3 spi + 2 i2c + 2 uart + 7 analog + 3 usb + 1 aref + 5 sd + 1 bottom pad + 1 battery adc
+
301 #define IS_PIN_DIGITAL(p) (((p) >= 0 && (p) <= 21))
+
302 #define IS_PIN_ANALOG(p) (((p) >= 15 && (p) < 15 + TOTAL_ANALOG_PINS) || (p) == 32)
+
303 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
+
304 #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4
+
305 #define IS_PIN_I2C(p) ((p) == 11 || (p) == 12) // SDA = 11, SCL = 12
+
306 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
307 #define IS_PIN_SERIAL(p) ((p) == PIN_SERIAL1_RX || (p) == PIN_SERIAL1_TX) //defined in variant.h RX = 13, TX = 14
+
308 #define PIN_TO_DIGITAL(p) (p)
+
309 #define PIN_TO_ANALOG(p) ((p) - 15)
+
310 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
+
311 #define PIN_TO_SERVO(p) (p) // deprecated since v2.4
+
312 
+
313 // Arduino MKR WAN 1300
+
314 #elif defined(ARDUINO_SAMD_MKRWAN1300)
+
315 #define TOTAL_ANALOG_PINS 7
+
316 #define TOTAL_PINS 33
+
317 #define IS_PIN_DIGITAL(p) (((p) >= 0 && (p) <= 21))
+
318 #define IS_PIN_ANALOG(p) (((p) >= 15 && (p) < 15 + TOTAL_ANALOG_PINS) || (p) == 32)
+
319 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
+
320 #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4
+
321 #define IS_PIN_I2C(p) ((p) == 11 || (p) == 12) // SDA = 11, SCL = 12
+
322 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
323 #define IS_PIN_SERIAL(p) ((p) == PIN_SERIAL1_RX || (p) == PIN_SERIAL1_TX) //defined in variant.h RX = 13, TX = 14
+
324 #define PIN_TO_DIGITAL(p) (p)
+
325 #define PIN_TO_ANALOG(p) ((p) - 15)
+
326 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
+
327 #define PIN_TO_SERVO(p) (p) // deprecated since v2.4
+
328 
+
329 // Arduino MKR GSM 1400
+
330 #elif defined(ARDUINO_SAMD_MKRGSM1400)
+
331 #define TOTAL_ANALOG_PINS 7
+
332 #define TOTAL_PINS 33
+
333 #define IS_PIN_DIGITAL(p) (((p) >= 0 && (p) <= 21))
+
334 #define IS_PIN_ANALOG(p) (((p) >= 15 && (p) < 15 + TOTAL_ANALOG_PINS) || (p) == 32)
+
335 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
+
336 #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4
+
337 #define IS_PIN_I2C(p) ((p) == 11 || (p) == 12) // SDA = 11, SCL = 12
+
338 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
339 #define IS_PIN_SERIAL(p) ((p) == PIN_SERIAL1_RX || (p) == PIN_SERIAL1_TX) //defined in variant.h RX = 13, TX = 14
+
340 #define PIN_TO_DIGITAL(p) (p)
+
341 #define PIN_TO_ANALOG(p) ((p) - 15)
+
342 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
+
343 #define PIN_TO_SERVO(p) (p) // deprecated since v2.4
+
344 
+
345 // Arduino Zero
+
346 // Note this will work with an Arduino Zero Pro, but not with an Arduino M0 Pro
+
347 // Arduino M0 Pro does not properly map pins to the board labeled pin numbers
+
348 #elif defined(_VARIANT_ARDUINO_ZERO_)
+
349 #define TOTAL_ANALOG_PINS 6
+
350 #define TOTAL_PINS 25 // 14 digital + 6 analog + 2 i2c + 3 spi
+
351 #define TOTAL_PORTS 3 // set when TOTAL_PINS > num digitial I/O pins
+
352 #define VERSION_BLINK_PIN LED_BUILTIN
+
353 //#define PIN_SERIAL1_RX 0 // already defined in zero core variant.h
+
354 //#define PIN_SERIAL1_TX 1 // already defined in zero core variant.h
+
355 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) <= 19)
+
356 #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS)
+
357 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
+
358 #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4
+
359 #define IS_PIN_I2C(p) ((p) == 20 || (p) == 21) // SDA = 20, SCL = 21
+
360 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) // SS = A2
+
361 #define IS_PIN_SERIAL(p) ((p) == 0 || (p) == 1)
+
362 #define PIN_TO_DIGITAL(p) (p)
+
363 #define PIN_TO_ANALOG(p) ((p) - 14)
+
364 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
+
365 #define PIN_TO_SERVO(p) (p) // deprecated since v2.4
+
366 
+
367 // Arduino Primo
+
368 #elif defined(ARDUINO_PRIMO)
+
369 #define TOTAL_ANALOG_PINS 6
+
370 #define TOTAL_PINS 22 //14 digital + 6 analog + 2 i2c
+
371 #define VERSION_BLINK_PIN LED_BUILTIN
+
372 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < 20)
+
373 #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 20)
+
374 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
+
375 #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS+2)
+
376 #define IS_PIN_I2C(p) ((p) == PIN_WIRE_SDA || (p) == PIN_WIRE_SCL) // SDA = 20, SCL = 21
+
377 #define IS_PIN_SPI(p) ((p) == SS || (p)== MOSI || (p) == MISO || (p == SCK)) // 10, 11, 12, 13
+
378 #define PIN_TO_DIGITAL(p) (p)
+
379 #define PIN_TO_ANALOG(p) ((p) - 14)
+
380 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
+
381 #define PIN_TO_SERVO(p) (p)
+
382 
+
383 // Arduino 101
+
384 #elif defined(_VARIANT_ARDUINO_101_X_)
+
385 #define TOTAL_ANALOG_PINS NUM_ANALOG_INPUTS
+
386 #define TOTAL_PINS NUM_DIGITAL_PINS // 15 digital (including ATN pin) + 6 analog
+
387 #define VERSION_BLINK_PIN LED_BUILTIN
+
388 #define PIN_SERIAL1_RX 0
+
389 #define PIN_SERIAL1_TX 1
+
390 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) <= 20)
+
391 #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS)
+
392 #define IS_PIN_PWM(p) digitalPinHasPWM(p) // 3, 5, 6, 9
+
393 #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4
+
394 #define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL) // SDA = 18, SCL = 19
+
395 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
396 #define IS_PIN_SERIAL(p) ((p) == 0 || (p) == 1)
+
397 #define PIN_TO_DIGITAL(p) (p)
+
398 #define PIN_TO_ANALOG(p) ((p) - 14)
+
399 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
+
400 #define PIN_TO_SERVO(p) (p) // deprecated since v2.4
+
401 
+
402 
+
403 // Teensy 1.0
+
404 #elif defined(__AVR_AT90USB162__)
+
405 #define TOTAL_ANALOG_PINS 0
+
406 #define TOTAL_PINS 21 // 21 digital + no analog
+
407 #define VERSION_BLINK_PIN 6
+
408 #define PIN_SERIAL1_RX 2
+
409 #define PIN_SERIAL1_TX 3
+
410 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
+
411 #define IS_PIN_ANALOG(p) (0)
+
412 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
+
413 #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
+
414 #define IS_PIN_I2C(p) (0)
+
415 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
416 #define IS_PIN_SERIAL(p) ((p) == 2 || (p) == 3)
+
417 #define PIN_TO_DIGITAL(p) (p)
+
418 #define PIN_TO_ANALOG(p) (0)
+
419 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
+
420 #define PIN_TO_SERVO(p) (p)
+
421 
+
422 
+
423 // Teensy 2.0
+
424 #elif defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY)
+
425 #define TOTAL_ANALOG_PINS 12
+
426 #define TOTAL_PINS 25 // 11 digital + 12 analog
+
427 #define VERSION_BLINK_PIN 11
+
428 #define PIN_SERIAL1_RX 7
+
429 #define PIN_SERIAL1_TX 8
+
430 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
+
431 #define IS_PIN_ANALOG(p) ((p) >= 11 && (p) <= 22)
+
432 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
+
433 #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
+
434 #define IS_PIN_I2C(p) ((p) == 5 || (p) == 6)
+
435 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
436 #define IS_PIN_SERIAL(p) ((p) == 7 || (p) == 8)
+
437 #define PIN_TO_DIGITAL(p) (p)
+
438 #define PIN_TO_ANALOG(p) (((p) < 22) ? 21 - (p) : 11)
+
439 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
+
440 #define PIN_TO_SERVO(p) (p)
+
441 
+
442 
+
443 // Teensy 3.5 and 3.6
+
444 // reference: https://github.com/PaulStoffregen/cores/blob/master/teensy3/pins_arduino.h
+
445 #elif defined(__MK64FX512__) || defined(__MK66FX1M0__)
+
446 #define TOTAL_ANALOG_PINS 27 // 3.5 has 27 and 3.6 has 25
+
447 #define TOTAL_PINS 70 // 43 digital + 21 analog-digital + 6 analog (64-69)
+
448 #define VERSION_BLINK_PIN 13
+
449 #define PIN_SERIAL1_RX 0
+
450 #define PIN_SERIAL1_TX 1
+
451 #define PIN_SERIAL2_RX 9
+
452 #define PIN_SERIAL2_TX 10
+
453 #define PIN_SERIAL3_RX 7
+
454 #define PIN_SERIAL3_TX 8
+
455 #define PIN_SERIAL4_RX 31
+
456 #define PIN_SERIAL4_TX 32
+
457 #define PIN_SERIAL5_RX 34
+
458 #define PIN_SERIAL5_TX 33
+
459 #define PIN_SERIAL6_RX 47
+
460 #define PIN_SERIAL6_TX 48
+
461 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) <= 63)
+
462 #define IS_PIN_ANALOG(p) (((p) >= 14 && (p) <= 23) || ((p) >= 31 && (p) <= 39) || ((p) >= 49 && (p) <= 50) || ((p) >= 64 && (p) <= 69))
+
463 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
+
464 #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
+
465 #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19)
+
466 #define IS_PIN_SERIAL(p) (((p) > 6 && (p) < 11) || ((p) == 0 || (p) == 1) || ((p) > 30 && (p) < 35) || ((p) == 47 || (p) == 48))
+
467 #define PIN_TO_DIGITAL(p) (p)
+
468 // A0-A9 = D14-D23; A12-A20 = D31-D39; A23-A24 = D49-D50; A10-A11 = D64-D65; A21-A22 = D66-D67; A25-A26 = D68-D69
+
469 #define PIN_TO_ANALOG(p) (((p) <= 23) ? (p) - 14 : (((p) <= 39) ? (p) - 19 : (((p) <= 50) ? (p) - 26 : (((p) <= 65) ? (p) - 55 : (((p) <= 67) ? (p) - 45 : (p) - 43)))))
+
470 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
+
471 #define PIN_TO_SERVO(p) (p)
+
472 
+
473 
+
474 // Teensy 3.0, 3.1 and 3.2
+
475 #elif defined(__MK20DX128__) || defined(__MK20DX256__)
+
476 #define TOTAL_ANALOG_PINS 14
+
477 #define TOTAL_PINS 38 // 24 digital + 10 analog-digital + 4 analog
+
478 #define VERSION_BLINK_PIN 13
+
479 #define PIN_SERIAL1_RX 0
+
480 #define PIN_SERIAL1_TX 1
+
481 #define PIN_SERIAL2_RX 9
+
482 #define PIN_SERIAL2_TX 10
+
483 #define PIN_SERIAL3_RX 7
+
484 #define PIN_SERIAL3_TX 8
+
485 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) <= 33)
+
486 #define IS_PIN_ANALOG(p) (((p) >= 14 && (p) <= 23) || ((p) >= 34 && (p) <= 38))
+
487 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
+
488 #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
+
489 #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19)
+
490 #define IS_PIN_SERIAL(p) (((p) > 6 && (p) < 11) || ((p) == 0 || (p) == 1))
+
491 #define PIN_TO_DIGITAL(p) (p)
+
492 #define PIN_TO_ANALOG(p) (((p) <= 23) ? (p) - 14 : (p) - 24)
+
493 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
+
494 #define PIN_TO_SERVO(p) (p)
+
495 
+
496 
+
497 // Teensy-LC
+
498 #elif defined(__MKL26Z64__)
+
499 #define TOTAL_ANALOG_PINS 13
+
500 #define TOTAL_PINS 27 // 27 digital + 13 analog-digital
+
501 #define VERSION_BLINK_PIN 13
+
502 #define PIN_SERIAL1_RX 0
+
503 #define PIN_SERIAL1_TX 1
+
504 #define PIN_SERIAL2_RX 9
+
505 #define PIN_SERIAL2_TX 10
+
506 #define PIN_SERIAL3_RX 7
+
507 #define PIN_SERIAL3_TX 8
+
508 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) <= 26)
+
509 #define IS_PIN_ANALOG(p) ((p) >= 14)
+
510 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
+
511 #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
+
512 #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19)
+
513 #define IS_PIN_SERIAL(p) (((p) > 6 && (p) < 11) || ((p) == 0 || (p) == 1))
+
514 #define PIN_TO_DIGITAL(p) (p)
+
515 #define PIN_TO_ANALOG(p) ((p) - 14)
+
516 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
+
517 #define PIN_TO_SERVO(p) (p)
+
518 
+
519 
+
520 // Teensy++ 1.0 and 2.0
+
521 #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
+
522 #define TOTAL_ANALOG_PINS 8
+
523 #define TOTAL_PINS 46 // 38 digital + 8 analog
+
524 #define VERSION_BLINK_PIN 6
+
525 #define PIN_SERIAL1_RX 2
+
526 #define PIN_SERIAL1_TX 3
+
527 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
+
528 #define IS_PIN_ANALOG(p) ((p) >= 38 && (p) < TOTAL_PINS)
+
529 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
+
530 #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
+
531 #define IS_PIN_I2C(p) ((p) == 0 || (p) == 1)
+
532 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
533 #define IS_PIN_SERIAL(p) ((p) == 2 || (p) == 3)
+
534 #define PIN_TO_DIGITAL(p) (p)
+
535 #define PIN_TO_ANALOG(p) ((p) - 38)
+
536 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
+
537 #define PIN_TO_SERVO(p) (p)
+
538 
+
539 
+
540 // Leonardo
+
541 #elif defined(__AVR_ATmega32U4__)
+
542 #define TOTAL_ANALOG_PINS 12
+
543 #define TOTAL_PINS 30 // 14 digital + 12 analog + 4 SPI (D14-D17 on ISP header)
+
544 #define VERSION_BLINK_PIN 13
+
545 #define PIN_SERIAL1_RX 0
+
546 #define PIN_SERIAL1_TX 1
+
547 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
+
548 #define IS_PIN_ANALOG(p) ((p) >= 18 && (p) < TOTAL_PINS)
+
549 #define IS_PIN_PWM(p) ((p) == 3 || (p) == 5 || (p) == 6 || (p) == 9 || (p) == 10 || (p) == 11 || (p) == 13)
+
550 #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
+
551 #define IS_PIN_I2C(p) ((p) == 2 || (p) == 3)
+
552 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
553 #define IS_PIN_SERIAL(p) ((p) == 0 || (p) == 1)
+
554 #define PIN_TO_DIGITAL(p) (p)
+
555 #define PIN_TO_ANALOG(p) (p) - 18
+
556 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
+
557 #define PIN_TO_SERVO(p) (p)
+
558 
+
559 
+
560 // Intel Galileo Board (gen 1 and 2) and Intel Edison
+
561 #elif defined(ARDUINO_LINUX)
+
562 #define TOTAL_ANALOG_PINS 6
+
563 #define TOTAL_PINS 20 // 14 digital + 6 analog
+
564 #define VERSION_BLINK_PIN 13
+
565 #define PIN_SERIAL1_RX 0
+
566 #define PIN_SERIAL1_TX 1
+
567 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19)
+
568 #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 19)
+
569 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
+
570 #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS)
+
571 #define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL)
+
572 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
573 #define IS_PIN_SERIAL(p) ((p) == 0 || (p) == 1)
+
574 #define PIN_TO_DIGITAL(p) (p)
+
575 #define PIN_TO_ANALOG(p) ((p) - 14)
+
576 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
+
577 #define PIN_TO_SERVO(p) ((p) - 2)
+
578 
+
579 
+
580 // RedBearLab BLE Nano with factory switch settings (S1 - S10)
+
581 #elif defined(BLE_NANO)
+
582 #define TOTAL_ANALOG_PINS 6
+
583 #define TOTAL_PINS 15 // 9 digital + 3 analog
+
584 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 14)
+
585 #define IS_PIN_ANALOG(p) ((p) == 8 || (p) == 9 || (p) == 10 || (p) == 11 || (p) == 12 || (p) == 14) //A0~A5
+
586 #define IS_PIN_PWM(p) ((p) == 3 || (p) == 5 || (p) == 6)
+
587 #define IS_PIN_SERVO(p) ((p) >= 2 && (p) <= 7)
+
588 #define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL)
+
589 #define IS_PIN_SPI(p) ((p) == CS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
590 #define PIN_TO_DIGITAL(p) (p)
+
591 #define PIN_TO_ANALOG(p) ((p) - 8)
+
592 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
+
593 #define PIN_TO_SERVO(p) (p)
+
594 
+
595 
+
596 // Sanguino
+
597 #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
+
598 #define TOTAL_ANALOG_PINS 8
+
599 #define TOTAL_PINS 32 // 24 digital + 8 analog
+
600 #define VERSION_BLINK_PIN 0
+
601 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
+
602 #define IS_PIN_ANALOG(p) ((p) >= 24 && (p) < TOTAL_PINS)
+
603 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
+
604 #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
+
605 #define IS_PIN_I2C(p) ((p) == 16 || (p) == 17)
+
606 #define PIN_TO_DIGITAL(p) (p)
+
607 #define PIN_TO_ANALOG(p) ((p) - 24)
+
608 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
+
609 #define PIN_TO_SERVO(p) ((p) - 2)
+
610 
+
611 // Sanguino/Melzi, e.g. Creality Ender-3
+
612 #elif defined(__AVR_ATmega1284P__)
+
613 #define TOTAL_ANALOG_PINS 8
+
614 #define TOTAL_PINS 32
+
615 #define VERSION_BLINK_PIN 13
+
616 #define PIN_SERIAL1_RX 8 //PD0
+
617 #define PIN_SERIAL1_TX 9 //PD1
+
618 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
+
619 #define IS_PIN_ANALOG(p) ((p) >= 24 && (p) < TOTAL_PINS)
+
620 #define IS_PIN_PWM(p) ((p) == 3 || (p) == 4 || (p) == 6 || (p) == 7 || (p) == 12 || (p) == 13 || (p) == 14 || (p) == 15)
+
621 #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
+
622 #define IS_PIN_I2C(p) ((p) == 16 || (p) == 17)
+
623 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
624 #define IS_PIN_SERIAL(p) ((p) == 8 || (p) == 9)
+
625 #define PIN_TO_DIGITAL(p) (p)
+
626 #define PIN_TO_ANALOG(p) (p) - 24
+
627 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
+
628 #define PIN_TO_SERVO(p) (p)
+
629 
+
630 
+
631 // Illuminato
+
632 #elif defined(__AVR_ATmega645__)
+
633 #define TOTAL_ANALOG_PINS 6
+
634 #define TOTAL_PINS 42 // 36 digital + 6 analog
+
635 #define VERSION_BLINK_PIN 13
+
636 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
+
637 #define IS_PIN_ANALOG(p) ((p) >= 36 && (p) < TOTAL_PINS)
+
638 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
+
639 #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
+
640 #define IS_PIN_I2C(p) ((p) == 4 || (p) == 5)
+
641 #define PIN_TO_DIGITAL(p) (p)
+
642 #define PIN_TO_ANALOG(p) ((p) - 36)
+
643 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
+
644 #define PIN_TO_SERVO(p) ((p) - 2)
+
645 
+
646 
+
647 // Pic32 chipKIT FubarinoSD
+
648 #elif defined(_BOARD_FUBARINO_SD_)
+
649 #define TOTAL_ANALOG_PINS NUM_ANALOG_PINS // 15
+
650 #define TOTAL_PINS NUM_DIGITAL_PINS // 45, All pins can be digital
+
651 #define MAX_SERVOS NUM_DIGITAL_PINS
+
652 #define VERSION_BLINK_PIN PIN_LED1
+
653 #define IS_PIN_DIGITAL(p) 1
+
654 #define IS_PIN_ANALOG(p) ((p) >= 30 && (p) <= 44)
+
655 #define IS_PIN_PWM(p) IS_PIN_DIGITAL(p)
+
656 #define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p)
+
657 #define IS_PIN_I2C(p) ((p) == 1 || (p) == 2)
+
658 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
659 #define PIN_TO_DIGITAL(p) (p)
+
660 #define PIN_TO_ANALOG(p) (14 - (p - 30))
+
661 #define PIN_TO_PWM(p) (p)
+
662 #define PIN_TO_SERVO(p) (p)
+
663 
+
664 
+
665 // Pic32 chipKIT FubarinoMini
+
666 // Note, FubarinoMini analog pin 20 will not function in Firmata as analog input due to limitation in analog mapping
+
667 #elif defined(_BOARD_FUBARINO_MINI_)
+
668 #define TOTAL_ANALOG_PINS 14 // We have to fake this because of the poor analog pin mapping planning in FubarinoMini
+
669 #define TOTAL_PINS NUM_DIGITAL_PINS // 33
+
670 #define MAX_SERVOS NUM_DIGITAL_PINS
+
671 #define VERSION_BLINK_PIN PIN_LED1
+
672 #define IS_PIN_DIGITAL(p) ((p) != 14 && (p) != 15 && (p) != 31 && (p) != 32)
+
673 #define IS_PIN_ANALOG(p) ((p) == 0 || ((p) >= 3 && (p) <= 13))
+
674 #define IS_PIN_PWM(p) IS_PIN_DIGITAL(p)
+
675 #define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p)
+
676 #define IS_PIN_I2C(p) ((p) == 25 || (p) == 26)
+
677 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
678 #define PIN_TO_DIGITAL(p) (p)
+
679 #define PIN_TO_ANALOG(p) (p)
+
680 #define PIN_TO_PWM(p) (p)
+
681 #define PIN_TO_SERVO(p) (p)
+
682 
+
683 
+
684 // Pic32 chipKIT UNO32
+
685 #elif defined(_BOARD_UNO_) && defined(__PIC32) // NOTE: no _BOARD_UNO32_ to use
+
686 #define TOTAL_ANALOG_PINS NUM_ANALOG_PINS // 12
+
687 #define TOTAL_PINS NUM_DIGITAL_PINS // 47 All pins can be digital
+
688 #define MAX_SERVOS NUM_DIGITAL_PINS // All pins can be servo with SoftPWMservo
+
689 #define VERSION_BLINK_PIN PIN_LED1
+
690 #define IS_PIN_DIGITAL(p) ((p) >= 2)
+
691 #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 25)
+
692 #define IS_PIN_PWM(p) IS_PIN_DIGITAL(p)
+
693 #define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p)
+
694 #define IS_PIN_I2C(p) ((p) == 45 || (p) == 46)
+
695 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
696 #define PIN_TO_DIGITAL(p) (p)
+
697 #define PIN_TO_ANALOG(p) ((p) - 14)
+
698 #define PIN_TO_PWM(p) (p)
+
699 #define PIN_TO_SERVO(p) (p)
+
700 
+
701 
+
702 // Pic32 chipKIT DP32
+
703 #elif defined(_BOARD_DP32_)
+
704 #define TOTAL_ANALOG_PINS 15 // Really only has 9, but have to override because of mistake in variant file
+
705 #define TOTAL_PINS NUM_DIGITAL_PINS // 19
+
706 #define MAX_SERVOS NUM_DIGITAL_PINS // All pins can be servo with SoftPWMservo
+
707 #define VERSION_BLINK_PIN PIN_LED1
+
708 #define IS_PIN_DIGITAL(p) (((p) != 1) && ((p) != 4) && ((p) != 5) && ((p) != 15) && ((p) != 16))
+
709 #define IS_PIN_ANALOG(p) ((p) >= 6 && (p) <= 14)
+
710 #define IS_PIN_PWM(p) IS_PIN_DIGITAL(p)
+
711 #define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p)
+
712 #define IS_PIN_I2C(p) ((p) == 2 || (p) == 3)
+
713 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
714 #define PIN_TO_DIGITAL(p) (p)
+
715 #define PIN_TO_ANALOG(p) (p)
+
716 #define PIN_TO_PWM(p) (p)
+
717 #define PIN_TO_SERVO(p) (p)
+
718 
+
719 
+
720 // Pic32 chipKIT uC32
+
721 #elif defined(_BOARD_UC32_)
+
722 #define TOTAL_ANALOG_PINS NUM_ANALOG_PINS // 12
+
723 #define TOTAL_PINS NUM_DIGITAL_PINS // 47 All pins can be digital
+
724 #define MAX_SERVOS NUM_DIGITAL_PINS // All pins can be servo with SoftPWMservo
+
725 #define VERSION_BLINK_PIN PIN_LED1
+
726 #define IS_PIN_DIGITAL(p) ((p) >= 2)
+
727 #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 25)
+
728 #define IS_PIN_PWM(p) IS_PIN_DIGITAL(p)
+
729 #define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p)
+
730 #define IS_PIN_I2C(p) ((p) == 45 || (p) == 46)
+
731 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
732 #define PIN_TO_DIGITAL(p) (p)
+
733 #define PIN_TO_ANALOG(p) ((p) - 14)
+
734 #define PIN_TO_PWM(p) (p)
+
735 #define PIN_TO_SERVO(p) (p)
+
736 
+
737 
+
738 // Pic32 chipKIT WF32
+
739 #elif defined(_BOARD_WF32_)
+
740 #define TOTAL_ANALOG_PINS NUM_ANALOG_PINS
+
741 #define TOTAL_PINS NUM_DIGITAL_PINS
+
742 #define MAX_SERVOS NUM_DIGITAL_PINS
+
743 #define VERSION_BLINK_PIN PIN_LED1
+
744 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 49) // Accounts for SD and WiFi dedicated pins
+
745 #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 25)
+
746 #define IS_PIN_PWM(p) IS_PIN_DIGITAL(p)
+
747 #define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p)
+
748 #define IS_PIN_I2C(p) ((p) == 34 || (p) == 35)
+
749 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
750 #define PIN_TO_DIGITAL(p) (p)
+
751 #define PIN_TO_ANALOG(p) ((p) - 14)
+
752 #define PIN_TO_PWM(p) (p)
+
753 #define PIN_TO_SERVO(p) (p)
+
754 
+
755 
+
756 // Pic32 chipKIT WiFire
+
757 #elif defined(_BOARD_WIFIRE_)
+
758 #define TOTAL_ANALOG_PINS NUM_ANALOG_PINS // 14
+
759 #define TOTAL_PINS NUM_DIGITAL_PINS // 71
+
760 #define MAX_SERVOS NUM_DIGITAL_PINS
+
761 #define VERSION_BLINK_PIN PIN_LED1
+
762 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 47) // Accounts for SD and WiFi dedicated pins
+
763 #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 25)
+
764 #define IS_PIN_PWM(p) IS_PIN_DIGITAL(p)
+
765 #define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p)
+
766 #define IS_PIN_I2C(p) ((p) == 34 || (p) == 35)
+
767 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
768 #define PIN_TO_DIGITAL(p) (p)
+
769 #define PIN_TO_ANALOG(p) ((p) <= 25 ? ((p) - 14) : (p) - 36)
+
770 #define PIN_TO_PWM(p) (p)
+
771 #define PIN_TO_SERVO(p) (p)
+
772 
+
773 
+
774 // Pic32 chipKIT MAX32
+
775 #elif defined(_BOARD_MEGA_) && defined(__PIC32) // NOTE: no _BOARD_MAX32_ to use
+
776 #define TOTAL_ANALOG_PINS NUM_ANALOG_PINS // 16
+
777 #define TOTAL_PINS NUM_DIGITAL_PINS // 87
+
778 #define MAX_SERVOS NUM_DIGITAL_PINS
+
779 #define VERSION_BLINK_PIN PIN_LED1
+
780 #define IS_PIN_DIGITAL(p) ((p) >= 2)
+
781 #define IS_PIN_ANALOG(p) ((p) >= 54 && (p) <= 69)
+
782 #define IS_PIN_PWM(p) IS_PIN_DIGITAL(p)
+
783 #define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p)
+
784 #define IS_PIN_I2C(p) ((p) == 34 || (p) == 35)
+
785 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
786 #define PIN_TO_DIGITAL(p) (p)
+
787 #define PIN_TO_ANALOG(p) ((p) - 54)
+
788 #define PIN_TO_PWM(p) (p)
+
789 #define PIN_TO_SERVO(p) (p)
+
790 
+
791 
+
792 // Pic32 chipKIT Pi
+
793 #elif defined(_BOARD_CHIPKIT_PI_)
+
794 #define TOTAL_ANALOG_PINS 16
+
795 #define TOTAL_PINS NUM_DIGITAL_PINS // 19
+
796 #define MAX_SERVOS NUM_DIGITAL_PINS
+
797 #define VERSION_BLINK_PIN PIN_LED1
+
798 #define IS_PIN_DIGITAL(p) (((p) >= 2) && ((p) <= 3) || (((p) >= 8) && ((p) <= 13)) || (((p) >= 14) && ((p) <= 17)))
+
799 #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 17)
+
800 #define IS_PIN_PWM(p) IS_PIN_DIGITAL(p)
+
801 #define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p)
+
802 #define IS_PIN_I2C(p) ((p) == 16 || (p) == 17)
+
803 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
804 #define PIN_TO_DIGITAL(p) (p)
+
805 #define PIN_TO_ANALOG(p) ((p) <= 15 ? (p) - 14 : (p) - 12)
+
806 //#define PIN_TO_ANALOG(p) (((p) <= 16) ? ((p) - 14) : ((p) - 16))
+
807 #define PIN_TO_PWM(p) (p)
+
808 #define PIN_TO_SERVO(p) (p)
+
809 
+
810 // Pinoccio Scout
+
811 // Note: digital pins 9-16 are usable but not labeled on the board numerically.
+
812 // SS=9, MOSI=10, MISO=11, SCK=12, RX1=13, TX1=14, SCL=15, SDA=16
+
813 #elif defined(ARDUINO_PINOCCIO)
+
814 #define TOTAL_ANALOG_PINS 8
+
815 #define TOTAL_PINS NUM_DIGITAL_PINS // 32
+
816 #define VERSION_BLINK_PIN 23
+
817 #define PIN_SERIAL1_RX 13
+
818 #define PIN_SERIAL1_TX 14
+
819 #define IS_PIN_DIGITAL(p) (((p) >= 2) && ((p) <= 16)) || (((p) >= 24) && ((p) <= 31))
+
820 #define IS_PIN_ANALOG(p) ((p) >= 24 && (p) <= 31)
+
821 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
+
822 #define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p)
+
823 #define IS_PIN_I2C(p) ((p) == SCL || (p) == SDA)
+
824 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
825 #define IS_PIN_SERIAL(p) ((p) == 13 || (p) == 14)
+
826 #define PIN_TO_DIGITAL(p) (p)
+
827 #define PIN_TO_ANALOG(p) ((p) - 24)
+
828 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
+
829 #define PIN_TO_SERVO(p) ((p) - 2)
+
830 
+
831 // ESP8266
+
832 // note: boot mode GPIOs 0, 2 and 15 can be used as outputs, GPIOs 6-11 are in use for flash IO
+
833 #elif defined(ESP8266)
+
834 #define TOTAL_ANALOG_PINS NUM_ANALOG_INPUTS
+
835 #define TOTAL_PINS A0 + NUM_ANALOG_INPUTS
+
836 #define PIN_SERIAL_RX 3
+
837 #define PIN_SERIAL_TX 1
+
838 #define IS_PIN_DIGITAL(p) (((p) >= 0 && (p) <= 5) || ((p) >= 12 && (p) < A0))
+
839 #define IS_PIN_ANALOG(p) ((p) >= A0 && (p) < A0 + NUM_ANALOG_INPUTS)
+
840 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
+
841 #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS)
+
842 #define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL)
+
843 #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
+
844 #define IS_PIN_INTERRUPT(p) (digitalPinToInterrupt(p) > NOT_AN_INTERRUPT)
+
845 #define IS_PIN_SERIAL(p) ((p) == PIN_SERIAL_RX || (p) == PIN_SERIAL_TX)
+
846 #define PIN_TO_DIGITAL(p) (p)
+
847 #define PIN_TO_ANALOG(p) ((p) - A0)
+
848 #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
+
849 #define PIN_TO_SERVO(p) (p)
+
850 #define DEFAULT_PWM_RESOLUTION 10
+
851 
+
852 // STM32 based boards
+
853 #elif defined(ARDUINO_ARCH_STM32)
+
854 #define TOTAL_ANALOG_PINS NUM_ANALOG_INPUTS
+
855 #define TOTAL_PINS NUM_DIGITAL_PINS
+
856 #define TOTAL_PORTS MAX_NB_PORT
+
857 #define VERSION_BLINK_PIN LED_BUILTIN
+
858 // PIN_SERIALY_RX/TX defined in the variant.h
+
859 #define IS_PIN_DIGITAL(p) (digitalPinIsValid(p) && !pinIsSerial(p))
+
860 #define IS_PIN_ANALOG(p) ((p >= A0) && (p < (A0 + TOTAL_ANALOG_PINS)) && !pinIsSerial(p))
+
861 #define IS_PIN_PWM(p) (IS_PIN_DIGITAL(p) && digitalPinHasPWM(p))
+
862 #define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p)
+
863 #define IS_PIN_I2C(p) (IS_PIN_DIGITAL(p) && digitalPinHasI2C(p))
+
864 #define IS_PIN_SPI(p) (IS_PIN_DIGITAL(p) && digitalPinHasSPI(p))
+
865 #define IS_PIN_INTERRUPT(p) (IS_PIN_DIGITAL(p) && (digitalPinToInterrupt(p) > NOT_AN_INTERRUPT)))
+
866 #define IS_PIN_SERIAL(p) (digitalPinHasSerial(p) && !pinIsSerial(p))
+
867 #define PIN_TO_DIGITAL(p) (p)
+
868 #define PIN_TO_ANALOG(p) (p-A0)
+
869 #define PIN_TO_PWM(p) (p)
+
870 #define PIN_TO_SERVO(p) (p)
+
871 #define DEFAULT_PWM_RESOLUTION PWM_RESOLUTION
+
872 
+
873 // Adafruit Bluefruit nRF52 boards
+
874 #elif defined(ARDUINO_NRF52_ADAFRUIT)
+
875 #define TOTAL_ANALOG_PINS NUM_ANALOG_INPUTS
+
876 #define TOTAL_PINS NUM_DIGITAL_PINS
+
877 #define VERSION_BLINK_PIN LED_BUILTIN
+
878 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
+
879 #define IS_PIN_ANALOG(p) ((p) == PIN_A0 || (p) == PIN_A1 || (p) == PIN_A2 || (p) == PIN_A3 || \
+
880  (p) == PIN_A4 || (p) == PIN_A5 || (p) == PIN_A6 || (p) == PIN_A7)
+
881 #define IS_PIN_PWM(p) digitalPinHasPWM(p)
+
882 #define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p)
+
883 #define IS_PIN_I2C(p) ((p) == PIN_WIRE_SDA || (p) == PIN_WIRE_SCL)
+
884 #define IS_PIN_SPI(p) ((p) == SS || (p)== MOSI || (p) == MISO || (p == SCK))
+
885 #define PIN_TO_DIGITAL(p) (p)
+
886 #define PIN_TO_ANALOG(p) ( ((p) == PIN_A0) ? 0 : ((p) == PIN_A1) ? 1 : ((p) == PIN_A2) ? 2 : ((p) == PIN_A3) ? 3 : \
+
887  ((p) == PIN_A4) ? 4 : ((p) == PIN_A5) ? 5 : ((p) == PIN_A6) ? 6 : ((p) == PIN_A7) ? 7 : (127))
+
888 #define PIN_TO_PWM(p) (p)
+
889 #define PIN_TO_SERVO(p) (p)
+
890 
+
891 // anything else
+
892 #else
+
893 #error "Please edit Boards.h with a hardware abstraction for this board"
+
894 #endif
+
895 
+
896 // as long this is not defined for all boards:
+
897 #ifndef IS_PIN_SPI
+
898 #define IS_PIN_SPI(p) 0
+
899 #endif
+
900 
+
901 #ifndef IS_PIN_SERIAL
+
902 #define IS_PIN_SERIAL(p) 0
+
903 #endif
+
904 
+
905 #ifndef DEFAULT_PWM_RESOLUTION
+
906 #define DEFAULT_PWM_RESOLUTION 8
+
907 #endif
+
908 
+
909 /*==============================================================================
+
910  * readPort() - Read an 8 bit port
+
911  *============================================================================*/
+
912 
+
913 static inline unsigned char readPort(byte, byte) __attribute__((always_inline, unused));
+
914 static inline unsigned char readPort(byte port, byte bitmask)
+
915 {
+
916 #if defined(ARDUINO_PINOUT_OPTIMIZE)
+
917  if (port == 0) return (PIND & 0xFC) & bitmask; // ignore Rx/Tx 0/1
+
918  if (port == 1) return ((PINB & 0x3F) | ((PINC & 0x03) << 6)) & bitmask;
+
919  if (port == 2) return ((PINC & 0x3C) >> 2) & bitmask;
+
920  return 0;
+
921 #else
+
922  unsigned char out = 0, pin = port * 8;
+
923  if (IS_PIN_DIGITAL(pin + 0) && (bitmask & 0x01) && digitalRead(PIN_TO_DIGITAL(pin + 0))) out |= 0x01;
+
924  if (IS_PIN_DIGITAL(pin + 1) && (bitmask & 0x02) && digitalRead(PIN_TO_DIGITAL(pin + 1))) out |= 0x02;
+
925  if (IS_PIN_DIGITAL(pin + 2) && (bitmask & 0x04) && digitalRead(PIN_TO_DIGITAL(pin + 2))) out |= 0x04;
+
926  if (IS_PIN_DIGITAL(pin + 3) && (bitmask & 0x08) && digitalRead(PIN_TO_DIGITAL(pin + 3))) out |= 0x08;
+
927  if (IS_PIN_DIGITAL(pin + 4) && (bitmask & 0x10) && digitalRead(PIN_TO_DIGITAL(pin + 4))) out |= 0x10;
+
928  if (IS_PIN_DIGITAL(pin + 5) && (bitmask & 0x20) && digitalRead(PIN_TO_DIGITAL(pin + 5))) out |= 0x20;
+
929  if (IS_PIN_DIGITAL(pin + 6) && (bitmask & 0x40) && digitalRead(PIN_TO_DIGITAL(pin + 6))) out |= 0x40;
+
930  if (IS_PIN_DIGITAL(pin + 7) && (bitmask & 0x80) && digitalRead(PIN_TO_DIGITAL(pin + 7))) out |= 0x80;
+
931  return out;
+
932 #endif
+
933 }
+
934 
+
935 /*==============================================================================
+
936  * writePort() - Write an 8 bit port, only touch pins specified by a bitmask
+
937  *============================================================================*/
+
938 
+
939 static inline unsigned char writePort(byte, byte, byte) __attribute__((always_inline, unused));
+
940 static inline unsigned char writePort(byte port, byte value, byte bitmask)
+
941 {
+
942 #if defined(ARDUINO_PINOUT_OPTIMIZE)
+
943  if (port == 0) {
+
944  bitmask = bitmask & 0xFC; // do not touch Tx & Rx pins
+
945  byte valD = value & bitmask;
+
946  byte maskD = ~bitmask;
+
947  cli();
+
948  PORTD = (PORTD & maskD) | valD;
+
949  sei();
+
950  } else if (port == 1) {
+
951  byte valB = (value & bitmask) & 0x3F;
+
952  byte valC = (value & bitmask) >> 6;
+
953  byte maskB = ~(bitmask & 0x3F);
+
954  byte maskC = ~((bitmask & 0xC0) >> 6);
+
955  cli();
+
956  PORTB = (PORTB & maskB) | valB;
+
957  PORTC = (PORTC & maskC) | valC;
+
958  sei();
+
959  } else if (port == 2) {
+
960  bitmask = bitmask & 0x0F;
+
961  byte valC = (value & bitmask) << 2;
+
962  byte maskC = ~(bitmask << 2);
+
963  cli();
+
964  PORTC = (PORTC & maskC) | valC;
+
965  sei();
+
966  }
+
967  return 1;
+
968 #else
+
969  byte pin = port * 8;
+
970  if ((bitmask & 0x01)) digitalWrite(PIN_TO_DIGITAL(pin + 0), (value & 0x01));
+
971  if ((bitmask & 0x02)) digitalWrite(PIN_TO_DIGITAL(pin + 1), (value & 0x02));
+
972  if ((bitmask & 0x04)) digitalWrite(PIN_TO_DIGITAL(pin + 2), (value & 0x04));
+
973  if ((bitmask & 0x08)) digitalWrite(PIN_TO_DIGITAL(pin + 3), (value & 0x08));
+
974  if ((bitmask & 0x10)) digitalWrite(PIN_TO_DIGITAL(pin + 4), (value & 0x10));
+
975  if ((bitmask & 0x20)) digitalWrite(PIN_TO_DIGITAL(pin + 5), (value & 0x20));
+
976  if ((bitmask & 0x40)) digitalWrite(PIN_TO_DIGITAL(pin + 6), (value & 0x40));
+
977  if ((bitmask & 0x80)) digitalWrite(PIN_TO_DIGITAL(pin + 7), (value & 0x80));
+
978  return 1;
+
979 #endif
+
980 }
+
981 
+
982 
+
983 
+
984 
+
985 #ifndef TOTAL_PORTS
+
986 #define TOTAL_PORTS ((TOTAL_PINS + 7) / 8)
+
987 #endif
+
988 
+
989 
+
990 #endif /* Firmata_Boards_h */
+
+ + + + diff --git a/docs/html/_firmata_8h_source.html b/docs/html/_firmata_8h_source.html new file mode 100644 index 00000000..7556f5fe --- /dev/null +++ b/docs/html/_firmata_8h_source.html @@ -0,0 +1,284 @@ + + + + + + + +Firmata firmware for Arduino: Firmata.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Firmata firmware for Arduino +
+
Firmata is a protocol for communicating with microcontrollers from software on a host computer
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Firmata.h
+
+
+
1 /*
+
2  Firmata.h - Firmata library v2.5.8 - 2018-04-15
+
3  Copyright (c) 2006-2008 Hans-Christoph Steiner. All rights reserved.
+
4  Copyright (C) 2009-2017 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 
+
14 #ifndef Firmata_h
+
15 #define Firmata_h
+
16 
+
17 #include "Boards.h" /* Hardware Abstraction Layer + Wiring/Arduino */
+
18 #include "FirmataDefines.h"
+
19 #include "FirmataMarshaller.h"
+
20 #include "FirmataParser.h"
+
21 
+
22 /* DEPRECATED as of Firmata v2.5.1. As of 2.5.1 there are separate version numbers for
+
23  * the protocol version and the firmware version.
+
24  */
+
25 #define FIRMATA_MAJOR_VERSION 2 // same as FIRMATA_PROTOCOL_MAJOR_VERSION
+
26 #define FIRMATA_MINOR_VERSION 5 // same as FIRMATA_PROTOCOL_MINOR_VERSION
+
27 #define FIRMATA_BUGFIX_VERSION 1 // same as FIRMATA_PROTOCOL_BUGFIX_VERSION
+
28 
+
29 // extended command set using sysex (0-127/0x00-0x7F)
+
30 /* 0x00-0x0F reserved for user-defined commands */
+
31 // these are DEPRECATED to make the naming more consistent
+
32 #define FIRMATA_STRING 0x71 // same as STRING_DATA
+
33 #define SYSEX_I2C_REQUEST 0x76 // same as I2C_REQUEST
+
34 #define SYSEX_I2C_REPLY 0x77 // same as I2C_REPLY
+
35 #define SYSEX_SAMPLING_INTERVAL 0x7A // same as SAMPLING_INTERVAL
+
36 
+
37 // pin modes
+
38 //#define INPUT 0x00 // defined in Arduino.h
+
39 //#define OUTPUT 0x01 // defined in Arduino.h
+
40 // DEPRECATED as of Firmata v2.5
+
41 #define ANALOG 0x02 // same as PIN_MODE_ANALOG
+
42 #define PWM 0x03 // same as PIN_MODE_PWM
+
43 #define SERVO 0x04 // same as PIN_MODE_SERVO
+
44 #define SHIFT 0x05 // same as PIN_MODE_SHIFT
+
45 #define I2C 0x06 // same as PIN_MODE_I2C
+
46 #define ONEWIRE 0x07 // same as PIN_MODE_ONEWIRE
+
47 #define STEPPER 0x08 // same as PIN_MODE_STEPPER
+
48 #define ENCODER 0x09 // same as PIN_MODE_ENCODER
+
49 #define IGNORE 0x7F // same as PIN_MODE_IGNORE
+
50 
+
51 namespace firmata {
+
52 
+
53 // TODO make it a subclass of a generic Serial/Stream base class
+ +
55 {
+
56  public:
+
57  typedef void (*callbackFunction)(uint8_t, int);
+
58  typedef void (*systemCallbackFunction)(void);
+
59  typedef void (*stringCallbackFunction)(char *);
+
60  typedef void (*sysexCallbackFunction)(uint8_t command, uint8_t argc, uint8_t *argv);
+
61 
+
62  FirmataClass();
+
63 
+
64  /* Arduino constructors */
+
65  void begin();
+
66  void begin(long);
+
67  void begin(Stream &s);
+
68 
+
69  /* querying functions */
+
70  void printVersion(void);
+
71  void blinkVersion(void);
+
72  void printFirmwareVersion(void);
+
73 
+
74  //void setFirmwareVersion(byte major, byte minor); // see macro below
+
75  void setFirmwareNameAndVersion(const char *name, byte major, byte minor);
+
76  void disableBlinkVersion();
+
77 
+
78  /* serial receive handling */
+
79  int available(void);
+
80  void processInput(void);
+
81  void parse(unsigned char value);
+
82  boolean isParsingMessage(void);
+
83 
+
84  /* serial send handling */
+
85  void sendAnalog(byte pin, int value);
+
86  void sendDigital(byte pin, int value); // TODO implement this
+
87  void sendDigitalPort(byte portNumber, int portData);
+
88  void sendString(const char *string);
+
89  void sendString(byte command, const char *string);
+
90  void sendSysex(byte command, byte bytec, byte *bytev);
+
91  void write(byte c);
+
92 
+
93  /* attach & detach callback functions to messages */
+
94  void attach(uint8_t command, callbackFunction newFunction);
+
95  void attach(uint8_t command, systemCallbackFunction newFunction);
+
96  void attach(uint8_t command, stringCallbackFunction newFunction);
+
97  void attach(uint8_t command, sysexCallbackFunction newFunction);
+
98  void detach(uint8_t command);
+
99 
+
100  /* access pin state and config */
+
101  byte getPinMode(byte pin);
+
102  void setPinMode(byte pin, byte config);
+
103 
+
104  /* access pin state */
+
105  int getPinState(byte pin);
+
106  void setPinState(byte pin, int state);
+
107 
+
108  /* utility methods */
+
109  void sendValueAsTwo7bitBytes(int value);
+
110  void startSysex(void);
+
111  void endSysex(void);
+
112 
+
113  private:
+
114  uint8_t parserBuffer[MAX_DATA_BYTES];
+
115  FirmataMarshaller marshaller;
+
116  FirmataParser parser;
+
117  Stream *FirmataStream;
+
118 
+
119  /* firmware name and version */
+
120  byte firmwareVersionCount;
+
121  byte *firmwareVersionVector;
+
122 
+
123  /* pin configuration */
+
124  byte pinConfig[TOTAL_PINS];
+
125  int pinState[TOTAL_PINS];
+
126 
+
127  boolean blinkVersionDisabled;
+
128 
+
129  /* private methods ------------------------------ */
+
130  void strobeBlinkPin(byte pin, int count, int onInterval, int offInterval);
+
131  friend void FirmataMarshaller::encodeByteStream (size_t bytec, uint8_t * bytev, size_t max_bytes = 0) const;
+
132 
+
133  /* callback functions */
+
134  static callbackFunction currentAnalogCallback;
+
135  static callbackFunction currentDigitalCallback;
+
136  static callbackFunction currentPinModeCallback;
+
137  static callbackFunction currentPinValueCallback;
+
138  static callbackFunction currentReportAnalogCallback;
+
139  static callbackFunction currentReportDigitalCallback;
+
140  static stringCallbackFunction currentStringCallback;
+
141  static sysexCallbackFunction currentSysexCallback;
+
142  static systemCallbackFunction currentSystemResetCallback;
+
143 
+
144  /* static callbacks */
+
145  inline static void staticAnalogCallback (void *, uint8_t command, uint16_t value) { if ( currentAnalogCallback ) { currentAnalogCallback(command,(int)value); } }
+
146  inline static void staticDigitalCallback (void *, uint8_t command, uint16_t value) { if ( currentDigitalCallback ) { currentDigitalCallback(command, (int)value); } }
+
147  inline static void staticPinModeCallback (void *, uint8_t command, uint16_t value) { if ( currentPinModeCallback ) { currentPinModeCallback(command, (int)value); } }
+
148  inline static void staticPinValueCallback (void *, uint8_t command, uint16_t value) { if ( currentPinValueCallback ) { currentPinValueCallback(command, (int)value); } }
+
149  inline static void staticReportAnalogCallback (void *, uint8_t command, uint16_t value) { if ( currentReportAnalogCallback ) { currentReportAnalogCallback(command, (int)value); } }
+
150  inline static void staticReportDigitalCallback (void *, uint8_t command, uint16_t value) { if ( currentReportDigitalCallback ) { currentReportDigitalCallback(command, (int)value); } }
+
151  inline static void staticStringCallback (void *, const char * c_str) { if ( currentStringCallback ) { currentStringCallback((char *)c_str); } }
+
152  inline static void staticSysexCallback (void *, uint8_t command, size_t argc, uint8_t *argv) { if ( currentSysexCallback ) { currentSysexCallback(command, (uint8_t)argc, argv); } }
+
153  inline static void staticReportFirmwareCallback (void * context, size_t, size_t, const char *) { if ( context ) { ((FirmataClass *)context)->printFirmwareVersion(); } }
+
154  inline static void staticReportVersionCallback (void * context) { if ( context ) { ((FirmataClass *)context)->printVersion(); } }
+
155  inline static void staticSystemResetCallback (void *) { if ( currentSystemResetCallback ) { currentSystemResetCallback(); } }
+
156 };
+
157 
+
158 } // namespace firmata
+
159 
+
160 extern "C" {
+
161  // callback function types
+
162  typedef firmata::FirmataClass::callbackFunction callbackFunction;
+
163  typedef firmata::FirmataClass::systemCallbackFunction systemCallbackFunction;
+
164  typedef firmata::FirmataClass::stringCallbackFunction stringCallbackFunction;
+
165  typedef firmata::FirmataClass::sysexCallbackFunction sysexCallbackFunction;
+
166 }
+
167 
+
168 extern firmata::FirmataClass Firmata;
+
169 
+
170 /*==============================================================================
+
171  * MACROS
+
172  *============================================================================*/
+
173 
+
174 /* shortcut for setFirmwareNameAndVersion() that uses __FILE__ to set the
+
175  * firmware name. It needs to be a macro so that __FILE__ is included in the
+
176  * firmware source file rather than the library source file.
+
177  */
+
178 #define setFirmwareVersion(x, y) setFirmwareNameAndVersion(__FILE__, x, y)
+
179 
+
180 #endif /* Firmata_h */
+
+
void processInput(void)
Definition: Firmata.cpp:252
+
void setPinMode(byte pin, byte config)
Definition: Firmata.cpp:486
+
boolean isParsingMessage(void)
Definition: Firmata.cpp:272
+
void sendString(const char *string)
Definition: Firmata.cpp:363
+
void write(byte c)
Definition: Firmata.cpp:373
+
void printFirmwareVersion(void)
Definition: Firmata.cpp:187
+
void setPinState(byte pin, int state)
Definition: Firmata.cpp:509
+
int getPinState(byte pin)
Definition: Firmata.cpp:498
+
int available(void)
Definition: Firmata.cpp:244
+
byte getPinMode(byte pin)
Definition: Firmata.cpp:474
+
void printVersion(void)
Definition: Firmata.cpp:147
+
void setFirmwareNameAndVersion(const char *name, byte major, byte minor)
Definition: Firmata.cpp:201
+
void sendAnalog(byte pin, int value)
Definition: Firmata.cpp:289
+
Definition: FirmataParser.h:27
+
void endSysex(void)
Definition: Firmata.cpp:67
+
void blinkVersion(void)
Definition: Firmata.cpp:159
+
void sendSysex(byte command, byte bytec, byte *bytev)
Definition: Firmata.cpp:342
+
void detach(uint8_t command)
Definition: Firmata.cpp:452
+
FirmataClass()
Definition: Firmata.cpp:80
+
void disableBlinkVersion()
Definition: Firmata.cpp:177
+
void parse(unsigned char value)
Definition: Firmata.cpp:264
+
Definition: Firmata.h:54
+
void sendDigitalPort(byte portNumber, int portData)
Definition: Firmata.cpp:330
+
void startSysex(void)
Definition: Firmata.cpp:59
+
Definition: FirmataMarshaller.h:29
+
void sendValueAsTwo7bitBytes(int value)
Definition: Firmata.cpp:51
+
void begin()
Definition: Firmata.cpp:109
+ + + + diff --git a/docs/html/_firmata_constants_8h_source.html b/docs/html/_firmata_constants_8h_source.html new file mode 100644 index 00000000..a5f23ead --- /dev/null +++ b/docs/html/_firmata_constants_8h_source.html @@ -0,0 +1,174 @@ + + + + + + + +Firmata firmware for Arduino: FirmataConstants.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Firmata firmware for Arduino +
+
Firmata is a protocol for communicating with microcontrollers from software on a host computer
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
FirmataConstants.h
+
+
+
1 /*
+
2  FirmataConstants.h
+
3  Copyright (c) 2006-2008 Hans-Christoph Steiner. All rights reserved.
+
4  Copyright (C) 2009-2017 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 
+
14 #ifndef FirmataConstants_h
+
15 #define FirmataConstants_h
+
16 
+
17 namespace firmata {
+
18 /* Version numbers for the Firmata library.
+
19  * The firmware version will not always equal the protocol version going forward.
+
20  * Query using the REPORT_FIRMWARE message.
+
21  */
+
22 static const int FIRMWARE_MAJOR_VERSION = 2;
+
23 static const int FIRMWARE_MINOR_VERSION = 5;
+
24 static const int FIRMWARE_BUGFIX_VERSION = 7;
+
25 
+
26 /* Version numbers for the protocol. The protocol is still changing, so these
+
27  * version numbers are important.
+
28  * Query using the REPORT_VERSION message.
+
29  */
+
30 static const int PROTOCOL_MAJOR_VERSION = 2; // for non-compatible changes
+
31 static const int PROTOCOL_MINOR_VERSION = 5; // for backwards compatible changes
+
32 static const int PROTOCOL_BUGFIX_VERSION = 1; // for bugfix releases
+
33 
+
34 static const int MAX_DATA_BYTES = 64; // max number of data bytes in incoming messages
+
35 
+
36 // message command bytes (128-255/0x80-0xFF)
+
37 
+
38 static const int DIGITAL_MESSAGE = 0x90; // send data for a digital port (collection of 8 pins)
+
39 static const int ANALOG_MESSAGE = 0xE0; // send data for an analog pin (or PWM)
+
40 static const int REPORT_ANALOG = 0xC0; // enable analog input by pin #
+
41 static const int REPORT_DIGITAL = 0xD0; // enable digital input by port pair
+
42 //
+
43 static const int SET_PIN_MODE = 0xF4; // set a pin to INPUT/OUTPUT/PWM/etc
+
44 static const int SET_DIGITAL_PIN_VALUE = 0xF5; // set value of an individual digital pin
+
45 //
+
46 static const int REPORT_VERSION = 0xF9; // report protocol version
+
47 static const int SYSTEM_RESET = 0xFF; // reset from MIDI
+
48 //
+
49 static const int START_SYSEX = 0xF0; // start a MIDI Sysex message
+
50 static const int END_SYSEX = 0xF7; // end a MIDI Sysex message
+
51 
+
52 // extended command set using sysex (0-127/0x00-0x7F)
+
53 /* 0x00-0x0F reserved for user-defined commands */
+
54 
+
55 static const int SERIAL_DATA = 0x60; // communicate with serial devices, including other boards
+
56 static const int ENCODER_DATA = 0x61; // reply with encoders current positions
+
57 static const int SERVO_CONFIG = 0x70; // set max angle, minPulse, maxPulse, freq
+
58 static const int STRING_DATA = 0x71; // a string message with 14-bits per char
+
59 static const int STEPPER_DATA = 0x72; // control a stepper motor
+
60 static const int ONEWIRE_DATA = 0x73; // send an OneWire read/write/reset/select/skip/search request
+
61 static const int SHIFT_DATA = 0x75; // a bitstream to/from a shift register
+
62 static const int I2C_REQUEST = 0x76; // send an I2C read/write request
+
63 static const int I2C_REPLY = 0x77; // a reply to an I2C read request
+
64 static const int I2C_CONFIG = 0x78; // config I2C settings such as delay times and power pins
+
65 static const int REPORT_FIRMWARE = 0x79; // report name and version of the firmware
+
66 static const int EXTENDED_ANALOG = 0x6F; // analog write (PWM, Servo, etc) to any pin
+
67 static const int PIN_STATE_QUERY = 0x6D; // ask for a pin's current mode and value
+
68 static const int PIN_STATE_RESPONSE = 0x6E; // reply with pin's current mode and value
+
69 static const int CAPABILITY_QUERY = 0x6B; // ask for supported modes and resolution of all pins
+
70 static const int CAPABILITY_RESPONSE = 0x6C; // reply with supported modes and resolution
+
71 static const int ANALOG_MAPPING_QUERY = 0x69; // ask for mapping of analog to pin numbers
+
72 static const int ANALOG_MAPPING_RESPONSE = 0x6A; // reply with mapping info
+
73 static const int SAMPLING_INTERVAL = 0x7A; // set the poll rate of the main loop
+
74 static const int SCHEDULER_DATA = 0x7B; // send a createtask/deletetask/addtotask/schedule/querytasks/querytask request to the scheduler
+
75 static const int SYSEX_NON_REALTIME = 0x7E; // MIDI Reserved for non-realtime messages
+
76 static const int SYSEX_REALTIME = 0x7F; // MIDI Reserved for realtime messages
+
77 
+
78 // pin modes
+
79 static const int PIN_MODE_INPUT = 0x00; // same as INPUT defined in Arduino.h
+
80 static const int PIN_MODE_OUTPUT = 0x01; // same as OUTPUT defined in Arduino.h
+
81 static const int PIN_MODE_ANALOG = 0x02; // analog pin in analogInput mode
+
82 static const int PIN_MODE_PWM = 0x03; // digital pin in PWM output mode
+
83 static const int PIN_MODE_SERVO = 0x04; // digital pin in Servo output mode
+
84 static const int PIN_MODE_SHIFT = 0x05; // shiftIn/shiftOut mode
+
85 static const int PIN_MODE_I2C = 0x06; // pin included in I2C setup
+
86 static const int PIN_MODE_ONEWIRE = 0x07; // pin configured for 1-wire
+
87 static const int PIN_MODE_STEPPER = 0x08; // pin configured for stepper motor
+
88 static const int PIN_MODE_ENCODER = 0x09; // pin configured for rotary encoders
+
89 static const int PIN_MODE_SERIAL = 0x0A; // pin configured for serial communication
+
90 static const int PIN_MODE_PULLUP = 0x0B; // enable internal pull-up resistor for pin
+
91 static const int PIN_MODE_IGNORE = 0x7F; // pin configured to be ignored by digitalWrite and capabilityResponse
+
92 
+
93 static const int TOTAL_PIN_MODES = 13;
+
94 
+
95 } // namespace firmata
+
96 
+
97 #endif // FirmataConstants_h
+
+ + + + diff --git a/docs/html/_firmata_defines_8h_source.html b/docs/html/_firmata_defines_8h_source.html new file mode 100644 index 00000000..5dd9dc98 --- /dev/null +++ b/docs/html/_firmata_defines_8h_source.html @@ -0,0 +1,360 @@ + + + + + + + +Firmata firmware for Arduino: FirmataDefines.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Firmata firmware for Arduino +
+
Firmata is a protocol for communicating with microcontrollers from software on a host computer
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
FirmataDefines.h
+
+
+
1 /*
+
2  FirmataDefines.h
+
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 
+
14 #ifndef FirmataDefines_h
+
15 #define FirmataDefines_h
+
16 
+
17 #include "FirmataConstants.h"
+
18 
+
19 /* Version numbers for the Firmata library.
+
20  * The firmware version will not always equal the protocol version going forward.
+
21  * Query using the REPORT_FIRMWARE message.
+
22  */
+
23 #define FIRMATA_FIRMWARE_MAJOR_VERSION firmata::FIRMWARE_MAJOR_VERSION
+
24 #define FIRMATA_FIRMWARE_MINOR_VERSION firmata::FIRMWARE_MINOR_VERSION
+
25 #define FIRMATA_FIRMWARE_BUGFIX_VERSION firmata::FIRMWARE_BUGFIX_VERSION
+
26 
+
27 /* Version numbers for the protocol. The protocol is still changing, so these
+
28  * version numbers are important.
+
29  * Query using the REPORT_VERSION message.
+
30  */
+
31 #define FIRMATA_PROTOCOL_MAJOR_VERSION firmata::PROTOCOL_MAJOR_VERSION // for non-compatible changes
+
32 #define FIRMATA_PROTOCOL_MINOR_VERSION firmata::PROTOCOL_MINOR_VERSION // for backwards compatible changes
+
33 #define FIRMATA_PROTOCOL_BUGFIX_VERSION firmata::PROTOCOL_BUGFIX_VERSION // for bugfix releases
+
34 
+
35 #ifdef MAX_DATA_BYTES
+
36 #undef MAX_DATA_BYTES
+
37 #endif
+
38 #define MAX_DATA_BYTES firmata::MAX_DATA_BYTES // max number of data bytes in incoming messages
+
39 
+
40 // message command bytes (128-255/0x80-0xFF)
+
41 
+
42 #ifdef DIGITAL_MESSAGE
+
43 #undef DIGITAL_MESSAGE
+
44 #endif
+
45 #define DIGITAL_MESSAGE firmata::DIGITAL_MESSAGE // send data for a digital port (collection of 8 pins)
+
46 
+
47 #ifdef ANALOG_MESSAGE
+
48 #undef ANALOG_MESSAGE
+
49 #endif
+
50 #define ANALOG_MESSAGE firmata::ANALOG_MESSAGE // send data for an analog pin (or PWM)
+
51 
+
52 #ifdef REPORT_ANALOG
+
53 #undef REPORT_ANALOG
+
54 #endif
+
55 #define REPORT_ANALOG firmata::REPORT_ANALOG // enable analog input by pin #
+
56 
+
57 #ifdef REPORT_DIGITAL
+
58 #undef REPORT_DIGITAL
+
59 #endif
+
60 #define REPORT_DIGITAL firmata::REPORT_DIGITAL // enable digital input by port pair
+
61 
+
62 //
+
63 
+
64 #ifdef SET_PIN_MODE
+
65 #undef SET_PIN_MODE
+
66 #endif
+
67 #define SET_PIN_MODE firmata::SET_PIN_MODE // set a pin to INPUT/OUTPUT/PWM/etc
+
68 
+
69 #ifdef SET_DIGITAL_PIN_VALUE
+
70 #undef SET_DIGITAL_PIN_VALUE
+
71 #endif
+
72 #define SET_DIGITAL_PIN_VALUE firmata::SET_DIGITAL_PIN_VALUE // set value of an individual digital pin
+
73 
+
74 //
+
75 
+
76 #ifdef REPORT_VERSION
+
77 #undef REPORT_VERSION
+
78 #endif
+
79 #define REPORT_VERSION firmata::REPORT_VERSION // report protocol version
+
80 
+
81 #ifdef SYSTEM_RESET
+
82 #undef SYSTEM_RESET
+
83 #endif
+
84 #define SYSTEM_RESET firmata::SYSTEM_RESET // reset from MIDI
+
85 
+
86 //
+
87 
+
88 #ifdef START_SYSEX
+
89 #undef START_SYSEX
+
90 #endif
+
91 #define START_SYSEX firmata::START_SYSEX // start a MIDI Sysex message
+
92 
+
93 #ifdef END_SYSEX
+
94 #undef END_SYSEX
+
95 #endif
+
96 #define END_SYSEX firmata::END_SYSEX // end a MIDI Sysex message
+
97 
+
98 // extended command set using sysex (0-127/0x00-0x7F)
+
99 /* 0x00-0x0F reserved for user-defined commands */
+
100 
+
101 #ifdef SERIAL_MESSAGE
+
102 #undef SERIAL_MESSAGE
+
103 #endif
+
104 #define SERIAL_MESSAGE firmata::SERIAL_DATA // communicate with serial devices, including other boards
+
105 
+
106 #ifdef ENCODER_DATA
+
107 #undef ENCODER_DATA
+
108 #endif
+
109 #define ENCODER_DATA firmata::ENCODER_DATA // reply with encoders current positions
+
110 
+
111 #ifdef SERVO_CONFIG
+
112 #undef SERVO_CONFIG
+
113 #endif
+
114 #define SERVO_CONFIG firmata::SERVO_CONFIG // set max angle, minPulse, maxPulse, freq
+
115 
+
116 #ifdef STRING_DATA
+
117 #undef STRING_DATA
+
118 #endif
+
119 #define STRING_DATA firmata::STRING_DATA // a string message with 14-bits per char
+
120 
+
121 #ifdef STEPPER_DATA
+
122 #undef STEPPER_DATA
+
123 #endif
+
124 #define STEPPER_DATA firmata::STEPPER_DATA // control a stepper motor
+
125 
+
126 #ifdef ONEWIRE_DATA
+
127 #undef ONEWIRE_DATA
+
128 #endif
+
129 #define ONEWIRE_DATA firmata::ONEWIRE_DATA // send an OneWire read/write/reset/select/skip/search request
+
130 
+
131 #ifdef SHIFT_DATA
+
132 #undef SHIFT_DATA
+
133 #endif
+
134 #define SHIFT_DATA firmata::SHIFT_DATA // a bitstream to/from a shift register
+
135 
+
136 #ifdef I2C_REQUEST
+
137 #undef I2C_REQUEST
+
138 #endif
+
139 #define I2C_REQUEST firmata::I2C_REQUEST // send an I2C read/write request
+
140 
+
141 #ifdef I2C_REPLY
+
142 #undef I2C_REPLY
+
143 #endif
+
144 #define I2C_REPLY firmata::I2C_REPLY // a reply to an I2C read request
+
145 
+
146 #ifdef I2C_CONFIG
+
147 #undef I2C_CONFIG
+
148 #endif
+
149 #define I2C_CONFIG firmata::I2C_CONFIG // config I2C settings such as delay times and power pins
+
150 
+
151 #ifdef REPORT_FIRMWARE
+
152 #undef REPORT_FIRMWARE
+
153 #endif
+
154 #define REPORT_FIRMWARE firmata::REPORT_FIRMWARE // report name and version of the firmware
+
155 
+
156 #ifdef EXTENDED_ANALOG
+
157 #undef EXTENDED_ANALOG
+
158 #endif
+
159 #define EXTENDED_ANALOG firmata::EXTENDED_ANALOG // analog write (PWM, Servo, etc) to any pin
+
160 
+
161 #ifdef PIN_STATE_QUERY
+
162 #undef PIN_STATE_QUERY
+
163 #endif
+
164 #define PIN_STATE_QUERY firmata::PIN_STATE_QUERY // ask for a pin's current mode and value
+
165 
+
166 #ifdef PIN_STATE_RESPONSE
+
167 #undef PIN_STATE_RESPONSE
+
168 #endif
+
169 #define PIN_STATE_RESPONSE firmata::PIN_STATE_RESPONSE // reply with pin's current mode and value
+
170 
+
171 #ifdef CAPABILITY_QUERY
+
172 #undef CAPABILITY_QUERY
+
173 #endif
+
174 #define CAPABILITY_QUERY firmata::CAPABILITY_QUERY // ask for supported modes and resolution of all pins
+
175 
+
176 #ifdef CAPABILITY_RESPONSE
+
177 #undef CAPABILITY_RESPONSE
+
178 #endif
+
179 #define CAPABILITY_RESPONSE firmata::CAPABILITY_RESPONSE // reply with supported modes and resolution
+
180 
+
181 #ifdef ANALOG_MAPPING_QUERY
+
182 #undef ANALOG_MAPPING_QUERY
+
183 #endif
+
184 #define ANALOG_MAPPING_QUERY firmata::ANALOG_MAPPING_QUERY // ask for mapping of analog to pin numbers
+
185 
+
186 #ifdef ANALOG_MAPPING_RESPONSE
+
187 #undef ANALOG_MAPPING_RESPONSE
+
188 #endif
+
189 #define ANALOG_MAPPING_RESPONSE firmata::ANALOG_MAPPING_RESPONSE // reply with mapping info
+
190 
+
191 #ifdef SAMPLING_INTERVAL
+
192 #undef SAMPLING_INTERVAL
+
193 #endif
+
194 #define SAMPLING_INTERVAL firmata::SAMPLING_INTERVAL // set the poll rate of the main loop
+
195 
+
196 #ifdef SCHEDULER_DATA
+
197 #undef SCHEDULER_DATA
+
198 #endif
+
199 #define SCHEDULER_DATA firmata::SCHEDULER_DATA // send a createtask/deletetask/addtotask/schedule/querytasks/querytask request to the scheduler
+
200 
+
201 #ifdef SYSEX_NON_REALTIME
+
202 #undef SYSEX_NON_REALTIME
+
203 #endif
+
204 #define SYSEX_NON_REALTIME firmata::SYSEX_NON_REALTIME // MIDI Reserved for non-realtime messages
+
205 
+
206 #ifdef SYSEX_REALTIME
+
207 #undef SYSEX_REALTIME
+
208 #endif
+
209 #define SYSEX_REALTIME firmata::SYSEX_REALTIME // MIDI Reserved for realtime messages
+
210 
+
211 // pin modes
+
212 
+
213 #ifdef PIN_MODE_INPUT
+
214 #undef PIN_MODE_INPUT
+
215 #endif
+
216 #define PIN_MODE_INPUT firmata::PIN_MODE_INPUT // same as INPUT defined in Arduino.h
+
217 
+
218 #ifdef PIN_MODE_OUTPUT
+
219 #undef PIN_MODE_OUTPUT
+
220 #endif
+
221 #define PIN_MODE_OUTPUT firmata::PIN_MODE_OUTPUT // same as OUTPUT defined in Arduino.h
+
222 
+
223 #ifdef PIN_MODE_ANALOG
+
224 #undef PIN_MODE_ANALOG
+
225 #endif
+
226 #define PIN_MODE_ANALOG firmata::PIN_MODE_ANALOG // analog pin in analogInput mode
+
227 
+
228 #ifdef PIN_MODE_PWM
+
229 #undef PIN_MODE_PWM
+
230 #endif
+
231 #define PIN_MODE_PWM firmata::PIN_MODE_PWM // digital pin in PWM output mode
+
232 
+
233 #ifdef PIN_MODE_SERVO
+
234 #undef PIN_MODE_SERVO
+
235 #endif
+
236 #define PIN_MODE_SERVO firmata::PIN_MODE_SERVO // digital pin in Servo output mode
+
237 
+
238 #ifdef PIN_MODE_SHIFT
+
239 #undef PIN_MODE_SHIFT
+
240 #endif
+
241 #define PIN_MODE_SHIFT firmata::PIN_MODE_SHIFT // shiftIn/shiftOut mode
+
242 
+
243 #ifdef PIN_MODE_I2C
+
244 #undef PIN_MODE_I2C
+
245 #endif
+
246 #define PIN_MODE_I2C firmata::PIN_MODE_I2C // pin included in I2C setup
+
247 
+
248 #ifdef PIN_MODE_ONEWIRE
+
249 #undef PIN_MODE_ONEWIRE
+
250 #endif
+
251 #define PIN_MODE_ONEWIRE firmata::PIN_MODE_ONEWIRE // pin configured for 1-wire
+
252 
+
253 #ifdef PIN_MODE_STEPPER
+
254 #undef PIN_MODE_STEPPER
+
255 #endif
+
256 #define PIN_MODE_STEPPER firmata::PIN_MODE_STEPPER // pin configured for stepper motor
+
257 
+
258 #ifdef PIN_MODE_ENCODER
+
259 #undef PIN_MODE_ENCODER
+
260 #endif
+
261 #define PIN_MODE_ENCODER firmata::PIN_MODE_ENCODER // pin configured for rotary encoders
+
262 
+
263 #ifdef PIN_MODE_SERIAL
+
264 #undef PIN_MODE_SERIAL
+
265 #endif
+
266 #define PIN_MODE_SERIAL firmata::PIN_MODE_SERIAL // pin configured for serial communication
+
267 
+
268 #ifdef PIN_MODE_PULLUP
+
269 #undef PIN_MODE_PULLUP
+
270 #endif
+
271 #define PIN_MODE_PULLUP firmata::PIN_MODE_PULLUP // enable internal pull-up resistor for pin
+
272 
+
273 #ifdef PIN_MODE_IGNORE
+
274 #undef PIN_MODE_IGNORE
+
275 #endif
+
276 #define PIN_MODE_IGNORE firmata::PIN_MODE_IGNORE // pin configured to be ignored by digitalWrite and capabilityResponse
+
277 
+
278 #ifdef TOTAL_PIN_MODES
+
279 #undef TOTAL_PIN_MODES
+
280 #endif
+
281 #define TOTAL_PIN_MODES firmata::TOTAL_PIN_MODES
+
282 
+
283 #endif // FirmataConstants_h
+
+ + + + diff --git a/docs/html/_firmata_marshaller_8h_source.html b/docs/html/_firmata_marshaller_8h_source.html new file mode 100644 index 00000000..e2b2b7be --- /dev/null +++ b/docs/html/_firmata_marshaller_8h_source.html @@ -0,0 +1,176 @@ + + + + + + + +Firmata firmware for Arduino: FirmataMarshaller.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Firmata firmware for Arduino +
+
Firmata is a protocol for communicating with microcontrollers from software on a host computer
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
FirmataMarshaller.h
+
+
+
1 /*
+
2  FirmataMarshaller.h
+
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 
+
14 #ifndef FirmataMarshaller_h
+
15 #define FirmataMarshaller_h
+
16 
+
17 #if defined(__cplusplus) && !defined(ARDUINO)
+
18  #include <cstddef>
+
19  #include <cstdint>
+
20 #else
+
21  #include <stddef.h>
+
22  #include <stdint.h>
+
23 #endif
+
24 
+
25 #include <Stream.h>
+
26 
+
27 namespace firmata {
+
28 
+ +
30 {
+
31  friend class FirmataClass;
+
32 
+
33  public:
+
34  /* constructors */
+ +
36 
+
37  /* public methods */
+
38  void begin(Stream &s);
+
39  void end();
+
40 
+
41  /* serial send handling */
+
42  void queryFirmwareVersion(void) const;
+
43  void queryVersion(void) const;
+
44  void reportAnalogDisable(uint8_t pin) const;
+
45  void reportAnalogEnable(uint8_t pin) const;
+
46  void reportDigitalPortDisable(uint8_t portNumber) const;
+
47  void reportDigitalPortEnable(uint8_t portNumber) const;
+
48  void sendAnalog(uint8_t pin, uint16_t value) const;
+
49  void sendAnalogMappingQuery(void) const;
+
50  void sendCapabilityQuery(void) const;
+
51  void sendDigital(uint8_t pin, uint8_t value) const;
+
52  void sendDigitalPort(uint8_t portNumber, uint16_t portData) const;
+
53  void sendFirmwareVersion(uint8_t major, uint8_t minor, size_t bytec, uint8_t *bytev) const;
+
54  void sendVersion(uint8_t major, uint8_t minor) const;
+
55  void sendPinMode(uint8_t pin, uint8_t config) const;
+
56  void sendPinStateQuery(uint8_t pin) const;
+
57  void sendString(const char *string) const;
+
58  void sendSysex(uint8_t command, size_t bytec, uint8_t *bytev) const;
+
59  void setSamplingInterval(uint16_t interval_ms) const;
+
60  void systemReset(void) const;
+
61 
+
62  private:
+
63  /* utility methods */
+
64  void reportAnalog(uint8_t pin, bool stream_enable) const;
+
65  void reportDigitalPort(uint8_t portNumber, bool stream_enable) const;
+
66  void sendExtendedAnalog(uint8_t pin, size_t bytec, uint8_t * bytev) const;
+
67  void encodeByteStream (size_t bytec, uint8_t * bytev, size_t max_bytes = 0) const;
+
68 
+
69  Stream * FirmataStream;
+
70 };
+
71 
+
72 } // namespace firmata
+
73 
+
74 #endif /* FirmataMarshaller_h */
+
75 
+
+
void reportDigitalPortEnable(uint8_t portNumber) const
Definition: FirmataMarshaller.cpp:230
+
void queryFirmwareVersion(void) const
Definition: FirmataMarshaller.cpp:165
+
void reportDigitalPortDisable(uint8_t portNumber) const
Definition: FirmataMarshaller.cpp:217
+
FirmataMarshaller()
Definition: FirmataMarshaller.cpp:129
+
void sendAnalogMappingQuery(void) const
Definition: FirmataMarshaller.cpp:262
+
void sendString(const char *string) const
Definition: FirmataMarshaller.cpp:405
+
void reportAnalogDisable(uint8_t pin) const
Definition: FirmataMarshaller.cpp:191
+
void begin(Stream &s)
Definition: FirmataMarshaller.cpp:145
+
void sendCapabilityQuery(void) const
Definition: FirmataMarshaller.cpp:273
+
void systemReset(void) const
Definition: FirmataMarshaller.cpp:426
+
void reportAnalogEnable(uint8_t pin) const
Definition: FirmataMarshaller.cpp:204
+
void sendPinStateQuery(uint8_t pin) const
Definition: FirmataMarshaller.cpp:371
+
void end()
Definition: FirmataMarshaller.cpp:153
+
void sendSysex(uint8_t command, size_t bytec, uint8_t *bytev) const
Definition: FirmataMarshaller.cpp:388
+
void sendFirmwareVersion(uint8_t major, uint8_t minor, size_t bytec, uint8_t *bytev) const
Definition: FirmataMarshaller.cpp:319
+
void sendDigital(uint8_t pin, uint8_t value) const
Definition: FirmataMarshaller.cpp:284
+
void queryVersion(void) const
Definition: FirmataMarshaller.cpp:177
+
void sendDigitalPort(uint8_t portNumber, uint16_t portData) const
Definition: FirmataMarshaller.cpp:302
+
Definition: Firmata.h:54
+
void sendVersion(uint8_t major, uint8_t minor) const
Definition: FirmataMarshaller.cpp:339
+
Definition: FirmataMarshaller.h:29
+
void sendAnalog(uint8_t pin, uint16_t value) const
Definition: FirmataMarshaller.cpp:245
+
void setSamplingInterval(uint16_t interval_ms) const
Definition: FirmataMarshaller.cpp:416
+
void sendPinMode(uint8_t pin, uint8_t config) const
Definition: FirmataMarshaller.cpp:355
+ + + + diff --git a/docs/html/_firmata_parser_8h_source.html b/docs/html/_firmata_parser_8h_source.html new file mode 100644 index 00000000..6db4f216 --- /dev/null +++ b/docs/html/_firmata_parser_8h_source.html @@ -0,0 +1,189 @@ + + + + + + + +Firmata firmware for Arduino: FirmataParser.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Firmata firmware for Arduino +
+
Firmata is a protocol for communicating with microcontrollers from software on a host computer
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
FirmataParser.h
+
+
+
1 /*
+
2  FirmataParser.h
+
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 
+
14 #ifndef FirmataParser_h
+
15 #define FirmataParser_h
+
16 
+
17 #if defined(__cplusplus) && !defined(ARDUINO)
+
18  #include <cstddef>
+
19  #include <cstdint>
+
20 #else
+
21  #include <stddef.h>
+
22  #include <stdint.h>
+
23 #endif
+
24 
+
25 namespace firmata {
+
26 
+ +
28 {
+
29  public:
+
30  /* callback function types */
+
31  typedef void (*callbackFunction)(void * context, uint8_t command, uint16_t value);
+
32  typedef void (*dataBufferOverflowCallbackFunction)(void * context);
+
33  typedef void (*stringCallbackFunction)(void * context, const char * c_str);
+
34  typedef void (*sysexCallbackFunction)(void * context, uint8_t command, size_t argc, uint8_t * argv);
+
35  typedef void (*systemCallbackFunction)(void * context);
+
36  typedef void (*versionCallbackFunction)(void * context, size_t sv_major, size_t sv_minor, const char * firmware);
+
37 
+
38  FirmataParser(uint8_t * dataBuffer = (uint8_t *)NULL, size_t dataBufferSize = 0);
+
39 
+
40  /* serial receive handling */
+
41  void parse(uint8_t value);
+
42  bool isParsingMessage(void) const;
+
43  int setDataBufferOfSize(uint8_t * dataBuffer, size_t dataBufferSize);
+
44 
+
45  /* attach & detach callback functions to messages */
+
46  void attach(uint8_t command, callbackFunction newFunction, void * context = NULL);
+
47  void attach(dataBufferOverflowCallbackFunction newFunction, void * context = NULL);
+
48  void attach(uint8_t command, stringCallbackFunction newFunction, void * context = NULL);
+
49  void attach(uint8_t command, sysexCallbackFunction newFunction, void * context = NULL);
+
50  void attach(uint8_t command, systemCallbackFunction newFunction, void * context = NULL);
+
51  void attach(uint8_t command, versionCallbackFunction newFunction, void * context = NULL);
+
52  void detach(uint8_t command);
+
53  void detach(dataBufferOverflowCallbackFunction);
+
54 
+
55  private:
+
56  /* input message handling */
+
57  bool allowBufferUpdate;
+
58  uint8_t * dataBuffer; // multi-byte data
+
59  size_t dataBufferSize;
+
60  uint8_t executeMultiByteCommand; // execute this after getting multi-byte data
+
61  uint8_t multiByteChannel; // channel data for multiByteCommands
+
62  size_t waitForData; // this flag says the next serial input will be data
+
63 
+
64  /* sysex */
+
65  bool parsingSysex;
+
66  size_t sysexBytesRead;
+
67 
+
68  /* callback context */
+
69  void * currentAnalogCallbackContext;
+
70  void * currentDigitalCallbackContext;
+
71  void * currentReportAnalogCallbackContext;
+
72  void * currentReportDigitalCallbackContext;
+
73  void * currentPinModeCallbackContext;
+
74  void * currentPinValueCallbackContext;
+
75  void * currentReportFirmwareCallbackContext;
+
76  void * currentReportVersionCallbackContext;
+
77  void * currentDataBufferOverflowCallbackContext;
+
78  void * currentStringCallbackContext;
+
79  void * currentSysexCallbackContext;
+
80  void * currentSystemResetCallbackContext;
+
81 
+
82  /* callback functions */
+
83  callbackFunction currentAnalogCallback;
+
84  callbackFunction currentDigitalCallback;
+
85  callbackFunction currentReportAnalogCallback;
+
86  callbackFunction currentReportDigitalCallback;
+
87  callbackFunction currentPinModeCallback;
+
88  callbackFunction currentPinValueCallback;
+
89  dataBufferOverflowCallbackFunction currentDataBufferOverflowCallback;
+
90  stringCallbackFunction currentStringCallback;
+
91  sysexCallbackFunction currentSysexCallback;
+
92  versionCallbackFunction currentReportFirmwareCallback;
+
93  systemCallbackFunction currentReportVersionCallback;
+
94  systemCallbackFunction currentSystemResetCallback;
+
95 
+
96  /* private methods ------------------------------ */
+
97  bool bufferDataAtPosition(const uint8_t data, const size_t pos);
+
98  size_t decodeByteStream(size_t bytec, uint8_t * bytev);
+
99  void processSysexMessage(void);
+
100  void systemReset(void);
+
101 };
+
102 
+
103 } // firmata
+
104 
+
105 #endif /* FirmataParser_h */
+
+
bool isParsingMessage(void) const
Definition: FirmataParser.cpp:176
+
FirmataParser(uint8_t *dataBuffer=(uint8_t *) NULL, size_t dataBufferSize=0)
Definition: FirmataParser.cpp:33
+
Definition: FirmataParser.h:27
+
void attach(uint8_t command, callbackFunction newFunction, void *context=NULL)
Definition: FirmataParser.cpp:216
+
void detach(uint8_t command)
Definition: FirmataParser.cpp:337
+
int setDataBufferOfSize(uint8_t *dataBuffer, size_t dataBufferSize)
Definition: FirmataParser.cpp:189
+
void parse(uint8_t value)
Definition: FirmataParser.cpp:81
+ + + + diff --git a/docs/html/annotated.html b/docs/html/annotated.html new file mode 100644 index 00000000..5a2b37a1 --- /dev/null +++ b/docs/html/annotated.html @@ -0,0 +1,85 @@ + + + + + + + +Firmata firmware for Arduino: Class List + + + + + + + + + +
+
+ + + + + + +
+
Firmata firmware for Arduino +
+
Firmata is a protocol for communicating with microcontrollers from software on a host computer
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Class List
+
+
+
Here are the classes, structs, unions and interfaces with brief descriptions:
+
[detail level 12]
+ + + + +
 Nfirmata
 CFirmataClass
 CFirmataMarshaller
 CFirmataParser
+
+
+ + + + diff --git a/docs/html/bc_s.png b/docs/html/bc_s.png new file mode 100644 index 0000000000000000000000000000000000000000..224b29aa9847d5a4b3902efd602b7ddf7d33e6c2 GIT binary patch literal 676 zcmV;V0$crwP)y__>=_9%My z{n931IS})GlGUF8K#6VIbs%684A^L3@%PlP2>_sk`UWPq@f;rU*V%rPy_ekbhXT&s z(GN{DxFv}*vZp`F>S!r||M`I*nOwwKX+BC~3P5N3-)Y{65c;ywYiAh-1*hZcToLHK ztpl1xomJ+Yb}K(cfbJr2=GNOnT!UFA7Vy~fBz8?J>XHsbZoDad^8PxfSa0GDgENZS zuLCEqzb*xWX2CG*b&5IiO#NzrW*;`VC9455M`o1NBh+(k8~`XCEEoC1Ybwf;vr4K3 zg|EB<07?SOqHp9DhLpS&bzgo70I+ghB_#)K7H%AMU3v}xuyQq9&Bm~++VYhF09a+U zl7>n7Jjm$K#b*FONz~fj;I->Bf;ule1prFN9FovcDGBkpg>)O*-}eLnC{6oZHZ$o% zXKW$;0_{8hxHQ>l;_*HATI(`7t#^{$(zLe}h*mqwOc*nRY9=?Sx4OOeVIfI|0V(V2 zBrW#G7Ss9wvzr@>H*`r>zE z+e8bOBgqIgldUJlG(YUDviMB`9+DH8n-s9SXRLyJHO1!=wY^79WYZMTa(wiZ!zP66 zA~!21vmF3H2{ngD;+`6j#~6j;$*f*G_2ZD1E;9(yaw7d-QnSCpK(cR1zU3qU0000< KMNUMnLSTYoA~SLT literal 0 HcmV?d00001 diff --git a/docs/html/bdwn.png b/docs/html/bdwn.png new file mode 100644 index 0000000000000000000000000000000000000000..940a0b950443a0bb1b216ac03c45b8a16c955452 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)H!3HEvS)PKZC{Gv1kP61Pb5HX&C2wk~_T + + + + + + +Firmata firmware for Arduino: Class Index + + + + + + + + + +
+
+ + + + + + +
+
Firmata firmware for Arduino +
+
Firmata is a protocol for communicating with microcontrollers from software on a host computer
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Class Index
+
+
+ + + + + + + + + + +
  f  
+
FirmataMarshaller (firmata)   FirmataParser (firmata)   
FirmataClass (firmata)   
+ +
+ + + + diff --git a/docs/html/classfirmata_1_1_firmata_class-members.html b/docs/html/classfirmata_1_1_firmata_class-members.html new file mode 100644 index 00000000..5663db31 --- /dev/null +++ b/docs/html/classfirmata_1_1_firmata_class-members.html @@ -0,0 +1,121 @@ + + + + + + + +Firmata firmware for Arduino: Member List + + + + + + + + + +
+
+ + + + + + +
+
Firmata firmware for Arduino +
+
Firmata is a protocol for communicating with microcontrollers from software on a host computer
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
firmata::FirmataClass Member List
+
+
+ +

This is the complete list of members for firmata::FirmataClass, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
attach(uint8_t command, callbackFunction newFunction) (defined in firmata::FirmataClass)firmata::FirmataClass
attach(uint8_t command, systemCallbackFunction newFunction)firmata::FirmataClass
attach(uint8_t command, stringCallbackFunction newFunction)firmata::FirmataClass
attach(uint8_t command, sysexCallbackFunction newFunction)firmata::FirmataClass
available(void)firmata::FirmataClass
begin()firmata::FirmataClass
begin(long)firmata::FirmataClass
begin(Stream &s)firmata::FirmataClass
blinkVersion(void)firmata::FirmataClass
callbackFunction typedef (defined in firmata::FirmataClass)firmata::FirmataClass
detach(uint8_t command)firmata::FirmataClass
disableBlinkVersion()firmata::FirmataClass
endSysex(void)firmata::FirmataClass
FirmataClass()firmata::FirmataClass
FirmataMarshaller::encodeByteStream (defined in firmata::FirmataClass)firmata::FirmataClassfriend
getPinMode(byte pin)firmata::FirmataClass
getPinState(byte pin)firmata::FirmataClass
isParsingMessage(void)firmata::FirmataClass
parse(unsigned char value)firmata::FirmataClass
printFirmwareVersion(void)firmata::FirmataClass
printVersion(void)firmata::FirmataClass
processInput(void)firmata::FirmataClass
sendAnalog(byte pin, int value)firmata::FirmataClass
sendDigital(byte pin, int value) (defined in firmata::FirmataClass)firmata::FirmataClass
sendDigitalPort(byte portNumber, int portData)firmata::FirmataClass
sendString(const char *string)firmata::FirmataClass
sendString(byte command, const char *string)firmata::FirmataClass
sendSysex(byte command, byte bytec, byte *bytev)firmata::FirmataClass
sendValueAsTwo7bitBytes(int value)firmata::FirmataClass
setFirmwareNameAndVersion(const char *name, byte major, byte minor)firmata::FirmataClass
setPinMode(byte pin, byte config)firmata::FirmataClass
setPinState(byte pin, int state)firmata::FirmataClass
startSysex(void)firmata::FirmataClass
stringCallbackFunction typedef (defined in firmata::FirmataClass)firmata::FirmataClass
sysexCallbackFunction typedef (defined in firmata::FirmataClass)firmata::FirmataClass
systemCallbackFunction typedef (defined in firmata::FirmataClass)firmata::FirmataClass
write(byte c)firmata::FirmataClass
+ + + + diff --git a/docs/html/classfirmata_1_1_firmata_class.html b/docs/html/classfirmata_1_1_firmata_class.html new file mode 100644 index 00000000..6d0a5a55 --- /dev/null +++ b/docs/html/classfirmata_1_1_firmata_class.html @@ -0,0 +1,972 @@ + + + + + + + +Firmata firmware for Arduino: firmata::FirmataClass Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Firmata firmware for Arduino +
+
Firmata is a protocol for communicating with microcontrollers from software on a host computer
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
firmata::FirmataClass Class Reference
+
+
+ + + + + + + + + + +

+Public Types

+typedef void(* callbackFunction) (uint8_t, int)
 
+typedef void(* systemCallbackFunction) (void)
 
+typedef void(* stringCallbackFunction) (char *)
 
+typedef void(* sysexCallbackFunction) (uint8_t command, uint8_t argc, uint8_t *argv)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 FirmataClass ()
 
void begin ()
 
void begin (long)
 
void begin (Stream &s)
 
void printVersion (void)
 
void blinkVersion (void)
 
void printFirmwareVersion (void)
 
void setFirmwareNameAndVersion (const char *name, byte major, byte minor)
 
void disableBlinkVersion ()
 
int available (void)
 
void processInput (void)
 
void parse (unsigned char value)
 
boolean isParsingMessage (void)
 
void sendAnalog (byte pin, int value)
 
+void sendDigital (byte pin, int value)
 
void sendDigitalPort (byte portNumber, int portData)
 
void sendString (const char *string)
 
void sendString (byte command, const char *string)
 
void sendSysex (byte command, byte bytec, byte *bytev)
 
void write (byte c)
 
+void attach (uint8_t command, callbackFunction newFunction)
 
void attach (uint8_t command, systemCallbackFunction newFunction)
 
void attach (uint8_t command, stringCallbackFunction newFunction)
 
void attach (uint8_t command, sysexCallbackFunction newFunction)
 
void detach (uint8_t command)
 
byte getPinMode (byte pin)
 
void setPinMode (byte pin, byte config)
 
int getPinState (byte pin)
 
void setPinState (byte pin, int state)
 
void sendValueAsTwo7bitBytes (int value)
 
void startSysex (void)
 
void endSysex (void)
 
+ + + +

+Friends

+void FirmataMarshaller::encodeByteStream (size_t bytec, uint8_t *bytev, size_t max_bytes=0) const
 
+

Constructor & Destructor Documentation

+ +

◆ FirmataClass()

+ +
+
+ + + + + + + +
FirmataClass::FirmataClass ()
+
+

The Firmata class. An instance named "Firmata" is created automatically for the user.

+ +
+
+

Member Function Documentation

+ +

◆ attach() [1/3]

+ +
+
+ + + + + + + + + + + + + + + + + + +
void FirmataClass::attach (uint8_t command,
stringCallbackFunction newFunction 
)
+
+

Attach a callback function for the STRING_DATA command.

Parameters
+ + + +
commandMust be set to STRING_DATA or it will be ignored.
newFunctionA reference to the string callback function to attach.
+
+
+ +
+
+ +

◆ attach() [2/3]

+ +
+
+ + + + + + + + + + + + + + + + + + +
void FirmataClass::attach (uint8_t command,
sysexCallbackFunction newFunction 
)
+
+

Attach a generic sysex callback function to sysex command.

Parameters
+ + + +
commandThe ID of the command to attach a callback function to.
newFunctionA reference to the sysex callback function to attach.
+
+
+ +
+
+ +

◆ attach() [3/3]

+ +
+
+ + + + + + + + + + + + + + + + + + +
void FirmataClass::attach (uint8_t command,
systemCallbackFunction newFunction 
)
+
+

Attach a callback function for the SYSTEM_RESET command.

Parameters
+ + + +
commandMust be set to SYSTEM_RESET or it will be ignored.
newFunctionA reference to the system reset callback function to attach.
+
+
+ +
+
+ +

◆ available()

+ +
+
+ + + + + + + + +
int FirmataClass::available (void )
+
+

A wrapper for Stream::available()

Returns
The number of bytes remaining in the input stream buffer.
+ +
+
+ +

◆ begin() [1/3]

+ +
+
+ + + + + + + + +
void FirmataClass::begin (void )
+
+

Initialize the default Serial transport at the default baud of 57600.

+ +
+
+ +

◆ begin() [2/3]

+ +
+
+ + + + + + + + +
void FirmataClass::begin (long speed)
+
+

Initialize the default Serial transport and override the default baud. Sends the protocol version to the host application followed by the firmware version and name. blinkVersion is also called. To skip the call to blinkVersion, call Firmata.disableBlinkVersion() before calling Firmata.begin(baud).

Parameters
+ + +
speedThe baud to use. 57600 baud is the default value.
+
+
+ +
+
+ +

◆ begin() [3/3]

+ +
+
+ + + + + + + + +
void FirmataClass::begin (Stream & s)
+
+

Reassign the Firmata stream transport.

Parameters
+ + +
sA reference to the Stream transport object. This can be any type of transport that implements the Stream interface. Some examples include Ethernet, WiFi and other UARTs on the board (Serial1, Serial2, etc).
+
+
+ +
+
+ +

◆ blinkVersion()

+ +
+
+ + + + + + + + +
void FirmataClass::blinkVersion (void )
+
+

Blink the Firmata protocol version to the onboard LEDs (if the board has an onboard LED). If VERSION_BLINK_PIN is not defined in Boards.h for a particular board, then this method does nothing. The first series of flashes indicates the firmware major version (2 flashes = 2). The second series of flashes indicates the firmware minor version (5 flashes = 5).

+ +
+
+ +

◆ detach()

+ +
+
+ + + + + + + + +
void FirmataClass::detach (uint8_t command)
+
+

Detach a callback function for a specified command (such as SYSTEM_RESET, STRING_DATA, ANALOG_MESSAGE, DIGITAL_MESSAGE, etc).

Parameters
+ + +
commandThe ID of the command to detatch the callback function from.
+
+
+ +
+
+ +

◆ disableBlinkVersion()

+ +
+
+ + + + + + + +
void FirmataClass::disableBlinkVersion ()
+
+

Provides a means to disable the version blink sequence on the onboard LED, trimming startup time by a couple of seconds. Call this before Firmata.begin(). It only applies when using the default Serial transport.

+ +
+
+ +

◆ endSysex()

+ +
+
+ + + + + + + + +
void FirmataClass::endSysex (void )
+
+

A helper method to write the end of a Sysex message transmission.

+ +
+
+ +

◆ getPinMode()

+ +
+
+ + + + + + + + +
byte FirmataClass::getPinMode (byte pin)
+
+
Parameters
+ + +
pinThe pin to get the configuration of.
+
+
+
Returns
The configuration of the specified pin.
+ +
+
+ +

◆ getPinState()

+ +
+
+ + + + + + + + +
int FirmataClass::getPinState (byte pin)
+
+
Parameters
+ + +
pinThe pin to get the state of.
+
+
+
Returns
The state of the specified pin.
+ +
+
+ +

◆ isParsingMessage()

+ +
+
+ + + + + + + + +
boolean FirmataClass::isParsingMessage (void )
+
+
Returns
Returns true if the parser is actively parsing data.
+ +
+
+ +

◆ parse()

+ +
+
+ + + + + + + + +
void FirmataClass::parse (unsigned char value)
+
+

Parse data from the input stream.

Parameters
+ + +
inputDataA single byte to be added to the parser.
+
+
+ +
+
+ +

◆ printFirmwareVersion()

+ +
+
+ + + + + + + + +
void FirmataClass::printFirmwareVersion (void )
+
+

Sends the firmware name and version to the Firmata host application. The major and minor version numbers are the first 2 bytes in the message. The following bytes are the characters of the firmware name.

+ +
+
+ +

◆ printVersion()

+ +
+
+ + + + + + + + +
void FirmataClass::printVersion (void )
+
+

Send the Firmata protocol version to the Firmata host application.

+ +
+
+ +

◆ processInput()

+ +
+
+ + + + + + + + +
void FirmataClass::processInput (void )
+
+

Read a single int from the input stream. If the value is not = -1, pass it on to parse(byte)

+ +
+
+ +

◆ sendAnalog()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void FirmataClass::sendAnalog (byte pin,
int value 
)
+
+

Send an analog message to the Firmata host application. The range of pins is limited to [0..15] when using the ANALOG_MESSAGE. The maximum value of the ANALOG_MESSAGE is limited to 14 bits (16384). To increase the pin range or value, see the documentation for the EXTENDED_ANALOG message.

Parameters
+ + + +
pinThe analog pin to send the value of (limited to pins 0 - 15).
valueThe value of the analog pin (0 - 1024 for 10-bit analog, 0 - 4096 for 12-bit, etc). The maximum value is 14-bits (16384).
+
+
+ +
+
+ +

◆ sendDigitalPort()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void FirmataClass::sendDigitalPort (byte portNumber,
int portData 
)
+
+

Send an 8-bit port in a single digital message (protocol v2 and later). Send 14-bits in a single digital message (protocol v1).

Parameters
+ + + +
portNumberThe port number to send. Note that this is not the same as a "port" on the physical microcontroller. Ports are defined in order per every 8 pins in ascending order of the Arduino digital pin numbering scheme. Port 0 = pins D0 - D7, port 1 = pins D8 - D15, etc.
portDataThe value of the port. The value of each pin in the port is represented by a bit.
+
+
+ +
+
+ +

◆ sendString() [1/2]

+ +
+
+ + + + + + + + + + + + + + + + + + +
void FirmataClass::sendString (byte command,
const char * string 
)
+
+

Send a string to the Firmata host application.

Parameters
+ + + +
commandMust be STRING_DATA
stringA pointer to the char string
+
+
+ +
+
+ +

◆ sendString() [2/2]

+ +
+
+ + + + + + + + +
void FirmataClass::sendString (const char * string)
+
+

Send a string to the Firmata host application.

Parameters
+ + +
stringA pointer to the char string
+
+
+ +
+
+ +

◆ sendSysex()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FirmataClass::sendSysex (byte command,
byte bytec,
byte * bytev 
)
+
+

Send a sysex message where all values after the command byte are packet as 2 7-bit bytes (this is not always the case so this function is not always used to send sysex messages).

Parameters
+ + + + +
commandThe sysex command byte.
bytecThe number of data bytes in the message (excludes start, command and end bytes).
bytevA pointer to the array of data bytes to send in the message.
+
+
+ +
+
+ +

◆ sendValueAsTwo7bitBytes()

+ +
+
+ + + + + + + + +
void FirmataClass::sendValueAsTwo7bitBytes (int value)
+
+

Split a 16-bit byte into two 7-bit values and write each value.

Parameters
+ + +
valueThe 16-bit value to be split and written separately.
+
+
+ +
+
+ +

◆ setFirmwareNameAndVersion()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FirmataClass::setFirmwareNameAndVersion (const char * name,
byte major,
byte minor 
)
+
+

Sets the name and version of the firmware. This is not the same version as the Firmata protocol (although at times the firmware version and protocol version may be the same number).

Parameters
+ + + + +
nameA pointer to the name char array
majorThe major version number
minorThe minor version number
+
+
+ +
+
+ +

◆ setPinMode()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void FirmataClass::setPinMode (byte pin,
byte config 
)
+
+

Set the pin mode/configuration. The pin configuration (or mode) in Firmata represents the current function of the pin. Examples are digital input or output, analog input, pwm, i2c, serial (uart), etc.

Parameters
+ + + +
pinThe pin to configure.
configThe configuration value for the specified pin.
+
+
+ +
+
+ +

◆ setPinState()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void FirmataClass::setPinState (byte pin,
int state 
)
+
+

Set the pin state. The pin state of an output pin is the pin value. The state of an input pin is 0, unless the pin has it's internal pull up resistor enabled, then the value is 1.

Parameters
+ + + +
pinThe pin to set the state of
stateSet the state of the specified pin
+
+
+ +
+
+ +

◆ startSysex()

+ +
+
+ + + + + + + + +
void FirmataClass::startSysex (void )
+
+

A helper method to write the beginning of a Sysex message transmission.

+ +
+
+ +

◆ write()

+ +
+
+ + + + + + + + +
void FirmataClass::write (byte c)
+
+

A wrapper for Stream::available(). Write a single byte to the output stream.

Parameters
+ + +
cThe byte to be written.
+
+
+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/docs/html/classfirmata_1_1_firmata_marshaller-members.html b/docs/html/classfirmata_1_1_firmata_marshaller-members.html new file mode 100644 index 00000000..7ffe8cae --- /dev/null +++ b/docs/html/classfirmata_1_1_firmata_marshaller-members.html @@ -0,0 +1,107 @@ + + + + + + + +Firmata firmware for Arduino: Member List + + + + + + + + + +
+
+ + + + + + +
+
Firmata firmware for Arduino +
+
Firmata is a protocol for communicating with microcontrollers from software on a host computer
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
firmata::FirmataMarshaller Member List
+
+
+ +

This is the complete list of members for firmata::FirmataMarshaller, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + +
begin(Stream &s)firmata::FirmataMarshaller
end()firmata::FirmataMarshaller
FirmataClass (defined in firmata::FirmataMarshaller)firmata::FirmataMarshallerfriend
FirmataMarshaller()firmata::FirmataMarshaller
queryFirmwareVersion(void) constfirmata::FirmataMarshaller
queryVersion(void) constfirmata::FirmataMarshaller
reportAnalogDisable(uint8_t pin) constfirmata::FirmataMarshaller
reportAnalogEnable(uint8_t pin) constfirmata::FirmataMarshaller
reportDigitalPortDisable(uint8_t portNumber) constfirmata::FirmataMarshaller
reportDigitalPortEnable(uint8_t portNumber) constfirmata::FirmataMarshaller
sendAnalog(uint8_t pin, uint16_t value) constfirmata::FirmataMarshaller
sendAnalogMappingQuery(void) constfirmata::FirmataMarshaller
sendCapabilityQuery(void) constfirmata::FirmataMarshaller
sendDigital(uint8_t pin, uint8_t value) constfirmata::FirmataMarshaller
sendDigitalPort(uint8_t portNumber, uint16_t portData) constfirmata::FirmataMarshaller
sendFirmwareVersion(uint8_t major, uint8_t minor, size_t bytec, uint8_t *bytev) constfirmata::FirmataMarshaller
sendPinMode(uint8_t pin, uint8_t config) constfirmata::FirmataMarshaller
sendPinStateQuery(uint8_t pin) constfirmata::FirmataMarshaller
sendString(const char *string) constfirmata::FirmataMarshaller
sendSysex(uint8_t command, size_t bytec, uint8_t *bytev) constfirmata::FirmataMarshaller
sendVersion(uint8_t major, uint8_t minor) constfirmata::FirmataMarshaller
setSamplingInterval(uint16_t interval_ms) constfirmata::FirmataMarshaller
systemReset(void) constfirmata::FirmataMarshaller
+ + + + diff --git a/docs/html/classfirmata_1_1_firmata_marshaller.html b/docs/html/classfirmata_1_1_firmata_marshaller.html new file mode 100644 index 00000000..7eb6ec8e --- /dev/null +++ b/docs/html/classfirmata_1_1_firmata_marshaller.html @@ -0,0 +1,738 @@ + + + + + + + +Firmata firmware for Arduino: firmata::FirmataMarshaller Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Firmata firmware for Arduino +
+
Firmata is a protocol for communicating with microcontrollers from software on a host computer
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
firmata::FirmataMarshaller Class Reference
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 FirmataMarshaller ()
 
void begin (Stream &s)
 
void end ()
 
void queryFirmwareVersion (void) const
 
void queryVersion (void) const
 
void reportAnalogDisable (uint8_t pin) const
 
void reportAnalogEnable (uint8_t pin) const
 
void reportDigitalPortDisable (uint8_t portNumber) const
 
void reportDigitalPortEnable (uint8_t portNumber) const
 
void sendAnalog (uint8_t pin, uint16_t value) const
 
void sendAnalogMappingQuery (void) const
 
void sendCapabilityQuery (void) const
 
void sendDigital (uint8_t pin, uint8_t value) const
 
void sendDigitalPort (uint8_t portNumber, uint16_t portData) const
 
void sendFirmwareVersion (uint8_t major, uint8_t minor, size_t bytec, uint8_t *bytev) const
 
void sendVersion (uint8_t major, uint8_t minor) const
 
void sendPinMode (uint8_t pin, uint8_t config) const
 
void sendPinStateQuery (uint8_t pin) const
 
void sendString (const char *string) const
 
void sendSysex (uint8_t command, size_t bytec, uint8_t *bytev) const
 
void setSamplingInterval (uint16_t interval_ms) const
 
void systemReset (void) const
 
+ + + +

+Friends

+class FirmataClass
 
+

Constructor & Destructor Documentation

+ +

◆ FirmataMarshaller()

+ +
+
+ + + + + + + +
FirmataMarshaller::FirmataMarshaller ()
+
+

The FirmataMarshaller class.

+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void FirmataMarshaller::begin (Stream & s)
+
+

Reassign the Firmata stream transport.

Parameters
+ + +
sA reference to the Stream transport object. This can be any type of transport that implements the Stream interface. Some examples include Ethernet, WiFi and other UARTs on the board (Serial1, Serial2, etc).
+
+
+ +
+
+ +

◆ end()

+ +
+
+ + + + + + + + +
void FirmataMarshaller::end (void )
+
+

Closes the FirmataMarshaller stream by setting its stream reference to (Stream *)NULL

+ +
+
+ +

◆ queryFirmwareVersion()

+ +
+
+ + + + + + + + +
void FirmataMarshaller::queryFirmwareVersion (void ) const
+
+

Query the target's firmware name and version

+ +
+
+ +

◆ queryVersion()

+ +
+
+ + + + + + + + +
void FirmataMarshaller::queryVersion (void ) const
+
+

Query the target's Firmata protocol version

+ +
+
+ +

◆ reportAnalogDisable()

+ +
+
+ + + + + + + + +
void FirmataMarshaller::reportAnalogDisable (uint8_t pin) const
+
+

Halt the stream of analog readings from the Firmata host application. The range of pins is limited to [0..15] when using the REPORT_ANALOG. The maximum result of the REPORT_ANALOG is limited to 14 bits (16384). To increase the pin range or value, see the documentation for the EXTENDED_ANALOG message.

Parameters
+ + +
pinThe analog pin for which to request the value (limited to pins 0 - 15).
+
+
+ +
+
+ +

◆ reportAnalogEnable()

+ +
+
+ + + + + + + + +
void FirmataMarshaller::reportAnalogEnable (uint8_t pin) const
+
+

Request a stream of analog readings from the Firmata host application. The range of pins is limited to [0..15] when using the REPORT_ANALOG. The maximum result of the REPORT_ANALOG is limited to 14 bits (16384). To increase the pin range or value, see the documentation for the EXTENDED_ANALOG message.

Parameters
+ + +
pinThe analog pin for which to request the value (limited to pins 0 - 15).
+
+
+ +
+
+ +

◆ reportDigitalPortDisable()

+ +
+
+ + + + + + + + +
void FirmataMarshaller::reportDigitalPortDisable (uint8_t portNumber) const
+
+

Halt an 8-bit port stream from the Firmata host application (protocol v2 and later). Send 14-bits in a single digital message (protocol v1).

Parameters
+ + +
portNumberThe port number for which to request the value. Note that this is not the same as a "port" on the physical microcontroller. Ports are defined in order per every 8 pins in ascending order of the Arduino digital pin numbering scheme. Port 0 = pins D0 - D7, port 1 = pins D8 - D15, etc.
+
+
+ +
+
+ +

◆ reportDigitalPortEnable()

+ +
+
+ + + + + + + + +
void FirmataMarshaller::reportDigitalPortEnable (uint8_t portNumber) const
+
+

Request an 8-bit port stream from the Firmata host application (protocol v2 and later). Send 14-bits in a single digital message (protocol v1).

Parameters
+ + +
portNumberThe port number for which to request the value. Note that this is not the same as a "port" on the physical microcontroller. Ports are defined in order per every 8 pins in ascending order of the Arduino digital pin numbering scheme. Port 0 = pins D0 - D7, port 1 = pins D8 - D15, etc.
+
+
+ +
+
+ +

◆ sendAnalog()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void FirmataMarshaller::sendAnalog (uint8_t pin,
uint16_t value 
) const
+
+

Send an analog message to the Firmata host application. The range of pins is limited to [0..15] when using the ANALOG_MESSAGE. The maximum value of the ANALOG_MESSAGE is limited to 14 bits (16384). To increase the pin range or value, see the documentation for the EXTENDED_ANALOG message.

Parameters
+ + + +
pinThe analog pin to which the value is sent.
valueThe value of the analog pin (0 - 1024 for 10-bit analog, 0 - 4096 for 12-bit, etc).
+
+
+
Note
The maximum value is 14-bits (16384).
+ +
+
+ +

◆ sendAnalogMappingQuery()

+ +
+
+ + + + + + + + +
void FirmataMarshaller::sendAnalogMappingQuery (void ) const
+
+

Send an analog mapping query to the Firmata host application. The resulting sysex message will have an ANALOG_MAPPING_RESPONSE command byte, followed by a list of pins [0-n]; where each pin will specify its corresponding analog pin number or 0x7F (127) if not applicable.

+ +
+
+ +

◆ sendCapabilityQuery()

+ +
+
+ + + + + + + + +
void FirmataMarshaller::sendCapabilityQuery (void ) const
+
+

Send a capability query to the Firmata host application. The resulting sysex message will have a CAPABILITY_RESPONSE command byte, followed by a list of byte tuples (mode and mode resolution) for each pin; where each pin list is terminated by 0x7F (127).

+ +
+
+ +

◆ sendDigital()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void FirmataMarshaller::sendDigital (uint8_t pin,
uint8_t value 
) const
+
+

Send a single digital pin value to the Firmata host application.

Parameters
+ + + +
pinThe digital pin to send the value of.
valueThe value of the pin.
+
+
+ +
+
+ +

◆ sendDigitalPort()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void FirmataMarshaller::sendDigitalPort (uint8_t portNumber,
uint16_t portData 
) const
+
+

Send an 8-bit port in a single digital message (protocol v2 and later). Send 14-bits in a single digital message (protocol v1).

Parameters
+ + + +
portNumberThe port number to send. Note that this is not the same as a "port" on the physical microcontroller. Ports are defined in order per every 8 pins in ascending order of the Arduino digital pin numbering scheme. Port 0 = pins D0 - D7, port 1 = pins D8 - D15, etc.
portDataThe value of the port. The value of each pin in the port is represented by a bit.
+
+
+ +
+
+ +

◆ sendFirmwareVersion()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void FirmataMarshaller::sendFirmwareVersion (uint8_t major,
uint8_t minor,
size_t bytec,
uint8_t * bytev 
) const
+
+

Sends the firmware name and version to the Firmata host application.

Parameters
+ + + + + +
majorThe major verison number
minorThe minor version number
bytecThe length of the firmware name
bytevThe firmware name array
+
+
+ +
+
+ +

◆ sendPinMode()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void FirmataMarshaller::sendPinMode (uint8_t pin,
uint8_t config 
) const
+
+

Send the pin mode/configuration. The pin configuration (or mode) in Firmata represents the current function of the pin. Examples are digital input or output, analog input, pwm, i2c, serial (uart), etc.

Parameters
+ + + +
pinThe pin to configure.
configThe configuration value for the specified pin.
+
+
+ +
+
+ +

◆ sendPinStateQuery()

+ +
+
+ + + + + + + + +
void FirmataMarshaller::sendPinStateQuery (uint8_t pin) const
+
+

Send a pin state query to the Firmata host application. The resulting sysex message will have a PIN_STATE_RESPONSE command byte, followed by the pin number, the pin mode and a stream of bits to indicate any data written to the pin (pin state).

Parameters
+ + +
pinThe pin to query
+
+
+
Note
The pin state is any data written to the pin (i.e. pin state != pin value)
+ +
+
+ +

◆ sendString()

+ +
+
+ + + + + + + + +
void FirmataMarshaller::sendString (const char * string) const
+
+

Send a string to the Firmata host application.

Parameters
+ + +
stringA pointer to the char string
+
+
+ +
+
+ +

◆ sendSysex()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FirmataMarshaller::sendSysex (uint8_t command,
size_t bytec,
uint8_t * bytev 
) const
+
+

Send a sysex message where all values after the command byte are packet as 2 7-bit bytes (this is not always the case so this function is not always used to send sysex messages).

Parameters
+ + + + +
commandThe sysex command byte.
bytecThe number of data bytes in the message (excludes start, command and end bytes).
bytevA pointer to the array of data bytes to send in the message.
+
+
+ +
+
+ +

◆ sendVersion()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void FirmataMarshaller::sendVersion (uint8_t major,
uint8_t minor 
) const
+
+

Send the Firmata protocol version to the Firmata host application.

Parameters
+ + + +
majorThe major verison number
minorThe minor version number
+
+
+ +
+
+ +

◆ setSamplingInterval()

+ +
+
+ + + + + + + + +
void FirmataMarshaller::setSamplingInterval (uint16_t interval_ms) const
+
+

The sampling interval sets how often analog data and i2c data is reported to the client.

Parameters
+ + +
interval_msThe interval (in milliseconds) at which to sample
+
+
+
Note
The default sampling interval is 19ms
+ +
+
+ +

◆ systemReset()

+ +
+
+ + + + + + + + +
void FirmataMarshaller::systemReset (void ) const
+
+

Perform a software reset on the target. For example, StandardFirmata.ino will initialize everything to a known state and reset the parsing buffer.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/docs/html/classfirmata_1_1_firmata_parser-members.html b/docs/html/classfirmata_1_1_firmata_parser-members.html new file mode 100644 index 00000000..52385b64 --- /dev/null +++ b/docs/html/classfirmata_1_1_firmata_parser-members.html @@ -0,0 +1,102 @@ + + + + + + + +Firmata firmware for Arduino: Member List + + + + + + + + + +
+
+ + + + + + +
+
Firmata firmware for Arduino +
+
Firmata is a protocol for communicating with microcontrollers from software on a host computer
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
firmata::FirmataParser Member List
+
+
+ +

This is the complete list of members for firmata::FirmataParser, including all inherited members.

+ + + + + + + + + + + + + + + + + + + +
attach(uint8_t command, callbackFunction newFunction, void *context=NULL)firmata::FirmataParser
attach(dataBufferOverflowCallbackFunction newFunction, void *context=NULL)firmata::FirmataParser
attach(uint8_t command, stringCallbackFunction newFunction, void *context=NULL)firmata::FirmataParser
attach(uint8_t command, sysexCallbackFunction newFunction, void *context=NULL)firmata::FirmataParser
attach(uint8_t command, systemCallbackFunction newFunction, void *context=NULL)firmata::FirmataParser
attach(uint8_t command, versionCallbackFunction newFunction, void *context=NULL)firmata::FirmataParser
callbackFunction typedef (defined in firmata::FirmataParser)firmata::FirmataParser
dataBufferOverflowCallbackFunction typedef (defined in firmata::FirmataParser)firmata::FirmataParser
detach(uint8_t command)firmata::FirmataParser
detach(dataBufferOverflowCallbackFunction)firmata::FirmataParser
FirmataParser(uint8_t *dataBuffer=(uint8_t *) NULL, size_t dataBufferSize=0)firmata::FirmataParser
isParsingMessage(void) constfirmata::FirmataParser
parse(uint8_t value)firmata::FirmataParser
setDataBufferOfSize(uint8_t *dataBuffer, size_t dataBufferSize)firmata::FirmataParser
stringCallbackFunction typedef (defined in firmata::FirmataParser)firmata::FirmataParser
sysexCallbackFunction typedef (defined in firmata::FirmataParser)firmata::FirmataParser
systemCallbackFunction typedef (defined in firmata::FirmataParser)firmata::FirmataParser
versionCallbackFunction typedef (defined in firmata::FirmataParser)firmata::FirmataParser
+ + + + diff --git a/docs/html/classfirmata_1_1_firmata_parser.html b/docs/html/classfirmata_1_1_firmata_parser.html new file mode 100644 index 00000000..adcbc363 --- /dev/null +++ b/docs/html/classfirmata_1_1_firmata_parser.html @@ -0,0 +1,552 @@ + + + + + + + +Firmata firmware for Arduino: firmata::FirmataParser Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Firmata firmware for Arduino +
+
Firmata is a protocol for communicating with microcontrollers from software on a host computer
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
firmata::FirmataParser Class Reference
+
+
+ + + + + + + + + + + + + + +

+Public Types

+typedef void(* callbackFunction) (void *context, uint8_t command, uint16_t value)
 
+typedef void(* dataBufferOverflowCallbackFunction) (void *context)
 
+typedef void(* stringCallbackFunction) (void *context, const char *c_str)
 
+typedef void(* sysexCallbackFunction) (void *context, uint8_t command, size_t argc, uint8_t *argv)
 
+typedef void(* systemCallbackFunction) (void *context)
 
+typedef void(* versionCallbackFunction) (void *context, size_t sv_major, size_t sv_minor, const char *firmware)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 FirmataParser (uint8_t *dataBuffer=(uint8_t *) NULL, size_t dataBufferSize=0)
 
void parse (uint8_t value)
 
bool isParsingMessage (void) const
 
int setDataBufferOfSize (uint8_t *dataBuffer, size_t dataBufferSize)
 
void attach (uint8_t command, callbackFunction newFunction, void *context=NULL)
 
void attach (dataBufferOverflowCallbackFunction newFunction, void *context=NULL)
 
void attach (uint8_t command, stringCallbackFunction newFunction, void *context=NULL)
 
void attach (uint8_t command, sysexCallbackFunction newFunction, void *context=NULL)
 
void attach (uint8_t command, systemCallbackFunction newFunction, void *context=NULL)
 
void attach (uint8_t command, versionCallbackFunction newFunction, void *context=NULL)
 
void detach (uint8_t command)
 
void detach (dataBufferOverflowCallbackFunction)
 
+

Constructor & Destructor Documentation

+ +

◆ FirmataParser()

+ +
+
+ + + + + + + + + + + + + + + + + + +
FirmataParser::FirmataParser (uint8_t * dataBuffer = (uint8_t *)NULL,
size_t dataBufferSize = 0 
)
+
+

The FirmataParser class.

Parameters
+ + + +
dataBufferA pointer to an external buffer used to store parsed data
dataBufferSizeThe size of the external buffer
+
+
+ +
+
+

Member Function Documentation

+ +

◆ attach() [1/6]

+ +
+
+ + + + + + + + + + + + + + + + + + +
void FirmataParser::attach (dataBufferOverflowCallbackFunction newFunction,
void * context = NULL 
)
+
+

Attach a buffer overflow callback

Parameters
+ + + +
newFunctionA reference to the buffer overflow callback function to attach.
contextAn optional context to be provided to the callback function (NULL by default).
+
+
+
Note
The context parameter is provided so you can pass a parameter, by reference, to your callback function.
+ +
+
+ +

◆ attach() [2/6]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FirmataParser::attach (uint8_t command,
callbackFunction newFunction,
void * context = NULL 
)
+
+

Attach a generic sysex callback function to a command (options are: ANALOG_MESSAGE, DIGITAL_MESSAGE, REPORT_ANALOG, REPORT DIGITAL, SET_PIN_MODE and SET_DIGITAL_PIN_VALUE).

Parameters
+ + + + +
commandThe ID of the command to attach a callback function to.
newFunctionA reference to the callback function to attach.
contextAn optional context to be provided to the callback function (NULL by default).
+
+
+
Note
The context parameter is provided so you can pass a parameter, by reference, to your callback function.
+ +
+
+ +

◆ attach() [3/6]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FirmataParser::attach (uint8_t command,
stringCallbackFunction newFunction,
void * context = NULL 
)
+
+

Attach a callback function for the STRING_DATA command.

Parameters
+ + + + +
commandMust be set to STRING_DATA or it will be ignored.
newFunctionA reference to the string callback function to attach.
contextAn optional context to be provided to the callback function (NULL by default).
+
+
+
Note
The context parameter is provided so you can pass a parameter, by reference, to your callback function.
+ +
+
+ +

◆ attach() [4/6]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FirmataParser::attach (uint8_t command,
sysexCallbackFunction newFunction,
void * context = NULL 
)
+
+

Attach a generic sysex callback function to sysex command.

Parameters
+ + + + +
commandThe ID of the command to attach a callback function to.
newFunctionA reference to the sysex callback function to attach.
contextAn optional context to be provided to the callback function (NULL by default).
+
+
+
Note
The context parameter is provided so you can pass a parameter, by reference, to your callback function.
+ +
+
+ +

◆ attach() [5/6]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FirmataParser::attach (uint8_t command,
systemCallbackFunction newFunction,
void * context = NULL 
)
+
+

Attach a system callback function (supported options are: SYSTEM_RESET, REPORT_VERSION).

Parameters
+ + + + +
commandThe ID of the command to attach a callback function to.
newFunctionA reference to the callback function to attach.
contextAn optional context to be provided to the callback function (NULL by default).
+
+
+
Note
The context parameter is provided so you can pass a parameter, by reference, to your callback function.
+ +
+
+ +

◆ attach() [6/6]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FirmataParser::attach (uint8_t command,
versionCallbackFunction newFunction,
void * context = NULL 
)
+
+

Attach a version callback function (supported option: REPORT_FIRMWARE).

Parameters
+ + + + +
commandThe ID of the command to attach a callback function to.
newFunctionA reference to the callback function to attach.
contextAn optional context to be provided to the callback function (NULL by default).
+
+
+
Note
The context parameter is provided so you can pass a parameter, by reference, to your callback function.
+ +
+
+ +

◆ detach() [1/2]

+ +
+
+ + + + + + + + +
void FirmataParser::detach (dataBufferOverflowCallbackFunction )
+
+

Detach the buffer overflow callback

Parameters
+ + +
<unused>Any pointer of type dataBufferOverflowCallbackFunction.
+
+
+ +
+
+ +

◆ detach() [2/2]

+ +
+
+ + + + + + + + +
void FirmataParser::detach (uint8_t command)
+
+

Detach a callback function for a specified command (such as SYSTEM_RESET, STRING_DATA, ANALOG_MESSAGE, DIGITAL_MESSAGE, etc).

Parameters
+ + +
commandThe ID of the command to detatch the callback function from.
+
+
+ +
+
+ +

◆ isParsingMessage()

+ +
+
+ + + + + + + + +
bool FirmataParser::isParsingMessage (void ) const
+
+
Returns
Returns true if the parser is actively parsing data.
+ +
+
+ +

◆ parse()

+ +
+
+ + + + + + + + +
void FirmataParser::parse (uint8_t inputData)
+
+

Parse data from the input stream.

Parameters
+ + +
inputDataA single byte to be added to the parser.
+
+
+ +
+
+ +

◆ setDataBufferOfSize()

+ +
+
+ + + + + + + + + + + + + + + + + + +
int FirmataParser::setDataBufferOfSize (uint8_t * dataBuffer,
size_t dataBufferSize 
)
+
+

Provides a mechanism to either set or update the working buffer of the parser. The method will be enabled when no buffer has been provided, or an overflow condition exists.

Parameters
+ + + +
dataBufferA pointer to an external buffer used to store parsed data
dataBufferSizeThe size of the external buffer
+
+
+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/docs/html/closed.png b/docs/html/closed.png new file mode 100644 index 0000000000000000000000000000000000000000..98cc2c909da37a6df914fbf67780eebd99c597f5 GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1|%O$WD@{V-kvUwAr*{o@8{^CZMh(5KoB^r_<4^zF@3)Cp&&t3hdujKf f*?bjBoY!V+E))@{xMcbjXe@)LtDnm{r-UW|*e5JT literal 0 HcmV?d00001 diff --git a/docs/html/doc.png b/docs/html/doc.png new file mode 100644 index 0000000000000000000000000000000000000000..17edabff95f7b8da13c9516a04efe05493c29501 GIT binary patch literal 746 zcmV7=@pnbNXRFEm&G8P!&WHG=d)>K?YZ1bzou)2{$)) zumDct!>4SyxL;zgaG>wy`^Hv*+}0kUfCrz~BCOViSb$_*&;{TGGn2^x9K*!Sf0=lV zpP=7O;GA0*Jm*tTYj$IoXvimpnV4S1Z5f$p*f$Db2iq2zrVGQUz~yq`ahn7ck(|CE z7Gz;%OP~J6)tEZWDzjhL9h2hdfoU2)Nd%T<5Kt;Y0XLt&<@6pQx!nw*5`@bq#?l*?3z{Hlzoc=Pr>oB5(9i6~_&-}A(4{Q$>c>%rV&E|a(r&;?i5cQB=} zYSDU5nXG)NS4HEs0it2AHe2>shCyr7`6@4*6{r@8fXRbTA?=IFVWAQJL&H5H{)DpM#{W(GL+Idzf^)uRV@oB8u$ z8v{MfJbTiiRg4bza<41NAzrl{=3fl_D+$t+^!xlQ8S}{UtY`e z;;&9UhyZqQRN%2pot{*Ei0*4~hSF_3AH2@fKU!$NSflS>{@tZpDT4`M2WRTTVH+D? z)GFlEGGHe?koB}i|1w45!BF}N_q&^HJ&-tyR{(afC6H7|aml|tBBbv}55C5DNP8p3 z)~jLEO4Z&2hZmP^i-e%(@d!(E|KRafiU8Q5u(wU((j8un3OR*Hvj+t literal 0 HcmV?d00001 diff --git a/docs/html/doxygen.css b/docs/html/doxygen.css new file mode 100644 index 00000000..5bc13aac --- /dev/null +++ b/docs/html/doxygen.css @@ -0,0 +1,1766 @@ +/* The standard CSS for doxygen 1.8.16 */ + +body, table, div, p, dl { + font: 400 14px/22px Roboto,sans-serif; +} + +p.reference, p.definition { + font: 400 14px/22px Roboto,sans-serif; +} + +/* @group Heading Levels */ + +h1.groupheader { + font-size: 150%; +} + +.title { + font: 400 14px/28px Roboto,sans-serif; + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h2.groupheader { + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 150%; + font-weight: normal; + margin-top: 1.75em; + padding-top: 8px; + padding-bottom: 4px; + width: 100%; +} + +h3.groupheader { + font-size: 100%; +} + +h1, h2, h3, h4, h5, h6 { + -webkit-transition: text-shadow 0.5s linear; + -moz-transition: text-shadow 0.5s linear; + -ms-transition: text-shadow 0.5s linear; + -o-transition: text-shadow 0.5s linear; + transition: text-shadow 0.5s linear; + margin-right: 15px; +} + +h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { + text-shadow: 0 0 15px cyan; +} + +dt { + font-weight: bold; +} + +ul.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; + column-count: 3; +} + +p.startli, p.startdd { + margin-top: 2px; +} + +p.starttd { + margin-top: 0px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +p.interli { +} + +p.interdd { +} + +p.intertd { +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.qindex, div.navtab{ + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; +} + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; +} + +div.navtab { + margin-right: 15px; +} + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #FFFFFF; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #FFFFFF; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited, a.line, a.line:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +ul { + overflow: hidden; /*Fixed: list item bullets overlap floating elements*/ +} + +#side-nav ul { + overflow: visible; /* reset ul rule for scroll bar in GENERATE_TREEVIEW window */ +} + +#main-nav ul { + overflow: visible; /* reset ul rule for the navigation bar drop down lists */ +} + +.fragment { + text-align: left; + direction: ltr; + overflow-x: auto; /*Fixed: fragment lines overlap floating elements*/ + overflow-y: hidden; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: monospace, fixed; + font-size: 105%; +} + +div.fragment { + padding: 0 0 1px 0; /*Fixed: last line underline overlap border*/ + margin: 4px 8px 4px 2px; + background-color: #FBFCFD; + border: 1px solid #C4CFE5; +} + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line:after { + content:"\000A"; + white-space: pre; +} + +div.line.glow { + background-color: cyan; + box-shadow: 0 0 10px cyan; +} + + +span.lineno { + padding-right: 4px; + text-align: right; + border-right: 2px solid #0F0; + background-color: #E8E8E8; + white-space: pre; +} +span.lineno a { + background-color: #D8D8D8; +} + +span.lineno a:hover { + background-color: #C8C8C8; +} + +.lineno { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +div.ah, span.ah { + background-color: black; + font-weight: bold; + color: #FFFFFF; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000 110%); +} + +div.classindex ul { + list-style: none; + padding-left: 0; +} + +div.classindex span.ai { + display: inline-block; +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background-color: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 12px; + margin-right: 8px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; + white-space: nowrap; + vertical-align: top; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl, img.inline { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +blockquote { + background-color: #F7F8FB; + border-left: 2px solid #9CAFD4; + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + +blockquote.DocNodeRTL { + border-left: 0; + border-right: 2px solid #9CAFD4; + margin: 0 4px 0 24px; + padding: 0 16px 0 12px; +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; +} + +th.dirtab { + background: #EBEFF6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.memberdecls td, .fieldtable tr { + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: cyan; + box-shadow: 0 0 15px cyan; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memSeparator { + border-bottom: 1px solid #DEE4F0; + line-height: 1px; + margin: 0px; + padding: 0px; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight { + width: 100%; +} + +.memTemplParams { + color: #4665A2; + white-space: nowrap; + font-size: 80%; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtitle { + padding: 8px; + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + border-top-right-radius: 4px; + border-top-left-radius: 4px; + margin-bottom: -1px; + background-image: url('nav_f.png'); + background-repeat: repeat-x; + background-color: #E2E8F2; + line-height: 1.25; + font-weight: 300; + float:left; +} + +.permalink +{ + font-size: 65%; + display: inline-block; + vertical-align: middle; +} + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; + -webkit-transition: box-shadow 0.5s linear; + -moz-transition: box-shadow 0.5s linear; + -ms-transition: box-shadow 0.5s linear; + -o-transition: box-shadow 0.5s linear; + transition: box-shadow 0.5s linear; + display: table !important; + width: 100%; +} + +.memitem.glow { + box-shadow: 0 0 15px cyan; +} + +.memname { + font-weight: 400; + margin-left: 6px; +} + +.memname td { + vertical-align: bottom; +} + +.memproto, dl.reflist dt { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + background-color: #DFE5F1; + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 4px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 4px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 4px; + +} + +.overload { + font-family: "courier new",courier,monospace; + font-size: 65%; +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 10px 2px 10px; + background-color: #FBFCFD; + border-top-width: 0; + background-image:url('nav_g.png'); + background-repeat:repeat-x; + background-color: #FFFFFF; + /* opera specific markup */ + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-bottomright: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} +.paramname code { + line-height: 14px; +} + +.params, .retval, .exception, .tparams { + margin-left: 0px; + padding-left: 0px; +} + +.params .paramname, .retval .paramname, .tparams .paramname, .exception .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype, .tparams .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir, .tparams .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + +table.mlabels { + border-spacing: 0px; +} + +td.mlabels-left { + width: 100%; + padding: 0px; +} + +td.mlabels-right { + vertical-align: bottom; + padding: 0px; + white-space: nowrap; +} + +span.mlabels { + margin-left: 8px; +} + +span.mlabel { + background-color: #728DC1; + border-top:1px solid #5373B4; + border-left:1px solid #5373B4; + border-right:1px solid #C4CFE5; + border-bottom:1px solid #C4CFE5; + text-shadow: none; + color: white; + margin-right: 4px; + padding: 2px 3px; + border-radius: 3px; + font-size: 7pt; + white-space: nowrap; + vertical-align: middle; +} + + + +/* @end */ + +/* these are for tree view inside a (index) page */ + +div.directory { + margin: 10px 0px; + border-top: 1px solid #9CAFD4; + border-bottom: 1px solid #9CAFD4; + width: 100%; +} + +.directory table { + border-collapse:collapse; +} + +.directory td { + margin: 0px; + padding: 0px; + vertical-align: top; +} + +.directory td.entry { + white-space: nowrap; + padding-right: 6px; + padding-top: 3px; +} + +.directory td.entry a { + outline:none; +} + +.directory td.entry a img { + border: none; +} + +.directory td.desc { + width: 100%; + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + border-left: 1px solid rgba(0,0,0,0.05); +} + +.directory tr.even { + padding-left: 6px; + background-color: #F7F8FB; +} + +.directory img { + vertical-align: -30%; +} + +.directory .levels { + white-space: nowrap; + width: 100%; + text-align: right; + font-size: 9pt; +} + +.directory .levels span { + cursor: pointer; + padding-left: 2px; + padding-right: 2px; + color: #3D578C; +} + +.arrow { + color: #9CAFD4; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: pointer; + font-size: 80%; + display: inline-block; + width: 16px; + height: 22px; +} + +.icon { + font-family: Arial, Helvetica; + font-weight: bold; + font-size: 12px; + height: 14px; + width: 16px; + display: inline-block; + background-color: #728DC1; + color: white; + text-align: center; + border-radius: 4px; + margin-left: 2px; + margin-right: 2px; +} + +.icona { + width: 24px; + height: 22px; + display: inline-block; +} + +.iconfopen { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderopen.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.iconfclosed { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderclosed.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.icondoc { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('doc.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +table.directory { + font: 400 14px Roboto,sans-serif; +} + +/* @end */ + +div.dynheader { + margin-top: 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable caption { + caption-side: top; +} + +table.doxtable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +table.fieldtable { + /*width: 100%;*/ + margin-bottom: 10px; + border: 1px solid #A8B8D9; + border-spacing: 0px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + vertical-align: top; +} + +.fieldtable td.fieldname { + padding-top: 3px; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid #A8B8D9; + /*width: 100%;*/ +} + +.fieldtable td.fielddoc p:first-child { + margin-top: 0px; +} + +.fieldtable td.fielddoc p:last-child { + margin-bottom: 2px; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + font-size: 90%; + color: #253555; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + font-weight: 400; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid #A8B8D9; +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + background-position: 0 -5px; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; + color: #283A5D; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +table.classindex +{ + margin: 10px; + white-space: nowrap; + margin-left: 3%; + margin-right: 3%; + width: 94%; + border: 0; + border-spacing: 0; + padding: 0; +} + +div.ingroups +{ + font-size: 8pt; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +.PageDocRTL-title div.headertitle { + text-align: right; + direction: rtl; +} + +dl { + padding: 0 0 0 0; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug, dl.examples */ +dl.section { + margin-left: 0px; + padding-left: 0px; +} + +dl.section.DocNodeRTL { + margin-right: 0px; + padding-right: 0px; +} + +dl.note { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #D0C000; +} + +dl.note.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #FF0000; +} + +dl.warning.DocNodeRTL, dl.attention.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #00D000; +} + +dl.pre.DocNodeRTL, dl.post.DocNodeRTL, dl.invariant.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #00D000; +} + +dl.deprecated { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #505050; +} + +dl.deprecated.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #505050; +} + +dl.todo { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #00C0E0; +} + +dl.todo.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #00C0E0; +} + +dl.test { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #3030E0; +} + +dl.test.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #3030E0; +} + +dl.bug { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #C08050; +} + +dl.bug.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #C08050; +} + +dl.section dd { + margin-bottom: 6px; +} + + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectalign +{ + vertical-align: middle; +} + +#projectname +{ + font: 300% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font: 120% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font: 50% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.plantumlgraph +{ + text-align: center; +} + +.diagraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +div.zoom +{ + border: 1px solid #90A5CE; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:#334975; + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; +} + +dl.citelist dd { + margin:2px 0; + padding:5px 0; +} + +div.toc { + padding: 14px 25px; + background-color: #F4F6FA; + border: 1px solid #D8DFEE; + border-radius: 7px 7px 7px 7px; + float: right; + height: auto; + margin: 0 8px 10px 10px; + width: 200px; +} + +.PageDocRTL-title div.toc { + float: left !important; + text-align: right; +} + +div.toc li { + background: url("bdwn.png") no-repeat scroll 0 5px transparent; + font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; + margin-top: 5px; + padding-left: 10px; + padding-top: 2px; +} + +.PageDocRTL-title div.toc li { + background-position-x: right !important; + padding-left: 0 !important; + padding-right: 10px; +} + +div.toc h3 { + font: bold 12px/1.2 Arial,FreeSans,sans-serif; + color: #4665A2; + border-bottom: 0 none; + margin: 0; +} + +div.toc ul { + list-style: none outside none; + border: medium none; + padding: 0px; +} + +div.toc li.level1 { + margin-left: 0px; +} + +div.toc li.level2 { + margin-left: 15px; +} + +div.toc li.level3 { + margin-left: 30px; +} + +div.toc li.level4 { + margin-left: 45px; +} + +.PageDocRTL-title div.toc li.level1 { + margin-left: 0 !important; + margin-right: 0; +} + +.PageDocRTL-title div.toc li.level2 { + margin-left: 0 !important; + margin-right: 15px; +} + +.PageDocRTL-title div.toc li.level3 { + margin-left: 0 !important; + margin-right: 30px; +} + +.PageDocRTL-title div.toc li.level4 { + margin-left: 0 !important; + margin-right: 45px; +} + +.inherit_header { + font-weight: bold; + color: gray; + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.inherit_header td { + padding: 6px 0px 2px 5px; +} + +.inherit { + display: none; +} + +tr.heading h2 { + margin-top: 12px; + margin-bottom: 4px; +} + +/* tooltip related style info */ + +.ttc { + position: absolute; + display: none; +} + +#powerTip { + cursor: default; + white-space: nowrap; + background-color: white; + border: 1px solid gray; + border-radius: 4px 4px 4px 4px; + box-shadow: 1px 1px 7px gray; + display: none; + font-size: smaller; + max-width: 80%; + opacity: 0.9; + padding: 1ex 1em 1em; + position: absolute; + z-index: 2147483647; +} + +#powerTip div.ttdoc { + color: grey; + font-style: italic; +} + +#powerTip div.ttname a { + font-weight: bold; +} + +#powerTip div.ttname { + font-weight: bold; +} + +#powerTip div.ttdeci { + color: #006318; +} + +#powerTip div { + margin: 0px; + padding: 0px; + font: 12px/16px Roboto,sans-serif; +} + +#powerTip:before, #powerTip:after { + content: ""; + position: absolute; + margin: 0px; +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.s:after, #powerTip.s:before, +#powerTip.w:after, #powerTip.w:before, +#powerTip.e:after, #powerTip.e:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.nw:after, #powerTip.nw:before, +#powerTip.sw:after, #powerTip.sw:before { + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; +} + +#powerTip.n:after, #powerTip.s:after, +#powerTip.w:after, #powerTip.e:after, +#powerTip.nw:after, #powerTip.ne:after, +#powerTip.sw:after, #powerTip.se:after { + border-color: rgba(255, 255, 255, 0); +} + +#powerTip.n:before, #powerTip.s:before, +#powerTip.w:before, #powerTip.e:before, +#powerTip.nw:before, #powerTip.ne:before, +#powerTip.sw:before, #powerTip.se:before { + border-color: rgba(128, 128, 128, 0); +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.nw:after, #powerTip.nw:before { + top: 100%; +} + +#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { + border-top-color: #FFFFFF; + border-width: 10px; + margin: 0px -10px; +} +#powerTip.n:before { + border-top-color: #808080; + border-width: 11px; + margin: 0px -11px; +} +#powerTip.n:after, #powerTip.n:before { + left: 50%; +} + +#powerTip.nw:after, #powerTip.nw:before { + right: 14px; +} + +#powerTip.ne:after, #powerTip.ne:before { + left: 14px; +} + +#powerTip.s:after, #powerTip.s:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.sw:after, #powerTip.sw:before { + bottom: 100%; +} + +#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { + border-bottom-color: #FFFFFF; + border-width: 10px; + margin: 0px -10px; +} + +#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { + border-bottom-color: #808080; + border-width: 11px; + margin: 0px -11px; +} + +#powerTip.s:after, #powerTip.s:before { + left: 50%; +} + +#powerTip.sw:after, #powerTip.sw:before { + right: 14px; +} + +#powerTip.se:after, #powerTip.se:before { + left: 14px; +} + +#powerTip.e:after, #powerTip.e:before { + left: 100%; +} +#powerTip.e:after { + border-left-color: #FFFFFF; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.e:before { + border-left-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +#powerTip.w:after, #powerTip.w:before { + right: 100%; +} +#powerTip.w:after { + border-right-color: #FFFFFF; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.w:before { + border-right-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } +} + +/* @group Markdown */ + +/* +table.markdownTable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.markdownTable td, table.markdownTable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.markdownTableHead tr { +} + +table.markdownTableBodyLeft td, table.markdownTable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +th.markdownTableHeadLeft th.markdownTableHeadRight th.markdownTableHeadCenter th.markdownTableHeadNone { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +th.markdownTableHeadLeft { + text-align: left +} + +th.markdownTableHeadRight { + text-align: right +} + +th.markdownTableHeadCenter { + text-align: center +} +*/ + +table.markdownTable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.markdownTable td, table.markdownTable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.markdownTable tr { +} + +th.markdownTableHeadLeft, th.markdownTableHeadRight, th.markdownTableHeadCenter, th.markdownTableHeadNone { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +th.markdownTableHeadLeft, td.markdownTableBodyLeft { + text-align: left +} + +th.markdownTableHeadRight, td.markdownTableBodyRight { + text-align: right +} + +th.markdownTableHeadCenter, td.markdownTableBodyCenter { + text-align: center +} + +.DocNodeRTL { + text-align: right; + direction: rtl; +} + +.DocNodeLTR { + text-align: left; + direction: ltr; +} + +table.DocNodeRTL { + width: auto; + margin-right: 0; + margin-left: auto; +} + +table.DocNodeLTR { + width: auto; + margin-right: auto; + margin-left: 0; +} + +tt, code, kbd, samp +{ + display: inline-block; + direction:ltr; +} +/* @end */ + +u { + text-decoration: underline; +} + diff --git a/docs/html/doxygen.png b/docs/html/doxygen.png new file mode 100644 index 0000000000000000000000000000000000000000..3ff17d807fd8aa003bed8bb2a69e8f0909592fd1 GIT binary patch literal 3779 zcmV;!4m|ORP)tMIv#Q0*~7*`IBSO7_x;@a8#Zk6_PeKR_s92J&)(m+);m9Iz3blw)z#Gi zP!9lj4$%+*>Hz@HCmM9L9|8c+0u=!H$O3?R0Kgx|#WP<6fKfC8fM-CQZT|_r@`>VO zX^Hgb|9cJqpdJA5$MCEK`F_2@2Y@s>^+;pF`~jdI0Pvr|vl4`=C)EH@1IFe7pdJ8F zH(qGi004~QnF)Ggga~8v08kGAs2hKTATxr7pwfNk|4#_AaT>w8P6TV+R2kbS$v==} zAjf`s0g#V8lB+b3)5oEI*q+{Yt$MZDruD2^;$+(_%Qn+%v0X-bJO=;@kiJ^ygLBnC z?1OVv_%aex1M@jKU|Z~$eI?PoF4Vj>fDzyo zAiLfpXY*a^Sj-S5D0S3@#V$sRW)g)_1e#$%8xdM>Jm7?!h zu0P2X=xoN>^!4DoPRgph2(2va07yfpXF+WH7EOg1GY%Zn z7~1A<(z7Q$ktEXhW_?GMpHp9l_UL18F3KOsxu81pqoBiNbFSGsof-W z6~eloMoz=4?OOnl2J268x5rOY`dCk0us(uS#Ud4yqOr@?=Q57a}tit|BhY>}~frH1sP`ScHS_d)oqH^lYy zZ%VP`#10MlE~P?cE(%(#(AUSv_T{+;t@$U}El}(1ig`vZo`Rm;+5&(AYzJ^Ae=h2X z@Re%vHwZU>|f0NI&%$*4eJweC5OROQrpPMA@*w|o z()A==l}(@bv^&>H1Ob3C=<^|hob?0+xJ?QQ3-ueQC}zy&JQNib!OqSO@-=>XzxlSF zAZ^U*1l6EEmg3r};_HY>&Jo_{dOPEFTWPmt=U&F#+0(O59^UIlHbNX+eF8UzyDR*T z(=5X$VF3!gm@RooS-&iiUYGG^`hMR(07zr_xP`d!^BH?uD>Phl8Rdifx3Af^Zr`Ku ztL+~HkVeL#bJ)7;`=>;{KNRvjmc}1}c58Sr#Treq=4{xo!ATy|c>iRSp4`dzMMVd@ zL8?uwXDY}Wqgh4mH`|$BTXpUIu6A1-cSq%hJw;@^Zr8TP=GMh*p(m(tN7@!^D~sl$ zz^tf4II4|};+irE$Fnm4NTc5%p{PRA`%}Zk`CE5?#h3|xcyQsS#iONZ z6H(@^i9td!$z~bZiJLTax$o>r(p}3o@< zyD7%(>ZYvy=6$U3e!F{Z`uSaYy`xQyl?b{}eg|G3&fz*`QH@mDUn)1%#5u`0m$%D} z?;tZ0u(mWeMV0QtzjgN!lT*pNRj;6510Wwx?Yi_=tYw|J#7@(Xe7ifDzXuK;JB;QO z#bg~K$cgm$@{QiL_3yr}y&~wuv=P=#O&Tj=Sr)aCUlYmZMcw?)T?c%0rUe1cS+o!qs_ zQ6Gp)-{)V!;=q}llyK3|^WeLKyjf%y;xHku;9(vM!j|~<7w1c*Mk-;P{T&yG) z@C-8E?QPynNQ<8f01D`2qexcVEIOU?y}MG)TAE6&VT5`rK8s(4PE;uQ92LTXUQ<>^ ztyQ@=@kRdh@ebUG^Z6NWWIL;_IGJ2ST>$t!$m$qvtj0Qmw8moN6GUV^!QKNK zHBXCtUH8)RY9++gH_TUV4^=-j$t}dD3qsN7GclJ^Zc&(j6&a_!$jCf}%c5ey`pm~1)@{yI3 zTdWyB+*X{JFw#z;PwRr5evb2!ueWF;v`B0HoUu4-(~aL=z;OXUUEtG`_$)Oxw6FKg zEzY`CyKaSBK3xt#8gA|r_|Kehn_HYVBMpEwbn9-fI*!u*eTA1ef8Mkl1=!jV4oYwWYM}i`A>_F4nhmlCIC6WLa zY%;4&@AlnaG11ejl61Jev21|r*m+?Kru3;1tFDl}#!OzUp6c>go4{C|^erwpG*&h6bspUPJag}oOkN2912Y3I?(eRc@U9>z#HPBHC?nps7H5!zP``90!Q1n80jo+B3TWXp!8Pe zwuKuLLI6l3Gv@+QH*Y}2wPLPQ1^EZhT#+Ed8q8Wo z1pTmIBxv14-{l&QVKxAyQF#8Q@NeJwWdKk>?cpiJLkJr+aZ!Me+Cfp!?FWSRf^j2k z73BRR{WSKaMkJ>1Nbx5dan5hg^_}O{Tj6u%iV%#QGz0Q@j{R^Ik)Z*+(YvY2ziBG)?AmJa|JV%4UT$k`hcOg5r9R?5>?o~JzK zJCrj&{i#hG>N7!B4kNX(%igb%kDj0fOQThC-8mtfap82PNRXr1D>lbgg)dYTQ(kbx z`Ee5kXG~Bh+BHQBf|kJEy6(ga%WfhvdQNDuOfQoe377l#ht&DrMGeIsI5C<&ai zWG$|hop2@@q5YDa)_-A?B02W;#fH!%k`daQLEItaJJ8Yf1L%8x;kg?)k)00P-lH+w z)5$QNV6r2$YtnV(4o=0^3{kmaXn*Dm0F*fU(@o)yVVjk|ln8ea6BMy%vZAhW9|wvA z8RoDkVoMEz1d>|5(k0Nw>22ZT){V<3$^C-cN+|~hKt2)){+l-?3m@-$c?-dlzQ)q- zZ)j%n^gerV{|+t}9m1_&&Ly!9$rtG4XX|WQ8`xYzGC~U@nYh~g(z9)bdAl#xH)xd5a=@|qql z|FzEil{P5(@gy!4ek05i$>`E^G~{;pnf6ftpLh$h#W?^#4UkPfa;;?bsIe&kz!+40 zI|6`F2n020)-r`pFaZ38F!S-lJM-o&inOw|66=GMeP@xQU5ghQH{~5Uh~TMTd;I9` z>YhVB`e^EVj*S7JF39ZgNf}A-0DwOcTT63ydN$I3b?yBQtUI*_fae~kPvzoD$zjX3 zoqBe#>12im4WzZ=f^4+u=!lA|#r%1`WB0-6*3BL#at`47#ebPpR|D1b)3BjT34nYY z%Ds%d?5$|{LgOIaRO{{oC&RK`O91$fqwM0(C_TALcozu*fWHb%%q&p-q{_8*2Zsi^ zh1ZCnr^UYa;4vQEtHk{~zi>wwMC5o{S=$P0X681y`SXwFH?Ewn{x-MOZynmc)JT5v zuHLwh;tLfxRrr%|k370}GofLl7thg>ACWWY&msqaVu&ry+`7+Ss>NL^%T1|z{IGMA zW-SKl=V-^{(f!Kf^#3(|T2W47d(%JVCI4JgRrT1pNz>+ietmFToNv^`gzC@&O-)+i zPQ~RwK8%C_vf%;%e>NyTp~dM5;!C|N0Q^6|CEb7Bw=Vz~$1#FA;Z*?mKSC)Hl-20s t8QyHj(g6VK0RYbl8UjE)0O0w=e*@m04r>stuEhWV002ovPDHLkV1hl;dM*F} literal 0 HcmV?d00001 diff --git a/docs/html/dynsections.js b/docs/html/dynsections.js new file mode 100644 index 00000000..ea0a7b39 --- /dev/null +++ b/docs/html/dynsections.js @@ -0,0 +1,120 @@ +/* + @licstart The following is the entire license notice for the + JavaScript code in this file. + + Copyright (C) 1997-2017 by Dimitri van Heesch + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + @licend The above is the entire license notice + for the JavaScript code in this file + */ +function toggleVisibility(linkObj) +{ + var base = $(linkObj).attr('id'); + var summary = $('#'+base+'-summary'); + var content = $('#'+base+'-content'); + var trigger = $('#'+base+'-trigger'); + var src=$(trigger).attr('src'); + if (content.is(':visible')===true) { + content.hide(); + summary.show(); + $(linkObj).addClass('closed').removeClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); + } else { + content.show(); + summary.hide(); + $(linkObj).removeClass('closed').addClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); + } + return false; +} + +function updateStripes() +{ + $('table.directory tr'). + removeClass('even').filter(':visible:even').addClass('even'); +} + +function toggleLevel(level) +{ + $('table.directory tr').each(function() { + var l = this.id.split('_').length-1; + var i = $('#img'+this.id.substring(3)); + var a = $('#arr'+this.id.substring(3)); + if (l + + + + + + +Firmata firmware for Arduino: File List + + + + + + + + + +
+
+ + + + + + +
+
Firmata firmware for Arduino +
+
Firmata is a protocol for communicating with microcontrollers from software on a host computer
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
File List
+
+
+
Here is a list of all documented files with brief descriptions:
+ + + + + + + +
 Boards.h
 Firmata.h
 FirmataConstants.h
 FirmataDefines.h
 FirmataMarshaller.h
 FirmataParser.h
+
+
+ + + + diff --git a/docs/html/folderclosed.png b/docs/html/folderclosed.png new file mode 100644 index 0000000000000000000000000000000000000000..bb8ab35edce8e97554e360005ee9fc5bffb36e66 GIT binary patch literal 616 zcmV-u0+;=XP)a9#ETzayK)T~Jw&MMH>OIr#&;dC}is*2Mqdf&akCc=O@`qC+4i z5Iu3w#1M@KqXCz8TIZd1wli&kkl2HVcAiZ8PUn5z_kG@-y;?yK06=cA0U%H0PH+kU zl6dp}OR(|r8-RG+YLu`zbI}5TlOU6ToR41{9=uz^?dGTNL;wIMf|V3`d1Wj3y!#6` zBLZ?xpKR~^2x}?~zA(_NUu3IaDB$tKma*XUdOZN~c=dLt_h_k!dbxm_*ibDM zlFX`g{k$X}yIe%$N)cn1LNu=q9_CS)*>A zsX_mM4L@`(cSNQKMFc$RtYbx{79#j-J7hk*>*+ZZhM4Hw?I?rsXCi#mRWJ=-0LGV5a-WR0Qgt<|Nqf)C-@80`5gIz45^_20000IqP)X=#(TiCT&PiIIVc55T}TU}EUh*{q$|`3@{d>{Tc9Bo>e= zfmF3!f>fbI9#GoEHh0f`i5)wkLpva0ztf%HpZneK?w-7AK@b4Itw{y|Zd3k!fH?q2 zlhckHd_V2M_X7+)U&_Xcfvtw60l;--DgZmLSw-Y?S>)zIqMyJ1#FwLU*%bl38ok+! zh78H87n`ZTS;uhzAR$M`zZ`bVhq=+%u9^$5jDplgxd44}9;IRqUH1YHH|@6oFe%z( zo4)_>E$F&^P-f(#)>(TrnbE>Pefs9~@iN=|)Rz|V`sGfHNrJ)0gJb8xx+SBmRf@1l zvuzt=vGfI)<-F9!o&3l?>9~0QbUDT(wFdnQPv%xdD)m*g%!20>Bc9iYmGAp<9YAa( z0QgYgTWqf1qN++Gqp z8@AYPTB3E|6s=WLG?xw0tm|U!o=&zd+H0oRYE;Dbx+Na9s^STqX|Gnq%H8s(nGDGJ j8vwW|`Ts`)fSK|Kx=IK@RG@g200000NkvXXu0mjfauFEA literal 0 HcmV?d00001 diff --git a/docs/html/functions.html b/docs/html/functions.html new file mode 100644 index 00000000..452a8a22 --- /dev/null +++ b/docs/html/functions.html @@ -0,0 +1,262 @@ + + + + + + + +Firmata firmware for Arduino: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Firmata firmware for Arduino +
+
Firmata is a protocol for communicating with microcontrollers from software on a host computer
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- a -

+ + +

- b -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- g -

+ + +

- i -

+ + +

- p -

+ + +

- q -

+ + +

- r -

+ + +

- s -

+ + +

- w -

+
+ + + + diff --git a/docs/html/functions_func.html b/docs/html/functions_func.html new file mode 100644 index 00000000..ad7b87be --- /dev/null +++ b/docs/html/functions_func.html @@ -0,0 +1,262 @@ + + + + + + + +Firmata firmware for Arduino: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Firmata firmware for Arduino +
+
Firmata is a protocol for communicating with microcontrollers from software on a host computer
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- a -

+ + +

- b -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- g -

+ + +

- i -

+ + +

- p -

+ + +

- q -

+ + +

- r -

+ + +

- s -

+ + +

- w -

+
+ + + + diff --git a/docs/html/index.html b/docs/html/index.html new file mode 100644 index 00000000..d07b9ead --- /dev/null +++ b/docs/html/index.html @@ -0,0 +1,275 @@ + + + + + + + +Firmata firmware for Arduino: Firmata + + + + + + + + + +
+
+ + + + + + +
+
Firmata firmware for Arduino +
+
Firmata is a protocol for communicating with microcontrollers from software on a host computer
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Firmata
+
+
+

Gitter

+

Firmata is a protocol for communicating with microcontrollers from software on a host computer. The protocol can be implemented in firmware on any microcontroller architecture as well as software on any host computer software package. The Arduino repository described here is a Firmata library for Arduino and Arduino-compatible devices. If you would like to contribute to Firmata, please see the Contributing section below.

+

+Contents

+ +

+Usage

+

There are two main models of usage of Firmata. In one model, the author of the Arduino sketch uses the various methods provided by the Firmata library to selectively send and receive data between the Arduino device and the software running on the host computer. For example, a user can send analog data to the host using Firmata.sendAnalog(analogPin, analogRead(analogPin)) or send data packed in a string using Firmata.sendString(stringToSend). See File -> Examples -> Firmata -> AnalogFirmata & EchoString respectively for examples.

+

The second and more common model is to load a general purpose sketch called StandardFirmata (or one of the variants such as StandardFirmataPlus or StandardFirmataEthernet depending on your needs) on the Arduino board and then use the host computer exclusively to interact with the Arduino board. StandardFirmata is located in the Arduino IDE in File -> Examples -> Firmata.

+

+Firmata Client Libraries

+

Most of the time you will be interacting with Arduino with a client library on the host computers. Several Firmata client libraries have been implemented in a variety of popular programming languages:

+ +

Note: The above libraries may support various versions of the Firmata protocol and therefore may not support all features of the latest Firmata spec nor all Arduino and Arduino-compatible boards. Refer to the respective projects for details.

+

+Updating Firmata in the Arduino IDE - Arduino 1.6.4 and higher

+

If you want to update to the latest stable version:

+
    +
  1. Open the Arduino IDE and navigate to: Sketch > Include Library > Manage Libraries
  2. +
  3. Filter by "Firmata" and click on the "Firmata by Firmata Developers" item in the list of results.
  4. +
  5. Click the Select version dropdown and select the most recent version (note you can also install previous versions)
  6. +
  7. Click Install.
  8. +
+

+Cloning Firmata

+

If you are contributing to Firmata or otherwise need a version newer than the latest tagged release, you can clone Firmata directly to your Arduino/libraries/ directory (where 3rd party libraries are installed). This only works for Arduino 1.6.4 and higher, for older versions you need to clone into the Arduino application directory (see section below titled "Using the Source code rather than release archive"). Be sure to change the name to Firmata as follows:

+
$ git clone git@github.com:firmata/arduino.git ~/Documents/Arduino/libraries/Firmata
+

Update path above if you're using Windows or Linux or changed the default Arduino directory on OS X

+

+Updating Firmata in the Arduino IDE - older versions (<= 1.6.3 or 1.0.x)

+

Download the latest release (for Arduino 1.0.x or Arduino 1.5.6 or higher) and replace the existing Firmata folder in your Arduino application. See the instructions below for your platform.

+

Note that Arduino 1.5.0 - 1.5.5 are not supported. Please use Arduino 1.5.6 or higher (or Arduino 1.0.5 or 1.0.6).

+

+Mac OSX:

+

The Firmata library is contained within the Arduino package.

+
    +
  1. Navigate to the Arduino application
  2. +
  3. Right click on the application icon and select Show Package Contents
  4. +
  5. Navigate to: /Contents/Resources/Java/libraries/ and replace the existing Firmata folder with latest Firmata release (note there is a different download for Arduino 1.0.x vs 1.6.x)
  6. +
  7. Restart the Arduino application and the latest version of Firmata will be available.
  8. +
+

If you are using the Java 7 version of Arduino 1.5.7 or higher, the file path will differ slightly: Contents/Java/libraries/Firmata (no Resources directory).

+

+Windows:

+
    +
  1. Navigate to c:/Program\ Files/arduino-1.x/libraries/ and replace the existing Firmata folder with the latest Firmata release (note there is a different download for Arduino 1.0.x vs 1.6.x).
  2. +
  3. Restart the Arduino application and the latest version of Firmata will be available.
  4. +
+

Update the path and Arduino version as necessary

+

+Linux:

+
    +
  1. Navigate to ~/arduino-1.x/libraries/ and replace the existing Firmata folder with the latest Firmata release (note there is a different download for Arduino 1.0.x vs 1.6.x).
  2. +
  3. Restart the Arduino application and the latest version of Firmata will be available.
  4. +
+

Update the path and Arduino version as necessary

+

+Using the Source code rather than release archive (only for versions older than Arduino 1.6.3)

+

It is recommended you update to Arduino 1.6.4 or higher if possible, that way you can clone directly into the external Arduino/libraries/ directory which persists between Arduino application updates. Otherwise you will need to move your clone each time you update to a newer version of the Arduino IDE.

+

If you're stuck with an older version of the IDE, then follow these keep reading otherwise jump up to the "Cloning Firmata section above".

+

Clone this repo directly into the core Arduino application libraries directory. If you are using Arduino 1.5.x or <= 1.6.3, the repo directory structure will not match the Arduino library format, however it should still compile as long as you are using Arduino 1.5.7 or higher.

+

You will first need to remove the existing Firmata library, then clone firmata/arduino into an empty Firmata directory:

+
$ rm -r /Applications/Arduino.app/Contents/Resources/Java/libraries/Firmata
+
$ git clone git@github.com:firmata/arduino.git /Applications/Arduino.app/Contents/Resources/Java/libraries/Firmata
+

Update paths if you're using Windows or Linux

+

To generate properly formatted versions of Firmata (for Arduino 1.0.x and Arduino 1.6.x), run the release.sh script.

+

+Contributing

+

If you discover a bug or would like to propose a new feature, please open a new issue. Due to the limited memory of standard Arduino boards we cannot add every requested feature to StandardFirmata. Requests to add new features to StandardFirmata will be evaluated by the Firmata developers. However it is still possible to add new features to other Firmata implementations (Firmata is a protocol whereas StandardFirmata is just one of many possible implementations).

+

To contribute, fork this repository and create a new topic branch for the bug, feature or other existing issue you are addressing. Submit the pull request against the master branch.

+

If you would like to contribute but don't have a specific bugfix or new feature to contribute, you can take on an existing issue, see issues labeled "pull-request-encouraged". Add a comment to the issue to express your intent to begin work and/or to get any additional information about the issue.

+

You must thoroughly test your contributed code. In your pull request, describe tests performed to ensure that no existing code is broken and that any changes maintain backwards compatibility with the existing api. Test on multiple Arduino board variants if possible. We hope to enable some form of automated (or at least semi-automated) testing in the future, but for now any tests will need to be executed manually by the contributor and reviewers.

+

Use Artistic Style (astyle) to format your code. Set the following rules for the astyle formatter:

+
style = ""
+
indent-spaces = 2
+
indent-classes = true
+
indent-switches = true
+
indent-cases = true
+
indent-col1-comments = true
+
pad-oper = true
+
pad-header = true
+
keep-one-line-statements = true
+

If you happen to use Sublime Text, this astyle plugin is helpful. Set the above rules in the user settings file.

+
+
+ + + + diff --git a/docs/html/jquery.js b/docs/html/jquery.js new file mode 100644 index 00000000..103c32d7 --- /dev/null +++ b/docs/html/jquery.js @@ -0,0 +1,35 @@ +/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;nx",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Vt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0a;a++)for(i in o[a])n=o[a][i],o[a].hasOwnProperty(i)&&void 0!==n&&(e[i]=t.isPlainObject(n)?t.isPlainObject(e[i])?t.widget.extend({},e[i],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,i){var n=i.prototype.widgetFullName||e;t.fn[e]=function(o){var a="string"==typeof o,r=s.call(arguments,1),h=this;return a?this.length||"instance"!==o?this.each(function(){var i,s=t.data(this,n);return"instance"===o?(h=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void 0!==i?(h=i&&i.jquery?h.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")}):h=void 0:(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new i(o,this))})),h}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
",options:{classes:{},disabled:!1,create:null},_createWidget:function(e,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+o.eventNamespace,c=h[2];c?n.on(l,c,r):i.on(l,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var n,o=Math.max,a=Math.abs,r=/left|center|right/,h=/top|center|bottom/,l=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,d=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==n)return n;var e,i,s=t("
"),o=s.children()[0];return t("body").append(s),e=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),n=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.widthi?"left":e>0?"right":"center",vertical:0>r?"top":s>0?"bottom":"middle"};l>p&&p>a(e+i)&&(u.horizontal="center"),c>f&&f>a(s+r)&&(u.vertical="middle"),u.important=o(a(e),a(i))>o(a(s),a(r))?"horizontal":"vertical",n.using.call(this,t,u)}),h.offset(t.extend(D,{using:r}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,h=n-r,l=r+e.collisionWidth-a-n;e.collisionWidth>a?h>0&&0>=l?(i=t.left+h+e.collisionWidth-a-n,t.left+=h-i):t.left=l>0&&0>=h?n:h>l?n+a-e.collisionWidth:n:h>0?t.left+=h:l>0?t.left-=l:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,h=n-r,l=r+e.collisionHeight-a-n;e.collisionHeight>a?h>0&&0>=l?(i=t.top+h+e.collisionHeight-a-n,t.top+=h-i):t.top=l>0&&0>=h?n:h>l?n+a-e.collisionHeight:n:h>0?t.top+=h:l>0?t.top-=l:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,r=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,u=l+e.collisionWidth-r-h,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-r-o,(0>i||a(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-h,(s>0||u>a(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,r=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,u=l+e.collisionHeight-r-h,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,m=-2*e.offset[1];0>c?(s=t.top+p+f+m+e.collisionHeight-r-o,(0>s||a(c)>s)&&(t.top+=p+f+m)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+m-h,(i>0||u>a(i))&&(t.top+=p+f+m))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.fn.extend({disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}}(),enableSelection:function(){return this.off(".ui-disableSelection")}}),t.ui.focusable=function(i,s){var n,o,a,r,h,l=i.nodeName.toLowerCase();return"area"===l?(n=i.parentNode,o=n.name,i.href&&o&&"map"===n.nodeName.toLowerCase()?(a=t("img[usemap='#"+o+"']"),a.length>0&&a.is(":visible")):!1):(/^(input|select|textarea|button|object)$/.test(l)?(r=!i.disabled,r&&(h=t(i).closest("fieldset")[0],h&&(r=!h.disabled))):r="a"===l?i.href||s:s,r&&t(i).is(":visible")&&e(t(i)))},t.extend(t.expr[":"],{focusable:function(e){return t.ui.focusable(e,null!=t.attr(e,"tabindex"))}}),t.ui.focusable,t.fn.form=function(){return"string"==typeof this[0].form?this.closest("form"):t(this[0].form)},t.ui.formResetMixin={_formResetHandler:function(){var e=t(this);setTimeout(function(){var i=e.data("ui-form-reset-instances");t.each(i,function(){this.refresh()})})},_bindFormResetHandler:function(){if(this.form=this.element.form(),this.form.length){var t=this.form.data("ui-form-reset-instances")||[];t.length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t)}},_unbindFormResetHandler:function(){if(this.form.length){var e=this.form.data("ui-form-reset-instances");e.splice(t.inArray(this,e),1),e.length?this.form.data("ui-form-reset-instances",e):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset")}}},"1.7"===t.fn.jquery.substring(0,3)&&(t.each(["Width","Height"],function(e,i){function s(e,i,s,o){return t.each(n,function(){i-=parseFloat(t.css(e,"padding"+this))||0,s&&(i-=parseFloat(t.css(e,"border"+this+"Width"))||0),o&&(i-=parseFloat(t.css(e,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],o=i.toLowerCase(),a={innerWidth:t.fn.innerWidth,innerHeight:t.fn.innerHeight,outerWidth:t.fn.outerWidth,outerHeight:t.fn.outerHeight};t.fn["inner"+i]=function(e){return void 0===e?a["inner"+i].call(this):this.each(function(){t(this).css(o,s(this,e)+"px")})},t.fn["outer"+i]=function(e,n){return"number"!=typeof e?a["outer"+i].call(this,e):this.each(function(){t(this).css(o,s(this,e,!0,n)+"px")})}}),t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.ui.escapeSelector=function(){var t=/([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;return function(e){return e.replace(t,"\\$1")}}(),t.fn.labels=function(){var e,i,s,n,o;return this[0].labels&&this[0].labels.length?this.pushStack(this[0].labels):(n=this.eq(0).parents("label"),s=this.attr("id"),s&&(e=this.eq(0).parents().last(),o=e.add(e.length?e.siblings():this.siblings()),i="label[for='"+t.ui.escapeSelector(s)+"']",n=n.add(o.find(i).addBack(i))),this.pushStack(n))},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.extend(t.expr[":"],{tabbable:function(e){var i=t.attr(e,"tabindex"),s=null!=i;return(!s||i>=0)&&t.ui.focusable(e,s)}}),t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var n=!1;t(document).on("mouseup",function(){n=!1}),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!n){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,s=1===e.which,o="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return s&&!o&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),n=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,n=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,s){var n,o=t.ui[e].prototype;for(n in s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;o.length>n;n++)t.options[o[n][0]]&&o[n][1].apply(t.element,i)}},t.widget("ui.resizable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return e[s]>0?!0:(e[s]=1,n=e[s]>0,e[s]=0,n)},_create:function(){var e,i=this.options,s=this;this._addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!i.aspectRatio,aspectRatio:i.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:i.helper||i.ghost||i.animate?i.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(t("
").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,e={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(e),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(e),this._proportionallyResize()),this._setupHandles(),i.autoHide&&t(this.element).on("mouseenter",function(){i.disabled||(s._removeClass("ui-resizable-autohide"),s._handles.show())}).on("mouseleave",function(){i.disabled||s.resizing||(s._addClass("ui-resizable-autohide"),s._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;default:}},_setupHandles:function(){var e,i,s,n,o,a=this.options,r=this;if(this.handles=a.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=t(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),s=this.handles.split(","),this.handles={},i=0;s.length>i;i++)e=t.trim(s[i]),n="ui-resizable-"+e,o=t("
"),this._addClass(o,"ui-resizable-handle "+n),o.css({zIndex:a.zIndex}),this.handles[e]=".ui-resizable-"+e,this.element.append(o);this._renderAxis=function(e){var i,s,n,o;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String?this.handles[i]=this.element.children(this.handles[i]).first().show():(this.handles[i].jquery||this.handles[i].nodeType)&&(this.handles[i]=t(this.handles[i]),this._on(this.handles[i],{mousedown:r._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=t(this.handles[i],this.element),o=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,o),this._proportionallyResize()),this._handles=this._handles.add(this.handles[i])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){r.resizing||(this.className&&(o=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),r.axis=o&&o[1]?o[1]:"se")}),a.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(e){var i,s,n,o=this.options,a=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),o.containment&&(i+=t(o.containment).scrollLeft()||0,s+=t(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:a.width(),height:a.height()},this.originalSize=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.sizeDiff={width:a.outerWidth()-a.width(),height:a.outerHeight()-a.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:e.pageX,top:e.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,n=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===n?this.axis+"-resize":n),this._addClass("ui-resizable-resizing"),this._propagate("start",e),!0},_mouseDrag:function(e){var i,s,n=this.originalMousePosition,o=this.axis,a=e.pageX-n.left||0,r=e.pageY-n.top||0,h=this._change[o];return this._updatePrevProperties(),h?(i=h.apply(this,[e,a,r]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",e,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,o,a,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&this._hasScroll(i[0],"left")?0:c.sizeDiff.height,o=s?0:c.sizeDiff.width,a={width:c.helper.width()-o,height:c.helper.height()-n},r=parseFloat(c.element.css("left"))+(c.position.left-c.originalPosition.left)||null,h=parseFloat(c.element.css("top"))+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(a,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s,n,o,a=this.options;o={minWidth:this._isNumber(a.minWidth)?a.minWidth:0,maxWidth:this._isNumber(a.maxWidth)?a.maxWidth:1/0,minHeight:this._isNumber(a.minHeight)?a.minHeight:0,maxHeight:this._isNumber(a.maxHeight)?a.maxHeight:1/0},(this._aspectRatio||t)&&(e=o.minHeight*this.aspectRatio,s=o.minWidth/this.aspectRatio,i=o.maxHeight*this.aspectRatio,n=o.maxWidth/this.aspectRatio,e>o.minWidth&&(o.minWidth=e),s>o.minHeight&&(o.minHeight=s),o.maxWidth>i&&(o.maxWidth=i),o.maxHeight>n&&(o.maxHeight=n)),this._vBoundaries=o},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidtht.width,a=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,r=this.originalPosition.left+this.originalSize.width,h=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),c=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),a&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=r-e.minWidth),s&&l&&(t.left=r-e.maxWidth),a&&c&&(t.top=h-e.minHeight),n&&c&&(t.top=h-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];4>e;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;this._proportionallyResizeElements.length>e;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("
"),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element +},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).resizable("instance"),s=i.options,n=i._proportionallyResizeElements,o=n.length&&/textarea/i.test(n[0].nodeName),a=o&&i._hasScroll(n[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-a},l=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,c=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var e,i,s,n,o,a,r,h=t(this).resizable("instance"),l=h.options,c=h.element,u=l.containment,d=u instanceof t?u.get(0):/parent/.test(u)?c.parent().get(0):u;d&&(h.containerElement=t(d),/document/.test(u)||u===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(e=t(d),i=[],t(["Top","Right","Left","Bottom"]).each(function(t,s){i[t]=h._num(e.css("padding"+s))}),h.containerOffset=e.offset(),h.containerPosition=e.position(),h.containerSize={height:e.innerHeight()-i[3],width:e.innerWidth()-i[1]},s=h.containerOffset,n=h.containerSize.height,o=h.containerSize.width,a=h._hasScroll(d,"left")?d.scrollWidth:o,r=h._hasScroll(d)?d.scrollHeight:n,h.parentData={element:d,left:s.left,top:s.top,width:a,height:r}))},resize:function(e){var i,s,n,o,a=t(this).resizable("instance"),r=a.options,h=a.containerOffset,l=a.position,c=a._aspectRatio||e.shiftKey,u={top:0,left:0},d=a.containerElement,p=!0;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(a._helper?h.left:0)&&(a.size.width=a.size.width+(a._helper?a.position.left-h.left:a.position.left-u.left),c&&(a.size.height=a.size.width/a.aspectRatio,p=!1),a.position.left=r.helper?h.left:0),l.top<(a._helper?h.top:0)&&(a.size.height=a.size.height+(a._helper?a.position.top-h.top:a.position.top),c&&(a.size.width=a.size.height*a.aspectRatio,p=!1),a.position.top=a._helper?h.top:0),n=a.containerElement.get(0)===a.element.parent().get(0),o=/relative|absolute/.test(a.containerElement.css("position")),n&&o?(a.offset.left=a.parentData.left+a.position.left,a.offset.top=a.parentData.top+a.position.top):(a.offset.left=a.element.offset().left,a.offset.top=a.element.offset().top),i=Math.abs(a.sizeDiff.width+(a._helper?a.offset.left-u.left:a.offset.left-h.left)),s=Math.abs(a.sizeDiff.height+(a._helper?a.offset.top-u.top:a.offset.top-h.top)),i+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-i,c&&(a.size.height=a.size.width/a.aspectRatio,p=!1)),s+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-s,c&&(a.size.width=a.size.height*a.aspectRatio,p=!1)),p||(a.position.left=a.prevPosition.left,a.position.top=a.prevPosition.top,a.size.width=a.prevSize.width,a.size.height=a.prevSize.height)},stop:function(){var e=t(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.containerPosition,o=e.containerElement,a=t(e.helper),r=a.offset(),h=a.outerWidth()-e.sizeDiff.width,l=a.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).resizable("instance"),i=e.options;t(i.alsoResize).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseFloat(e.width()),height:parseFloat(e.height()),left:parseFloat(e.css("left")),top:parseFloat(e.css("top"))})})},resize:function(e,i){var s=t(this).resizable("instance"),n=s.options,o=s.originalSize,a=s.originalPosition,r={height:s.size.height-o.height||0,width:s.size.width-o.width||0,top:s.position.top-a.top||0,left:s.position.left-a.left||0};t(n.alsoResize).each(function(){var e=t(this),s=t(this).data("ui-resizable-alsoresize"),n={},o=e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(o,function(t,e){var i=(s[e]||0)+(r[e]||0);i&&i>=0&&(n[e]=i||null)}),e.css(n)})},stop:function(){t(this).removeData("ui-resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).resizable("instance"),i=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:i.height,width:i.width,margin:0,left:0,top:0}),e._addClass(e.ghost,"ui-resizable-ghost"),t.uiBackCompat!==!1&&"string"==typeof e.options.ghost&&e.ghost.addClass(this.options.ghost),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).resizable("instance");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).resizable("instance");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e,i=t(this).resizable("instance"),s=i.options,n=i.size,o=i.originalSize,a=i.originalPosition,r=i.axis,h="number"==typeof s.grid?[s.grid,s.grid]:s.grid,l=h[0]||1,c=h[1]||1,u=Math.round((n.width-o.width)/l)*l,d=Math.round((n.height-o.height)/c)*c,p=o.width+u,f=o.height+d,m=s.maxWidth&&p>s.maxWidth,g=s.maxHeight&&f>s.maxHeight,_=s.minWidth&&s.minWidth>p,v=s.minHeight&&s.minHeight>f;s.grid=h,_&&(p+=l),v&&(f+=c),m&&(p-=l),g&&(f-=c),/^(se|s|e)$/.test(r)?(i.size.width=p,i.size.height=f):/^(ne)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.top=a.top-d):/^(sw)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.left=a.left-u):((0>=f-c||0>=p-l)&&(e=i._getPaddingPlusBorderDimensions(this)),f-c>0?(i.size.height=f,i.position.top=a.top-d):(f=c-e.height,i.size.height=f,i.position.top=a.top+o.height-f),p-l>0?(i.size.width=p,i.position.left=a.left-u):(p=l-e.width,i.size.width=p,i.position.left=a.left+o.width-p))}}),t.ui.resizable});/** + * Copyright (c) 2007 Ariel Flesler - aflesler ○ gmail • com | https://github.com/flesler + * Licensed under MIT + * @author Ariel Flesler + * @version 2.1.2 + */ +;(function(f){"use strict";"function"===typeof define&&define.amd?define(["jquery"],f):"undefined"!==typeof module&&module.exports?module.exports=f(require("jquery")):f(jQuery)})(function($){"use strict";function n(a){return!a.nodeName||-1!==$.inArray(a.nodeName.toLowerCase(),["iframe","#document","html","body"])}function h(a){return $.isFunction(a)||$.isPlainObject(a)?a:{top:a,left:a}}var p=$.scrollTo=function(a,d,b){return $(window).scrollTo(a,d,b)};p.defaults={axis:"xy",duration:0,limit:!0};$.fn.scrollTo=function(a,d,b){"object"=== typeof d&&(b=d,d=0);"function"===typeof b&&(b={onAfter:b});"max"===a&&(a=9E9);b=$.extend({},p.defaults,b);d=d||b.duration;var u=b.queue&&1=f[g]?0:Math.min(f[g],n));!a&&1-1){targetElements.on(evt+EVENT_NAMESPACE,function elementToggle(event){$.powerTip.toggle(this,event)})}else{targetElements.on(evt+EVENT_NAMESPACE,function elementOpen(event){$.powerTip.show(this,event)})}});$.each(options.closeEvents,function(idx,evt){if($.inArray(evt,options.openEvents)<0){targetElements.on(evt+EVENT_NAMESPACE,function elementClose(event){$.powerTip.hide(this,!isMouseEvent(event))})}});targetElements.on("keydown"+EVENT_NAMESPACE,function elementKeyDown(event){if(event.keyCode===27){$.powerTip.hide(this,true)}})}return targetElements};$.fn.powerTip.defaults={fadeInTime:200,fadeOutTime:100,followMouse:false,popupId:"powerTip",popupClass:null,intentSensitivity:7,intentPollInterval:100,closeDelay:100,placement:"n",smartPlacement:false,offset:10,mouseOnToPopup:false,manual:false,openEvents:["mouseenter","focus"],closeEvents:["mouseleave","blur"]};$.fn.powerTip.smartPlacementLists={n:["n","ne","nw","s"],e:["e","ne","se","w","nw","sw","n","s","e"],s:["s","se","sw","n"],w:["w","nw","sw","e","ne","se","n","s","w"],nw:["nw","w","sw","n","s","se","nw"],ne:["ne","e","se","n","s","sw","ne"],sw:["sw","w","nw","s","n","ne","sw"],se:["se","e","ne","s","n","nw","se"],"nw-alt":["nw-alt","n","ne-alt","sw-alt","s","se-alt","w","e"],"ne-alt":["ne-alt","n","nw-alt","se-alt","s","sw-alt","e","w"],"sw-alt":["sw-alt","s","se-alt","nw-alt","n","ne-alt","w","e"],"se-alt":["se-alt","s","sw-alt","ne-alt","n","nw-alt","e","w"]};$.powerTip={show:function apiShowTip(element,event){if(isMouseEvent(event)){trackMouse(event);session.previousX=event.pageX;session.previousY=event.pageY;$(element).data(DATA_DISPLAYCONTROLLER).show()}else{$(element).first().data(DATA_DISPLAYCONTROLLER).show(true,true)}return element},reposition:function apiResetPosition(element){$(element).first().data(DATA_DISPLAYCONTROLLER).resetPosition();return element},hide:function apiCloseTip(element,immediate){var displayController;immediate=element?immediate:true;if(element){displayController=$(element).first().data(DATA_DISPLAYCONTROLLER)}else if(session.activeHover){displayController=session.activeHover.data(DATA_DISPLAYCONTROLLER)}if(displayController){displayController.hide(immediate)}return element},toggle:function apiToggle(element,event){if(session.activeHover&&session.activeHover.is(element)){$.powerTip.hide(element,!isMouseEvent(event))}else{$.powerTip.show(element,event)}return element}};$.powerTip.showTip=$.powerTip.show;$.powerTip.closeTip=$.powerTip.hide;function CSSCoordinates(){var me=this;me.top="auto";me.left="auto";me.right="auto";me.bottom="auto";me.set=function(property,value){if($.isNumeric(value)){me[property]=Math.round(value)}}}function DisplayController(element,options,tipController){var hoverTimer=null,myCloseDelay=null;function openTooltip(immediate,forceOpen){cancelTimer();if(!element.data(DATA_HASACTIVEHOVER)){if(!immediate){session.tipOpenImminent=true;hoverTimer=setTimeout(function intentDelay(){hoverTimer=null;checkForIntent()},options.intentPollInterval)}else{if(forceOpen){element.data(DATA_FORCEDOPEN,true)}closeAnyDelayed();tipController.showTip(element)}}else{cancelClose()}}function closeTooltip(disableDelay){if(myCloseDelay){myCloseDelay=session.closeDelayTimeout=clearTimeout(myCloseDelay);session.delayInProgress=false}cancelTimer();session.tipOpenImminent=false;if(element.data(DATA_HASACTIVEHOVER)){element.data(DATA_FORCEDOPEN,false);if(!disableDelay){session.delayInProgress=true;session.closeDelayTimeout=setTimeout(function closeDelay(){session.closeDelayTimeout=null;tipController.hideTip(element);session.delayInProgress=false;myCloseDelay=null},options.closeDelay);myCloseDelay=session.closeDelayTimeout}else{tipController.hideTip(element)}}}function checkForIntent(){var xDifference=Math.abs(session.previousX-session.currentX),yDifference=Math.abs(session.previousY-session.currentY),totalDifference=xDifference+yDifference;if(totalDifference",{id:options.popupId});if($body.length===0){$body=$("body")}$body.append(tipElement);session.tooltips=session.tooltips?session.tooltips.add(tipElement):tipElement}if(options.followMouse){if(!tipElement.data(DATA_HASMOUSEMOVE)){$document.on("mousemove"+EVENT_NAMESPACE,positionTipOnCursor);$window.on("scroll"+EVENT_NAMESPACE,positionTipOnCursor);tipElement.data(DATA_HASMOUSEMOVE,true)}}function beginShowTip(element){element.data(DATA_HASACTIVEHOVER,true);tipElement.queue(function queueTipInit(next){showTip(element);next()})}function showTip(element){var tipContent;if(!element.data(DATA_HASACTIVEHOVER)){return}if(session.isTipOpen){if(!session.isClosing){hideTip(session.activeHover)}tipElement.delay(100).queue(function queueTipAgain(next){showTip(element);next()});return}element.trigger("powerTipPreRender");tipContent=getTooltipContent(element);if(tipContent){tipElement.empty().append(tipContent)}else{return}element.trigger("powerTipRender");session.activeHover=element;session.isTipOpen=true;tipElement.data(DATA_MOUSEONTOTIP,options.mouseOnToPopup);tipElement.addClass(options.popupClass);if(!options.followMouse||element.data(DATA_FORCEDOPEN)){positionTipOnElement(element);session.isFixedTipOpen=true}else{positionTipOnCursor()}if(!element.data(DATA_FORCEDOPEN)&&!options.followMouse){$document.on("click"+EVENT_NAMESPACE,function documentClick(event){var target=event.target;if(target!==element[0]){if(options.mouseOnToPopup){if(target!==tipElement[0]&&!$.contains(tipElement[0],target)){$.powerTip.hide()}}else{$.powerTip.hide()}}})}if(options.mouseOnToPopup&&!options.manual){tipElement.on("mouseenter"+EVENT_NAMESPACE,function tipMouseEnter(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).cancel()}});tipElement.on("mouseleave"+EVENT_NAMESPACE,function tipMouseLeave(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).hide()}})}tipElement.fadeIn(options.fadeInTime,function fadeInCallback(){if(!session.desyncTimeout){session.desyncTimeout=setInterval(closeDesyncedTip,500)}element.trigger("powerTipOpen")})}function hideTip(element){session.isClosing=true;session.isTipOpen=false;session.desyncTimeout=clearInterval(session.desyncTimeout);element.data(DATA_HASACTIVEHOVER,false);element.data(DATA_FORCEDOPEN,false);$document.off("click"+EVENT_NAMESPACE);tipElement.off(EVENT_NAMESPACE);tipElement.fadeOut(options.fadeOutTime,function fadeOutCallback(){var coords=new CSSCoordinates;session.activeHover=null;session.isClosing=false;session.isFixedTipOpen=false;tipElement.removeClass();coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);tipElement.css(coords);element.trigger("powerTipClose")})}function positionTipOnCursor(){var tipWidth,tipHeight,coords,collisions,collisionCount;if(!session.isFixedTipOpen&&(session.isTipOpen||session.tipOpenImminent&&tipElement.data(DATA_HASMOUSEMOVE))){tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=new CSSCoordinates;coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);collisions=getViewportCollisions(coords,tipWidth,tipHeight);if(collisions!==Collision.none){collisionCount=countFlags(collisions);if(collisionCount===1){if(collisions===Collision.right){coords.set("left",session.scrollLeft+session.windowWidth-tipWidth)}else if(collisions===Collision.bottom){coords.set("top",session.scrollTop+session.windowHeight-tipHeight)}}else{coords.set("left",session.currentX-tipWidth-options.offset);coords.set("top",session.currentY-tipHeight-options.offset)}}tipElement.css(coords)}}function positionTipOnElement(element){var priorityList,finalPlacement;if(options.smartPlacement||options.followMouse&&element.data(DATA_FORCEDOPEN)){priorityList=$.fn.powerTip.smartPlacementLists[options.placement];$.each(priorityList,function(idx,pos){var collisions=getViewportCollisions(placeTooltip(element,pos),tipElement.outerWidth(),tipElement.outerHeight());finalPlacement=pos;return collisions!==Collision.none})}else{placeTooltip(element,options.placement);finalPlacement=options.placement}tipElement.removeClass("w nw sw e ne se n s w se-alt sw-alt ne-alt nw-alt");tipElement.addClass(finalPlacement)}function placeTooltip(element,placement){var iterationCount=0,tipWidth,tipHeight,coords=new CSSCoordinates;coords.set("top",0);coords.set("left",0);tipElement.css(coords);do{tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=placementCalculator.compute(element,placement,tipWidth,tipHeight,options.offset);tipElement.css(coords)}while(++iterationCount<=5&&(tipWidth!==tipElement.outerWidth()||tipHeight!==tipElement.outerHeight()));return coords}function closeDesyncedTip(){var isDesynced=false,hasDesyncableCloseEvent=$.grep(["mouseleave","mouseout","blur","focusout"],function(eventType){return $.inArray(eventType,options.closeEvents)!==-1}).length>0;if(session.isTipOpen&&!session.isClosing&&!session.delayInProgress&&hasDesyncableCloseEvent){if(session.activeHover.data(DATA_HASACTIVEHOVER)===false||session.activeHover.is(":disabled")){isDesynced=true}else if(!isMouseOver(session.activeHover)&&!session.activeHover.is(":focus")&&!session.activeHover.data(DATA_FORCEDOPEN)){if(tipElement.data(DATA_MOUSEONTOTIP)){if(!isMouseOver(tipElement)){isDesynced=true}}else{isDesynced=true}}if(isDesynced){hideTip(session.activeHover)}}}this.showTip=beginShowTip;this.hideTip=hideTip;this.resetPosition=positionTipOnElement}function isSvgElement(element){return Boolean(window.SVGElement&&element[0]instanceof SVGElement)}function isMouseEvent(event){return Boolean(event&&$.inArray(event.type,MOUSE_EVENTS)>-1&&typeof event.pageX==="number")}function initTracking(){if(!session.mouseTrackingActive){session.mouseTrackingActive=true;getViewportDimensions();$(getViewportDimensions);$document.on("mousemove"+EVENT_NAMESPACE,trackMouse);$window.on("resize"+EVENT_NAMESPACE,trackResize);$window.on("scroll"+EVENT_NAMESPACE,trackScroll)}}function getViewportDimensions(){session.scrollLeft=$window.scrollLeft();session.scrollTop=$window.scrollTop();session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackResize(){session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackScroll(){var x=$window.scrollLeft(),y=$window.scrollTop();if(x!==session.scrollLeft){session.currentX+=x-session.scrollLeft;session.scrollLeft=x}if(y!==session.scrollTop){session.currentY+=y-session.scrollTop;session.scrollTop=y}}function trackMouse(event){session.currentX=event.pageX;session.currentY=event.pageY}function isMouseOver(element){var elementPosition=element.offset(),elementBox=element[0].getBoundingClientRect(),elementWidth=elementBox.right-elementBox.left,elementHeight=elementBox.bottom-elementBox.top;return session.currentX>=elementPosition.left&&session.currentX<=elementPosition.left+elementWidth&&session.currentY>=elementPosition.top&&session.currentY<=elementPosition.top+elementHeight}function getTooltipContent(element){var tipText=element.data(DATA_POWERTIP),tipObject=element.data(DATA_POWERTIPJQ),tipTarget=element.data(DATA_POWERTIPTARGET),targetElement,content;if(tipText){if($.isFunction(tipText)){tipText=tipText.call(element[0])}content=tipText}else if(tipObject){if($.isFunction(tipObject)){tipObject=tipObject.call(element[0])}if(tipObject.length>0){content=tipObject.clone(true,true)}}else if(tipTarget){targetElement=$("#"+tipTarget);if(targetElement.length>0){content=targetElement.html()}}return content}function getViewportCollisions(coords,elementWidth,elementHeight){var viewportTop=session.scrollTop,viewportLeft=session.scrollLeft,viewportBottom=viewportTop+session.windowHeight,viewportRight=viewportLeft+session.windowWidth,collisions=Collision.none;if(coords.topviewportBottom||Math.abs(coords.bottom-session.windowHeight)>viewportBottom){collisions|=Collision.bottom}if(coords.leftviewportRight){collisions|=Collision.left}if(coords.left+elementWidth>viewportRight||coords.right1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);/*! SmartMenus jQuery Plugin - v1.1.0 - September 17, 2017 + * http://www.smartmenus.org/ + * Copyright Vasil Dinkov, Vadikom Web Ltd. http://vadikom.com; Licensed MIT */(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof module&&"object"==typeof module.exports?module.exports=t(require("jquery")):t(jQuery)})(function($){function initMouseDetection(t){var e=".smartmenus_mouse";if(mouseDetectionEnabled||t)mouseDetectionEnabled&&t&&($(document).off(e),mouseDetectionEnabled=!1);else{var i=!0,s=null,o={mousemove:function(t){var e={x:t.pageX,y:t.pageY,timeStamp:(new Date).getTime()};if(s){var o=Math.abs(s.x-e.x),a=Math.abs(s.y-e.y);if((o>0||a>0)&&2>=o&&2>=a&&300>=e.timeStamp-s.timeStamp&&(mouse=!0,i)){var n=$(t.target).closest("a");n.is("a")&&$.each(menuTrees,function(){return $.contains(this.$root[0],n[0])?(this.itemEnter({currentTarget:n[0]}),!1):void 0}),i=!1}}s=e}};o[touchEvents?"touchstart":"pointerover pointermove pointerout MSPointerOver MSPointerMove MSPointerOut"]=function(t){isTouchEvent(t.originalEvent)&&(mouse=!1)},$(document).on(getEventsNS(o,e)),mouseDetectionEnabled=!0}}function isTouchEvent(t){return!/^(4|mouse)$/.test(t.pointerType)}function getEventsNS(t,e){e||(e="");var i={};for(var s in t)i[s.split(" ").join(e+" ")+e]=t[s];return i}var menuTrees=[],mouse=!1,touchEvents="ontouchstart"in window,mouseDetectionEnabled=!1,requestAnimationFrame=window.requestAnimationFrame||function(t){return setTimeout(t,1e3/60)},cancelAnimationFrame=window.cancelAnimationFrame||function(t){clearTimeout(t)},canAnimate=!!$.fn.animate;return $.SmartMenus=function(t,e){this.$root=$(t),this.opts=e,this.rootId="",this.accessIdPrefix="",this.$subArrow=null,this.activatedItems=[],this.visibleSubMenus=[],this.showTimeout=0,this.hideTimeout=0,this.scrollTimeout=0,this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.idInc=0,this.$firstLink=null,this.$firstSub=null,this.disabled=!1,this.$disableOverlay=null,this.$touchScrollingSub=null,this.cssTransforms3d="perspective"in t.style||"webkitPerspective"in t.style,this.wasCollapsible=!1,this.init()},$.extend($.SmartMenus,{hideAll:function(){$.each(menuTrees,function(){this.menuHideAll()})},destroy:function(){for(;menuTrees.length;)menuTrees[0].destroy();initMouseDetection(!0)},prototype:{init:function(t){var e=this;if(!t){menuTrees.push(this),this.rootId=((new Date).getTime()+Math.random()+"").replace(/\D/g,""),this.accessIdPrefix="sm-"+this.rootId+"-",this.$root.hasClass("sm-rtl")&&(this.opts.rightToLeftSubMenus=!0);var i=".smartmenus";this.$root.data("smartmenus",this).attr("data-smartmenus-id",this.rootId).dataSM("level",1).on(getEventsNS({"mouseover focusin":$.proxy(this.rootOver,this),"mouseout focusout":$.proxy(this.rootOut,this),keydown:$.proxy(this.rootKeyDown,this)},i)).on(getEventsNS({mouseenter:$.proxy(this.itemEnter,this),mouseleave:$.proxy(this.itemLeave,this),mousedown:$.proxy(this.itemDown,this),focus:$.proxy(this.itemFocus,this),blur:$.proxy(this.itemBlur,this),click:$.proxy(this.itemClick,this)},i),"a"),i+=this.rootId,this.opts.hideOnClick&&$(document).on(getEventsNS({touchstart:$.proxy(this.docTouchStart,this),touchmove:$.proxy(this.docTouchMove,this),touchend:$.proxy(this.docTouchEnd,this),click:$.proxy(this.docClick,this)},i)),$(window).on(getEventsNS({"resize orientationchange":$.proxy(this.winResize,this)},i)),this.opts.subIndicators&&(this.$subArrow=$("").addClass("sub-arrow"),this.opts.subIndicatorsText&&this.$subArrow.html(this.opts.subIndicatorsText)),initMouseDetection()}if(this.$firstSub=this.$root.find("ul").each(function(){e.menuInit($(this))}).eq(0),this.$firstLink=this.$root.find("a").eq(0),this.opts.markCurrentItem){var s=/(index|default)\.[^#\?\/]*/i,o=/#.*/,a=window.location.href.replace(s,""),n=a.replace(o,"");this.$root.find("a").each(function(){var t=this.href.replace(s,""),i=$(this);(t==a||t==n)&&(i.addClass("current"),e.opts.markCurrentTree&&i.parentsUntil("[data-smartmenus-id]","ul").each(function(){$(this).dataSM("parent-a").addClass("current")}))})}this.wasCollapsible=this.isCollapsible()},destroy:function(t){if(!t){var e=".smartmenus";this.$root.removeData("smartmenus").removeAttr("data-smartmenus-id").removeDataSM("level").off(e),e+=this.rootId,$(document).off(e),$(window).off(e),this.opts.subIndicators&&(this.$subArrow=null)}this.menuHideAll();var i=this;this.$root.find("ul").each(function(){var t=$(this);t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.dataSM("shown-before")&&((i.opts.subMenusMinWidth||i.opts.subMenusMaxWidth)&&t.css({width:"",minWidth:"",maxWidth:""}).removeClass("sm-nowrap"),t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.css({zIndex:"",top:"",left:"",marginLeft:"",marginTop:"",display:""})),0==(t.attr("id")||"").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeDataSM("in-mega").removeDataSM("shown-before").removeDataSM("scroll-arrows").removeDataSM("parent-a").removeDataSM("level").removeDataSM("beforefirstshowfired").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeAttr("aria-expanded"),this.$root.find("a.has-submenu").each(function(){var t=$(this);0==t.attr("id").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeClass("has-submenu").removeDataSM("sub").removeAttr("aria-haspopup").removeAttr("aria-controls").removeAttr("aria-expanded").closest("li").removeDataSM("sub"),this.opts.subIndicators&&this.$root.find("span.sub-arrow").remove(),this.opts.markCurrentItem&&this.$root.find("a.current").removeClass("current"),t||(this.$root=null,this.$firstLink=null,this.$firstSub=null,this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),menuTrees.splice($.inArray(this,menuTrees),1))},disable:function(t){if(!this.disabled){if(this.menuHideAll(),!t&&!this.opts.isPopup&&this.$root.is(":visible")){var e=this.$root.offset();this.$disableOverlay=$('
').css({position:"absolute",top:e.top,left:e.left,width:this.$root.outerWidth(),height:this.$root.outerHeight(),zIndex:this.getStartZIndex(!0),opacity:0}).appendTo(document.body)}this.disabled=!0}},docClick:function(t){return this.$touchScrollingSub?(this.$touchScrollingSub=null,void 0):((this.visibleSubMenus.length&&!$.contains(this.$root[0],t.target)||$(t.target).closest("a").length)&&this.menuHideAll(),void 0)},docTouchEnd:function(){if(this.lastTouch){if(!(!this.visibleSubMenus.length||void 0!==this.lastTouch.x2&&this.lastTouch.x1!=this.lastTouch.x2||void 0!==this.lastTouch.y2&&this.lastTouch.y1!=this.lastTouch.y2||this.lastTouch.target&&$.contains(this.$root[0],this.lastTouch.target))){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var t=this;this.hideTimeout=setTimeout(function(){t.menuHideAll()},350)}this.lastTouch=null}},docTouchMove:function(t){if(this.lastTouch){var e=t.originalEvent.touches[0];this.lastTouch.x2=e.pageX,this.lastTouch.y2=e.pageY}},docTouchStart:function(t){var e=t.originalEvent.touches[0];this.lastTouch={x1:e.pageX,y1:e.pageY,target:e.target}},enable:function(){this.disabled&&(this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),this.disabled=!1)},getClosestMenu:function(t){for(var e=$(t).closest("ul");e.dataSM("in-mega");)e=e.parent().closest("ul");return e[0]||null},getHeight:function(t){return this.getOffset(t,!0)},getOffset:function(t,e){var i;"none"==t.css("display")&&(i={position:t[0].style.position,visibility:t[0].style.visibility},t.css({position:"absolute",visibility:"hidden"}).show());var s=t[0].getBoundingClientRect&&t[0].getBoundingClientRect(),o=s&&(e?s.height||s.bottom-s.top:s.width||s.right-s.left);return o||0===o||(o=e?t[0].offsetHeight:t[0].offsetWidth),i&&t.hide().css(i),o},getStartZIndex:function(t){var e=parseInt(this[t?"$root":"$firstSub"].css("z-index"));return!t&&isNaN(e)&&(e=parseInt(this.$root.css("z-index"))),isNaN(e)?1:e},getTouchPoint:function(t){return t.touches&&t.touches[0]||t.changedTouches&&t.changedTouches[0]||t},getViewport:function(t){var e=t?"Height":"Width",i=document.documentElement["client"+e],s=window["inner"+e];return s&&(i=Math.min(i,s)),i},getViewportHeight:function(){return this.getViewport(!0)},getViewportWidth:function(){return this.getViewport()},getWidth:function(t){return this.getOffset(t)},handleEvents:function(){return!this.disabled&&this.isCSSOn()},handleItemEvents:function(t){return this.handleEvents()&&!this.isLinkInMegaMenu(t)},isCollapsible:function(){return"static"==this.$firstSub.css("position")},isCSSOn:function(){return"inline"!=this.$firstLink.css("display")},isFixed:function(){var t="fixed"==this.$root.css("position");return t||this.$root.parentsUntil("body").each(function(){return"fixed"==$(this).css("position")?(t=!0,!1):void 0}),t},isLinkInMegaMenu:function(t){return $(this.getClosestMenu(t[0])).hasClass("mega-menu")},isTouchMode:function(){return!mouse||this.opts.noMouseOver||this.isCollapsible()},itemActivate:function(t,e){var i=t.closest("ul"),s=i.dataSM("level");if(s>1&&(!this.activatedItems[s-2]||this.activatedItems[s-2][0]!=i.dataSM("parent-a")[0])){var o=this;$(i.parentsUntil("[data-smartmenus-id]","ul").get().reverse()).add(i).each(function(){o.itemActivate($(this).dataSM("parent-a"))})}if((!this.isCollapsible()||e)&&this.menuHideSubMenus(this.activatedItems[s-1]&&this.activatedItems[s-1][0]==t[0]?s:s-1),this.activatedItems[s-1]=t,this.$root.triggerHandler("activate.smapi",t[0])!==!1){var a=t.dataSM("sub");a&&(this.isTouchMode()||!this.opts.showOnClick||this.clickActivated)&&this.menuShow(a)}},itemBlur:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&this.$root.triggerHandler("blur.smapi",e[0])},itemClick:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(this.$touchScrollingSub&&this.$touchScrollingSub[0]==e.closest("ul")[0])return this.$touchScrollingSub=null,t.stopPropagation(),!1;if(this.$root.triggerHandler("click.smapi",e[0])===!1)return!1;var i=$(t.target).is(".sub-arrow"),s=e.dataSM("sub"),o=s?2==s.dataSM("level"):!1,a=this.isCollapsible(),n=/toggle$/.test(this.opts.collapsibleBehavior),r=/link$/.test(this.opts.collapsibleBehavior),h=/^accordion/.test(this.opts.collapsibleBehavior);if(s&&!s.is(":visible")){if((!r||!a||i)&&(this.opts.showOnClick&&o&&(this.clickActivated=!0),this.itemActivate(e,h),s.is(":visible")))return this.focusActivated=!0,!1}else if(a&&(n||i))return this.itemActivate(e,h),this.menuHide(s),n&&(this.focusActivated=!1),!1;return this.opts.showOnClick&&o||e.hasClass("disabled")||this.$root.triggerHandler("select.smapi",e[0])===!1?!1:void 0}},itemDown:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&e.dataSM("mousedown",!0)},itemEnter:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(!this.isTouchMode()){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);var i=this;this.showTimeout=setTimeout(function(){i.itemActivate(e)},this.opts.showOnClick&&1==e.closest("ul").dataSM("level")?1:this.opts.showTimeout)}this.$root.triggerHandler("mouseenter.smapi",e[0])}},itemFocus:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(!this.focusActivated||this.isTouchMode()&&e.dataSM("mousedown")||this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0]==e[0]||this.itemActivate(e,!0),this.$root.triggerHandler("focus.smapi",e[0]))},itemLeave:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(this.isTouchMode()||(e[0].blur(),this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0)),e.removeDataSM("mousedown"),this.$root.triggerHandler("mouseleave.smapi",e[0]))},menuHide:function(t){if(this.$root.triggerHandler("beforehide.smapi",t[0])!==!1&&(canAnimate&&t.stop(!0,!0),"none"!=t.css("display"))){var e=function(){t.css("z-index","")};this.isCollapsible()?canAnimate&&this.opts.collapsibleHideFunction?this.opts.collapsibleHideFunction.call(this,t,e):t.hide(this.opts.collapsibleHideDuration,e):canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,t,e):t.hide(this.opts.hideDuration,e),t.dataSM("scroll")&&(this.menuScrollStop(t),t.css({"touch-action":"","-ms-touch-action":"","-webkit-transform":"",transform:""}).off(".smartmenus_scroll").removeDataSM("scroll").dataSM("scroll-arrows").hide()),t.dataSM("parent-a").removeClass("highlighted").attr("aria-expanded","false"),t.attr({"aria-expanded":"false","aria-hidden":"true"});var i=t.dataSM("level");this.activatedItems.splice(i-1,1),this.visibleSubMenus.splice($.inArray(t,this.visibleSubMenus),1),this.$root.triggerHandler("hide.smapi",t[0])}},menuHideAll:function(){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);for(var t=this.opts.isPopup?1:0,e=this.visibleSubMenus.length-1;e>=t;e--)this.menuHide(this.visibleSubMenus[e]);this.opts.isPopup&&(canAnimate&&this.$root.stop(!0,!0),this.$root.is(":visible")&&(canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,this.$root):this.$root.hide(this.opts.hideDuration))),this.activatedItems=[],this.visibleSubMenus=[],this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.$root.triggerHandler("hideAll.smapi")},menuHideSubMenus:function(t){for(var e=this.activatedItems.length-1;e>=t;e--){var i=this.activatedItems[e].dataSM("sub");i&&this.menuHide(i)}},menuInit:function(t){if(!t.dataSM("in-mega")){t.hasClass("mega-menu")&&t.find("ul").dataSM("in-mega",!0);for(var e=2,i=t[0];(i=i.parentNode.parentNode)!=this.$root[0];)e++;var s=t.prevAll("a").eq(-1);s.length||(s=t.prevAll().find("a").eq(-1)),s.addClass("has-submenu").dataSM("sub",t),t.dataSM("parent-a",s).dataSM("level",e).parent().dataSM("sub",t);var o=s.attr("id")||this.accessIdPrefix+ ++this.idInc,a=t.attr("id")||this.accessIdPrefix+ ++this.idInc;s.attr({id:o,"aria-haspopup":"true","aria-controls":a,"aria-expanded":"false"}),t.attr({id:a,role:"group","aria-hidden":"true","aria-labelledby":o,"aria-expanded":"false"}),this.opts.subIndicators&&s[this.opts.subIndicatorsPos](this.$subArrow.clone())}},menuPosition:function(t){var e,i,s=t.dataSM("parent-a"),o=s.closest("li"),a=o.parent(),n=t.dataSM("level"),r=this.getWidth(t),h=this.getHeight(t),u=s.offset(),l=u.left,c=u.top,d=this.getWidth(s),m=this.getHeight(s),p=$(window),f=p.scrollLeft(),v=p.scrollTop(),b=this.getViewportWidth(),S=this.getViewportHeight(),g=a.parent().is("[data-sm-horizontal-sub]")||2==n&&!a.hasClass("sm-vertical"),M=this.opts.rightToLeftSubMenus&&!o.is("[data-sm-reverse]")||!this.opts.rightToLeftSubMenus&&o.is("[data-sm-reverse]"),w=2==n?this.opts.mainMenuSubOffsetX:this.opts.subMenusSubOffsetX,T=2==n?this.opts.mainMenuSubOffsetY:this.opts.subMenusSubOffsetY;if(g?(e=M?d-r-w:w,i=this.opts.bottomToTopSubMenus?-h-T:m+T):(e=M?w-r:d-w,i=this.opts.bottomToTopSubMenus?m-T-h:T),this.opts.keepInViewport){var y=l+e,I=c+i;if(M&&f>y?e=g?f-y+e:d-w:!M&&y+r>f+b&&(e=g?f+b-r-y+e:w-r),g||(S>h&&I+h>v+S?i+=v+S-h-I:(h>=S||v>I)&&(i+=v-I)),g&&(I+h>v+S+.49||v>I)||!g&&h>S+.49){var x=this;t.dataSM("scroll-arrows")||t.dataSM("scroll-arrows",$([$('')[0],$('')[0]]).on({mouseenter:function(){t.dataSM("scroll").up=$(this).hasClass("scroll-up"),x.menuScroll(t)},mouseleave:function(e){x.menuScrollStop(t),x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(t){t.preventDefault()}}).insertAfter(t));var A=".smartmenus_scroll";if(t.dataSM("scroll",{y:this.cssTransforms3d?0:i-m,step:1,itemH:m,subH:h,arrowDownH:this.getHeight(t.dataSM("scroll-arrows").eq(1))}).on(getEventsNS({mouseover:function(e){x.menuScrollOver(t,e)},mouseout:function(e){x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(e){x.menuScrollMousewheel(t,e)}},A)).dataSM("scroll-arrows").css({top:"auto",left:"0",marginLeft:e+(parseInt(t.css("border-left-width"))||0),width:r-(parseInt(t.css("border-left-width"))||0)-(parseInt(t.css("border-right-width"))||0),zIndex:t.css("z-index")}).eq(g&&this.opts.bottomToTopSubMenus?0:1).show(),this.isFixed()){var C={};C[touchEvents?"touchstart touchmove touchend":"pointerdown pointermove pointerup MSPointerDown MSPointerMove MSPointerUp"]=function(e){x.menuScrollTouch(t,e)},t.css({"touch-action":"none","-ms-touch-action":"none"}).on(getEventsNS(C,A))}}}t.css({top:"auto",left:"0",marginLeft:e,marginTop:i-m})},menuScroll:function(t,e,i){var s,o=t.dataSM("scroll"),a=t.dataSM("scroll-arrows"),n=o.up?o.upEnd:o.downEnd;if(!e&&o.momentum){if(o.momentum*=.92,s=o.momentum,.5>s)return this.menuScrollStop(t),void 0}else s=i||(e||!this.opts.scrollAccelerate?this.opts.scrollStep:Math.floor(o.step));var r=t.dataSM("level");if(this.activatedItems[r-1]&&this.activatedItems[r-1].dataSM("sub")&&this.activatedItems[r-1].dataSM("sub").is(":visible")&&this.menuHideSubMenus(r-1),o.y=o.up&&o.y>=n||!o.up&&n>=o.y?o.y:Math.abs(n-o.y)>s?o.y+(o.up?s:-s):n,t.css(this.cssTransforms3d?{"-webkit-transform":"translate3d(0, "+o.y+"px, 0)",transform:"translate3d(0, "+o.y+"px, 0)"}:{marginTop:o.y}),mouse&&(o.up&&o.y>o.downEnd||!o.up&&o.y0;t.dataSM("scroll-arrows").eq(i?0:1).is(":visible")&&(t.dataSM("scroll").up=i,this.menuScroll(t,!0))}e.preventDefault()},menuScrollOut:function(t,e){mouse&&(/^scroll-(up|down)/.test((e.relatedTarget||"").className)||(t[0]==e.relatedTarget||$.contains(t[0],e.relatedTarget))&&this.getClosestMenu(e.relatedTarget)==t[0]||t.dataSM("scroll-arrows").css("visibility","hidden"))},menuScrollOver:function(t,e){if(mouse&&!/^scroll-(up|down)/.test(e.target.className)&&this.getClosestMenu(e.target)==t[0]){this.menuScrollRefreshData(t);var i=t.dataSM("scroll"),s=$(window).scrollTop()-t.dataSM("parent-a").offset().top-i.itemH;t.dataSM("scroll-arrows").eq(0).css("margin-top",s).end().eq(1).css("margin-top",s+this.getViewportHeight()-i.arrowDownH).end().css("visibility","visible")}},menuScrollRefreshData:function(t){var e=t.dataSM("scroll"),i=$(window).scrollTop()-t.dataSM("parent-a").offset().top-e.itemH;this.cssTransforms3d&&(i=-(parseFloat(t.css("margin-top"))-i)),$.extend(e,{upEnd:i,downEnd:i+this.getViewportHeight()-e.subH})},menuScrollStop:function(t){return this.scrollTimeout?(cancelAnimationFrame(this.scrollTimeout),this.scrollTimeout=0,t.dataSM("scroll").step=1,!0):void 0},menuScrollTouch:function(t,e){if(e=e.originalEvent,isTouchEvent(e)){var i=this.getTouchPoint(e);if(this.getClosestMenu(i.target)==t[0]){var s=t.dataSM("scroll");if(/(start|down)$/i.test(e.type))this.menuScrollStop(t)?(e.preventDefault(),this.$touchScrollingSub=t):this.$touchScrollingSub=null,this.menuScrollRefreshData(t),$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp});else if(/move$/i.test(e.type)){var o=void 0!==s.touchY?s.touchY:s.touchStartY;if(void 0!==o&&o!=i.pageY){this.$touchScrollingSub=t;var a=i.pageY>o;void 0!==s.up&&s.up!=a&&$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp}),$.extend(s,{up:a,touchY:i.pageY}),this.menuScroll(t,!0,Math.abs(i.pageY-o))}e.preventDefault()}else void 0!==s.touchY&&((s.momentum=15*Math.pow(Math.abs(i.pageY-s.touchStartY)/(e.timeStamp-s.touchStartTime),2))&&(this.menuScrollStop(t),this.menuScroll(t),e.preventDefault()),delete s.touchY)}}},menuShow:function(t){if((t.dataSM("beforefirstshowfired")||(t.dataSM("beforefirstshowfired",!0),this.$root.triggerHandler("beforefirstshow.smapi",t[0])!==!1))&&this.$root.triggerHandler("beforeshow.smapi",t[0])!==!1&&(t.dataSM("shown-before",!0),canAnimate&&t.stop(!0,!0),!t.is(":visible"))){var e=t.dataSM("parent-a"),i=this.isCollapsible();if((this.opts.keepHighlighted||i)&&e.addClass("highlighted"),i)t.removeClass("sm-nowrap").css({zIndex:"",width:"auto",minWidth:"",maxWidth:"",top:"",left:"",marginLeft:"",marginTop:""});else{if(t.css("z-index",this.zIndexInc=(this.zIndexInc||this.getStartZIndex())+1),(this.opts.subMenusMinWidth||this.opts.subMenusMaxWidth)&&(t.css({width:"auto",minWidth:"",maxWidth:""}).addClass("sm-nowrap"),this.opts.subMenusMinWidth&&t.css("min-width",this.opts.subMenusMinWidth),this.opts.subMenusMaxWidth)){var s=this.getWidth(t);t.css("max-width",this.opts.subMenusMaxWidth),s>this.getWidth(t)&&t.removeClass("sm-nowrap").css("width",this.opts.subMenusMaxWidth)}this.menuPosition(t)}var o=function(){t.css("overflow","")};i?canAnimate&&this.opts.collapsibleShowFunction?this.opts.collapsibleShowFunction.call(this,t,o):t.show(this.opts.collapsibleShowDuration,o):canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,t,o):t.show(this.opts.showDuration,o),e.attr("aria-expanded","true"),t.attr({"aria-expanded":"true","aria-hidden":"false"}),this.visibleSubMenus.push(t),this.$root.triggerHandler("show.smapi",t[0])}},popupHide:function(t){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},t?1:this.opts.hideTimeout)},popupShow:function(t,e){if(!this.opts.isPopup)return alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'),void 0;if(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),this.$root.dataSM("shown-before",!0),canAnimate&&this.$root.stop(!0,!0),!this.$root.is(":visible")){this.$root.css({left:t,top:e});var i=this,s=function(){i.$root.css("overflow","")};canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,this.$root,s):this.$root.show(this.opts.showDuration,s),this.visibleSubMenus[0]=this.$root}},refresh:function(){this.destroy(!0),this.init(!0)},rootKeyDown:function(t){if(this.handleEvents())switch(t.keyCode){case 27:var e=this.activatedItems[0];if(e){this.menuHideAll(),e[0].focus();var i=e.dataSM("sub");i&&this.menuHide(i)}break;case 32:var s=$(t.target);if(s.is("a")&&this.handleItemEvents(s)){var i=s.dataSM("sub");i&&!i.is(":visible")&&(this.itemClick({currentTarget:t.target}),t.preventDefault())}}},rootOut:function(t){if(this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),!this.opts.showOnClick||!this.opts.hideOnClick)){var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},this.opts.hideTimeout)}},rootOver:function(t){this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0)},winResize:function(t){if(this.handleEvents()){if(!("onorientationchange"in window)||"orientationchange"==t.type){var e=this.isCollapsible();this.wasCollapsible&&e||(this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0].blur(),this.menuHideAll()),this.wasCollapsible=e}}else if(this.$disableOverlay){var i=this.$root.offset();this.$disableOverlay.css({top:i.top,left:i.left,width:this.$root.outerWidth(),height:this.$root.outerHeight()})}}}}),$.fn.dataSM=function(t,e){return e?this.data(t+"_smartmenus",e):this.data(t+"_smartmenus")},$.fn.removeDataSM=function(t){return this.removeData(t+"_smartmenus")},$.fn.smartmenus=function(options){if("string"==typeof options){var args=arguments,method=options;return Array.prototype.shift.call(args),this.each(function(){var t=$(this).data("smartmenus");t&&t[method]&&t[method].apply(t,args)})}return this.each(function(){var dataOpts=$(this).data("sm-options")||null;if(dataOpts)try{dataOpts=eval("("+dataOpts+")")}catch(e){dataOpts=null,alert('ERROR\n\nSmartMenus jQuery init:\nInvalid "data-sm-options" attribute value syntax.')}new $.SmartMenus(this,$.extend({},$.fn.smartmenus.defaults,options,dataOpts))})},$.fn.smartmenus.defaults={isPopup:!1,mainMenuSubOffsetX:0,mainMenuSubOffsetY:0,subMenusSubOffsetX:0,subMenusSubOffsetY:0,subMenusMinWidth:"10em",subMenusMaxWidth:"20em",subIndicators:!0,subIndicatorsPos:"append",subIndicatorsText:"",scrollStep:30,scrollAccelerate:!0,showTimeout:250,hideTimeout:500,showDuration:0,showFunction:null,hideDuration:0,hideFunction:function(t,e){t.fadeOut(200,e)},collapsibleShowDuration:0,collapsibleShowFunction:function(t,e){t.slideDown(200,e)},collapsibleHideDuration:0,collapsibleHideFunction:function(t,e){t.slideUp(200,e)},showOnClick:!1,hideOnClick:!0,noMouseOver:!1,keepInViewport:!0,keepHighlighted:!0,markCurrentItem:!1,markCurrentTree:!0,rightToLeftSubMenus:!1,bottomToTopSubMenus:!1,collapsibleBehavior:"default"},$}); \ No newline at end of file diff --git a/docs/html/md_readme.html b/docs/html/md_readme.html new file mode 100644 index 00000000..c4979525 --- /dev/null +++ b/docs/html/md_readme.html @@ -0,0 +1,275 @@ + + + + + + + +Firmata firmware for Arduino: Firmata + + + + + + + + + +
+
+ + + + + + +
+
Firmata firmware for Arduino +
+
Firmata is a protocol for communicating with microcontrollers from software on a host computer
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
Firmata
+
+
+

Gitter

+

Firmata is a protocol for communicating with microcontrollers from software on a host computer. The protocol can be implemented in firmware on any microcontroller architecture as well as software on any host computer software package. The Arduino repository described here is a Firmata library for Arduino and Arduino-compatible devices. If you would like to contribute to Firmata, please see the Contributing section below.

+

+Contents

+ +

+Usage

+

There are two main models of usage of Firmata. In one model, the author of the Arduino sketch uses the various methods provided by the Firmata library to selectively send and receive data between the Arduino device and the software running on the host computer. For example, a user can send analog data to the host using Firmata.sendAnalog(analogPin, analogRead(analogPin)) or send data packed in a string using Firmata.sendString(stringToSend). See File -> Examples -> Firmata -> AnalogFirmata & EchoString respectively for examples.

+

The second and more common model is to load a general purpose sketch called StandardFirmata (or one of the variants such as StandardFirmataPlus or StandardFirmataEthernet depending on your needs) on the Arduino board and then use the host computer exclusively to interact with the Arduino board. StandardFirmata is located in the Arduino IDE in File -> Examples -> Firmata.

+

+Firmata Client Libraries

+

Most of the time you will be interacting with Arduino with a client library on the host computers. Several Firmata client libraries have been implemented in a variety of popular programming languages:

+ +

Note: The above libraries may support various versions of the Firmata protocol and therefore may not support all features of the latest Firmata spec nor all Arduino and Arduino-compatible boards. Refer to the respective projects for details.

+

+Updating Firmata in the Arduino IDE - Arduino 1.6.4 and higher

+

If you want to update to the latest stable version:

+
    +
  1. Open the Arduino IDE and navigate to: Sketch > Include Library > Manage Libraries
  2. +
  3. Filter by "Firmata" and click on the "Firmata by Firmata Developers" item in the list of results.
  4. +
  5. Click the Select version dropdown and select the most recent version (note you can also install previous versions)
  6. +
  7. Click Install.
  8. +
+

+Cloning Firmata

+

If you are contributing to Firmata or otherwise need a version newer than the latest tagged release, you can clone Firmata directly to your Arduino/libraries/ directory (where 3rd party libraries are installed). This only works for Arduino 1.6.4 and higher, for older versions you need to clone into the Arduino application directory (see section below titled "Using the Source code rather than release archive"). Be sure to change the name to Firmata as follows:

+
$ git clone git@github.com:firmata/arduino.git ~/Documents/Arduino/libraries/Firmata
+

Update path above if you're using Windows or Linux or changed the default Arduino directory on OS X

+

+Updating Firmata in the Arduino IDE - older versions (<= 1.6.3 or 1.0.x)

+

Download the latest release (for Arduino 1.0.x or Arduino 1.5.6 or higher) and replace the existing Firmata folder in your Arduino application. See the instructions below for your platform.

+

Note that Arduino 1.5.0 - 1.5.5 are not supported. Please use Arduino 1.5.6 or higher (or Arduino 1.0.5 or 1.0.6).

+

+Mac OSX:

+

The Firmata library is contained within the Arduino package.

+
    +
  1. Navigate to the Arduino application
  2. +
  3. Right click on the application icon and select Show Package Contents
  4. +
  5. Navigate to: /Contents/Resources/Java/libraries/ and replace the existing Firmata folder with latest Firmata release (note there is a different download for Arduino 1.0.x vs 1.6.x)
  6. +
  7. Restart the Arduino application and the latest version of Firmata will be available.
  8. +
+

If you are using the Java 7 version of Arduino 1.5.7 or higher, the file path will differ slightly: Contents/Java/libraries/Firmata (no Resources directory).

+

+Windows:

+
    +
  1. Navigate to c:/Program\ Files/arduino-1.x/libraries/ and replace the existing Firmata folder with the latest Firmata release (note there is a different download for Arduino 1.0.x vs 1.6.x).
  2. +
  3. Restart the Arduino application and the latest version of Firmata will be available.
  4. +
+

Update the path and Arduino version as necessary

+

+Linux:

+
    +
  1. Navigate to ~/arduino-1.x/libraries/ and replace the existing Firmata folder with the latest Firmata release (note there is a different download for Arduino 1.0.x vs 1.6.x).
  2. +
  3. Restart the Arduino application and the latest version of Firmata will be available.
  4. +
+

Update the path and Arduino version as necessary

+

+Using the Source code rather than release archive (only for versions older than Arduino 1.6.3)

+

It is recommended you update to Arduino 1.6.4 or higher if possible, that way you can clone directly into the external Arduino/libraries/ directory which persists between Arduino application updates. Otherwise you will need to move your clone each time you update to a newer version of the Arduino IDE.

+

If you're stuck with an older version of the IDE, then follow these keep reading otherwise jump up to the "Cloning Firmata section above".

+

Clone this repo directly into the core Arduino application libraries directory. If you are using Arduino 1.5.x or <= 1.6.3, the repo directory structure will not match the Arduino library format, however it should still compile as long as you are using Arduino 1.5.7 or higher.

+

You will first need to remove the existing Firmata library, then clone firmata/arduino into an empty Firmata directory:

+
$ rm -r /Applications/Arduino.app/Contents/Resources/Java/libraries/Firmata
+
$ git clone git@github.com:firmata/arduino.git /Applications/Arduino.app/Contents/Resources/Java/libraries/Firmata
+

Update paths if you're using Windows or Linux

+

To generate properly formatted versions of Firmata (for Arduino 1.0.x and Arduino 1.6.x), run the release.sh script.

+

+Contributing

+

If you discover a bug or would like to propose a new feature, please open a new issue. Due to the limited memory of standard Arduino boards we cannot add every requested feature to StandardFirmata. Requests to add new features to StandardFirmata will be evaluated by the Firmata developers. However it is still possible to add new features to other Firmata implementations (Firmata is a protocol whereas StandardFirmata is just one of many possible implementations).

+

To contribute, fork this repository and create a new topic branch for the bug, feature or other existing issue you are addressing. Submit the pull request against the master branch.

+

If you would like to contribute but don't have a specific bugfix or new feature to contribute, you can take on an existing issue, see issues labeled "pull-request-encouraged". Add a comment to the issue to express your intent to begin work and/or to get any additional information about the issue.

+

You must thoroughly test your contributed code. In your pull request, describe tests performed to ensure that no existing code is broken and that any changes maintain backwards compatibility with the existing api. Test on multiple Arduino board variants if possible. We hope to enable some form of automated (or at least semi-automated) testing in the future, but for now any tests will need to be executed manually by the contributor and reviewers.

+

Use Artistic Style (astyle) to format your code. Set the following rules for the astyle formatter:

+
style = ""
+
indent-spaces = 2
+
indent-classes = true
+
indent-switches = true
+
indent-cases = true
+
indent-col1-comments = true
+
pad-oper = true
+
pad-header = true
+
keep-one-line-statements = true
+

If you happen to use Sublime Text, this astyle plugin is helpful. Set the above rules in the user settings file.

+
+
+ + + + diff --git a/docs/html/menu.js b/docs/html/menu.js new file mode 100644 index 00000000..433c15b8 --- /dev/null +++ b/docs/html/menu.js @@ -0,0 +1,50 @@ +/* + @licstart The following is the entire license notice for the + JavaScript code in this file. + + Copyright (C) 1997-2017 by Dimitri van Heesch + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + @licend The above is the entire license notice + for the JavaScript code in this file + */ +function initMenu(relPath,searchEnabled,serverSide,searchPage,search) { + function makeTree(data,relPath) { + var result=''; + if ('children' in data) { + result+=''; + } + return result; + } + + $('#main-nav').append(makeTree(menudata,relPath)); + $('#main-nav').children(':first').addClass('sm sm-dox').attr('id','main-menu'); + if (searchEnabled) { + if (serverSide) { + $('#main-menu').append('
  • '); + } else { + $('#main-menu').append('
  • '); + } + } + $('#main-menu').smartmenus(); +} +/* @license-end */ diff --git a/docs/html/menudata.js b/docs/html/menudata.js new file mode 100644 index 00000000..dc5f7896 --- /dev/null +++ b/docs/html/menudata.js @@ -0,0 +1,56 @@ +/* +@licstart The following is the entire license notice for the +JavaScript code in this file. + +Copyright (C) 1997-2019 by Dimitri van Heesch + +This program is free software; you can redistribute it and/or modify +it under the terms of version 2 of the GNU General Public License as published by +the Free Software Foundation + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +@licend The above is the entire license notice +for the JavaScript code in this file +*/ +var menudata={children:[ +{text:"Main Page",url:"index.html"}, +{text:"Classes",url:"annotated.html",children:[ +{text:"Class List",url:"annotated.html"}, +{text:"Class Index",url:"classes.html"}, +{text:"Class Members",url:"functions.html",children:[ +{text:"All",url:"functions.html",children:[ +{text:"a",url:"functions.html#index_a"}, +{text:"b",url:"functions.html#index_b"}, +{text:"d",url:"functions.html#index_d"}, +{text:"e",url:"functions.html#index_e"}, +{text:"f",url:"functions.html#index_f"}, +{text:"g",url:"functions.html#index_g"}, +{text:"i",url:"functions.html#index_i"}, +{text:"p",url:"functions.html#index_p"}, +{text:"q",url:"functions.html#index_q"}, +{text:"r",url:"functions.html#index_r"}, +{text:"s",url:"functions.html#index_s"}, +{text:"w",url:"functions.html#index_w"}]}, +{text:"Functions",url:"functions_func.html",children:[ +{text:"a",url:"functions_func.html#index_a"}, +{text:"b",url:"functions_func.html#index_b"}, +{text:"d",url:"functions_func.html#index_d"}, +{text:"e",url:"functions_func.html#index_e"}, +{text:"f",url:"functions_func.html#index_f"}, +{text:"g",url:"functions_func.html#index_g"}, +{text:"i",url:"functions_func.html#index_i"}, +{text:"p",url:"functions_func.html#index_p"}, +{text:"q",url:"functions_func.html#index_q"}, +{text:"r",url:"functions_func.html#index_r"}, +{text:"s",url:"functions_func.html#index_s"}, +{text:"w",url:"functions_func.html#index_w"}]}]}]}, +{text:"Files",url:"files.html",children:[ +{text:"File List",url:"files.html"}]}]} diff --git a/docs/html/nav_f.png b/docs/html/nav_f.png new file mode 100644 index 0000000000000000000000000000000000000000..72a58a529ed3a9ed6aa0c51a79cf207e026deee2 GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI`!2~2XGqLUlQVE_ejv*C{Z|{2ZH7M}7UYxc) zn!W8uqtnIQ>_z8U literal 0 HcmV?d00001 diff --git a/docs/html/nav_g.png b/docs/html/nav_g.png new file mode 100644 index 0000000000000000000000000000000000000000..2093a237a94f6c83e19ec6e5fd42f7ddabdafa81 GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^j6lrB!3HFm1ilyoDK$?Q$B+ufw|5PB85lU25BhtE tr?otc=hd~V+ws&_A@j8Fiv!KF$B+ufw|5=67#uj90@pIL wZ=Q8~_Ju`#59=RjDrmm`tMD@M=!-l18IR?&vFVdQ&MBb@0HFXL1|%O$WD@{VPM$7~Ar*{o?;hlAFyLXmaDC0y znK1_#cQqJWPES%4Uujug^TE?jMft$}Eq^WaR~)%f)vSNs&gek&x%A9X9sM + + + + + + +Firmata firmware for Arduino: Related Pages + + + + + + + + + +
    +
    + + + + + + +
    +
    Firmata firmware for Arduino +
    +
    Firmata is a protocol for communicating with microcontrollers from software on a host computer
    +
    +
    + + + + + + + +
    + +
    +
    + + +
    + +
    + +
    +
    +
    Related Pages
    +
    +
    +
    Here is a list of all related documentation pages:
    + + +
     Firmata
    +
    +
    + + + + diff --git a/docs/html/search/all_0.html b/docs/html/search/all_0.html new file mode 100644 index 00000000..a52d5f05 --- /dev/null +++ b/docs/html/search/all_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/all_0.js b/docs/html/search/all_0.js new file mode 100644 index 00000000..b0514350 --- /dev/null +++ b/docs/html/search/all_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['attach_0',['attach',['../classfirmata_1_1_firmata_class.html#adc3db897058f33e902097ce89bb01bb3',1,'firmata::FirmataClass::attach(uint8_t command, systemCallbackFunction newFunction)'],['../classfirmata_1_1_firmata_class.html#a074887a70f9aca0c0aae7e9bdc103f77',1,'firmata::FirmataClass::attach(uint8_t command, stringCallbackFunction newFunction)'],['../classfirmata_1_1_firmata_class.html#a78e360c0c8d70cffeb9c935fdec23f77',1,'firmata::FirmataClass::attach(uint8_t command, sysexCallbackFunction newFunction)'],['../classfirmata_1_1_firmata_parser.html#a2a472a925ed7e626ed36dee94ceae45e',1,'firmata::FirmataParser::attach(uint8_t command, callbackFunction newFunction, void *context=NULL)'],['../classfirmata_1_1_firmata_parser.html#ae176414892a2d240b921c2b8037a8ade',1,'firmata::FirmataParser::attach(dataBufferOverflowCallbackFunction newFunction, void *context=NULL)'],['../classfirmata_1_1_firmata_parser.html#a239b37e09dea042d229fc2171d3a1979',1,'firmata::FirmataParser::attach(uint8_t command, stringCallbackFunction newFunction, void *context=NULL)'],['../classfirmata_1_1_firmata_parser.html#aaa1d755b20b21e528bfa62d6a7c2dc0f',1,'firmata::FirmataParser::attach(uint8_t command, sysexCallbackFunction newFunction, void *context=NULL)'],['../classfirmata_1_1_firmata_parser.html#affc821e7742d889965e61b248c204842',1,'firmata::FirmataParser::attach(uint8_t command, systemCallbackFunction newFunction, void *context=NULL)'],['../classfirmata_1_1_firmata_parser.html#a876105f2203f5e8f1fb06c8236a96933',1,'firmata::FirmataParser::attach(uint8_t command, versionCallbackFunction newFunction, void *context=NULL)']]], + ['available_1',['available',['../classfirmata_1_1_firmata_class.html#a119734b867186567c1cd011e52e59d2d',1,'firmata::FirmataClass']]] +]; diff --git a/docs/html/search/all_1.html b/docs/html/search/all_1.html new file mode 100644 index 00000000..0fcb7040 --- /dev/null +++ b/docs/html/search/all_1.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/all_1.js b/docs/html/search/all_1.js new file mode 100644 index 00000000..bda5c136 --- /dev/null +++ b/docs/html/search/all_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['begin_2',['begin',['../classfirmata_1_1_firmata_class.html#a2fddcc643892bec2f4aa7aef6dba70eb',1,'firmata::FirmataClass::begin()'],['../classfirmata_1_1_firmata_class.html#ab0b7b837d2c32b4ce79e62895ced2731',1,'firmata::FirmataClass::begin(long)'],['../classfirmata_1_1_firmata_class.html#a0c7b0e10168e3c5dc6442d77c65a156e',1,'firmata::FirmataClass::begin(Stream &s)'],['../classfirmata_1_1_firmata_marshaller.html#a5be18ca3658875dbe5580c2254071c76',1,'firmata::FirmataMarshaller::begin()']]], + ['blinkversion_3',['blinkVersion',['../classfirmata_1_1_firmata_class.html#a9421550f2501fc1df60fd174b154e606',1,'firmata::FirmataClass']]] +]; diff --git a/docs/html/search/all_2.html b/docs/html/search/all_2.html new file mode 100644 index 00000000..19c530f2 --- /dev/null +++ b/docs/html/search/all_2.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/all_2.js b/docs/html/search/all_2.js new file mode 100644 index 00000000..eb289a71 --- /dev/null +++ b/docs/html/search/all_2.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['detach_4',['detach',['../classfirmata_1_1_firmata_class.html#a5db0faee74b9291d1b783d2dde0929d1',1,'firmata::FirmataClass::detach()'],['../classfirmata_1_1_firmata_parser.html#a7cd707386c0807bee733a3e27d161c7d',1,'firmata::FirmataParser::detach(uint8_t command)'],['../classfirmata_1_1_firmata_parser.html#a280ac17e428f8374afd30bce75e9a861',1,'firmata::FirmataParser::detach(dataBufferOverflowCallbackFunction)']]], + ['disableblinkversion_5',['disableBlinkVersion',['../classfirmata_1_1_firmata_class.html#a5ddba465c3772f841828ef82c79d4307',1,'firmata::FirmataClass']]] +]; diff --git a/docs/html/search/all_3.html b/docs/html/search/all_3.html new file mode 100644 index 00000000..1ae887fc --- /dev/null +++ b/docs/html/search/all_3.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/all_3.js b/docs/html/search/all_3.js new file mode 100644 index 00000000..f78f16bd --- /dev/null +++ b/docs/html/search/all_3.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['end_6',['end',['../classfirmata_1_1_firmata_marshaller.html#ab856434fc577b1e069cba51c39daf1de',1,'firmata::FirmataMarshaller']]], + ['endsysex_7',['endSysex',['../classfirmata_1_1_firmata_class.html#a9bb68afbb1d37a7990f59a1d419e64c9',1,'firmata::FirmataClass']]] +]; diff --git a/docs/html/search/all_4.html b/docs/html/search/all_4.html new file mode 100644 index 00000000..14c90ef5 --- /dev/null +++ b/docs/html/search/all_4.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/all_4.js b/docs/html/search/all_4.js new file mode 100644 index 00000000..5ebeac62 --- /dev/null +++ b/docs/html/search/all_4.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['firmataclass_8',['FirmataClass',['../classfirmata_1_1_firmata_class.html',1,'firmata::FirmataClass'],['../classfirmata_1_1_firmata_class.html#a75b035ab8d96d87d28deeb87badfe11a',1,'firmata::FirmataClass::FirmataClass()']]], + ['firmatamarshaller_9',['FirmataMarshaller',['../classfirmata_1_1_firmata_marshaller.html',1,'firmata::FirmataMarshaller'],['../classfirmata_1_1_firmata_marshaller.html#ad1a42532bdf77088c47c1a62f5a03829',1,'firmata::FirmataMarshaller::FirmataMarshaller()']]], + ['firmataparser_10',['FirmataParser',['../classfirmata_1_1_firmata_parser.html',1,'firmata::FirmataParser'],['../classfirmata_1_1_firmata_parser.html#ac8c388b593a00e88856646712beae68b',1,'firmata::FirmataParser::FirmataParser()']]], + ['firmata_11',['Firmata',['../index.html',1,'']]] +]; diff --git a/docs/html/search/all_5.html b/docs/html/search/all_5.html new file mode 100644 index 00000000..60fa53e9 --- /dev/null +++ b/docs/html/search/all_5.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/all_5.js b/docs/html/search/all_5.js new file mode 100644 index 00000000..3a076e7b --- /dev/null +++ b/docs/html/search/all_5.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['getpinmode_12',['getPinMode',['../classfirmata_1_1_firmata_class.html#a0c434227456ce2ba97b3b1142c329f96',1,'firmata::FirmataClass']]], + ['getpinstate_13',['getPinState',['../classfirmata_1_1_firmata_class.html#acf5d4f460b9a2298653d4a71de918dfe',1,'firmata::FirmataClass']]] +]; diff --git a/docs/html/search/all_6.html b/docs/html/search/all_6.html new file mode 100644 index 00000000..71803631 --- /dev/null +++ b/docs/html/search/all_6.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/all_6.js b/docs/html/search/all_6.js new file mode 100644 index 00000000..da4c8abb --- /dev/null +++ b/docs/html/search/all_6.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['isparsingmessage_14',['isParsingMessage',['../classfirmata_1_1_firmata_class.html#a58e9d787957c3085f22d33b59b1f6ea6',1,'firmata::FirmataClass::isParsingMessage()'],['../classfirmata_1_1_firmata_parser.html#a67902b70695eaf0cf8f7b06175ca3902',1,'firmata::FirmataParser::isParsingMessage()']]] +]; diff --git a/docs/html/search/all_7.html b/docs/html/search/all_7.html new file mode 100644 index 00000000..ee6d2e4a --- /dev/null +++ b/docs/html/search/all_7.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/all_7.js b/docs/html/search/all_7.js new file mode 100644 index 00000000..923c587c --- /dev/null +++ b/docs/html/search/all_7.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['parse_15',['parse',['../classfirmata_1_1_firmata_class.html#aaeaac8b1f8facf070615b0035120c432',1,'firmata::FirmataClass::parse()'],['../classfirmata_1_1_firmata_parser.html#a754c97b890b7fd66c8d953a3e615acbf',1,'firmata::FirmataParser::parse()']]], + ['printfirmwareversion_16',['printFirmwareVersion',['../classfirmata_1_1_firmata_class.html#abe49261eab0bd4892a09fa8b8980b11a',1,'firmata::FirmataClass']]], + ['printversion_17',['printVersion',['../classfirmata_1_1_firmata_class.html#abd8a0370db6d9e923e7e3d5836e78d7a',1,'firmata::FirmataClass']]], + ['processinput_18',['processInput',['../classfirmata_1_1_firmata_class.html#aa698f5f5a234173d5eebb54831350676',1,'firmata::FirmataClass']]] +]; diff --git a/docs/html/search/all_8.html b/docs/html/search/all_8.html new file mode 100644 index 00000000..7829aa40 --- /dev/null +++ b/docs/html/search/all_8.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/all_8.js b/docs/html/search/all_8.js new file mode 100644 index 00000000..518d5d64 --- /dev/null +++ b/docs/html/search/all_8.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['queryfirmwareversion_19',['queryFirmwareVersion',['../classfirmata_1_1_firmata_marshaller.html#af954bcf09b77458b3c4f032897d14697',1,'firmata::FirmataMarshaller']]], + ['queryversion_20',['queryVersion',['../classfirmata_1_1_firmata_marshaller.html#a488fbbd372c894ec78ebb99e0faf5167',1,'firmata::FirmataMarshaller']]] +]; diff --git a/docs/html/search/all_9.html b/docs/html/search/all_9.html new file mode 100644 index 00000000..e4242c71 --- /dev/null +++ b/docs/html/search/all_9.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/all_9.js b/docs/html/search/all_9.js new file mode 100644 index 00000000..0c28921f --- /dev/null +++ b/docs/html/search/all_9.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['reportanalogdisable_21',['reportAnalogDisable',['../classfirmata_1_1_firmata_marshaller.html#a2668d1332704bbf9938f386e247a8f30',1,'firmata::FirmataMarshaller']]], + ['reportanalogenable_22',['reportAnalogEnable',['../classfirmata_1_1_firmata_marshaller.html#a67b3db7232143acf63bd48b765fcc4db',1,'firmata::FirmataMarshaller']]], + ['reportdigitalportdisable_23',['reportDigitalPortDisable',['../classfirmata_1_1_firmata_marshaller.html#aa00582e6e014605a65a8953f8275a5ad',1,'firmata::FirmataMarshaller']]], + ['reportdigitalportenable_24',['reportDigitalPortEnable',['../classfirmata_1_1_firmata_marshaller.html#a608c28cdc966c33d0cc2239d9465ef7c',1,'firmata::FirmataMarshaller']]] +]; diff --git a/docs/html/search/all_a.html b/docs/html/search/all_a.html new file mode 100644 index 00000000..47a4a78d --- /dev/null +++ b/docs/html/search/all_a.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/all_a.js b/docs/html/search/all_a.js new file mode 100644 index 00000000..6768baad --- /dev/null +++ b/docs/html/search/all_a.js @@ -0,0 +1,22 @@ +var searchData= +[ + ['sendanalog_25',['sendAnalog',['../classfirmata_1_1_firmata_class.html#ae14e1d8d9bd72068f6e8ca07721e8dda',1,'firmata::FirmataClass::sendAnalog()'],['../classfirmata_1_1_firmata_marshaller.html#a4d9f2d3bb058237404dfe433cfe7571a',1,'firmata::FirmataMarshaller::sendAnalog()']]], + ['sendanalogmappingquery_26',['sendAnalogMappingQuery',['../classfirmata_1_1_firmata_marshaller.html#a1c987a534cc8dd197eb2f2a728bdacb3',1,'firmata::FirmataMarshaller']]], + ['sendcapabilityquery_27',['sendCapabilityQuery',['../classfirmata_1_1_firmata_marshaller.html#a1f1c5ce29ba4488306c9a1e3f158b781',1,'firmata::FirmataMarshaller']]], + ['senddigital_28',['sendDigital',['../classfirmata_1_1_firmata_marshaller.html#a2d90627f0543b6298be71f7d903399b3',1,'firmata::FirmataMarshaller']]], + ['senddigitalport_29',['sendDigitalPort',['../classfirmata_1_1_firmata_class.html#a799b91e5a888dd21b066a2020d8e2b68',1,'firmata::FirmataClass::sendDigitalPort()'],['../classfirmata_1_1_firmata_marshaller.html#a346dcb4487a51efaa95de42d292ad951',1,'firmata::FirmataMarshaller::sendDigitalPort()']]], + ['sendfirmwareversion_30',['sendFirmwareVersion',['../classfirmata_1_1_firmata_marshaller.html#aed71d62cc41f2e0bf3f161894b91be7c',1,'firmata::FirmataMarshaller']]], + ['sendpinmode_31',['sendPinMode',['../classfirmata_1_1_firmata_marshaller.html#a36b6cc103609d900cce36149a239f221',1,'firmata::FirmataMarshaller']]], + ['sendpinstatequery_32',['sendPinStateQuery',['../classfirmata_1_1_firmata_marshaller.html#afc378ab4a39c843d4419acdee944972b',1,'firmata::FirmataMarshaller']]], + ['sendstring_33',['sendString',['../classfirmata_1_1_firmata_class.html#abe11f621154afd308926129de349fc6e',1,'firmata::FirmataClass::sendString(const char *string)'],['../classfirmata_1_1_firmata_class.html#ab139c0d784e69003c88eb5be8807dcdf',1,'firmata::FirmataClass::sendString(byte command, const char *string)'],['../classfirmata_1_1_firmata_marshaller.html#a483ac2dea885ab3472dc38b99bfdec2f',1,'firmata::FirmataMarshaller::sendString()']]], + ['sendsysex_34',['sendSysex',['../classfirmata_1_1_firmata_class.html#a81e2de5b37eb2372c8a3d9a43d5eb0cc',1,'firmata::FirmataClass::sendSysex()'],['../classfirmata_1_1_firmata_marshaller.html#ade4f4592877ec0b9f8d6c74e909bad8e',1,'firmata::FirmataMarshaller::sendSysex()']]], + ['sendvalueastwo7bitbytes_35',['sendValueAsTwo7bitBytes',['../classfirmata_1_1_firmata_class.html#a770e43f26f18204e43acebf9202a6d39',1,'firmata::FirmataClass']]], + ['sendversion_36',['sendVersion',['../classfirmata_1_1_firmata_marshaller.html#a95d58949e32ad285088705dbe5680b29',1,'firmata::FirmataMarshaller']]], + ['setdatabufferofsize_37',['setDataBufferOfSize',['../classfirmata_1_1_firmata_parser.html#a8fbe143ddb428a97c00a15993c31a516',1,'firmata::FirmataParser']]], + ['setfirmwarenameandversion_38',['setFirmwareNameAndVersion',['../classfirmata_1_1_firmata_class.html#ab7aa66b528027566c15b7d64c8cd0f89',1,'firmata::FirmataClass']]], + ['setpinmode_39',['setPinMode',['../classfirmata_1_1_firmata_class.html#a32c41dd94c1d23aa0e6d3d1dbe5c0c04',1,'firmata::FirmataClass']]], + ['setpinstate_40',['setPinState',['../classfirmata_1_1_firmata_class.html#aa9f98ba5069823b4c1d08db9f8999ba8',1,'firmata::FirmataClass']]], + ['setsamplinginterval_41',['setSamplingInterval',['../classfirmata_1_1_firmata_marshaller.html#abb8f4c79dd8a0dbee3f5e04c587ae20c',1,'firmata::FirmataMarshaller']]], + ['startsysex_42',['startSysex',['../classfirmata_1_1_firmata_class.html#a3cc7ea1af348bca3ea0bd570314cada3',1,'firmata::FirmataClass']]], + ['systemreset_43',['systemReset',['../classfirmata_1_1_firmata_marshaller.html#a3a585937f94b1f9e51797e5950a33206',1,'firmata::FirmataMarshaller']]] +]; diff --git a/docs/html/search/all_b.html b/docs/html/search/all_b.html new file mode 100644 index 00000000..1320a43f --- /dev/null +++ b/docs/html/search/all_b.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/all_b.js b/docs/html/search/all_b.js new file mode 100644 index 00000000..18c55ecd --- /dev/null +++ b/docs/html/search/all_b.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['write_44',['write',['../classfirmata_1_1_firmata_class.html#ae8f29a829e17379602fcb9fd6a497807',1,'firmata::FirmataClass']]] +]; diff --git a/docs/html/search/classes_0.html b/docs/html/search/classes_0.html new file mode 100644 index 00000000..d585e6a9 --- /dev/null +++ b/docs/html/search/classes_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/classes_0.js b/docs/html/search/classes_0.js new file mode 100644 index 00000000..48d27db1 --- /dev/null +++ b/docs/html/search/classes_0.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['firmataclass_45',['FirmataClass',['../classfirmata_1_1_firmata_class.html',1,'firmata']]], + ['firmatamarshaller_46',['FirmataMarshaller',['../classfirmata_1_1_firmata_marshaller.html',1,'firmata']]], + ['firmataparser_47',['FirmataParser',['../classfirmata_1_1_firmata_parser.html',1,'firmata']]] +]; diff --git a/docs/html/search/close.png b/docs/html/search/close.png new file mode 100644 index 0000000000000000000000000000000000000000..9342d3dfeea7b7c4ee610987e717804b5a42ceb9 GIT binary patch literal 273 zcmV+s0q*{ZP)4(RlMby96)VwnbG{ zbe&}^BDn7x>$<{ck4zAK-=nT;=hHG)kmplIF${xqm8db3oX6wT3bvp`TE@m0cg;b) zBuSL}5?N7O(iZLdAlz@)b)Rd~DnSsSX&P5qC`XwuFwcAYLC+d2>+1(8on;wpt8QIC X2MT$R4iQDd00000NkvXXu0mjfia~GN literal 0 HcmV?d00001 diff --git a/docs/html/search/functions_0.html b/docs/html/search/functions_0.html new file mode 100644 index 00000000..8a729f78 --- /dev/null +++ b/docs/html/search/functions_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/functions_0.js b/docs/html/search/functions_0.js new file mode 100644 index 00000000..8ab9073e --- /dev/null +++ b/docs/html/search/functions_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['attach_48',['attach',['../classfirmata_1_1_firmata_class.html#adc3db897058f33e902097ce89bb01bb3',1,'firmata::FirmataClass::attach(uint8_t command, systemCallbackFunction newFunction)'],['../classfirmata_1_1_firmata_class.html#a074887a70f9aca0c0aae7e9bdc103f77',1,'firmata::FirmataClass::attach(uint8_t command, stringCallbackFunction newFunction)'],['../classfirmata_1_1_firmata_class.html#a78e360c0c8d70cffeb9c935fdec23f77',1,'firmata::FirmataClass::attach(uint8_t command, sysexCallbackFunction newFunction)'],['../classfirmata_1_1_firmata_parser.html#a2a472a925ed7e626ed36dee94ceae45e',1,'firmata::FirmataParser::attach(uint8_t command, callbackFunction newFunction, void *context=NULL)'],['../classfirmata_1_1_firmata_parser.html#ae176414892a2d240b921c2b8037a8ade',1,'firmata::FirmataParser::attach(dataBufferOverflowCallbackFunction newFunction, void *context=NULL)'],['../classfirmata_1_1_firmata_parser.html#a239b37e09dea042d229fc2171d3a1979',1,'firmata::FirmataParser::attach(uint8_t command, stringCallbackFunction newFunction, void *context=NULL)'],['../classfirmata_1_1_firmata_parser.html#aaa1d755b20b21e528bfa62d6a7c2dc0f',1,'firmata::FirmataParser::attach(uint8_t command, sysexCallbackFunction newFunction, void *context=NULL)'],['../classfirmata_1_1_firmata_parser.html#affc821e7742d889965e61b248c204842',1,'firmata::FirmataParser::attach(uint8_t command, systemCallbackFunction newFunction, void *context=NULL)'],['../classfirmata_1_1_firmata_parser.html#a876105f2203f5e8f1fb06c8236a96933',1,'firmata::FirmataParser::attach(uint8_t command, versionCallbackFunction newFunction, void *context=NULL)']]], + ['available_49',['available',['../classfirmata_1_1_firmata_class.html#a119734b867186567c1cd011e52e59d2d',1,'firmata::FirmataClass']]] +]; diff --git a/docs/html/search/functions_1.html b/docs/html/search/functions_1.html new file mode 100644 index 00000000..d4929aaf --- /dev/null +++ b/docs/html/search/functions_1.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/functions_1.js b/docs/html/search/functions_1.js new file mode 100644 index 00000000..8e87ba1e --- /dev/null +++ b/docs/html/search/functions_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['begin_50',['begin',['../classfirmata_1_1_firmata_class.html#a2fddcc643892bec2f4aa7aef6dba70eb',1,'firmata::FirmataClass::begin()'],['../classfirmata_1_1_firmata_class.html#ab0b7b837d2c32b4ce79e62895ced2731',1,'firmata::FirmataClass::begin(long)'],['../classfirmata_1_1_firmata_class.html#a0c7b0e10168e3c5dc6442d77c65a156e',1,'firmata::FirmataClass::begin(Stream &s)'],['../classfirmata_1_1_firmata_marshaller.html#a5be18ca3658875dbe5580c2254071c76',1,'firmata::FirmataMarshaller::begin()']]], + ['blinkversion_51',['blinkVersion',['../classfirmata_1_1_firmata_class.html#a9421550f2501fc1df60fd174b154e606',1,'firmata::FirmataClass']]] +]; diff --git a/docs/html/search/functions_2.html b/docs/html/search/functions_2.html new file mode 100644 index 00000000..07e3fdad --- /dev/null +++ b/docs/html/search/functions_2.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/functions_2.js b/docs/html/search/functions_2.js new file mode 100644 index 00000000..63c6a6d0 --- /dev/null +++ b/docs/html/search/functions_2.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['detach_52',['detach',['../classfirmata_1_1_firmata_class.html#a5db0faee74b9291d1b783d2dde0929d1',1,'firmata::FirmataClass::detach()'],['../classfirmata_1_1_firmata_parser.html#a7cd707386c0807bee733a3e27d161c7d',1,'firmata::FirmataParser::detach(uint8_t command)'],['../classfirmata_1_1_firmata_parser.html#a280ac17e428f8374afd30bce75e9a861',1,'firmata::FirmataParser::detach(dataBufferOverflowCallbackFunction)']]], + ['disableblinkversion_53',['disableBlinkVersion',['../classfirmata_1_1_firmata_class.html#a5ddba465c3772f841828ef82c79d4307',1,'firmata::FirmataClass']]] +]; diff --git a/docs/html/search/functions_3.html b/docs/html/search/functions_3.html new file mode 100644 index 00000000..40bd389e --- /dev/null +++ b/docs/html/search/functions_3.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/functions_3.js b/docs/html/search/functions_3.js new file mode 100644 index 00000000..d019efe2 --- /dev/null +++ b/docs/html/search/functions_3.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['end_54',['end',['../classfirmata_1_1_firmata_marshaller.html#ab856434fc577b1e069cba51c39daf1de',1,'firmata::FirmataMarshaller']]], + ['endsysex_55',['endSysex',['../classfirmata_1_1_firmata_class.html#a9bb68afbb1d37a7990f59a1d419e64c9',1,'firmata::FirmataClass']]] +]; diff --git a/docs/html/search/functions_4.html b/docs/html/search/functions_4.html new file mode 100644 index 00000000..8a4df4cd --- /dev/null +++ b/docs/html/search/functions_4.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/functions_4.js b/docs/html/search/functions_4.js new file mode 100644 index 00000000..caec8006 --- /dev/null +++ b/docs/html/search/functions_4.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['firmataclass_56',['FirmataClass',['../classfirmata_1_1_firmata_class.html#a75b035ab8d96d87d28deeb87badfe11a',1,'firmata::FirmataClass']]], + ['firmatamarshaller_57',['FirmataMarshaller',['../classfirmata_1_1_firmata_marshaller.html#ad1a42532bdf77088c47c1a62f5a03829',1,'firmata::FirmataMarshaller']]], + ['firmataparser_58',['FirmataParser',['../classfirmata_1_1_firmata_parser.html#ac8c388b593a00e88856646712beae68b',1,'firmata::FirmataParser']]] +]; diff --git a/docs/html/search/functions_5.html b/docs/html/search/functions_5.html new file mode 100644 index 00000000..2b983b21 --- /dev/null +++ b/docs/html/search/functions_5.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/functions_5.js b/docs/html/search/functions_5.js new file mode 100644 index 00000000..75d8c445 --- /dev/null +++ b/docs/html/search/functions_5.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['getpinmode_59',['getPinMode',['../classfirmata_1_1_firmata_class.html#a0c434227456ce2ba97b3b1142c329f96',1,'firmata::FirmataClass']]], + ['getpinstate_60',['getPinState',['../classfirmata_1_1_firmata_class.html#acf5d4f460b9a2298653d4a71de918dfe',1,'firmata::FirmataClass']]] +]; diff --git a/docs/html/search/functions_6.html b/docs/html/search/functions_6.html new file mode 100644 index 00000000..f7d283d1 --- /dev/null +++ b/docs/html/search/functions_6.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/functions_6.js b/docs/html/search/functions_6.js new file mode 100644 index 00000000..cfa73aeb --- /dev/null +++ b/docs/html/search/functions_6.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['isparsingmessage_61',['isParsingMessage',['../classfirmata_1_1_firmata_class.html#a58e9d787957c3085f22d33b59b1f6ea6',1,'firmata::FirmataClass::isParsingMessage()'],['../classfirmata_1_1_firmata_parser.html#a67902b70695eaf0cf8f7b06175ca3902',1,'firmata::FirmataParser::isParsingMessage()']]] +]; diff --git a/docs/html/search/functions_7.html b/docs/html/search/functions_7.html new file mode 100644 index 00000000..a74fe44a --- /dev/null +++ b/docs/html/search/functions_7.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/functions_7.js b/docs/html/search/functions_7.js new file mode 100644 index 00000000..746df096 --- /dev/null +++ b/docs/html/search/functions_7.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['parse_62',['parse',['../classfirmata_1_1_firmata_class.html#aaeaac8b1f8facf070615b0035120c432',1,'firmata::FirmataClass::parse()'],['../classfirmata_1_1_firmata_parser.html#a754c97b890b7fd66c8d953a3e615acbf',1,'firmata::FirmataParser::parse()']]], + ['printfirmwareversion_63',['printFirmwareVersion',['../classfirmata_1_1_firmata_class.html#abe49261eab0bd4892a09fa8b8980b11a',1,'firmata::FirmataClass']]], + ['printversion_64',['printVersion',['../classfirmata_1_1_firmata_class.html#abd8a0370db6d9e923e7e3d5836e78d7a',1,'firmata::FirmataClass']]], + ['processinput_65',['processInput',['../classfirmata_1_1_firmata_class.html#aa698f5f5a234173d5eebb54831350676',1,'firmata::FirmataClass']]] +]; diff --git a/docs/html/search/functions_8.html b/docs/html/search/functions_8.html new file mode 100644 index 00000000..75fc0bea --- /dev/null +++ b/docs/html/search/functions_8.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/functions_8.js b/docs/html/search/functions_8.js new file mode 100644 index 00000000..2d768241 --- /dev/null +++ b/docs/html/search/functions_8.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['queryfirmwareversion_66',['queryFirmwareVersion',['../classfirmata_1_1_firmata_marshaller.html#af954bcf09b77458b3c4f032897d14697',1,'firmata::FirmataMarshaller']]], + ['queryversion_67',['queryVersion',['../classfirmata_1_1_firmata_marshaller.html#a488fbbd372c894ec78ebb99e0faf5167',1,'firmata::FirmataMarshaller']]] +]; diff --git a/docs/html/search/functions_9.html b/docs/html/search/functions_9.html new file mode 100644 index 00000000..7541c9e3 --- /dev/null +++ b/docs/html/search/functions_9.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/functions_9.js b/docs/html/search/functions_9.js new file mode 100644 index 00000000..56d890a8 --- /dev/null +++ b/docs/html/search/functions_9.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['reportanalogdisable_68',['reportAnalogDisable',['../classfirmata_1_1_firmata_marshaller.html#a2668d1332704bbf9938f386e247a8f30',1,'firmata::FirmataMarshaller']]], + ['reportanalogenable_69',['reportAnalogEnable',['../classfirmata_1_1_firmata_marshaller.html#a67b3db7232143acf63bd48b765fcc4db',1,'firmata::FirmataMarshaller']]], + ['reportdigitalportdisable_70',['reportDigitalPortDisable',['../classfirmata_1_1_firmata_marshaller.html#aa00582e6e014605a65a8953f8275a5ad',1,'firmata::FirmataMarshaller']]], + ['reportdigitalportenable_71',['reportDigitalPortEnable',['../classfirmata_1_1_firmata_marshaller.html#a608c28cdc966c33d0cc2239d9465ef7c',1,'firmata::FirmataMarshaller']]] +]; diff --git a/docs/html/search/functions_a.html b/docs/html/search/functions_a.html new file mode 100644 index 00000000..5a5be630 --- /dev/null +++ b/docs/html/search/functions_a.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/functions_a.js b/docs/html/search/functions_a.js new file mode 100644 index 00000000..fca5da61 --- /dev/null +++ b/docs/html/search/functions_a.js @@ -0,0 +1,22 @@ +var searchData= +[ + ['sendanalog_72',['sendAnalog',['../classfirmata_1_1_firmata_class.html#ae14e1d8d9bd72068f6e8ca07721e8dda',1,'firmata::FirmataClass::sendAnalog()'],['../classfirmata_1_1_firmata_marshaller.html#a4d9f2d3bb058237404dfe433cfe7571a',1,'firmata::FirmataMarshaller::sendAnalog()']]], + ['sendanalogmappingquery_73',['sendAnalogMappingQuery',['../classfirmata_1_1_firmata_marshaller.html#a1c987a534cc8dd197eb2f2a728bdacb3',1,'firmata::FirmataMarshaller']]], + ['sendcapabilityquery_74',['sendCapabilityQuery',['../classfirmata_1_1_firmata_marshaller.html#a1f1c5ce29ba4488306c9a1e3f158b781',1,'firmata::FirmataMarshaller']]], + ['senddigital_75',['sendDigital',['../classfirmata_1_1_firmata_marshaller.html#a2d90627f0543b6298be71f7d903399b3',1,'firmata::FirmataMarshaller']]], + ['senddigitalport_76',['sendDigitalPort',['../classfirmata_1_1_firmata_class.html#a799b91e5a888dd21b066a2020d8e2b68',1,'firmata::FirmataClass::sendDigitalPort()'],['../classfirmata_1_1_firmata_marshaller.html#a346dcb4487a51efaa95de42d292ad951',1,'firmata::FirmataMarshaller::sendDigitalPort()']]], + ['sendfirmwareversion_77',['sendFirmwareVersion',['../classfirmata_1_1_firmata_marshaller.html#aed71d62cc41f2e0bf3f161894b91be7c',1,'firmata::FirmataMarshaller']]], + ['sendpinmode_78',['sendPinMode',['../classfirmata_1_1_firmata_marshaller.html#a36b6cc103609d900cce36149a239f221',1,'firmata::FirmataMarshaller']]], + ['sendpinstatequery_79',['sendPinStateQuery',['../classfirmata_1_1_firmata_marshaller.html#afc378ab4a39c843d4419acdee944972b',1,'firmata::FirmataMarshaller']]], + ['sendstring_80',['sendString',['../classfirmata_1_1_firmata_class.html#abe11f621154afd308926129de349fc6e',1,'firmata::FirmataClass::sendString(const char *string)'],['../classfirmata_1_1_firmata_class.html#ab139c0d784e69003c88eb5be8807dcdf',1,'firmata::FirmataClass::sendString(byte command, const char *string)'],['../classfirmata_1_1_firmata_marshaller.html#a483ac2dea885ab3472dc38b99bfdec2f',1,'firmata::FirmataMarshaller::sendString()']]], + ['sendsysex_81',['sendSysex',['../classfirmata_1_1_firmata_class.html#a81e2de5b37eb2372c8a3d9a43d5eb0cc',1,'firmata::FirmataClass::sendSysex()'],['../classfirmata_1_1_firmata_marshaller.html#ade4f4592877ec0b9f8d6c74e909bad8e',1,'firmata::FirmataMarshaller::sendSysex()']]], + ['sendvalueastwo7bitbytes_82',['sendValueAsTwo7bitBytes',['../classfirmata_1_1_firmata_class.html#a770e43f26f18204e43acebf9202a6d39',1,'firmata::FirmataClass']]], + ['sendversion_83',['sendVersion',['../classfirmata_1_1_firmata_marshaller.html#a95d58949e32ad285088705dbe5680b29',1,'firmata::FirmataMarshaller']]], + ['setdatabufferofsize_84',['setDataBufferOfSize',['../classfirmata_1_1_firmata_parser.html#a8fbe143ddb428a97c00a15993c31a516',1,'firmata::FirmataParser']]], + ['setfirmwarenameandversion_85',['setFirmwareNameAndVersion',['../classfirmata_1_1_firmata_class.html#ab7aa66b528027566c15b7d64c8cd0f89',1,'firmata::FirmataClass']]], + ['setpinmode_86',['setPinMode',['../classfirmata_1_1_firmata_class.html#a32c41dd94c1d23aa0e6d3d1dbe5c0c04',1,'firmata::FirmataClass']]], + ['setpinstate_87',['setPinState',['../classfirmata_1_1_firmata_class.html#aa9f98ba5069823b4c1d08db9f8999ba8',1,'firmata::FirmataClass']]], + ['setsamplinginterval_88',['setSamplingInterval',['../classfirmata_1_1_firmata_marshaller.html#abb8f4c79dd8a0dbee3f5e04c587ae20c',1,'firmata::FirmataMarshaller']]], + ['startsysex_89',['startSysex',['../classfirmata_1_1_firmata_class.html#a3cc7ea1af348bca3ea0bd570314cada3',1,'firmata::FirmataClass']]], + ['systemreset_90',['systemReset',['../classfirmata_1_1_firmata_marshaller.html#a3a585937f94b1f9e51797e5950a33206',1,'firmata::FirmataMarshaller']]] +]; diff --git a/docs/html/search/functions_b.html b/docs/html/search/functions_b.html new file mode 100644 index 00000000..fc2d5aa4 --- /dev/null +++ b/docs/html/search/functions_b.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/functions_b.js b/docs/html/search/functions_b.js new file mode 100644 index 00000000..4eaed0dc --- /dev/null +++ b/docs/html/search/functions_b.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['write_91',['write',['../classfirmata_1_1_firmata_class.html#ae8f29a829e17379602fcb9fd6a497807',1,'firmata::FirmataClass']]] +]; diff --git a/docs/html/search/mag_sel.png b/docs/html/search/mag_sel.png new file mode 100644 index 0000000000000000000000000000000000000000..39c0ed52a25dd9d080ee0d42ae6c6042bdfa04d7 GIT binary patch literal 465 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz6!2%?$TA$hhDVB6cUq=Rpjs4tz5?O(Kg=CK) zUj~NU84L`?eGCi_EEpJ?t}-xGu`@87+QPtK?83kxQ`TapwHK(CDaqU2h2ejD|C#+j z9%q3^WHAE+w=f7ZGR&GI0Tg5}@$_|Nf5gMiEhFgvHvB$N=!mC_V~EE2vzPXI9ZnEo zd+1zHor@dYLod2Y{ z@R$7$Z!PXTbY$|@#T!bMzm?`b<(R`cbw(gxJHzu zB$lLFB^RXvDF!10LknF)BV7aY5JN*NBMU1-b8Q0yD+2>vd*|CI8glbfGSez?Ylunu RoetE%;OXk;vd$@?2>>CYplSdB literal 0 HcmV?d00001 diff --git a/docs/html/search/nomatches.html b/docs/html/search/nomatches.html new file mode 100644 index 00000000..43773208 --- /dev/null +++ b/docs/html/search/nomatches.html @@ -0,0 +1,12 @@ + + + + + + + +
    +
    No Matches
    +
    + + diff --git a/docs/html/search/pages_0.html b/docs/html/search/pages_0.html new file mode 100644 index 00000000..32cbf498 --- /dev/null +++ b/docs/html/search/pages_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/html/search/pages_0.js b/docs/html/search/pages_0.js new file mode 100644 index 00000000..a24cb5da --- /dev/null +++ b/docs/html/search/pages_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['firmata_92',['Firmata',['../index.html',1,'']]] +]; diff --git a/docs/html/search/search.css b/docs/html/search/search.css new file mode 100644 index 00000000..3cf9df94 --- /dev/null +++ b/docs/html/search/search.css @@ -0,0 +1,271 @@ +/*---------------- Search Box */ + +#FSearchBox { + float: left; +} + +#MSearchBox { + white-space : nowrap; + float: none; + margin-top: 8px; + right: 0px; + width: 170px; + height: 24px; + z-index: 102; +} + +#MSearchBox .left +{ + display:block; + position:absolute; + left:10px; + width:20px; + height:19px; + background:url('search_l.png') no-repeat; + background-position:right; +} + +#MSearchSelect { + display:block; + position:absolute; + width:20px; + height:19px; +} + +.left #MSearchSelect { + left:4px; +} + +.right #MSearchSelect { + right:5px; +} + +#MSearchField { + display:block; + position:absolute; + height:19px; + background:url('search_m.png') repeat-x; + border:none; + width:115px; + margin-left:20px; + padding-left:4px; + color: #909090; + outline: none; + font: 9pt Arial, Verdana, sans-serif; + -webkit-border-radius: 0px; +} + +#FSearchBox #MSearchField { + margin-left:15px; +} + +#MSearchBox .right { + display:block; + position:absolute; + right:10px; + top:8px; + width:20px; + height:19px; + background:url('search_r.png') no-repeat; + background-position:left; +} + +#MSearchClose { + display: none; + position: absolute; + top: 4px; + background : none; + border: none; + margin: 0px 4px 0px 0px; + padding: 0px 0px; + outline: none; +} + +.left #MSearchClose { + left: 6px; +} + +.right #MSearchClose { + right: 2px; +} + +.MSearchBoxActive #MSearchField { + color: #000000; +} + +/*---------------- Search filter selection */ + +#MSearchSelectWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #90A5CE; + background-color: #F9FAFC; + z-index: 10001; + padding-top: 4px; + padding-bottom: 4px; + -moz-border-radius: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +.SelectItem { + font: 8pt Arial, Verdana, sans-serif; + padding-left: 2px; + padding-right: 12px; + border: 0px; +} + +span.SelectionMark { + margin-right: 4px; + font-family: monospace; + outline-style: none; + text-decoration: none; +} + +a.SelectItem { + display: block; + outline-style: none; + color: #000000; + text-decoration: none; + padding-left: 6px; + padding-right: 12px; +} + +a.SelectItem:focus, +a.SelectItem:active { + color: #000000; + outline-style: none; + text-decoration: none; +} + +a.SelectItem:hover { + color: #FFFFFF; + background-color: #3D578C; + outline-style: none; + text-decoration: none; + cursor: pointer; + display: block; +} + +/*---------------- Search results window */ + +iframe#MSearchResults { + width: 60ex; + height: 15em; +} + +#MSearchResultsWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #000; + background-color: #EEF1F7; + z-index:10000; +} + +/* ----------------------------------- */ + + +#SRIndex { + clear:both; + padding-bottom: 15px; +} + +.SREntry { + font-size: 10pt; + padding-left: 1ex; +} + +.SRPage .SREntry { + font-size: 8pt; + padding: 1px 5px; +} + +body.SRPage { + margin: 5px 2px; +} + +.SRChildren { + padding-left: 3ex; padding-bottom: .5em +} + +.SRPage .SRChildren { + display: none; +} + +.SRSymbol { + font-weight: bold; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRScope { + display: block; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRSymbol:focus, a.SRSymbol:active, +a.SRScope:focus, a.SRScope:active { + text-decoration: underline; +} + +span.SRScope { + padding-left: 4px; +} + +.SRPage .SRStatus { + padding: 2px 5px; + font-size: 8pt; + font-style: italic; +} + +.SRResult { + display: none; +} + +DIV.searchresults { + margin-left: 10px; + margin-right: 10px; +} + +/*---------------- External search page results */ + +.searchresult { + background-color: #F0F3F8; +} + +.pages b { + color: white; + padding: 5px 5px 3px 5px; + background-image: url("../tab_a.png"); + background-repeat: repeat-x; + text-shadow: 0 1px 1px #000000; +} + +.pages { + line-height: 17px; + margin-left: 4px; + text-decoration: none; +} + +.hl { + font-weight: bold; +} + +#searchresults { + margin-bottom: 20px; +} + +.searchpages { + margin-top: 10px; +} + diff --git a/docs/html/search/search.js b/docs/html/search/search.js new file mode 100644 index 00000000..a554ab9c --- /dev/null +++ b/docs/html/search/search.js @@ -0,0 +1,814 @@ +/* + @licstart The following is the entire license notice for the + JavaScript code in this file. + + Copyright (C) 1997-2017 by Dimitri van Heesch + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + @licend The above is the entire license notice + for the JavaScript code in this file + */ +function convertToId(search) +{ + var result = ''; + for (i=0;i do a search + { + this.Search(); + } + } + + this.OnSearchSelectKey = function(evt) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 && this.searchIndex0) // Up + { + this.searchIndex--; + this.OnSelectItem(this.searchIndex); + } + else if (e.keyCode==13 || e.keyCode==27) + { + this.OnSelectItem(this.searchIndex); + this.CloseSelectionWindow(); + this.DOMSearchField().focus(); + } + return false; + } + + // --------- Actions + + // Closes the results window. + this.CloseResultsWindow = function() + { + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.Activate(false); + } + + this.CloseSelectionWindow = function() + { + this.DOMSearchSelectWindow().style.display = 'none'; + } + + // Performs a search. + this.Search = function() + { + this.keyTimeout = 0; + + // strip leading whitespace + var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); + + var code = searchValue.toLowerCase().charCodeAt(0); + var idxChar = searchValue.substr(0, 1).toLowerCase(); + if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair + { + idxChar = searchValue.substr(0, 2); + } + + var resultsPage; + var resultsPageWithSearch; + var hasResultsPage; + + var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar); + if (idx!=-1) + { + var hexCode=idx.toString(16); + resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html'; + resultsPageWithSearch = resultsPage+'?'+escape(searchValue); + hasResultsPage = true; + } + else // nothing available for this search term + { + resultsPage = this.resultsPath + '/nomatches.html'; + resultsPageWithSearch = resultsPage; + hasResultsPage = false; + } + + window.frames.MSearchResults.location = resultsPageWithSearch; + var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + + if (domPopupSearchResultsWindow.style.display!='block') + { + var domSearchBox = this.DOMSearchBox(); + this.DOMSearchClose().style.display = 'inline'; + if (this.insideFrame) + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + domPopupSearchResultsWindow.style.position = 'relative'; + domPopupSearchResultsWindow.style.display = 'block'; + var width = document.body.clientWidth - 8; // the -8 is for IE :-( + domPopupSearchResultsWindow.style.width = width + 'px'; + domPopupSearchResults.style.width = width + 'px'; + } + else + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth; + var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1; + domPopupSearchResultsWindow.style.display = 'block'; + left -= domPopupSearchResults.offsetWidth; + domPopupSearchResultsWindow.style.top = top + 'px'; + domPopupSearchResultsWindow.style.left = left + 'px'; + } + } + + this.lastSearchValue = searchValue; + this.lastResultsPage = resultsPage; + } + + // -------- Activation Functions + + // Activates or deactivates the search panel, resetting things to + // their default values if necessary. + this.Activate = function(isActive) + { + if (isActive || // open it + this.DOMPopupSearchResultsWindow().style.display == 'block' + ) + { + this.DOMSearchBox().className = 'MSearchBoxActive'; + + var searchField = this.DOMSearchField(); + + if (searchField.value == this.searchLabel) // clear "Search" term upon entry + { + searchField.value = ''; + this.searchActive = true; + } + } + else if (!isActive) // directly remove the panel + { + this.DOMSearchBox().className = 'MSearchBoxInactive'; + this.DOMSearchField().value = this.searchLabel; + this.searchActive = false; + this.lastSearchValue = '' + this.lastResultsPage = ''; + } + } +} + +// ----------------------------------------------------------------------- + +// The class that handles everything on the search results page. +function SearchResults(name) +{ + // The number of matches from the last run of . + this.lastMatchCount = 0; + this.lastKey = 0; + this.repeatOn = false; + + // Toggles the visibility of the passed element ID. + this.FindChildElement = function(id) + { + var parentElement = document.getElementById(id); + var element = parentElement.firstChild; + + while (element && element!=parentElement) + { + if (element.nodeName == 'DIV' && element.className == 'SRChildren') + { + return element; + } + + if (element.nodeName == 'DIV' && element.hasChildNodes()) + { + element = element.firstChild; + } + else if (element.nextSibling) + { + element = element.nextSibling; + } + else + { + do + { + element = element.parentNode; + } + while (element && element!=parentElement && !element.nextSibling); + + if (element && element!=parentElement) + { + element = element.nextSibling; + } + } + } + } + + this.Toggle = function(id) + { + var element = this.FindChildElement(id); + if (element) + { + if (element.style.display == 'block') + { + element.style.display = 'none'; + } + else + { + element.style.display = 'block'; + } + } + } + + // Searches for the passed string. If there is no parameter, + // it takes it from the URL query. + // + // Always returns true, since other documents may try to call it + // and that may or may not be possible. + this.Search = function(search) + { + if (!search) // get search word from URL + { + search = window.location.search; + search = search.substring(1); // Remove the leading '?' + search = unescape(search); + } + + search = search.replace(/^ +/, ""); // strip leading spaces + search = search.replace(/ +$/, ""); // strip trailing spaces + search = search.toLowerCase(); + search = convertToId(search); + + var resultRows = document.getElementsByTagName("div"); + var matches = 0; + + var i = 0; + while (i < resultRows.length) + { + var row = resultRows.item(i); + if (row.className == "SRResult") + { + var rowMatchName = row.id.toLowerCase(); + rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' + + if (search.length<=rowMatchName.length && + rowMatchName.substr(0, search.length)==search) + { + row.style.display = 'block'; + matches++; + } + else + { + row.style.display = 'none'; + } + } + i++; + } + document.getElementById("Searching").style.display='none'; + if (matches == 0) // no results + { + document.getElementById("NoMatches").style.display='block'; + } + else // at least one result + { + document.getElementById("NoMatches").style.display='none'; + } + this.lastMatchCount = matches; + return true; + } + + // return the first item with index index or higher that is visible + this.NavNext = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index++; + } + return focusItem; + } + + this.NavPrev = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index--; + } + return focusItem; + } + + this.ProcessKeys = function(e) + { + if (e.type == "keydown") + { + this.repeatOn = false; + this.lastKey = e.keyCode; + } + else if (e.type == "keypress") + { + if (!this.repeatOn) + { + if (this.lastKey) this.repeatOn = true; + return false; // ignore first keypress after keydown + } + } + else if (e.type == "keyup") + { + this.lastKey = 0; + this.repeatOn = false; + } + return this.lastKey!=0; + } + + this.Nav = function(evt,itemIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + var newIndex = itemIndex-1; + var focusItem = this.NavPrev(newIndex); + if (focusItem) + { + var child = this.FindChildElement(focusItem.parentNode.parentNode.id); + if (child && child.style.display == 'block') // children visible + { + var n=0; + var tmpElem; + while (1) // search for last child + { + tmpElem = document.getElementById('Item'+newIndex+'_c'+n); + if (tmpElem) + { + focusItem = tmpElem; + } + else // found it! + { + break; + } + n++; + } + } + } + if (focusItem) + { + focusItem.focus(); + } + else // return focus to search field + { + parent.document.getElementById("MSearchField").focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = itemIndex+1; + var focusItem; + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem && elem.style.display == 'block') // children visible + { + focusItem = document.getElementById('Item'+itemIndex+'_c0'); + } + if (!focusItem) focusItem = this.NavNext(newIndex); + if (focusItem) focusItem.focus(); + } + else if (this.lastKey==39) // Right + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'block'; + } + else if (this.lastKey==37) // Left + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'none'; + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } + + this.NavChild = function(evt,itemIndex,childIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + if (childIndex>0) + { + var newIndex = childIndex-1; + document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); + } + else // already at first child, jump to parent + { + document.getElementById('Item'+itemIndex).focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = childIndex+1; + var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); + if (!elem) // last child, jump to parent next parent + { + elem = this.NavNext(itemIndex+1); + } + if (elem) + { + elem.focus(); + } + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } +} + +function setKeyActions(elem,action) +{ + elem.setAttribute('onkeydown',action); + elem.setAttribute('onkeypress',action); + elem.setAttribute('onkeyup',action); +} + +function setClassAttr(elem,attr) +{ + elem.setAttribute('class',attr); + elem.setAttribute('className',attr); +} + +function createResults() +{ + var results = document.getElementById("SRResults"); + for (var e=0; e(R!W8j_r#qQ#gnr4kAxdU#F0+OBry$Z+ z_0PMi;P|#{d%mw(dnw=jM%@$onTJa%@6Nm3`;2S#nwtVFJI#`U@2Q@@JCCctagvF- z8H=anvo~dTmJ2YA%wA6IHRv%{vxvUm|R)kgZeo zmX%Zb;mpflGZdXCTAgit`||AFzkI#z&(3d4(htA?U2FOL4WF6wY&TB#n3n*I4+hl| z*NBpo#FA92vEu822WQ%mvv4FO#qs` BFGc_W literal 0 HcmV?d00001 diff --git a/docs/html/search/search_r.png b/docs/html/search/search_r.png new file mode 100644 index 0000000000000000000000000000000000000000..1af5d21ee13e070d7600f1c4657fde843b953a69 GIT binary patch literal 553 zcmeAS@N?(olHy`uVBq!ia0vp^LO?9c!2%@BXHTsJQY`6?zK#qG8~eHcB(ehe3dtTp zz6=bxGZ+|(`xqD=STHa&U1eaXVrO7DwS|Gf*oA>XrmV$GYcEhOQT(QLuS{~ooZ2P@v=Xc@RKW@Irliv8_;wroU0*)0O?temdsA~70jrdux+`@W7 z-N(<(C)L?hOO?KV{>8(jC{hpKsws)#Fh zvsO>IB+gb@b+rGWaO&!a9Z{!U+fV*s7TS>fdt&j$L%^U@Epd$~Nl7e8wMs5Z1yT$~ z28I^8hDN#u<{^fLRz?<9hUVG^237_Jy7tbuQ8eV{r(~v8;?@w8^gA7>fx*+&&t;uc GLK6VEQpiUD literal 0 HcmV?d00001 diff --git a/docs/html/search/searchdata.js b/docs/html/search/searchdata.js new file mode 100644 index 00000000..d8fd087d --- /dev/null +++ b/docs/html/search/searchdata.js @@ -0,0 +1,24 @@ +var indexSectionsWithContent = +{ + 0: "abdefgipqrsw", + 1: "f", + 2: "abdefgipqrsw", + 3: "f" +}; + +var indexSectionNames = +{ + 0: "all", + 1: "classes", + 2: "functions", + 3: "pages" +}; + +var indexSectionLabels = +{ + 0: "All", + 1: "Classes", + 2: "Functions", + 3: "Pages" +}; + diff --git a/docs/html/splitbar.png b/docs/html/splitbar.png new file mode 100644 index 0000000000000000000000000000000000000000..fe895f2c58179b471a22d8320b39a4bd7312ec8e GIT binary patch literal 314 zcmeAS@N?(olHy`uVBq!ia0vp^Yzz!63>-{AmhX=Jf(#6djGiuzAr*{o?=JLmPLyc> z_*`QK&+BH@jWrYJ7>r6%keRM@)Qyv8R=enp0jiI>aWlGyB58O zFVR20d+y`K7vDw(hJF3;>dD*3-?v=<8M)@x|EEGLnJsniYK!2U1 Y!`|5biEc?d1`HDhPgg&ebxsLQ02F6;9RL6T literal 0 HcmV?d00001 diff --git a/docs/html/sync_off.png b/docs/html/sync_off.png new file mode 100644 index 0000000000000000000000000000000000000000..3b443fc62892114406e3d399421b2a881b897acc GIT binary patch literal 853 zcmV-b1FHOqP)oT|#XixUYy%lpuf3i8{fX!o zUyDD0jOrAiT^tq>fLSOOABs-#u{dV^F$b{L9&!2=9&RmV;;8s^x&UqB$PCj4FdKbh zoB1WTskPUPu05XzFbA}=KZ-GP1fPpAfSs>6AHb12UlR%-i&uOlTpFNS7{jm@mkU1V zh`nrXr~+^lsV-s1dkZOaI|kYyVj3WBpPCY{n~yd%u%e+d=f%`N0FItMPtdgBb@py; zq@v6NVArhyTC7)ULw-Jy8y42S1~4n(3LkrW8mW(F-4oXUP3E`e#g**YyqI7h-J2zK zK{m9##m4ri!7N>CqQqCcnI3hqo1I;Yh&QLNY4T`*ptiQGozK>FF$!$+84Z`xwmeMh zJ0WT+OH$WYFALEaGj2_l+#DC3t7_S`vHpSivNeFbP6+r50cO8iu)`7i%Z4BTPh@_m3Tk!nAm^)5Bqnr%Ov|Baunj#&RPtRuK& z4RGz|D5HNrW83-#ydk}tVKJrNmyYt-sTxLGlJY5nc&Re zU4SgHNPx8~Yxwr$bsju?4q&%T1874xxzq+_%?h8_ofw~(bld=o3iC)LUNR*BY%c0y zWd_jX{Y8`l%z+ol1$@Qa?Cy!(0CVIEeYpKZ`(9{z>3$CIe;pJDQk$m3p}$>xBm4lb zKo{4S)`wdU9Ba9jJbVJ0C=SOefZe%d$8=2r={nu<_^a3~>c#t_U6dye5)JrR(_a^E f@}b6j1K9lwFJq@>o)+Ry00000NkvXXu0mjfWa5j* literal 0 HcmV?d00001 diff --git a/docs/html/sync_on.png b/docs/html/sync_on.png new file mode 100644 index 0000000000000000000000000000000000000000..e08320fb64e6fa33b573005ed6d8fe294e19db76 GIT binary patch literal 845 zcmV-T1G4;yP)Y;xxyHF2B5Wzm| zOOGupOTn@c(JmBOl)e;XMNnZuiTJP>rM8<|Q`7I_))aP?*T)ow&n59{}X4$3Goat zgjs?*aasfbrokzG5cT4K=uG`E14xZl@z)F={P0Y^?$4t z>v!teRnNZym<6h{7sLyF1V0HsfEl+l6TrZpsfr1}luH~F7L}ktXu|*uVX^RG$L0`K zWs3j|0tIvVe(N%_?2{(iCPFGf#B6Hjy6o&}D$A%W%jfO8_W%ZO#-mh}EM$LMn7joJ z05dHr!5Y92g+31l<%i1(=L1a1pXX+OYnalY>31V4K}BjyRe3)9n#;-cCVRD_IG1fT zOKGeNY8q;TL@K{dj@D^scf&VCs*-Jb>8b>|`b*osv52-!A?BpbYtTQBns5EAU**$m zSnVSm(teh>tQi*S*A>#ySc=n;`BHz`DuG4&g4Kf8lLhca+zvZ7t7RflD6-i-mcK=M z!=^P$*u2)bkY5asG4gsss!Hn%u~>}kIW`vMs%lJLH+u*9<4PaV_c6U`KqWXQH%+Nu zTv41O(^ZVi@qhjQdG!fbZw&y+2o!iYymO^?ud3{P*HdoX83YV*Uu_HB=?U&W9%AU# z80}k1SS-CXTU7dcQlsm<^oYLxVSseqY6NO}dc`Nj?8vrhNuCdm@^{a3AQ_>6myOj+ z`1RsLUXF|dm|3k7s2jD(B{rzE>WI2scH8i1;=O5Cc9xB3^aJk%fQjqsu+kH#0=_5a z0nCE8@dbQa-|YIuUVvG0L_IwHMEhOj$Mj4Uq05 X8=0q~qBNan00000NkvXXu0mjfptF>5 literal 0 HcmV?d00001 diff --git a/docs/html/tab_a.png b/docs/html/tab_a.png new file mode 100644 index 0000000000000000000000000000000000000000..3b725c41c5a527a3a3e40097077d0e206a681247 GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QlXwMjv*C{Z|8b*H5dputLHD# z=<0|*y7z(Vor?d;H&?EG&cXR}?!j-Lm&u1OOI7AIF5&c)RFE;&p0MYK>*Kl@eiymD r@|NpwKX@^z+;{u_Z~trSBfrMKa%3`zocFjEXaR$#tDnm{r-UW|TZ1%4 literal 0 HcmV?d00001 diff --git a/docs/html/tab_b.png b/docs/html/tab_b.png new file mode 100644 index 0000000000000000000000000000000000000000..e2b4a8638cb3496a016eaed9e16ffc12846dea18 GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QU#tajv*C{Z}0l@H7kg?K0Lnr z!j&C6_(~HV9oQ0Pa6x{-v0AGV_E?vLn=ZI-;YrdjIl`U`uzuDWSP?o#Dmo{%SgM#oan kX~E1%D-|#H#QbHoIja2U-MgvsK&LQxy85}Sb4q9e0Efg%P5=M^ literal 0 HcmV?d00001 diff --git a/docs/html/tabs.css b/docs/html/tabs.css new file mode 100644 index 00000000..85a0cd5b --- /dev/null +++ b/docs/html/tabs.css @@ -0,0 +1 @@ +.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:rgba(0,0,0,0)}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sm-dox{background-image:url("tab_b.png")}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0 12px;padding-right:43px;font-family:"Lucida Grande","Geneva","Helvetica",Arial,sans-serif;font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:0 1px 1px rgba(255,255,255,0.9);color:#283a5d;outline:0}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox a.current{color:#d23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace!important;text-align:center;text-shadow:none;background:rgba(255,255,255,0.5);-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{-moz-border-radius:5px 5px 0 0;-webkit-border-radius:5px;border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{-moz-border-radius:0 0 5px 5px;-webkit-border-radius:0;border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox ul{background:rgba(162,162,162,0.1)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:white;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media(min-width:768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:url("tab_b.png");line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:#283a5d transparent transparent transparent;background:transparent;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0 12px;background-image:url("tab_s.png");background-repeat:no-repeat;background-position:right;-moz-border-radius:0!important;-webkit-border-radius:0;border-radius:0!important}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox a:hover span.sub-arrow{border-color:white transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent #fff transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:#fff;-moz-border-radius:5px!important;-webkit-border-radius:5px;border-radius:5px!important;-moz-box-shadow:0 5px 9px rgba(0,0,0,0.2);-webkit-box-shadow:0 5px 9px rgba(0,0,0,0.2);box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent #555;border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:#555;background-image:none;border:0!important;color:#555;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent white}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:#fff;height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #d23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#d23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent #555 transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:#555 transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px!important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:url("tab_b.png")}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:#fff}} \ No newline at end of file diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 00000000..cfd32901 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,2 @@ + + From bdc289213cb61a47113abf6f281e9333c2e9d3f7 Mon Sep 17 00:00:00 2001 From: Jeff Hoefs Date: Fri, 11 Oct 2019 21:42:34 -0700 Subject: [PATCH 42/81] Update readme.md --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 042c28d2..ed5d319f 100644 --- a/readme.md +++ b/readme.md @@ -19,7 +19,7 @@ Firmata is a protocol for communicating with microcontrollers from software on a ## Usage -There are two main models of usage of Firmata. In one model, the author of the Arduino sketch uses the various methods provided by the Firmata library to selectively send and receive data between the Arduino device and the software running on the host computer. For example, a user can send analog data to the host using ``` Firmata.sendAnalog(analogPin, analogRead(analogPin)) ``` or send data packed in a string using ``` Firmata.sendString(stringToSend) ```. See File -> Examples -> Firmata -> AnalogFirmata & EchoString respectively for examples. +There are two main models of usage of Firmata. In one model, the author of the Arduino sketch uses the various methods provided by the Firmata library to selectively send and receive data between the Arduino device and the software running on the host computer. For example, a user can send analog data to the host using ``` Firmata.sendAnalog(analogPin, analogRead(analogPin)) ``` or send data packed in a string using ``` Firmata.sendString(stringToSend) ```. See File -> Examples -> Firmata -> AnalogFirmata & EchoString respectively for examples. Browse the API documentation [here](https://firmata.github.io/arduino/html/index.html). The second and more common model is to load a general purpose sketch called StandardFirmata (or one of the variants such as StandardFirmataPlus or StandardFirmataEthernet depending on your needs) on the Arduino board and then use the host computer exclusively to interact with the Arduino board. StandardFirmata is located in the Arduino IDE in File -> Examples -> Firmata. From 663454a5f8db6fef9800b11bee4aceb10a0eb75c Mon Sep 17 00:00:00 2001 From: baggio63446333 <55774994+baggio63446333@users.noreply.github.com> Date: Sun, 20 Oct 2019 15:17:04 +0900 Subject: [PATCH 43/81] Add support for SPRESENSE board --- Boards.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Boards.h b/Boards.h index 730826f6..d9d2ae02 100644 --- a/Boards.h +++ b/Boards.h @@ -888,6 +888,23 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_PWM(p) (p) #define PIN_TO_SERVO(p) (p) +// SPRESENSE +#elif defined(ARDUINO_ARCH_SPRESENSE) +#define TOTAL_ANALOG_PINS NUM_ANALOG_INPUTS +#define TOTAL_PINS NUM_DIGITAL_PINS + 4 + NUM_ANALOG_INPUTS // + 4 built-in led +#define VERSION_BLINK_PIN LED_BUILTIN +#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < (NUM_DIGITAL_PINS + 4)) +#define IS_PIN_ANALOG(p) ((p) >= (TOTAL_PINS - NUM_ANALOG_INPUTS) && (p) < TOTAL_PINS) +#define IS_PIN_PWM(p) ((p) == 6 || (p) == 5 || (p) == 9 || (p) == 3) +#define IS_PIN_SERVO(p) ((p) < NUM_DIGITAL_PINS) +#define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL) +#define IS_PIN_SPI(p) ((p) == 10 || (p) == 11 || (p) == 12 || (p) == 13) +#define PIN_TO_DIGITAL(p) (((p) < NUM_DIGITAL_PINS) ? (p) : (_LED_PIN((p) - NUM_DIGITAL_PINS))) +#define PIN_TO_ANALOG(p) ((p) - (TOTAL_PINS - NUM_ANALOG_INPUTS)) +#define PIN_TO_PWM(p) (p) +#define PIN_TO_SERVO(p) (p) +#define analogRead(p) analogRead(_ANALOG_PIN(p)) // wrap function for analogRead() + // anything else #else #error "Please edit Boards.h with a hardware abstraction for this board" From a142327e5a1e1e3450b0774c93b7c642f827c60c Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Mon, 9 Dec 2019 09:28:05 +0100 Subject: [PATCH 44/81] Fix build issue with arm none eabi gcc v9.2.1 Firmata/Firmata.h:131:17: error: friend declaration of 'void encodeByteStream(size_t, uint8_t*, size_t) const' specifies default arguments and isn't a definition [-fpermissive] 131 | friend void FirmataMarshaller::encodeByteStream (size_t bytec, uint8_t * bytev, size_t max_bytes = 0) const; | ^~~~~~~~~~~~~~~~~ Ref: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2000/n1263.html Fixes #437 Signed-off-by: Frederic Pillon --- Firmata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmata.h b/Firmata.h index fa0fa6c2..fb993d79 100644 --- a/Firmata.h +++ b/Firmata.h @@ -128,7 +128,7 @@ class FirmataClass /* private methods ------------------------------ */ void strobeBlinkPin(byte pin, int count, int onInterval, int offInterval); - friend void FirmataMarshaller::encodeByteStream (size_t bytec, uint8_t * bytev, size_t max_bytes = 0) const; + friend void FirmataMarshaller::encodeByteStream (size_t bytec, uint8_t * bytev, size_t max_bytes) const; /* callback functions */ static callbackFunction currentAnalogCallback; From 4d0742fc367eb8539957ae980ac12347896b7e7e Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Tue, 3 Dec 2019 08:44:58 +0100 Subject: [PATCH 45/81] [STM32] Define VERSION_BLINK_PIN only if LED_BUILTIN is defined Not all STM32 boards have a LED_BUILTIN. Signed-off-by: Frederic Pillon --- Boards.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Boards.h b/Boards.h index d9d2ae02..d00fb89e 100644 --- a/Boards.h +++ b/Boards.h @@ -854,7 +854,9 @@ writePort(port, value, bitmask): Write an 8 bit port. #define TOTAL_ANALOG_PINS NUM_ANALOG_INPUTS #define TOTAL_PINS NUM_DIGITAL_PINS #define TOTAL_PORTS MAX_NB_PORT +#ifdef LED_BUILTIN #define VERSION_BLINK_PIN LED_BUILTIN +#endif // PIN_SERIALY_RX/TX defined in the variant.h #define IS_PIN_DIGITAL(p) (digitalPinIsValid(p) && !pinIsSerial(p)) #define IS_PIN_ANALOG(p) ((p >= A0) && (p < (A0 + TOTAL_ANALOG_PINS)) && !pinIsSerial(p)) From 5d37416f89e31ff8e10a8a109924c2d7a1f985b1 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Tue, 3 Dec 2019 11:46:19 +0100 Subject: [PATCH 46/81] [STM32] Update analog macro Since STM32 core version 1.8.0, analog pins definition can be not contiguous Signed-off-by: Frederic Pillon --- Boards.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Boards.h b/Boards.h index d00fb89e..b6937545 100644 --- a/Boards.h +++ b/Boards.h @@ -859,15 +859,23 @@ writePort(port, value, bitmask): Write an 8 bit port. #endif // PIN_SERIALY_RX/TX defined in the variant.h #define IS_PIN_DIGITAL(p) (digitalPinIsValid(p) && !pinIsSerial(p)) +#if !defined(STM32_CORE_VERSION) || (STM32_CORE_VERSION <= 0x01080000) #define IS_PIN_ANALOG(p) ((p >= A0) && (p < (A0 + TOTAL_ANALOG_PINS)) && !pinIsSerial(p)) +#else +#define IS_PIN_ANALOG(p) (pinIsAnalogInput(p) && !pinIsSerial(p)) +#endif #define IS_PIN_PWM(p) (IS_PIN_DIGITAL(p) && digitalPinHasPWM(p)) -#define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p) +#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p)) #define IS_PIN_I2C(p) (IS_PIN_DIGITAL(p) && digitalPinHasI2C(p)) #define IS_PIN_SPI(p) (IS_PIN_DIGITAL(p) && digitalPinHasSPI(p)) #define IS_PIN_INTERRUPT(p) (IS_PIN_DIGITAL(p) && (digitalPinToInterrupt(p) > NOT_AN_INTERRUPT))) #define IS_PIN_SERIAL(p) (digitalPinHasSerial(p) && !pinIsSerial(p)) #define PIN_TO_DIGITAL(p) (p) +#if !defined(STM32_CORE_VERSION) || (STM32_CORE_VERSION <= 0x01080000) #define PIN_TO_ANALOG(p) (p-A0) +#else +#define PIN_TO_ANALOG(p) (digitalPinToAnalogInput(p)) +#endif #define PIN_TO_PWM(p) (p) #define PIN_TO_SERVO(p) (p) #define DEFAULT_PWM_RESOLUTION PWM_RESOLUTION From b102e745441bdeab51bbcd6202ca12598954ad17 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Mon, 20 Jan 2020 07:52:01 +0100 Subject: [PATCH 47/81] [STM32] Fix version checking Signed-off-by: Frederic Pillon --- Boards.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Boards.h b/Boards.h index b6937545..a56ed8d6 100644 --- a/Boards.h +++ b/Boards.h @@ -859,7 +859,7 @@ writePort(port, value, bitmask): Write an 8 bit port. #endif // PIN_SERIALY_RX/TX defined in the variant.h #define IS_PIN_DIGITAL(p) (digitalPinIsValid(p) && !pinIsSerial(p)) -#if !defined(STM32_CORE_VERSION) || (STM32_CORE_VERSION <= 0x01080000) +#if !defined(STM32_CORE_VERSION) || (STM32_CORE_VERSION < 0x01080000) #define IS_PIN_ANALOG(p) ((p >= A0) && (p < (A0 + TOTAL_ANALOG_PINS)) && !pinIsSerial(p)) #else #define IS_PIN_ANALOG(p) (pinIsAnalogInput(p) && !pinIsSerial(p)) @@ -871,7 +871,7 @@ writePort(port, value, bitmask): Write an 8 bit port. #define IS_PIN_INTERRUPT(p) (IS_PIN_DIGITAL(p) && (digitalPinToInterrupt(p) > NOT_AN_INTERRUPT))) #define IS_PIN_SERIAL(p) (digitalPinHasSerial(p) && !pinIsSerial(p)) #define PIN_TO_DIGITAL(p) (p) -#if !defined(STM32_CORE_VERSION) || (STM32_CORE_VERSION <= 0x01080000) +#if !defined(STM32_CORE_VERSION) || (STM32_CORE_VERSION < 0x01080000) #define PIN_TO_ANALOG(p) (p-A0) #else #define PIN_TO_ANALOG(p) (digitalPinToAnalogInput(p)) From edc329ac25dd83a1b3a13800fd7ad094ac3f3410 Mon Sep 17 00:00:00 2001 From: Jens B Date: Sun, 15 Mar 2020 13:11:51 +0100 Subject: [PATCH 48/81] EthernetClientStream host connection callback - added host connection callback hook to notfiy connect and disconnect (WiFiStream feature) --- .../StandardFirmataEthernet.ino | 26 +++++++++++++++++- utility/EthernetClientStream.h | 27 ++++++++++++++++++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino b/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino index f512ccea..ff1409dd 100644 --- a/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino +++ b/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino @@ -20,7 +20,7 @@ See file LICENSE.txt for further informations on licensing terms. - Last updated August 17th, 2017 + Last updated March 10th, 2020 */ /* @@ -832,6 +832,26 @@ void systemResetCallback() isResetting = false; } +#ifdef ETHERNETCLIENTSTREAM_H +/* + * Called when a TCP connection is either connected or disconnected. + * TODO: + * - report connected or reconnected state to host (to be added to protocol) + * - report current state to host (to be added to protocol) + */ +void hostConnectionCallback(byte state) +{ + switch (state) { + case HOST_CONNECTION_CONNECTED: + DEBUG_PRINTLN( "TCP connection established" ); + break; + case HOST_CONNECTION_DISCONNECTED: + DEBUG_PRINTLN( "TCP connection disconnected" ); + break; + } +} +#endif + void printEthernetStatus() { DEBUG_PRINT("Local IP Address: "); @@ -873,6 +893,10 @@ void ignorePins() void initTransport() { +#ifdef ETHERNETCLIENTSTREAM_H + stream.attach(hostConnectionCallback); +#endif + #ifdef YUN_ETHERNET Bridge.begin(); #else diff --git a/utility/EthernetClientStream.h b/utility/EthernetClientStream.h index 1b7d2e29..73ed5ca4 100644 --- a/utility/EthernetClientStream.h +++ b/utility/EthernetClientStream.h @@ -14,7 +14,7 @@ See file LICENSE.txt for further informations on licensing terms. - Last updated June 18th, 2016 + Last updated March 10th, 2020 */ #ifndef ETHERNETCLIENTSTREAM_H @@ -28,6 +28,14 @@ #define MILLIS_RECONNECT 5000 +#define HOST_CONNECTION_DISCONNECTED 0 +#define HOST_CONNECTION_CONNECTED 1 + +extern "C" { + // callback function types + typedef void (*hostConnectionCallbackFunction)(byte); +} + class EthernetClientStream : public Stream { public: @@ -38,6 +46,7 @@ class EthernetClientStream : public Stream void flush(); size_t write(uint8_t); void maintain(IPAddress localip); + void attach(hostConnectionCallbackFunction newFunction); private: Client &client; @@ -47,6 +56,7 @@ class EthernetClientStream : public Stream uint16_t port; bool connected; uint32_t time_connect; + hostConnectionCallbackFunction currentHostConnectionCallback; bool maintain(); void stop(); }; @@ -64,6 +74,7 @@ EthernetClientStream::EthernetClientStream(Client &client, IPAddress localip, IP host(host), port(port), connected(false) + , currentHostConnectionCallback(nullptr) { } @@ -112,10 +123,20 @@ void EthernetClientStream::stop() { client.stop(); + if (currentHostConnectionCallback) + { + (*currentHostConnectionCallback)(HOST_CONNECTION_DISCONNECTED); + } connected = false; time_connect = millis(); } +void +EthernetClientStream::attach(hostConnectionCallbackFunction newFunction) +{ + currentHostConnectionCallback = newFunction; +} + bool EthernetClientStream::maintain() { @@ -133,6 +154,10 @@ EthernetClientStream::maintain() DEBUG_PRINTLN("Connection failed. Attempting to reconnect..."); } else { DEBUG_PRINTLN("Connected"); + if (currentHostConnectionCallback) + { + (*currentHostConnectionCallback)(HOST_CONNECTION_CONNECTED); + } } } return connected; From 4048f224be228c75e156cfa5202f0de0a2e6c358 Mon Sep 17 00:00:00 2001 From: Jens B Date: Sun, 15 Mar 2020 13:23:00 +0100 Subject: [PATCH 49/81] SerialFirmata store & forward - delay single byte reads to avoid single byte transfers - explitly define Arduino constant SERIAL_RX_BUFFER_SIZE equivalent for ESP8266 platform --- utility/SerialFirmata.cpp | 86 +++++++++++++++++++++++++++++++-------- utility/SerialFirmata.h | 34 +++++++++++++++- 2 files changed, 102 insertions(+), 18 deletions(-) diff --git a/utility/SerialFirmata.cpp b/utility/SerialFirmata.cpp index 8b703e13..02efcf73 100644 --- a/utility/SerialFirmata.cpp +++ b/utility/SerialFirmata.cpp @@ -14,11 +14,19 @@ - handlePinMode calls Firmata::setPinMode - Last updated October 16th, 2016 + Last updated March 16th, 2020 */ #include "SerialFirmata.h" +// The RX and TX hardware FIFOs of the ESP8266 hold 128 bytes that can be +// extended using interrupt handlers. The Arduino constants are not available +// for the ESP8266 platform. +#if !defined(SERIAL_RX_BUFFER_SIZE) && defined(UART_TX_FIFO_SIZE) +#define SERIAL_RX_BUFFER_SIZE UART_TX_FIFO_SIZE +#endif + + SerialFirmata::SerialFirmata() { #if defined(SoftwareSerial_h) @@ -29,6 +37,12 @@ SerialFirmata::SerialFirmata() #endif serialIndex = -1; + +#if defined(FIRMATA_SERIAL_RX_DELAY) + for (byte i = 0; i < SERIAL_READ_ARR_LEN; i++) { + maxRxDelay[i] = FIRMATA_SERIAL_RX_DELAY; // @todo provide setter + } +#endif } boolean SerialFirmata::handlePinMode(byte pin, int mode) @@ -56,13 +70,17 @@ boolean SerialFirmata::handleSysex(byte command, byte argc, byte *argv) Stream *serialPort; byte mode = argv[0] & SERIAL_MODE_MASK; byte portId = argv[0] & SERIAL_PORT_ID_MASK; + if (portId >= SERIAL_READ_ARR_LEN) return false; switch (mode) { case SERIAL_CONFIG: { long baud = (long)argv[1] | ((long)argv[2] << 7) | ((long)argv[3] << 14); serial_pins pins; - +#if defined(FIRMATA_SERIAL_RX_DELAY) + lastBytesAvailable[portId] = 0; + lastBytesReceived[portId] = 0; +#endif if (portId < 8) { serialPort = getPortFromId(portId); if (serialPort != NULL) { @@ -229,6 +247,10 @@ void SerialFirmata::reset() serialIndex = -1; for (byte i = 0; i < SERIAL_READ_ARR_LEN; i++) { serialBytesToRead[i] = 0; +#if defined(FIRMATA_SERIAL_RX_DELAY) + lastBytesAvailable[i] = 0; + lastBytesReceived[i] = 0; +#endif } } @@ -302,6 +324,10 @@ void SerialFirmata::checkSerial() if (serialIndex > -1) { +#if defined(FIRMATA_SERIAL_RX_DELAY) + unsigned long currentMillis = millis(); +#endif + // loop through all reporting (READ_CONTINUOUS) serial ports for (byte i = 0; i < serialIndex + 1; i++) { portId = reportSerial[i]; @@ -316,27 +342,53 @@ void SerialFirmata::checkSerial() continue; } #endif - if (serialPort->available() > 0) { - Firmata.write(START_SYSEX); - Firmata.write(SERIAL_MESSAGE); - Firmata.write(SERIAL_REPLY | portId); - - if (bytesToRead == 0 || (serialPort->available() <= bytesToRead)) { - numBytesToRead = serialPort->available(); + int bytesAvailable = serialPort->available(); + if (bytesAvailable > 0) { +#if defined(FIRMATA_SERIAL_RX_DELAY) + if (bytesAvailable > lastBytesAvailable[portId]) { + lastBytesReceived[portId] = currentMillis; + } + lastBytesAvailable[portId] = bytesAvailable; +#endif + if (bytesToRead <= 0 || (bytesAvailable <= bytesToRead)) { + numBytesToRead = bytesAvailable; } else { numBytesToRead = bytesToRead; } - +#if defined(FIRMATA_SERIAL_RX_DELAY) + if (maxRxDelay[portId] >= 0 && numBytesToRead > 0) { + // read and send immediately only if + // - expected bytes are unknown and the receive buffer has reached 50 % + // - expected bytes are available + // - maxRxDelay has expired since last receive (or time counter wrap) + if (!((bytesToRead <= 0 && bytesAvailable >= SERIAL_RX_BUFFER_SIZE/2) + || (bytesToRead > 0 && bytesAvailable >= bytesToRead) + || (maxRxDelay[portId] > 0 && (currentMillis < lastBytesReceived[portId] || (currentMillis - lastBytesReceived[portId]) >= maxRxDelay[portId])))) { + // delay + numBytesToRead = 0; + } + } +#endif // relay serial data to the serial device - while (numBytesToRead > 0) { - serialData = serialPort->read(); - Firmata.write(serialData & 0x7F); - Firmata.write((serialData >> 7) & 0x7F); - numBytesToRead--; + if (numBytesToRead > 0) { +#if defined(FIRMATA_SERIAL_RX_DELAY) + lastBytesAvailable[portId] -= numBytesToRead; +#endif + Firmata.write(START_SYSEX); + Firmata.write(SERIAL_MESSAGE); + Firmata.write(SERIAL_REPLY | portId); + + // relay serial data to the serial device + while (numBytesToRead > 0) { + serialData = serialPort->read(); + Firmata.write(serialData & 0x7F); + Firmata.write((serialData >> 7) & 0x7F); + numBytesToRead--; + } + + Firmata.write(END_SYSEX); } - Firmata.write(END_SYSEX); } - } } } diff --git a/utility/SerialFirmata.h b/utility/SerialFirmata.h index 365fde48..a05b761a 100644 --- a/utility/SerialFirmata.h +++ b/utility/SerialFirmata.h @@ -15,7 +15,7 @@ - Defines FIRMATA_SERIAL_FEATURE (could add to Configurable version as well) - Imports Firmata.h rather than ConfigurableFirmata.h - Last updated October 16th, 2016 + Last updated March 11th, 2020 */ #ifndef SerialFirmata_h @@ -30,6 +30,32 @@ #include #endif +// If defined and set to a value between 0 and 255 milliseconds the received bytes +// will be not be read until until one of the following conditions are met: +// 1) the expected number of bytes have been received +// 2) the serial receive buffer is filled to 50 % (default size is 64 bytes) +// 3) the delay since the last received byte exceeds the configured FIRMATA_SERIAL_RX_DELAY +// hints: 5 bytes at 9600 baud take 5 ms, human perception of a delay starts at 50 ms +// This feature can significantly reduce the load on the transport layer when +// the byte receive rate is equal or lower than the average Firmata main loop execution +// duration by preventing single byte transmits if the underlying Firmata stream supports +// transmit buffering (currently only available with EthernetClientStream). The effect +// can be increased with higher values of FIRMATA_SERIAL_RX_DELAY. +// Notes +// 1) Enabling this feature will delay the received data and may concatenate +// bytes into one transmit that would otherwise be transmitted separately. +// 2) The usefulness and configuration of this feature depends on the baud rate and the serial message type: +// a) continuous streaming at higher baud rates: enable but set to 0 (receive buffer store & forward) +// b) messages: set to a value below min. inter message delay (message store & forward) +// c) continuous streaming at lower baud rates or random characters: undefine or set to -1 (disable) +// 3) Smaller delays may not have the desired effect, especially with less powerful CPUs, +// if set to a value near or below the average Firmata main loop duration. +// 4) The Firmata stream write buffer size must be equal or greater than the max. +// serial buffer/message size and the Firmata frame size (4 bytes) to prevent fragmentation +// on the transport layer. +//#define FIRMATA_SERIAL_RX_DELAY 50 // [ms] +#define FIRMATA_SERIAL_RX_DELAY 50 + #define FIRMATA_SERIAL_FEATURE // Serial port Ids @@ -194,6 +220,12 @@ class SerialFirmata: public FirmataFeature int serialBytesToRead[SERIAL_READ_ARR_LEN]; signed char serialIndex; +#if defined(FIRMATA_SERIAL_RX_DELAY) + byte maxRxDelay[SERIAL_READ_ARR_LEN]; + int lastBytesAvailable[SERIAL_READ_ARR_LEN]; + unsigned long lastBytesReceived[SERIAL_READ_ARR_LEN]; +#endif + #if defined(SoftwareSerial_h) Stream *swSerial0; Stream *swSerial1; From 2963dd6b3181f0192fba91c08bceacf91ad93827 Mon Sep 17 00:00:00 2001 From: Jeff Hoefs Date: Thu, 9 Apr 2020 20:54:23 -0700 Subject: [PATCH 50/81] Add Node-RED to list of client libraries --- readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.md b/readme.md index ed5d319f..43d45919 100644 --- a/readme.md +++ b/readme.md @@ -49,6 +49,7 @@ Most of the time you will be interacting with Arduino with a client library on t * [https://github.com/firmata/firmata.js](https://github.com/firmata/firmata.js) * [https://github.com/rwldrn/johnny-five](https://github.com/rwldrn/johnny-five) * [http://breakoutjs.com](http://breakoutjs.com) + * [https://nodered.org/docs/faq/interacting-with-arduino#firmata](Node-RED) * java * [https://github.com/kurbatov/firmata4j](https://github.com/kurbatov/firmata4j) * [https://github.com/4ntoine/Firmata](https://github.com/4ntoine/Firmata) From e5204bed4ff5a46deb426c625a596ee5c188d4ee Mon Sep 17 00:00:00 2001 From: Jeff Hoefs Date: Thu, 9 Apr 2020 20:59:20 -0700 Subject: [PATCH 51/81] Fix client library links --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 43d45919..6e0faa42 100644 --- a/readme.md +++ b/readme.md @@ -31,7 +31,7 @@ Most of the time you will be interacting with Arduino with a client library on t * [http://funnel.cc](http://funnel.cc) * python * [https://github.com/MrYsLab/pymata-aio](https://github.com/MrYsLab/pymata-aio) - * [https://github.com/MrYsLab/PyMata]([https://github.com/MrYsLab/PyMata) + * [https://github.com/MrYsLab/PyMata](https://github.com/MrYsLab/PyMata) * [https://github.com/tino/pyFirmata](https://github.com/tino/pyFirmata) * [https://github.com/lupeke/python-firmata](https://github.com/lupeke/python-firmata) * [https://github.com/firmata/pyduino](https://github.com/firmata/pyduino) @@ -49,7 +49,7 @@ Most of the time you will be interacting with Arduino with a client library on t * [https://github.com/firmata/firmata.js](https://github.com/firmata/firmata.js) * [https://github.com/rwldrn/johnny-five](https://github.com/rwldrn/johnny-five) * [http://breakoutjs.com](http://breakoutjs.com) - * [https://nodered.org/docs/faq/interacting-with-arduino#firmata](Node-RED) + * [https://nodered.org/docs/faq/interacting-with-arduino#firmata](https://nodered.org/docs/faq/interacting-with-arduino#firmata) * java * [https://github.com/kurbatov/firmata4j](https://github.com/kurbatov/firmata4j) * [https://github.com/4ntoine/Firmata](https://github.com/4ntoine/Firmata) From 9eac4a864efa0aea3472f67f9a3496242cc9d72a Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Sun, 19 Apr 2020 07:35:00 +0200 Subject: [PATCH 52/81] Return only as many bytes as were received in I2C transfers. --- examples/StandardFirmata/StandardFirmata.ino | 1 + examples/StandardFirmataBLE/StandardFirmataBLE.ino | 1 + examples/StandardFirmataChipKIT/StandardFirmataChipKIT.ino | 1 + examples/StandardFirmataEthernet/StandardFirmataEthernet.ino | 1 + examples/StandardFirmataPlus/StandardFirmataPlus.ino | 1 + examples/StandardFirmataWiFi/StandardFirmataWiFi.ino | 1 + 6 files changed, 6 insertions(+) diff --git a/examples/StandardFirmata/StandardFirmata.ino b/examples/StandardFirmata/StandardFirmata.ino index b043c11e..0e05a812 100755 --- a/examples/StandardFirmata/StandardFirmata.ino +++ b/examples/StandardFirmata/StandardFirmata.ino @@ -206,6 +206,7 @@ void readAndReportData(byte address, int theRegister, byte numBytes, byte stopTX Firmata.sendString("I2C: Too many bytes received"); } else if (numBytes > Wire.available()) { Firmata.sendString("I2C: Too few bytes received"); + numBytes = Wire.available(); } i2cRxData[0] = address; diff --git a/examples/StandardFirmataBLE/StandardFirmataBLE.ino b/examples/StandardFirmataBLE/StandardFirmataBLE.ino index ebbe2efc..ba80e8d8 100755 --- a/examples/StandardFirmataBLE/StandardFirmataBLE.ino +++ b/examples/StandardFirmataBLE/StandardFirmataBLE.ino @@ -219,6 +219,7 @@ void readAndReportData(byte address, int theRegister, byte numBytes, byte stopTX Firmata.sendString("I2C: Too many bytes received"); } else if (numBytes > Wire.available()) { Firmata.sendString("I2C: Too few bytes received"); + numBytes = Wire.available(); } i2cRxData[0] = address; diff --git a/examples/StandardFirmataChipKIT/StandardFirmataChipKIT.ino b/examples/StandardFirmataChipKIT/StandardFirmataChipKIT.ino index e13d166d..e7a79353 100644 --- a/examples/StandardFirmataChipKIT/StandardFirmataChipKIT.ino +++ b/examples/StandardFirmataChipKIT/StandardFirmataChipKIT.ino @@ -203,6 +203,7 @@ void readAndReportData(byte address, int theRegister, byte numBytes, byte stopTX Firmata.sendString("I2C: Too many bytes received"); } else if (numBytes > Wire.available()) { Firmata.sendString("I2C: Too few bytes received"); + numBytes = Wire.available(); } i2cRxData[0] = address; diff --git a/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino b/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino index ff1409dd..6795c215 100644 --- a/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino +++ b/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino @@ -285,6 +285,7 @@ void readAndReportData(byte address, int theRegister, byte numBytes, byte stopTX Firmata.sendString("I2C: Too many bytes received"); } else if (numBytes > Wire.available()) { Firmata.sendString("I2C: Too few bytes received"); + numBytes = Wire.available(); } i2cRxData[0] = address; diff --git a/examples/StandardFirmataPlus/StandardFirmataPlus.ino b/examples/StandardFirmataPlus/StandardFirmataPlus.ino index 8fb51ebe..caece95c 100644 --- a/examples/StandardFirmataPlus/StandardFirmataPlus.ino +++ b/examples/StandardFirmataPlus/StandardFirmataPlus.ino @@ -231,6 +231,7 @@ void readAndReportData(byte address, int theRegister, byte numBytes, byte stopTX Firmata.sendString("I2C: Too many bytes received"); } else if (numBytes > Wire.available()) { Firmata.sendString("I2C: Too few bytes received"); + numBytes = Wire.available(); } i2cRxData[0] = address; diff --git a/examples/StandardFirmataWiFi/StandardFirmataWiFi.ino b/examples/StandardFirmataWiFi/StandardFirmataWiFi.ino index 032357d5..98b33587 100644 --- a/examples/StandardFirmataWiFi/StandardFirmataWiFi.ino +++ b/examples/StandardFirmataWiFi/StandardFirmataWiFi.ino @@ -290,6 +290,7 @@ void readAndReportData(byte address, int theRegister, byte numBytes, byte stopTX Firmata.sendString("I2C: Too many bytes received"); } else if (numBytes > Wire.available()) { Firmata.sendString("I2C: Too few bytes received"); + numBytes = Wire.available(); } i2cRxData[0] = address; From 7b893faf803b121122f45559aeb8235ccdfc89d4 Mon Sep 17 00:00:00 2001 From: wallarug Date: Sat, 2 May 2020 22:39:22 +1000 Subject: [PATCH 53/81] Added Robotics Masters Robo HAT MM1 board to boards.h --- Boards.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Boards.h b/Boards.h index a56ed8d6..8ee1c28d 100644 --- a/Boards.h +++ b/Boards.h @@ -915,6 +915,26 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_SERVO(p) (p) #define analogRead(p) analogRead(_ANALOG_PIN(p)) // wrap function for analogRead() +// Robo HAT MM1 +#elif defined(ROBOTICSMASTERS_ROBOHATMM1_M4) +#define TOTAL_ANALOG_PINS 7 +#define TOTAL_PINS 46 // 14 digital + 7 analog + 4 i2c + 6 spi + 4 serial +#define TOTAL_PORTS 3 // set when TOTAL_PINS > num digitial I/O pins +#define VERSION_BLINK_PIN LED_BUILTIN +//#define PIN_SERIAL1_RX 0 // already defined in zero core variant.h +//#define PIN_SERIAL1_TX 1 // already defined in zero core variant.h +#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) <= 13) +#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4 +#define IS_PIN_I2C(p) ((p) == 21 || (p) == 22) // SDA = 21, SCL = 21 +#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) // SS = A2 +#define IS_PIN_SERIAL(p) ((p) == 0 || (p) == 1) +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) ((p) - 14) +#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) +#define PIN_TO_SERVO(p) (p) // deprecated since v2.4 + // anything else #else #error "Please edit Boards.h with a hardware abstraction for this board" From e928ced601f16acdddff54b46c04e1e4f4bfd7f9 Mon Sep 17 00:00:00 2001 From: James Harton Date: Sun, 3 May 2020 10:03:03 +1200 Subject: [PATCH 54/81] Add the Board configuration for Teensy 4.0 --- Boards.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Boards.h b/Boards.h index a56ed8d6..57bf4b6f 100644 --- a/Boards.h +++ b/Boards.h @@ -536,6 +536,36 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) #define PIN_TO_SERVO(p) (p) +// Teensy 4.0 +#elif defined(__IMXRT1062__) +#define TOTAL_ANALOG_PINS 14 +#define TOTAL_PINS 40 +#define VERSION_BLINK_PIN 13 +#define PIN_SERIAL1_RX 0 +#define PIN_SERIAL1_TX 1 +#define PIN_SERIAL2_RX 7 +#define PIN_SERIAL2_TX 8 +#define PIN_SERIAL3_RX 15 +#define PIN_SERIAL3_TX 14 +#define PIN_SERIAL4_RX 16 +#define PIN_SERIAL4_TX 17 +#define PIN_SERIAL5_RX 21 +#define PIN_SERIAL5_TX 20 +#define PIN_SERIAL6_RX 25 +#define PIN_SERIAL6_TX 24 +#define PIN_SERIAL7_RX 28 +#define PIN_SERIAL7_TX 29 +#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) +#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 27) +#define IS_PIN_PWM(p) (((p) >= 0 && (p) <= 16) || ((p) >= 18 && (p) <= 19) || ((p) >= 22 && (p) <= 25) || ((p) >= 28 && (p) <= 29)|| ((p) >= 33 && (p) <= 39)) +#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) +#define IS_PIN_I2C(p) ((p) == 18 || (p) == 19) +#define IS_PIN_SERIAL(p) (((p) >= 0 && (p) <= 1) || ((p) >= 7 && (p) <= 8) || ((p) >= 14 && (p) <= 17) || ((p) >= 20 && (p) <= 21) || ((p) >= 24 && (p) <= 25) || ((p) >= 28 && (p) <= 29)) +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) ((p) - 14) +#define PIN_TO_PWM(p) (p) +#define PIN_TO_SERVO(p) (p) + // Leonardo #elif defined(__AVR_ATmega32U4__) From 5f42c13d07600a3019aada39b4fabec9f764d263 Mon Sep 17 00:00:00 2001 From: James Harton Date: Sun, 3 May 2020 10:42:49 +1200 Subject: [PATCH 55/81] Enable support for all seven Teensy 4.0 UARTS. --- utility/SerialFirmata.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/utility/SerialFirmata.h b/utility/SerialFirmata.h index a05b761a..f8ec2d7b 100644 --- a/utility/SerialFirmata.h +++ b/utility/SerialFirmata.h @@ -66,7 +66,7 @@ #define HW_SERIAL4 0x04 #define HW_SERIAL5 0x05 #define HW_SERIAL6 0x06 -// extensible up to 0x07 +#define HW_SERIAL7 0x07 #define SW_SERIAL0 0x08 #define SW_SERIAL1 0x09 @@ -91,6 +91,8 @@ #define RES_TX5 0x0b #define RES_RX6 0x0c #define RES_TX6 0x0d +#define RES_RX7 0x0e +#define RES_TX7 0x0f // Serial command bytes #define SERIAL_CONFIG 0x10 @@ -143,6 +145,10 @@ namespace { #if defined(PIN_SERIAL6_RX) if (pin == PIN_SERIAL6_RX) return RES_RX6; if (pin == PIN_SERIAL6_TX) return RES_TX6; + #endif + #if defined(PIN_SERIAL7_RX) + if (pin == PIN_SERIAL7_RX) return RES_RX7; + if (pin == PIN_SERIAL7_TX) return RES_TX7; #endif return 0; } @@ -193,6 +199,12 @@ namespace { pins.rx = PIN_SERIAL6_RX; pins.tx = PIN_SERIAL6_TX; break; + #endif + #if defined(PIN_SERIAL7_RX) + case HW_SERIAL7: + pins.rx = PIN_SERIAL7_RX; + pins.tx = PIN_SERIAL7_TX; + break; #endif default: pins.rx = 0; From ceb289a22cb51191a68c32c978f368d02c3ae565 Mon Sep 17 00:00:00 2001 From: MrYsLab Date: Fri, 8 May 2020 18:04:09 -0400 Subject: [PATCH 56/81] Update pymata links --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 6e0faa42..3632b1f6 100644 --- a/readme.md +++ b/readme.md @@ -30,8 +30,8 @@ Most of the time you will be interacting with Arduino with a client library on t * [https://github.com/firmata/processing](https://github.com/firmata/processing) * [http://funnel.cc](http://funnel.cc) * python - * [https://github.com/MrYsLab/pymata-aio](https://github.com/MrYsLab/pymata-aio) - * [https://github.com/MrYsLab/PyMata](https://github.com/MrYsLab/PyMata) + * [https://github.com/MrYsLab/pymata4](https://github.com/MrYsLab/pymata4) + * [https://github.com/MrYsLab/pymata-express](https://github.com/MrYsLab/pymata-express) * [https://github.com/tino/pyFirmata](https://github.com/tino/pyFirmata) * [https://github.com/lupeke/python-firmata](https://github.com/lupeke/python-firmata) * [https://github.com/firmata/pyduino](https://github.com/firmata/pyduino) From d20889e5acf025f7922b8eff85410036153bd3ff Mon Sep 17 00:00:00 2001 From: Jeff Hoefs Date: Sat, 11 Jul 2020 23:52:08 -0700 Subject: [PATCH 57/81] Fix compile error for M0 boards --- utility/SerialFirmata.h | 1 - 1 file changed, 1 deletion(-) diff --git a/utility/SerialFirmata.h b/utility/SerialFirmata.h index a05b761a..9c905aef 100644 --- a/utility/SerialFirmata.h +++ b/utility/SerialFirmata.h @@ -54,7 +54,6 @@ // serial buffer/message size and the Firmata frame size (4 bytes) to prevent fragmentation // on the transport layer. //#define FIRMATA_SERIAL_RX_DELAY 50 // [ms] -#define FIRMATA_SERIAL_RX_DELAY 50 #define FIRMATA_SERIAL_FEATURE From 61a54c77c748846dfbd2443e081c321e2576b6f9 Mon Sep 17 00:00:00 2001 From: Malik Enes Safak Date: Thu, 20 Aug 2020 21:32:49 +0300 Subject: [PATCH 58/81] New firmata clients for Max and Pure Data --- readme.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/readme.md b/readme.md index 3632b1f6..80a00b83 100644 --- a/readme.md +++ b/readme.md @@ -73,6 +73,7 @@ Most of the time you will be interacting with Arduino with a client library on t * [https://github.com/nfrancois/firmata](https://github.com/nfrancois/firmata) * Max/MSP * [http://www.maxuino.org/](http://www.maxuino.org/) + * [https://github.com/NullMember/MaxFirmata](https://github.com/NullMember/MaxFirmata) * Elixir * [https://github.com/kfatehi/firmata](https://github.com/kfatehi/firmata) * Modelica @@ -85,6 +86,8 @@ Most of the time you will be interacting with Arduino with a client library on t * [http://openframeworks.cc/documentation/communication/ofArduino/](http://openframeworks.cc/documentation/communication/ofArduino/) * Rust * [https://github.com/zankich/rust-firmata](https://github.com/zankich/rust-firmata) +* Pure Data + * [https://github.com/NullMember/PDFirmata](https://github.com/NullMember/PDFirmata) Note: The above libraries may support various versions of the Firmata protocol and therefore may not support all features of the latest Firmata spec nor all Arduino and Arduino-compatible boards. Refer to the respective projects for details. From 06ad2338c4154cf83e9d556f52d7e9ade03cecf3 Mon Sep 17 00:00:00 2001 From: Jeff Hoefs Date: Sun, 29 Nov 2020 15:44:48 -0800 Subject: [PATCH 59/81] add nono-33-iot to Boards.h --- Boards.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Boards.h b/Boards.h index 34610be8..b2d149bd 100644 --- a/Boards.h +++ b/Boards.h @@ -261,6 +261,23 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_SERVO(p) ((p) - 2) +// Arduino Nano 33 IoT +#elif defined(ARDUINO_SAMD_NANO_33_IOT) +#define TOTAL_ANALOG_PINS 8 +#define TOTAL_PINS 22 // 14 Digital + 8 Analog +#define IS_PIN_DIGITAL(p) ((p) < TOTAL_PINS) +#define IS_PIN_ANALOG(p) ((p) > 13 && (p) < 14 + TOTAL_ANALOG_PINS) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4 +#define IS_PIN_I2C(p) ((p) == PIN_WIRE_SDA || (p) == PIN_WIRE_SCL) +#define IS_PIN_SPI(p) ((p) == PIN_SPI_SS || (p) == PIN_SPI_MOSI || (p) == PIN_SPI_MISO || (p) == PIN_SPI_SCK) +#define IS_PIN_SERIAL(p) ((p) == PIN_SERIAL1_RX || (p) == PIN_SERIAL1_TX) //defined in variant.h RX = 0 TX = 1 +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) ((p) - 14) +#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) +#define PIN_TO_SERVO(p) (p) // deprecated since v2.4 + + // Arduino/Genuino MKR1000 or MKR1010 #elif defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRWIFI1010) #define TOTAL_ANALOG_PINS 7 From ff8bc9336e0b70a3821a86b7dca0bdd1f45b1b3d Mon Sep 17 00:00:00 2001 From: Jeff Karney Date: Sun, 28 Mar 2021 15:16:02 -0500 Subject: [PATCH 60/81] Add missing link for PHP Client "carica" The link to https://github.com/ThomasWeinert/carica-firmata was empty so it linked nowhere. Updated to actually link to the URL. --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 80a00b83..f79e8821 100644 --- a/readme.md +++ b/readme.md @@ -63,7 +63,7 @@ Most of the time you will be interacting with Arduino with a client library on t * Pharo * [https://github.com/pharo-iot/Firmata](https://github.com/pharo-iot/Firmata) * PHP - * [https://github.com/ThomasWeinert/carica-firmata]() + * [https://github.com/ThomasWeinert/carica-firmata](https://github.com/ThomasWeinert/carica-firmata) * [https://github.com/oasynnoum/phpmake_firmata](https://github.com/oasynnoum/phpmake_firmata) * Haskell * [http://hackage.haskell.org/package/hArduino](http://hackage.haskell.org/package/hArduino) From 1a30384e9e420949df2e40e1c2759c5fa7c5b343 Mon Sep 17 00:00:00 2001 From: Christopher Stawarz Date: Mon, 12 Apr 2021 15:13:27 -0400 Subject: [PATCH 61/81] Added Arduino Nano 33 BLE to Boards.h --- Boards.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Boards.h b/Boards.h index b2d149bd..fa8a3466 100644 --- a/Boards.h +++ b/Boards.h @@ -278,6 +278,23 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_SERVO(p) (p) // deprecated since v2.4 +// Arduino Nano 33 BLE +#elif defined(ARDUINO_ARDUINO_NANO33BLE) +#define TOTAL_ANALOG_PINS 8 +#define TOTAL_PINS 22 // 14 Digital + 8 Analog +#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) +#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4 +#define IS_PIN_I2C(p) ((p) == PIN_WIRE_SDA || (p) == PIN_WIRE_SCL) // SDA = 18, SCL = 19 +#define IS_PIN_SPI(p) ((p) == PIN_SPI_SS || (p) == PIN_SPI_MOSI || (p) == PIN_SPI_MISO || (p) == PIN_SPI_SCK) +#define IS_PIN_SERIAL(p) ((p) == PIN_SERIAL_RX || (p) == PIN_SERIAL_TX) //defined in pins_arduino.h RX = 1 TX = 0 +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) ((p) - 14) +#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) +#define PIN_TO_SERVO(p) (p) // deprecated since v2.4 + + // Arduino/Genuino MKR1000 or MKR1010 #elif defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRWIFI1010) #define TOTAL_ANALOG_PINS 7 From dd69de8684d131ca47dcc48da011eca799b290da Mon Sep 17 00:00:00 2001 From: Christopher Stawarz Date: Fri, 7 May 2021 09:29:49 -0400 Subject: [PATCH 62/81] Add support for ArduinoBLE devices to StandardFirmataBLE --- examples/StandardFirmataBLE/bleConfig.h | 39 +++- utility/ArduinoBLE_UART_Stream.cpp | 3 + utility/ArduinoBLE_UART_Stream.h | 256 ++++++++++++++++++++++++ 3 files changed, 291 insertions(+), 7 deletions(-) create mode 100644 utility/ArduinoBLE_UART_Stream.cpp create mode 100644 utility/ArduinoBLE_UART_Stream.h diff --git a/examples/StandardFirmataBLE/bleConfig.h b/examples/StandardFirmataBLE/bleConfig.h index a783ce9b..def71f17 100644 --- a/examples/StandardFirmataBLE/bleConfig.h +++ b/examples/StandardFirmataBLE/bleConfig.h @@ -1,15 +1,15 @@ /*================================================================================================== * BLE CONFIGURATION * - * If you are using an Arduino 101, you do not need to make any changes to this file (unless you - * need a unique ble local name (see below). If you are using another supported BLE board or shield, - * follow the instructions for the specific board or shield below. - * - * Make sure you have the Intel Curie Boards package v2.0.2 or higher installed via the Arduino - * Boards Manager. + * If you are using a device supported by the ArduinoBLE library or an Arduino 101, you do not need + * to make any changes to this file (unless you need a unique ble local name (see below)). If you + * are using another supported BLE board or shield, follow the instructions for the specific board + * or shield below. * * Supported boards and shields: - * - Arduino 101 (recommended) + * - Devices supported by the ArduinoBLE library, including the Arduino MKR WiFi 1010, + * Arduino UNO WiFi Rev.2, Arduino Nano 33 IoT, and Arduino Nano 33 BLE + * - Arduino 101 * - RedBearLab BLE Shield (v2) ** to be verified ** * - RedBearLab BLE Nano ** works with modifications ** * - Adafruit Feather M0 Bluefruit LE @@ -20,6 +20,25 @@ // within the same physical space #define FIRMATA_BLE_LOCAL_NAME "FIRMATA" +/* + * ArduinoBLE devices + * + * Be sure to install the ArduinoBLE library via the Arduino Library Manager. + * + */ +#if defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_AVR_UNO_WIFI_REV2) || defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_ARDUINO_NANO33BLE) +#define ARDUINO_BLE + +// Value is specified in units of 0.625 ms +#define FIRMATA_BLE_ADVERTISING_INTERVAL 32 // 20ms (20 / 0.625) + +// These values are specified in units of 1.25 ms and must be between +// 0x0006 (7.5ms) and 0x0c80 (4s). +#define FIRMATA_BLE_MIN_INTERVAL 0x000c // 15ms (15 / 1.25) +#define FIRMATA_BLE_MAX_INTERVAL 0x0018 // 30ms (30 / 1.25) +#endif + + /* * Arduino 101 * @@ -107,6 +126,12 @@ * END BLE CONFIGURATION - you should not need to change anything below this line *================================================================================================*/ +#ifdef ARDUINO_BLE +#include "utility/ArduinoBLE_UART_Stream.h" +ArduinoBLE_UART_Stream stream; +#endif + + #ifdef _VARIANT_ARDUINO_101_X_ #include "utility/BLEStream.h" BLEStream stream; diff --git a/utility/ArduinoBLE_UART_Stream.cpp b/utility/ArduinoBLE_UART_Stream.cpp new file mode 100644 index 00000000..3fffed30 --- /dev/null +++ b/utility/ArduinoBLE_UART_Stream.cpp @@ -0,0 +1,3 @@ +/* + * Implementation is in ArduinoBLE_UART_Stream.h to avoid linker issues. + */ diff --git a/utility/ArduinoBLE_UART_Stream.h b/utility/ArduinoBLE_UART_Stream.h new file mode 100644 index 00000000..e87c4669 --- /dev/null +++ b/utility/ArduinoBLE_UART_Stream.h @@ -0,0 +1,256 @@ +/* + ArduinoBLE_UART_Stream.h + + Based on BLEStream.h and the HardwareBLESerial library: + https://github.com/Uberi/Arduino-HardwareBLESerial + */ + +#ifndef _ARDUINO_BLE_UART_STREAM_H_ +#define _ARDUINO_BLE_UART_STREAM_H_ + +#include + +#define BLE_ATTRIBUTE_MAX_VALUE_LENGTH 20 + + +class ArduinoBLE_UART_Stream : public Stream +{ + public: + ArduinoBLE_UART_Stream(); + + void setLocalName(const char *localName); + void setAdvertisingInterval(unsigned short advertisingInterval); + void setConnectionInterval(unsigned short minConnInterval, unsigned short maxConnInterval); + void setFlushInterval(int flushInterval); + + void begin(); + bool poll(); + void end(); + + // Print overrides + size_t write(uint8_t byte); + using Print::write; // Expose other write variants + + // Stream overrides + int available(); + int read(); + int peek(); + void flush(); + + private: + void dataReceived(const unsigned char *data, size_t size); + + static void connectedHandler(BLEDevice central); + static void disconnectedHandler(BLEDevice central); + + static void rxWrittenHandler(BLEDevice central, BLECharacteristic characteristic); + + static void txSubscribedHandler(BLEDevice central, BLECharacteristic characteristic); + static void txUnsubscribedHandler(BLEDevice central, BLECharacteristic characteristic); + + BLEService uartService; + BLECharacteristic rxCharacteristic; + BLECharacteristic txCharacteristic; + + String localName; + unsigned short advertisingInterval; + unsigned short minConnInterval; + unsigned short maxConnInterval; + int flushInterval; + + bool connected; + + unsigned char rxBuffer[256]; + size_t rxHead; + size_t rxTail; + + bool txSubscribed; + unsigned char txBuffer[BLE_ATTRIBUTE_MAX_VALUE_LENGTH]; + size_t txCount; + unsigned long lastFlushTime; + + static ArduinoBLE_UART_Stream *instance; +}; + + +ArduinoBLE_UART_Stream::ArduinoBLE_UART_Stream() : + uartService("6E400001-B5A3-F393-E0A9-E50E24DCCA9E"), + rxCharacteristic("6E400002-B5A3-F393-E0A9-E50E24DCCA9E", BLEWriteWithoutResponse | BLEWrite, BLE_ATTRIBUTE_MAX_VALUE_LENGTH), + txCharacteristic("6E400003-B5A3-F393-E0A9-E50E24DCCA9E", BLENotify, BLE_ATTRIBUTE_MAX_VALUE_LENGTH), + advertisingInterval(0), + minConnInterval(0), + maxConnInterval(0), + flushInterval(100), // Default flush interval is 100ms + connected(false), + rxHead(0), + rxTail(0), + txSubscribed(false), + txCount(0), + lastFlushTime(0) +{ + instance = this; +} + +void ArduinoBLE_UART_Stream::setLocalName(const char *localName) +{ + this->localName = localName; +} + +void ArduinoBLE_UART_Stream::setAdvertisingInterval(unsigned short advertisingInterval) +{ + this->advertisingInterval = advertisingInterval; +} + +void ArduinoBLE_UART_Stream::setConnectionInterval(unsigned short minConnInterval, unsigned short maxConnInterval) +{ + this->minConnInterval = minConnInterval; + this->maxConnInterval = maxConnInterval; +} + +void ArduinoBLE_UART_Stream::setFlushInterval(int flushInterval) +{ + // The minimum allowed connection interval is 7.5ms, so don't try to flush + // more frequently than that + this->flushInterval = max(flushInterval, 8); +} + +void ArduinoBLE_UART_Stream::begin() +{ + BLE.begin(); + + if (localName.length() > 0) { + BLE.setLocalName(localName.c_str()); + } + if (advertisingInterval > 0) { + BLE.setAdvertisingInterval(advertisingInterval); + } + if (minConnInterval > 0 && maxConnInterval > 0) { + BLE.setConnectionInterval(minConnInterval, maxConnInterval); + } + + BLE.setEventHandler(BLEConnected, connectedHandler); + BLE.setEventHandler(BLEDisconnected, disconnectedHandler); + + rxCharacteristic.setEventHandler(BLEWritten, rxWrittenHandler); + uartService.addCharacteristic(rxCharacteristic); + + txCharacteristic.setEventHandler(BLESubscribed, txSubscribedHandler); + txCharacteristic.setEventHandler(BLEUnsubscribed, txUnsubscribedHandler); + uartService.addCharacteristic(txCharacteristic); + + BLE.addService(uartService); + BLE.setAdvertisedService(uartService); + BLE.advertise(); +} + +bool ArduinoBLE_UART_Stream::poll() +{ + if (millis() - lastFlushTime > flushInterval) { + flush(); // Always calls BLE.poll() + } else { + BLE.poll(); + } + return connected; +} + +void ArduinoBLE_UART_Stream::end() +{ + flush(); + txCharacteristic.setEventHandler(BLEUnsubscribed, NULL); + txCharacteristic.setEventHandler(BLESubscribed, NULL); + txSubscribed = false; + + rxCharacteristic.setEventHandler(BLEWritten, NULL); + rxHead = 0; + rxTail = 0; + + BLE.setEventHandler(BLEDisconnected, NULL); + BLE.setEventHandler(BLEConnected, NULL); + connected = false; + + BLE.end(); +} + +size_t ArduinoBLE_UART_Stream::write(uint8_t byte) +{ + if (!txSubscribed) { + return 0; + } + txBuffer[txCount] = byte; + txCount++; + if (txCount == sizeof(txBuffer)) { + flush(); + } + return 1; +} + +int ArduinoBLE_UART_Stream::available() +{ + return (rxHead - rxTail + sizeof(rxBuffer)) % sizeof(rxBuffer); +} + +int ArduinoBLE_UART_Stream::read() +{ + if (rxTail == rxHead) { + return -1; + } + uint8_t byte = rxBuffer[rxTail]; + rxTail = (rxTail + 1) % sizeof(rxBuffer); + return byte; +} + +int ArduinoBLE_UART_Stream::peek() +{ + if (rxTail == rxHead) { + return -1; + } + return rxBuffer[rxTail]; +} + +void ArduinoBLE_UART_Stream::flush() +{ + if (txCount > 0) { + txCharacteristic.setValue(txBuffer, txCount); + txCount = 0; + } + lastFlushTime = millis(); + BLE.poll(); +} + +void ArduinoBLE_UART_Stream::dataReceived(const unsigned char *data, size_t size) +{ + for (size_t i = 0; i < size; i++) { + rxBuffer[rxHead] = data[i]; + rxHead = (rxHead + 1) % sizeof(rxBuffer); + } +} + +void ArduinoBLE_UART_Stream::connectedHandler(BLEDevice central) +{ + instance->connected = true; +} + +void ArduinoBLE_UART_Stream::disconnectedHandler(BLEDevice central) +{ + instance->connected = false; +} + +void ArduinoBLE_UART_Stream::rxWrittenHandler(BLEDevice central, BLECharacteristic characteristic) +{ + instance->dataReceived(characteristic.value(), characteristic.valueLength()); +} + +void ArduinoBLE_UART_Stream::txSubscribedHandler(BLEDevice central, BLECharacteristic characteristic) +{ + instance->txSubscribed = true; +} + +void ArduinoBLE_UART_Stream::txUnsubscribedHandler(BLEDevice central, BLECharacteristic characteristic) +{ + instance->txSubscribed = false; +} + +ArduinoBLE_UART_Stream * ArduinoBLE_UART_Stream::instance = NULL; + + +#endif // _ARDUINO_BLE_UART_STREAM_H_ From 74b036386f0969529732b82c3b3bcf2545a816ba Mon Sep 17 00:00:00 2001 From: Christopher Stawarz Date: Mon, 1 Nov 2021 09:43:44 -0400 Subject: [PATCH 63/81] Clarify why the implementations of ArduinoBLE_UART_Stream and BluefruitLE_SPI_Stream are in their respective header files --- utility/ArduinoBLE_UART_Stream.cpp | 3 ++- utility/BluefruitLE_SPI_Stream.cpp | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/utility/ArduinoBLE_UART_Stream.cpp b/utility/ArduinoBLE_UART_Stream.cpp index 3fffed30..747fa84e 100644 --- a/utility/ArduinoBLE_UART_Stream.cpp +++ b/utility/ArduinoBLE_UART_Stream.cpp @@ -1,3 +1,4 @@ /* - * Implementation is in ArduinoBLE_UART_Stream.h to avoid linker issues. + * Implementation is in ArduinoBLE_UART_Stream.h to avoid making ArduinoBLE a + * build-time dependency for all projects that use the Firmata library. */ diff --git a/utility/BluefruitLE_SPI_Stream.cpp b/utility/BluefruitLE_SPI_Stream.cpp index 93953e96..86d2788c 100644 --- a/utility/BluefruitLE_SPI_Stream.cpp +++ b/utility/BluefruitLE_SPI_Stream.cpp @@ -1,3 +1,5 @@ /* - * Implementation is in BluefruitLE_SPI_Stream.h to avoid linker issues. + * Implementation is in BluefruitLE_SPI_Stream.h to avoid making + * Adafruit_BluefruitLE_nRF51 a build-time dependency for all projects that use + * the Firmata library. */ From d337c155c960c9ffcf2baf4d2c2f475e1342dacf Mon Sep 17 00:00:00 2001 From: Space Date: Sat, 15 Jan 2022 19:03:30 +0200 Subject: [PATCH 64/81] Arduino Uno Wifi Rev 2 Configured For Pyfirmata Major Changes: Added Arduino Uno Wifi Rev 2's pinouts to boards.h Added HWSerial port ID to utility/SerialFirmata.h --- Boards.h | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/Boards.h b/Boards.h index fa8a3466..bcd4405c 100644 --- a/Boards.h +++ b/Boards.h @@ -675,7 +675,7 @@ writePort(port, value, bitmask): Write an 8 bit port. // Sanguino/Melzi, e.g. Creality Ender-3 #elif defined(__AVR_ATmega1284P__) #define TOTAL_ANALOG_PINS 8 -#define TOTAL_PINS 32 +#define TOTAL_PINS 32 #define VERSION_BLINK_PIN 13 #define PIN_SERIAL1_RX 8 //PD0 #define PIN_SERIAL1_TX 9 //PD1 @@ -999,6 +999,31 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) #define PIN_TO_SERVO(p) (p) // deprecated since v2.4 +//Arduino Uno Wifi Rev2 +#elif defined(__AVR_ATmega4809__) +#define TOTAL_ANALOG_PINS NUM_ANALOG_INPUTS //6 +#define TOTAL_PINS 41 // 14 digital + 6 analog + 6 reserved + 10 internal used + 2 I2C + 3 SPI +#define TOTAL_PORTS 3 +#define VERSION_BLINK_PIN LED_BUILTIN //25 +#define PIN_SERIAL1_RX 0 +#define PIN_SERIAL1_TX 1 +#define PIN_SERIAL2_RX 23 +#define PIN_SERIAL2_TX 24 +#define PIN_SERIAL0_RX 26 +#define PIN_SERIAL0_TX 27 +#define IS_PIN_DIGITAL(p) (((p) >= 0 && (p) < 20) || (p) == 25) +#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 19) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) +#define IS_PIN_I2C(p) ((p) == 20 || (p) == 21) +#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) +#define IS_PIN_SERIAL(p) ((p) == 23 || (p) == 24 || (p) == 26 || (p) == 27) +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) ((p) - 14) +#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) +#define PIN_TO_SERVO(p) (p) + + // anything else #else #error "Please edit Boards.h with a hardware abstraction for this board" From 0595a293bd5081f83d03271e69123fea13675da2 Mon Sep 17 00:00:00 2001 From: Space Date: Sat, 15 Jan 2022 19:04:51 +0200 Subject: [PATCH 65/81] Arduino Uno Wifi Rev 2 Configured For Pyfirmata Major Changes: Added Arduino Uno Wifi Rev 2's pinouts to boards.h Added HWSerial port ID to utility/SerialFirmata.h --- utility/SerialFirmata.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/utility/SerialFirmata.h b/utility/SerialFirmata.h index 3ce33299..eb969da1 100644 --- a/utility/SerialFirmata.h +++ b/utility/SerialFirmata.h @@ -48,9 +48,9 @@ // a) continuous streaming at higher baud rates: enable but set to 0 (receive buffer store & forward) // b) messages: set to a value below min. inter message delay (message store & forward) // c) continuous streaming at lower baud rates or random characters: undefine or set to -1 (disable) -// 3) Smaller delays may not have the desired effect, especially with less powerful CPUs, +// 3) Smaller delays may not have the desired effect, especially with less powerful CPUs, // if set to a value near or below the average Firmata main loop duration. -// 4) The Firmata stream write buffer size must be equal or greater than the max. +// 4) The Firmata stream write buffer size must be equal or greater than the max. // serial buffer/message size and the Firmata frame size (4 bytes) to prevent fragmentation // on the transport layer. //#define FIRMATA_SERIAL_RX_DELAY 50 // [ms] @@ -78,6 +78,8 @@ #define SERIAL_READ_ARR_LEN 12 // map configuration query response resolution value to serial pin type +#define RES_RX0 0x00 +#define RES_TX0 0x01 #define RES_RX1 0x02 #define RES_TX1 0x03 #define RES_RX2 0x04 @@ -121,6 +123,10 @@ namespace { #if defined(PIN_SERIAL_RX) // TODO when use of HW_SERIAL0 is enabled #endif + #if defined(PIN_SERIAL0_RX) + if (pin == PIN_SERIAL0_RX) return RES_RX0; + if (pin == PIN_SERIAL0_TX) return RES_TX0; + #endif #if defined(PIN_SERIAL1_RX) if (pin == PIN_SERIAL1_RX) return RES_RX1; if (pin == PIN_SERIAL1_TX) return RES_TX1; @@ -163,6 +169,12 @@ namespace { // // TODO when use of HW_SERIAL0 is enabled // break; #endif + #if defined(PIN_SERIAL0_RX) + case HW_SERIAL0: + pins.rx = PIN_SERIAL0_RX; + pins.tx = PIN_SERIAL0_TX; + break; + #endif #if defined(PIN_SERIAL1_RX) case HW_SERIAL1: pins.rx = PIN_SERIAL1_RX; From 8ae1ad602e0cb3918748b428778d8daa3f1bbdee Mon Sep 17 00:00:00 2001 From: bovid-19 <103042464+bovid-19@users.noreply.github.com> Date: Tue, 19 Apr 2022 12:14:04 +0200 Subject: [PATCH 66/81] cl-firmata (Common Lisp) added to readme/libraries --- readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/readme.md b/readme.md index f79e8821..8777587b 100644 --- a/readme.md +++ b/readme.md @@ -88,6 +88,8 @@ Most of the time you will be interacting with Arduino with a client library on t * [https://github.com/zankich/rust-firmata](https://github.com/zankich/rust-firmata) * Pure Data * [https://github.com/NullMember/PDFirmata](https://github.com/NullMember/PDFirmata) +* Common Lisp + * [https://github.com/cjfuller/cl-firmata](https://github.com/cjfuller/cl-firmata) Note: The above libraries may support various versions of the Firmata protocol and therefore may not support all features of the latest Firmata spec nor all Arduino and Arduino-compatible boards. Refer to the respective projects for details. From 2a9dbcefc2cc96968e07ac5d5c24ba11a67a5bb8 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Sun, 15 May 2022 17:23:27 +0200 Subject: [PATCH 67/81] Support for Arduino Nano Every --- Boards.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Boards.h b/Boards.h index fa8a3466..52286fac 100644 --- a/Boards.h +++ b/Boards.h @@ -238,6 +238,20 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) #define PIN_TO_SERVO(p) (p) +#elif defined(AVR_NANO_EVERY) || defined(ARDUINO_NANO_EVERY) || defined(ARDUINO_AVR_NANO_EVERY) +#define TOTAL_ANALOG_PINS 8 +#define TOTAL_PINS 24 // 14 digital + 8 analog + 2 i2c +#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 21) // TBD if pins 0 and 1 are usable +#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4 +#define IS_PIN_I2C(p) ((p) == PIN_WIRE_SDA || (p) == PIN_WIRE_SCL) // SDA = 22, SCL = 23 +#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) ((p) - 14) +#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) +#define PIN_TO_SERVO(p) (p) // deprecated since v2.4 + // Arduino DUE #elif defined(__SAM3X8E__) #define TOTAL_ANALOG_PINS 12 From d006ab48f29878422c5a6ef2655d7a6f6d2f8a23 Mon Sep 17 00:00:00 2001 From: Kevin Gilliam Date: Thu, 15 Sep 2022 16:23:45 -0700 Subject: [PATCH 68/81] Added Teensy 4.1 pins to Boards.h --- Boards.h | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 70 insertions(+), 7 deletions(-) diff --git a/Boards.h b/Boards.h index 355af4eb..211404cb 100644 --- a/Boards.h +++ b/Boards.h @@ -584,10 +584,23 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) #define PIN_TO_SERVO(p) (p) -// Teensy 4.0 +// Teensy 4.0 and Teensy 4.1 #elif defined(__IMXRT1062__) -#define TOTAL_ANALOG_PINS 14 -#define TOTAL_PINS 40 +#if !defined(TEENSY40) && !defined(TEENSY41) + #warning Assuming TEENSY40. Please #define TEENSY40 or TEENSY41. + #define TEENSY40 +#endif +#if defined(TEENSY40) + #define TOTAL_PINS 40 + #define TOTAL_ANALOG_PINS 14 + #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 27) + #define PIN_TO_ANALOG(p) ((p) - 14) +#elif defined(TEENSY41) + #define TOTAL_PINS 55 + #define TOTAL_ANALOG_PINS 18 + #define IS_PIN_ANALOG(p) (((p) >= 14 && (p) <= 27) || ((p) >= 38 && (p) <= 41)) + #define PIN_TO_ANALOG(p) (((p) <= 27) ? ((p) - 14 ) : ((p) - 24)) +#endif #define VERSION_BLINK_PIN 13 #define PIN_SERIAL1_RX 0 #define PIN_SERIAL1_TX 1 @@ -603,14 +616,64 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_SERIAL6_TX 24 #define PIN_SERIAL7_RX 28 #define PIN_SERIAL7_TX 29 +#if defined(TEENSY40) + #define IS_PIN_SERIAL(p) (((p) == PIN_SERIAL1_RX) || \ + ((p) == PIN_SERIAL1_TX) || \ + ((p) == PIN_SERIAL2_RX) || \ + ((p) == PIN_SERIAL2_TX) || \ + ((p) == PIN_SERIAL3_RX) || \ + ((p) == PIN_SERIAL3_TX) || \ + ((p) == PIN_SERIAL4_RX) || \ + ((p) == PIN_SERIAL4_TX) || \ + ((p) == PIN_SERIAL5_RX) || \ + ((p) == PIN_SERIAL5_TX) || \ + ((p) == PIN_SERIAL6_RX) || \ + ((p) == PIN_SERIAL6_TX) || \ + ((p) == PIN_SERIAL7_RX) || \ + ((p) == PIN_SERIAL7_TX)) + #define IS_PIN_PWM(p) (((p) >= 0 && (p) <= 16) || \ + ((p) == 18) || \ + ((p) == 19) || \ + ((p) >= 22 && (p) <= 25) || \ + ((p) == 28) || \ + ((p) == 29) || \ + ((p) >= 33 && (p) <= 39)) +#elif defined(TEENSY41) + #define PIN_SERIAL8_RX 34 + #define PIN_SERIAL8_TX 35 + #define IS_PIN_SERIAL(p) (((p) == PIN_SERIAL1_RX) || \ + ((p) == PIN_SERIAL1_TX) || \ + ((p) == PIN_SERIAL2_RX) || \ + ((p) == PIN_SERIAL2_TX) || \ + ((p) == PIN_SERIAL3_RX) || \ + ((p) == PIN_SERIAL3_TX) || \ + ((p) == PIN_SERIAL4_RX) || \ + ((p) == PIN_SERIAL4_TX) || \ + ((p) == PIN_SERIAL5_RX) || \ + ((p) == PIN_SERIAL5_TX) || \ + ((p) == PIN_SERIAL6_RX) || \ + ((p) == PIN_SERIAL6_TX) || \ + ((p) == PIN_SERIAL7_RX) || \ + ((p) == PIN_SERIAL7_TX) ||\ + ((p) == PIN_SERIAL8_RX) || \ + ((p) == PIN_SERIAL8_TX)) + #define IS_PIN_PWM(p) (((p) >= 0 && (p) <= 15) || \ + ((p) == 18) || \ + ((p) == 19) || \ + ((p) >= 22 && (p) <= 25) || \ + ((p) == 28) || \ + ((p) == 29) || \ + ((p) == 33) || \ + ((p) == 36) || \ + ((p) == 37) || \ + ((p) >= 42 && (p) <= 47) || \ + ((p) == 51) || \ + ((p) == 54)) +#endif #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) -#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 27) -#define IS_PIN_PWM(p) (((p) >= 0 && (p) <= 16) || ((p) >= 18 && (p) <= 19) || ((p) >= 22 && (p) <= 25) || ((p) >= 28 && (p) <= 29)|| ((p) >= 33 && (p) <= 39)) #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19) -#define IS_PIN_SERIAL(p) (((p) >= 0 && (p) <= 1) || ((p) >= 7 && (p) <= 8) || ((p) >= 14 && (p) <= 17) || ((p) >= 20 && (p) <= 21) || ((p) >= 24 && (p) <= 25) || ((p) >= 28 && (p) <= 29)) #define PIN_TO_DIGITAL(p) (p) -#define PIN_TO_ANALOG(p) ((p) - 14) #define PIN_TO_PWM(p) (p) #define PIN_TO_SERVO(p) (p) From e8781a40e8d94597d7783b59f368fb5ce85f67a4 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Tue, 13 Dec 2022 20:13:35 +0100 Subject: [PATCH 69/81] Remove broken link Fixes #496 --- readme.md | 1 - 1 file changed, 1 deletion(-) diff --git a/readme.md b/readme.md index 8777587b..66ef8e3a 100644 --- a/readme.md +++ b/readme.md @@ -28,7 +28,6 @@ Most of the time you will be interacting with Arduino with a client library on t * processing * [https://github.com/firmata/processing](https://github.com/firmata/processing) - * [http://funnel.cc](http://funnel.cc) * python * [https://github.com/MrYsLab/pymata4](https://github.com/MrYsLab/pymata4) * [https://github.com/MrYsLab/pymata-express](https://github.com/MrYsLab/pymata-express) From b2d893edb666cff98402b9dc945f3261f906bf44 Mon Sep 17 00:00:00 2001 From: Jeff Hoefs Date: Tue, 13 Dec 2022 16:28:19 -0800 Subject: [PATCH 70/81] Update bugfix version --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 0dc9a348..04e0ff47 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Firmata -version=2.5.8 +version=2.5.9 author=Firmata Developers maintainer=https://github.com/firmata/arduino sentence=Enables the communication with computer apps using a standard serial protocol. For all Arduino/Genuino boards. From 376428187efcf004c26022edd151dbd2233aafbb Mon Sep 17 00:00:00 2001 From: Jeff Hoefs Date: Tue, 13 Dec 2022 16:31:00 -0800 Subject: [PATCH 71/81] Add note about .sh file --- release.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/release.sh b/release.sh index 0c47db8d..089f34e3 100644 --- a/release.sh +++ b/release.sh @@ -1,6 +1,6 @@ #!/bin/sh -# use this script to package Firmata for distribution +# [Optional] use this script to package Firmata for distribution # package for Arduino 1.0.x mkdir -p temp/Firmata @@ -15,7 +15,7 @@ cd temp find . -name "*.DS_Store" -type f -delete zip -r Firmata.zip ./Firmata/ cd .. -mv ./temp/Firmata.zip Arduino-1.0.x-Firmata-2.5.8.zip +mv ./temp/Firmata.zip Arduino-1.0.x-Firmata-2.5.9.zip #package for Arduino 1.6.x and 1.8.x cp library.properties temp/Firmata @@ -29,5 +29,5 @@ cd .. find . -name "*.DS_Store" -type f -delete zip -r Firmata.zip ./Firmata/ cd .. -mv ./temp/Firmata.zip Firmata-2.5.8.zip +mv ./temp/Firmata.zip Firmata-2.5.9.zip rm -r ./temp From 28ac1e062b4700d6ab84c4125fbaa7e7c603dfa7 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Wed, 28 Dec 2022 08:51:08 +0100 Subject: [PATCH 72/81] Remove test sketch Fails linter check, and tests are done from the PC now --- test/firmata_test/firmata_test.ino | 172 ----------------------------- test/readme.md | 13 --- 2 files changed, 185 deletions(-) delete mode 100644 test/firmata_test/firmata_test.ino delete mode 100644 test/readme.md diff --git a/test/firmata_test/firmata_test.ino b/test/firmata_test/firmata_test.ino deleted file mode 100644 index db058535..00000000 --- a/test/firmata_test/firmata_test.ino +++ /dev/null @@ -1,172 +0,0 @@ -/* - * To run this test suite, you must first install the ArduinoUnit library - * to your Arduino/libraries/ directory. - * You can get ArduinoUnit here: https://github.com/mmurdoch/arduinounit - * Download version 2.0 or greater or install it via the Arduino library manager. - */ - -#include -#include - -void setup() -{ - Serial.begin(9600); -} - -void loop() -{ - Test::run(); -} - -test(beginPrintsVersion) -{ - FakeStream stream; - - Firmata.begin(stream); - - char expected[] = { - REPORT_VERSION, - FIRMATA_PROTOCOL_MAJOR_VERSION, - FIRMATA_PROTOCOL_MINOR_VERSION, - 0 - }; - assertEqual(expected, stream.bytesWritten()); -} - -void processMessage(const byte *message, size_t length) -{ - FakeStream stream; - Firmata.begin(stream); - - for (size_t i = 0; i < length; i++) { - stream.nextByte(message[i]); - Firmata.processInput(); - } -} - -byte _digitalPort; -int _digitalPortValue; -void writeToDigitalPort(byte port, int value) -{ - _digitalPort = port; - _digitalPortValue = value; -} - -void setupDigitalPort() -{ - _digitalPort = 0; - _digitalPortValue = 0; -} - -char * _receivedString; -void handleStringCallback(char *str) -{ - _receivedString = str; -} - -test(processWriteDigital_0) -{ - setupDigitalPort(); - Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort); - - byte message[] = { DIGITAL_MESSAGE, 0, 0 }; - processMessage(message, 3); - - assertEqual(0, _digitalPortValue); -} - -test(processWriteDigital_127) -{ - setupDigitalPort(); - Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort); - - byte message[] = { DIGITAL_MESSAGE, 127, 0 }; - processMessage(message, 3); - - assertEqual(127, _digitalPortValue); -} - -test(processWriteDigital_128) -{ - setupDigitalPort(); - Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort); - - byte message[] = { DIGITAL_MESSAGE, 0, 1 }; - processMessage(message, 3); - - assertEqual(128, _digitalPortValue); -} - -test(processWriteLargestDigitalValue) -{ - setupDigitalPort(); - Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort); - - byte message[] = { DIGITAL_MESSAGE, 0x7F, 0x7F }; - processMessage(message, 3); - - // Maximum of 14 bits can be set (B0011111111111111) - assertEqual(0x3FFF, _digitalPortValue); -} - -test(defaultDigitalWritePortIsZero) -{ - setupDigitalPort(); - Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort); - - byte message[] = { DIGITAL_MESSAGE, 0, 0 }; - processMessage(message, 3); - - assertEqual(0, _digitalPort); -} - -test(specifiedDigitalWritePort) -{ - setupDigitalPort(); - Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort); - - byte message[] = { DIGITAL_MESSAGE + 1, 0, 0 }; - processMessage(message, 3); - - assertEqual(1, _digitalPort); -} - -test(setFirmwareVersionDoesNotLeakMemory) -{ - Firmata.setFirmwareVersion(1, 0); - int initialMemory = freeMemory(); - - Firmata.setFirmwareVersion(1, 0); - - assertEqual(0, initialMemory - freeMemory()); -} - -test(sendStringShouldEncode2BytesPerChar) -{ - FakeStream stream; - Firmata.begin(stream); - // reset the buffer because the firmware name string will be sent on Firmata.begin - stream.reset(); - - char testString[] = "hi!"; - Firmata.sendString(testString); - - byte expected[] = { START_SYSEX, STRING_DATA, 'h', 0, 'i', 0, '!', 0, END_SYSEX }; - - int len = stream.bytesWritten().length(); - assertEqual(sizeof(expected), len); - for (byte i = 0; i < len; i++) { - assertEqual(expected[i], (byte)stream.bytesWritten().charAt(i)); - } -} - -test(receivedStringShouldDecodeFrom2BytesPerChar) -{ - Firmata.attach(STRING_DATA, handleStringCallback); - - byte message[] = { START_SYSEX, STRING_DATA, 'b', 0, 'y', 0, 'e', 0, '!', 0, END_SYSEX }; - processMessage(message, 11); - - assertEqual("bye!", _receivedString); -} - diff --git a/test/readme.md b/test/readme.md deleted file mode 100644 index ab8f8c3d..00000000 --- a/test/readme.md +++ /dev/null @@ -1,13 +0,0 @@ -# Testing Firmata - -Tests tests are written using the [ArduinoUnit](https://github.com/mmurdoch/arduinounit) library (version 2.0). - -Follow the instructions in the [ArduinoUnit readme](https://github.com/mmurdoch/arduinounit/blob/master/readme.md) to install the library. - -Compile and upload the test sketch as you would any other sketch. Then open the -Serial Monitor to view the test results. - -If you make changes to Firmata.cpp, run the tests in /test/ to ensure -that your changes have not produced any unexpected errors. - -You should also perform manual tests against actual hardware. From c285135275c4dd4f0d0bbf82da3c5844a29eaf07 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Wed, 28 Dec 2022 08:52:44 +0100 Subject: [PATCH 73/81] Fix linter warning --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 04e0ff47..6e27f0b8 100644 --- a/library.properties +++ b/library.properties @@ -1,7 +1,7 @@ name=Firmata version=2.5.9 author=Firmata Developers -maintainer=https://github.com/firmata/arduino +maintainer=Firmata team sentence=Enables the communication with computer apps using a standard serial protocol. For all Arduino/Genuino boards. paragraph=The Firmata library implements the Firmata protocol for communicating with software on the host computer. This allows you to write custom firmware without having to create your own protocol and objects for the programming environment that you are using. category=Device Control From c243c077e99c6404a32d4397af5b65b945aec99f Mon Sep 17 00:00:00 2001 From: joreg Date: Tue, 25 Apr 2023 22:44:47 +0200 Subject: [PATCH 74/81] added link to vvvv/VL implementation --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 66ef8e3a..9d72f2e6 100644 --- a/readme.md +++ b/readme.md @@ -79,8 +79,8 @@ Most of the time you will be interacting with Arduino with a client library on t * [https://www.wolfram.com/system-modeler/libraries/model-plug/](https://www.wolfram.com/system-modeler/libraries/model-plug/) * Go * [https://github.com/kraman/go-firmata](https://github.com/kraman/go-firmata) -* vvvv - * [https://vvvv.org/blog/arduino-second-service](https://vvvv.org/blog/arduino-second-service) +* vvvv/VL + * [https://github.com/vvvv/VL.IO.Firmata](https://github.com/vvvv/VL.IO.Firmata) * openFrameworks * [http://openframeworks.cc/documentation/communication/ofArduino/](http://openframeworks.cc/documentation/communication/ofArduino/) * Rust From e276e3446b25d039090219d8f01f0a8ea533ff2a Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Mon, 24 Jul 2023 19:54:25 +0200 Subject: [PATCH 75/81] #505 Arduino Nano Every is a ATMega 4809 Therefore this definition must come after. Basically, no board should directly use the ATMega 4809 bare definitions. --- Boards.h | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Boards.h b/Boards.h index 211404cb..d8bf4dde 100644 --- a/Boards.h +++ b/Boards.h @@ -219,6 +219,20 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) #define PIN_TO_SERVO(p) ((p) - 2) +#elif defined(AVR_NANO_EVERY) || defined(ARDUINO_NANO_EVERY) || defined(ARDUINO_AVR_NANO_EVERY) +#define TOTAL_ANALOG_PINS 8 +#define TOTAL_PINS 24 // 14 digital + 8 analog + 2 i2c +#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 21) // TBD if pins 0 and 1 are usable +#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4 +#define IS_PIN_I2C(p) ((p) == PIN_WIRE_SDA || (p) == PIN_WIRE_SCL) // SDA = 22, SCL = 23 +#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) ((p) - 14) +#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) +#define PIN_TO_SERVO(p) (p) // deprecated since v2.4 + // Arduino UNO WiFi rev2 (ATMega 4809) #elif defined(__AVR_ATmega4809__) #define TOTAL_ANALOG_PINS 6 @@ -238,20 +252,6 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) #define PIN_TO_SERVO(p) (p) -#elif defined(AVR_NANO_EVERY) || defined(ARDUINO_NANO_EVERY) || defined(ARDUINO_AVR_NANO_EVERY) -#define TOTAL_ANALOG_PINS 8 -#define TOTAL_PINS 24 // 14 digital + 8 analog + 2 i2c -#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 21) // TBD if pins 0 and 1 are usable -#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS) -#define IS_PIN_PWM(p) digitalPinHasPWM(p) -#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4 -#define IS_PIN_I2C(p) ((p) == PIN_WIRE_SDA || (p) == PIN_WIRE_SCL) // SDA = 22, SCL = 23 -#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) -#define PIN_TO_DIGITAL(p) (p) -#define PIN_TO_ANALOG(p) ((p) - 14) -#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) -#define PIN_TO_SERVO(p) (p) // deprecated since v2.4 - // Arduino DUE #elif defined(__SAM3X8E__) #define TOTAL_ANALOG_PINS 12 From 931b692b8a075f5a00f79a4c5af85d62ca40e8c5 Mon Sep 17 00:00:00 2001 From: PaulStoffregen Date: Thu, 10 Aug 2023 03:21:19 -0700 Subject: [PATCH 76/81] Improve defines for Teensy 4.0 and Teensy 4.1 --- Boards.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Boards.h b/Boards.h index d8bf4dde..a54f755c 100644 --- a/Boards.h +++ b/Boards.h @@ -586,16 +586,16 @@ writePort(port, value, bitmask): Write an 8 bit port. // Teensy 4.0 and Teensy 4.1 #elif defined(__IMXRT1062__) -#if !defined(TEENSY40) && !defined(TEENSY41) - #warning Assuming TEENSY40. Please #define TEENSY40 or TEENSY41. - #define TEENSY40 +#if !defined(ARDUINO_TEENSY40) && !defined(ARDUINO_TEENSY41) + #warning Assuming ARDUINO_TEENSY40. Please #define ARDUINO_TEENSY40 or ARDUINO_TEENSY41. + #define ARDUINO_TEENSY40 #endif -#if defined(TEENSY40) +#if defined(ARDUINO_TEENSY40) #define TOTAL_PINS 40 #define TOTAL_ANALOG_PINS 14 #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 27) #define PIN_TO_ANALOG(p) ((p) - 14) -#elif defined(TEENSY41) +#elif defined(ARDUINO_TEENSY41) #define TOTAL_PINS 55 #define TOTAL_ANALOG_PINS 18 #define IS_PIN_ANALOG(p) (((p) >= 14 && (p) <= 27) || ((p) >= 38 && (p) <= 41)) @@ -616,7 +616,7 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_SERIAL6_TX 24 #define PIN_SERIAL7_RX 28 #define PIN_SERIAL7_TX 29 -#if defined(TEENSY40) +#if defined(ARDUINO_TEENSY40) #define IS_PIN_SERIAL(p) (((p) == PIN_SERIAL1_RX) || \ ((p) == PIN_SERIAL1_TX) || \ ((p) == PIN_SERIAL2_RX) || \ @@ -638,7 +638,7 @@ writePort(port, value, bitmask): Write an 8 bit port. ((p) == 28) || \ ((p) == 29) || \ ((p) >= 33 && (p) <= 39)) -#elif defined(TEENSY41) +#elif defined(ARDUINO_TEENSY41) #define PIN_SERIAL8_RX 34 #define PIN_SERIAL8_TX 35 #define IS_PIN_SERIAL(p) (((p) == PIN_SERIAL1_RX) || \ From 24308ec7a5969076050b85e5039aaf5c40d970dc Mon Sep 17 00:00:00 2001 From: "Zachary J. Fields" Date: Mon, 28 Aug 2023 08:20:28 -0500 Subject: [PATCH 77/81] feat: Arduino Uno R4 support --- Boards.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/Boards.h b/Boards.h index a54f755c..f6cc0422 100644 --- a/Boards.h +++ b/Boards.h @@ -141,6 +141,13 @@ writePort(port, value, bitmask): Write an 8 bit port. #define digitalPinHasPWM(p) IS_PIN_DIGITAL(p) #endif +#undef IS_PIN_INTERRUPT +#if defined(digitalPinToInterrupt) && defined(NOT_AN_INTERRUPT) +#define IS_PIN_INTERRUPT(p) (digitalPinToInterrupt(p) > NOT_AN_INTERRUPT) +#else +#define IS_PIN_INTERRUPT(p) (0) +#endif + // Arduino Duemilanove, Diecimila, and NG #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__) #if defined(NUM_ANALOG_INPUTS) && NUM_ANALOG_INPUTS == 6 @@ -447,6 +454,30 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) #define PIN_TO_SERVO(p) (p) // deprecated since v2.4 +// Arduino UNO R4 Minima and Wifi +// The pinout is the same as for the classical UNO R3 +#elif defined(ARDUINO_UNOR4_MINIMA) || defined(ARDUINO_UNOR4_WIFI) +#if defined(NUM_ANALOG_INPUTS) && NUM_ANALOG_INPUTS == 6 +#define TOTAL_ANALOG_PINS 6 +#define TOTAL_PINS 20 // 14 digital + 6 analog +#else +#define TOTAL_ANALOG_PINS 8 +#define TOTAL_PINS 22 // 14 digital + 8 analog +#endif +// These have conflicting(?) definitions in the core for this CPU +#undef IS_PIN_PWM +#undef IS_PIN_ANALOG +#define VERSION_BLINK_PIN 13 +#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19) +#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS) +#define IS_PIN_I2C(p) ((p) == 18 || (p) == 19) +#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) ((p) - 14) +#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) +#define PIN_TO_SERVO(p) ((p) - 2) // Teensy 1.0 #elif defined(__AVR_AT90USB162__) From a46444edfee2410a9c08168c8b48c710b18dad9e Mon Sep 17 00:00:00 2001 From: Birger Koblitz Date: Sun, 3 Sep 2023 09:46:58 +0200 Subject: [PATCH 78/81] Documentation: Add reference to the Firmata Linux Kernel module Adds a reference to the (experimental) Linux Kernel Module firmata_mod, which allows users to use standard Linux userspace APIs/tools to access GPIO, I2C or SPI devices made available on an Arduino attached to a Linux host PC via a serial interface and running the Firmata firmware. In addition, existing Linux Kernel modules for devices using I2C/SPI can also be associated with devices on the Arduino. --- readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/readme.md b/readme.md index 9d72f2e6..cde48641 100644 --- a/readme.md +++ b/readme.md @@ -89,6 +89,8 @@ Most of the time you will be interacting with Arduino with a client library on t * [https://github.com/NullMember/PDFirmata](https://github.com/NullMember/PDFirmata) * Common Lisp * [https://github.com/cjfuller/cl-firmata](https://github.com/cjfuller/cl-firmata) +* Linux Kernel Module + * [https://github.com/logicog/firmata_mod] Note: The above libraries may support various versions of the Firmata protocol and therefore may not support all features of the latest Firmata spec nor all Arduino and Arduino-compatible boards. Refer to the respective projects for details. From 1b593388fb2d0996d38063cd999c541d5fcd3725 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Mon, 9 Sep 2024 07:17:36 +0200 Subject: [PATCH 79/81] Fix compilation for UNOR4 --- Boards.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Boards.h b/Boards.h index f6cc0422..b53d2447 100644 --- a/Boards.h +++ b/Boards.h @@ -470,7 +470,7 @@ writePort(port, value, bitmask): Write an 8 bit port. #define VERSION_BLINK_PIN 13 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19) #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS) -#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS) #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19) #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) From 1866deb3343a1e95b552e2de8f2037119bd02617 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Thu, 12 Sep 2024 21:10:04 +0200 Subject: [PATCH 80/81] A correct definition already exists --- Boards.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/Boards.h b/Boards.h index b53d2447..0a7c3eb7 100644 --- a/Boards.h +++ b/Boards.h @@ -465,12 +465,10 @@ writePort(port, value, bitmask): Write an 8 bit port. #define TOTAL_PINS 22 // 14 digital + 8 analog #endif // These have conflicting(?) definitions in the core for this CPU -#undef IS_PIN_PWM #undef IS_PIN_ANALOG #define VERSION_BLINK_PIN 13 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19) #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS) -#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS) #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19) #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) From 6c48901d3f608ee44f3e8b93999457391e3573f4 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Thu, 12 Sep 2024 21:19:50 +0200 Subject: [PATCH 81/81] This also is no longer used --- Boards.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/Boards.h b/Boards.h index 0a7c3eb7..1d92cddd 100644 --- a/Boards.h +++ b/Boards.h @@ -464,11 +464,8 @@ writePort(port, value, bitmask): Write an 8 bit port. #define TOTAL_ANALOG_PINS 8 #define TOTAL_PINS 22 // 14 digital + 8 analog #endif -// These have conflicting(?) definitions in the core for this CPU -#undef IS_PIN_ANALOG #define VERSION_BLINK_PIN 13 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19) -#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS) #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS) #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19) #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)