diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index dd6ad5614..6de3c4882 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -2048,87 +2048,38 @@ public class Editor extends JFrame implements RunnerListener { * modifications (if any) to the previous sketch need to be saved. */ protected boolean handleOpenInternal(String path) { - // rename .pde files to .ino - File[] oldFiles = (new File(path)).getParentFile().listFiles(new FilenameFilter() { - public boolean accept(File dir, String name) { - return (name.toLowerCase().endsWith(".pde")); - } - }); - - if (oldFiles != null && oldFiles.length > 0) { - if (!Preferences.getBoolean("editor.update_extension")) { - Object[] options = { "OK", "Cancel" }; - String prompt = - "In Arduino 1.0, the file extension for sketches changed\n" + - "from \".pde\" to \".ino\". This version of the software only\n" + - "supports the new extension. Rename the files in this sketch\n" + - "(and future sketches) and continue?"; - - int result = JOptionPane.showOptionDialog(this, - prompt, - "New extension", - JOptionPane.YES_NO_OPTION, - JOptionPane.QUESTION_MESSAGE, - null, - options, - options[0]); - if (result != JOptionPane.YES_OPTION) { - return false; - } - - Preferences.setBoolean("editor.update_extension", true); - } - - for (int i = 0; i < oldFiles.length; i++) { - String oldPath = oldFiles[i].getPath(); - File newFile = new File(oldPath.substring(0, oldPath.length() - 4) + ".ino"); - try { - Base.copyFile(oldFiles[i], newFile); - } catch (IOException e) { - Base.showWarning("Error", "Could not copy to a proper location.", e); - return false; - } - - // remove the original file, so user doesn't get confused - oldFiles[i].delete(); - - // update with the new path - if (oldFiles[i].compareTo(new File(path)) == 0) { - path = newFile.getAbsolutePath(); - } - } - } - // check to make sure that this .pde file is // in a folder of the same name File file = new File(path); - File parentFile = new File(file.getParent()); - String parentName = parentFile.getName(); - String pdeName = parentName + ".ino"; - File altFile = new File(file.getParent(), pdeName); + String fileName = file.getName(); + File parent = file.getParentFile(); + String parentName = parent.getName(); + String pdeName = parentName + ".pde"; + File altPdeFile = new File(parent, pdeName); + String inoName = parentName + ".ino"; + File altInoFile = new File(parent, pdeName); - if (pdeName.equals(file.getName())) { + if (pdeName.equals(fileName) || inoName.equals(fileName)) { // no beef with this guy - } else if (altFile.exists()) { - // user selected a .java from the same sketch, - // but open the .pde instead - path = altFile.getAbsolutePath(); - //System.out.println("found alt file in same folder"); - - } else if (!path.endsWith(".ino")) { + } else if (altPdeFile.exists()) { + // user selected a .java from the same sketch, but open the .pde instead + path = altPdeFile.getAbsolutePath(); + } else if (altInoFile.exists()) { + path = altInoFile.getAbsolutePath(); + } else if (!path.endsWith(".ino") && !path.endsWith(".pde")) { Base.showWarning("Bad file selected", "Processing can only open its own sketches\n" + - "and other files ending in .ino", null); + "and other files ending in .ino or .pde", null); return false; } else { String properParent = - file.getName().substring(0, file.getName().length() - 4); + fileName.substring(0, fileName.length() - 4); Object[] options = { "OK", "Cancel" }; String prompt = - "The file \"" + file.getName() + "\" needs to be inside\n" + + "The file \"" + fileName + "\" needs to be inside\n" + "a sketch folder named \"" + properParent + "\".\n" + "Create this folder, move the file, and continue?"; @@ -2223,7 +2174,7 @@ public class Editor extends JFrame implements RunnerListener { // need to get the name, user might also cancel here } else if (immediately) { - handleSave2(); + return handleSave2(); } else { SwingUtilities.invokeLater(new Runnable() { @@ -2236,15 +2187,16 @@ public class Editor extends JFrame implements RunnerListener { } - protected void handleSave2() { + protected boolean handleSave2() { toolbar.activate(EditorToolbar.SAVE); statusNotice("Saving..."); + boolean saved = false; try { - if (sketch.save()) { + saved = sketch.save(); + if (saved) statusNotice("Done Saving."); - } else { + else statusEmpty(); - } // rebuild sketch menu in case a save-as was forced // Disabling this for 0125, instead rebuild the menu inside // the Save As method of the Sketch object, since that's the @@ -2263,6 +2215,7 @@ public class Editor extends JFrame implements RunnerListener { } //toolbar.clear(); toolbar.deactivate(EditorToolbar.SAVE); + return saved; } diff --git a/app/src/processing/app/Sketch.java b/app/src/processing/app/Sketch.java index 93b8e40dc..58cbd3deb 100644 --- a/app/src/processing/app/Sketch.java +++ b/app/src/processing/app/Sketch.java @@ -36,6 +36,7 @@ import java.awt.event.*; import java.beans.*; import java.io.*; import java.util.*; +import java.util.List; import java.util.zip.*; import javax.swing.*; @@ -261,7 +262,6 @@ public class Sketch { } } - boolean renamingCode; /** @@ -709,13 +709,42 @@ public class Sketch { if (!saveAs()) return false; } + // rename .pde files to .ino + File mainFile = new File(getMainFilePath()); + File mainFolder = mainFile.getParentFile(); + File[] pdeFiles = mainFolder.listFiles(new FilenameFilter() { + public boolean accept(File dir, String name) { + return name.toLowerCase().endsWith(".pde"); + } + }); + + if (pdeFiles != null && pdeFiles.length > 0) { + // Do rename of all .pde files to new .ino extension + for (File pdeFile : pdeFiles) + renameCodeToInoExtension(pdeFile); + } + for (int i = 0; i < codeCount; i++) { - if (code[i].isModified()) code[i].save(); + if (code[i].isModified()) + code[i].save(); } calcModified(); return true; } + + protected boolean renameCodeToInoExtension(File pdeFile) { + for (SketchCode c : code) { + if (!c.getFile().equals(pdeFile)) + continue; + + String pdeName = pdeFile.getPath(); + pdeName = pdeName.substring(0, pdeName.length() - 4) + ".ino"; + return c.renameTo(new File(pdeName), "ino"); + } + return false; + } + /** * Handles 'Save As' for a sketch. @@ -1261,7 +1290,7 @@ public class Sketch { StringBuffer bigCode = new StringBuffer(); int bigCount = 0; for (SketchCode sc : code) { - if (sc.isExtension("ino")) { + if (sc.isExtension("ino") || sc.isExtension("pde")) { sc.setPreprocOffset(bigCount); bigCode.append(sc.getProgram()); bigCode.append('\n'); @@ -1357,7 +1386,7 @@ public class Sketch { } // sc.setPreprocName(filename); - } else if (sc.isExtension("ino")) { + } else if (sc.isExtension("ino") || sc.isExtension("pde")) { // The compiler and runner will need this to have a proper offset sc.addPreprocOffset(headerOffset); } @@ -1762,7 +1791,7 @@ public class Sketch { * For Processing, this is true for .pde files. (Broken out for subclasses.) */ public boolean hideExtension(String what) { - return what.equals(getDefaultExtension()); + return getHiddenExtensions().contains(what); } @@ -1802,12 +1831,17 @@ public class Sketch { return "ino"; } + static private List hiddenExtensions = Arrays.asList("ino", "pde"); + public List getHiddenExtensions() { + return hiddenExtensions; + } + /** * Returns a String[] array of proper extensions. */ public String[] getExtensions() { - return new String[] { "ino", "c", "cpp", "h" }; + return new String[] { "ino", "pde", "c", "cpp", "h" }; } diff --git a/app/src/processing/app/SketchCode.java b/app/src/processing/app/SketchCode.java index f7dae32bb..2a6e82560 100644 --- a/app/src/processing/app/SketchCode.java +++ b/app/src/processing/app/SketchCode.java @@ -113,8 +113,8 @@ public class SketchCode { protected boolean renameTo(File what, String ext) { boolean success = file.renameTo(what); if (success) { - this.file = what; // necessary? - this.extension = ext; + file = what; + extension = ext; makePrettyName(); } return success; diff --git a/build/linux/dist/tools/avrdude64 b/build/linux/dist/tools/avrdude64 index f13912adc..8d97d8b32 100755 Binary files a/build/linux/dist/tools/avrdude64 and b/build/linux/dist/tools/avrdude64 differ diff --git a/build/macosx/template.app/Contents/Info.plist b/build/macosx/template.app/Contents/Info.plist index 6c10f2579..f8bfd3250 100755 --- a/build/macosx/template.app/Contents/Info.plist +++ b/build/macosx/template.app/Contents/Info.plist @@ -7,11 +7,11 @@ CFBundleGetInfoString - 1.0-beta3 + 1.0-beta4 CFBundleVersion 0100 CFBundleShortVersionString - 1.0-beta3 + 1.0-beta4 CFBundleAllowMixedLocalizations diff --git a/hardware/arduino/cores/arduino/Stream.cpp b/hardware/arduino/cores/arduino/Stream.cpp index d267bf0cb..8b6f1e8b2 100644 --- a/hardware/arduino/cores/arduino/Stream.cpp +++ b/hardware/arduino/cores/arduino/Stream.cpp @@ -29,30 +29,39 @@ // private method to read stream with timeout int Stream::timedRead() { - //Serial.println(_timeout); - this->_startMillis = millis(); - while(millis() - this->_startMillis < this->_timeout) - { - if (this->available() > 0) { - return this->read(); - } - } + int c; + _startMillis = millis(); + do { + c = read(); + if (c >= 0) return c; + } while(millis() - _startMillis < _timeout); return -1; // -1 indicates timeout } -// returns the next digit in the stream or -1 if timeout -// discards non-numeric characters -int Stream::getNextDigit() +// private method to peek stream with timeout +int Stream::timedPeek() { int c; - do{ - c = timedRead(); - if( c < 0) - return c; // timeout - } - while( c != '-' && (c < '0' || c > '9') ) ; + _startMillis = millis(); + do { + c = peek(); + if (c >= 0) return c; + } while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} -return c; +// returns peek of the next digit in the stream or -1 if timeout +// discards non-numeric characters +int Stream::peekNextDigit() +{ + int c; + while (1) { + c = timedPeek(); + if (c < 0) return c; // timeout + if (c == '-') return c; + if (c >= '0' && c <= '9') return c; + read(); // discard non-numeric + } } // Public Methods @@ -130,7 +139,7 @@ long Stream::parseInt(char skipChar) long value = 0; int c; - c = getNextDigit(); + c = peekNextDigit(); // ignore non numeric leading characters if(c < 0) return 0; // zero returned if timeout @@ -142,9 +151,10 @@ long Stream::parseInt(char skipChar) isNegative = true; else if(c >= '0' && c <= '9') // is c a digit? value = value * 10 + c - '0'; - c = timedRead(); + read(); // consume the character we got with peek + c = timedPeek(); } - while( (c >= '0' && c <= '9') || c == skipChar ); + while( (c >= '0' && c <= '9') || c == skipChar ); if(isNegative) value = -value; @@ -168,7 +178,7 @@ float Stream::parseFloat(char skipChar){ char c; float fraction = 1.0; - c = getNextDigit(); + c = peekNextDigit(); // ignore non numeric leading characters if(c < 0) return 0; // zero returned if timeout @@ -185,7 +195,8 @@ float Stream::parseFloat(char skipChar){ if(isFraction) fraction *= 0.1; } - c = timedRead(); + read(); // consume the character we got with peek + c = timedPeek(); } while( (c >= '0' && c <= '9') || c == '.' || c == skipChar ); diff --git a/hardware/arduino/cores/arduino/Stream.h b/hardware/arduino/cores/arduino/Stream.h index 1633f15d5..3c6d025e9 100644 --- a/hardware/arduino/cores/arduino/Stream.h +++ b/hardware/arduino/cores/arduino/Stream.h @@ -41,7 +41,8 @@ class Stream : public Print long _timeout; // number of milliseconds to wait for the next char before aborting timed read long _startMillis; // used for timeout measurement int timedRead(); // private method to read stream with timeout - int getNextDigit(); // returns the next numeric digit in the stream or -1 if timeout + int timedPeek(); // private method to peek stream with timeout + int peekNextDigit(); // returns the next numeric digit in the stream or -1 if timeout public: virtual int available() = 0; diff --git a/libraries/Firmata/Boards.h b/libraries/Firmata/Boards.h index 52f61873f..06f69c629 100644 --- a/libraries/Firmata/Boards.h +++ b/libraries/Firmata/Boards.h @@ -124,6 +124,10 @@ writePort(port, value, bitmask): Write an 8 bit port. * Board Specific Configuration *============================================================================*/ +#ifndef digitalPinHasPWM +#define digitalPinHasPWM(p) IS_PIN_DIGITAL(p) +#endif + // Arduino Duemilanove, Diecimila, and NG #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) #if defined(NUM_ANALOG_INPUTS) && NUM_ANALOG_INPUTS == 6 @@ -136,7 +140,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) IS_PIN_DIGITAL(p) +#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 PIN_TO_DIGITAL(p) (p) @@ -151,7 +155,7 @@ writePort(port, value, bitmask): Write an 8 bit port. #define VERSION_BLINK_PIN WLED #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) #define IS_PIN_ANALOG(p) ((p) >= FIRST_ANALOG_PIN && (p) < (FIRST_ANALOG_PIN+TOTAL_ANALOG_PINS)) -#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) #define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL) #define PIN_TO_DIGITAL(p) (p) @@ -167,7 +171,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) <= 19) -#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) +#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 PIN_TO_DIGITAL(p) (p) @@ -178,13 +182,13 @@ writePort(port, value, bitmask): Write an 8 bit port. // Arduino Mega -#elif defined(__AVR_ATmega1280__) +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) #define TOTAL_ANALOG_PINS 16 #define TOTAL_PINS 70 // 54 digital + 16 analog #define VERSION_BLINK_PIN 13 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS) #define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS) -#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) #define IS_PIN_SERVO(p) ((p) >= 2 && (p) - 2 < MAX_SERVOS) #define IS_PIN_I2C(p) ((p) == 20 || (p) == 21) #define PIN_TO_DIGITAL(p) (p) @@ -200,7 +204,7 @@ writePort(port, value, bitmask): Write an 8 bit port. #define VERSION_BLINK_PIN 6 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) #define IS_PIN_ANALOG(p) (0) -#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) #define IS_PIN_I2C(p) (0) #define PIN_TO_DIGITAL(p) (p) @@ -216,7 +220,7 @@ writePort(port, value, bitmask): Write an 8 bit port. #define VERSION_BLINK_PIN 11 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) #define IS_PIN_ANALOG(p) ((p) >= 11 && (p) <= 22) -#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) #define IS_PIN_I2C(p) ((p) == 5 || (p) == 6) #define PIN_TO_DIGITAL(p) (p) @@ -232,7 +236,7 @@ writePort(port, value, bitmask): Write an 8 bit port. #define VERSION_BLINK_PIN 6 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) #define IS_PIN_ANALOG(p) ((p) >= 38 && (p) < TOTAL_PINS) -#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) #define IS_PIN_I2C(p) ((p) == 0 || (p) == 1) #define PIN_TO_DIGITAL(p) (p) @@ -248,7 +252,7 @@ writePort(port, value, bitmask): Write an 8 bit port. #define VERSION_BLINK_PIN 0 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS) #define IS_PIN_ANALOG(p) ((p) >= 24 && (p) < TOTAL_PINS) -#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) #define IS_PIN_I2C(p) ((p) == 16 || (p) == 17) #define PIN_TO_DIGITAL(p) (p) @@ -264,7 +268,7 @@ writePort(port, value, bitmask): Write an 8 bit port. #define VERSION_BLINK_PIN 13 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS) #define IS_PIN_ANALOG(p) ((p) >= 36 && (p) < TOTAL_PINS) -#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) #define IS_PIN_I2C(p) ((p) == 4 || (p) == 5) #define PIN_TO_DIGITAL(p) (p) diff --git a/libraries/Firmata/Firmata.cpp b/libraries/Firmata/Firmata.cpp index 0d68a5744..e81c10bb1 100644 --- a/libraries/Firmata/Firmata.cpp +++ b/libraries/Firmata/Firmata.cpp @@ -68,7 +68,6 @@ void FirmataClass::begin(long speed) Serial.begin(speed); FirmataSerial = Serial; blinkVersion(); - delay(300); printVersion(); printFirmwareVersion(); } @@ -92,11 +91,10 @@ void FirmataClass::blinkVersion(void) { // flash the pin with the protocol version pinMode(VERSION_BLINK_PIN,OUTPUT); - pin13strobe(FIRMATA_MAJOR_VERSION, 200, 400); - delay(300); - pin13strobe(2,1,4); // separator, a quick burst - delay(300); - pin13strobe(FIRMATA_MINOR_VERSION, 200, 400); + pin13strobe(FIRMATA_MAJOR_VERSION, 40, 210); + delay(250); + pin13strobe(FIRMATA_MINOR_VERSION, 40, 210); + delay(125); } void FirmataClass::printFirmwareVersion(void) diff --git a/libraries/Firmata/examples/AllInputsFirmata/AllInputsFirmata.ino b/libraries/Firmata/examples/AllInputsFirmata/AllInputsFirmata.ino index 775594938..bff736699 100644 --- a/libraries/Firmata/examples/AllInputsFirmata/AllInputsFirmata.ino +++ b/libraries/Firmata/examples/AllInputsFirmata/AllInputsFirmata.ino @@ -1,3 +1,14 @@ +/* + * Firmata is a generic protocol for communicating with microcontrollers + * from software on a host computer. It is intended to work with + * any host computer software package. + * + * To download a host software package, please clink on the following link + * to open the download page in your default browser. + * + * http://firmata.org/wiki/Download + */ + /* * This firmware reads all inputs and sends them as fast as it can. It was * inspired by the ease-of-use of the Arduino2Max program. diff --git a/libraries/Firmata/examples/AnalogFirmata/AnalogFirmata.ino b/libraries/Firmata/examples/AnalogFirmata/AnalogFirmata.ino index df8b674b9..ff1d664b8 100644 --- a/libraries/Firmata/examples/AnalogFirmata/AnalogFirmata.ino +++ b/libraries/Firmata/examples/AnalogFirmata/AnalogFirmata.ino @@ -1,3 +1,14 @@ +/* + * Firmata is a generic protocol for communicating with microcontrollers + * from software on a host computer. It is intended to work with + * any host computer software package. + * + * To download a host software package, please clink on the following link + * to open the download page in your default browser. + * + * http://firmata.org/wiki/Download + */ + /* This firmware supports as many analog ports as possible, all analog inputs, * four PWM outputs, and two with servo support. * diff --git a/libraries/Firmata/examples/EchoString/EchoString.ino b/libraries/Firmata/examples/EchoString/EchoString.ino index e708ec210..5079697a5 100644 --- a/libraries/Firmata/examples/EchoString/EchoString.ino +++ b/libraries/Firmata/examples/EchoString/EchoString.ino @@ -1,3 +1,14 @@ +/* + * Firmata is a generic protocol for communicating with microcontrollers + * from software on a host computer. It is intended to work with + * any host computer software package. + * + * To download a host software package, please clink on the following link + * to open the download page in your default browser. + * + * http://firmata.org/wiki/Download + */ + /* This sketch accepts strings and raw sysex messages and echos them back. * * This example code is in the public domain. diff --git a/libraries/Firmata/examples/I2CFirmata/I2CFirmata.ino b/libraries/Firmata/examples/I2CFirmata/I2CFirmata.ino index f2c931b95..1da8963a0 100644 --- a/libraries/Firmata/examples/I2CFirmata/I2CFirmata.ino +++ b/libraries/Firmata/examples/I2CFirmata/I2CFirmata.ino @@ -1,3 +1,14 @@ +/* + * Firmata is a generic protocol for communicating with microcontrollers + * from software on a host computer. It is intended to work with + * any host computer software package. + * + * To download a host software package, please clink on the following link + * to open the download page in your default browser. + * + * http://firmata.org/wiki/Download + */ + /* Copyright (C) 2009 Jeff Hoefs. All rights reserved. Copyright (C) 2009 Shigeru Kobayashi. All rights reserved. diff --git a/libraries/Firmata/examples/OldStandardFirmata/OldStandardFirmata.ino b/libraries/Firmata/examples/OldStandardFirmata/OldStandardFirmata.ino index 56a47acd4..d306c70d7 100644 --- a/libraries/Firmata/examples/OldStandardFirmata/OldStandardFirmata.ino +++ b/libraries/Firmata/examples/OldStandardFirmata/OldStandardFirmata.ino @@ -1,3 +1,14 @@ +/* + * Firmata is a generic protocol for communicating with microcontrollers + * from software on a host computer. It is intended to work with + * any host computer software package. + * + * To download a host software package, please clink on the following link + * to open the download page in your default browser. + * + * http://firmata.org/wiki/Download + */ + /* Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved. diff --git a/libraries/Firmata/examples/ServoFirmata/ServoFirmata.ino b/libraries/Firmata/examples/ServoFirmata/ServoFirmata.ino index 6f78ccd32..cdcfff04d 100644 --- a/libraries/Firmata/examples/ServoFirmata/ServoFirmata.ino +++ b/libraries/Firmata/examples/ServoFirmata/ServoFirmata.ino @@ -1,3 +1,14 @@ +/* + * Firmata is a generic protocol for communicating with microcontrollers + * from software on a host computer. It is intended to work with + * any host computer software package. + * + * To download a host software package, please clink on the following link + * to open the download page in your default browser. + * + * http://firmata.org/wiki/Download + */ + /* This firmware supports as many servos as possible using the Servo library * included in Arduino 0017 * diff --git a/libraries/Firmata/examples/SimpleAnalogFirmata/SimpleAnalogFirmata.ino b/libraries/Firmata/examples/SimpleAnalogFirmata/SimpleAnalogFirmata.ino index b505b3391..44ea91eea 100644 --- a/libraries/Firmata/examples/SimpleAnalogFirmata/SimpleAnalogFirmata.ino +++ b/libraries/Firmata/examples/SimpleAnalogFirmata/SimpleAnalogFirmata.ino @@ -1,3 +1,14 @@ +/* + * Firmata is a generic protocol for communicating with microcontrollers + * from software on a host computer. It is intended to work with + * any host computer software package. + * + * To download a host software package, please clink on the following link + * to open the download page in your default browser. + * + * http://firmata.org/wiki/Download + */ + /* Supports as many analog inputs and analog PWM outputs as possible. * * This example code is in the public domain. diff --git a/libraries/Firmata/examples/SimpleDigitalFirmata/SimpleDigitalFirmata.ino b/libraries/Firmata/examples/SimpleDigitalFirmata/SimpleDigitalFirmata.ino index bbe42ed8d..a0d764f72 100644 --- a/libraries/Firmata/examples/SimpleDigitalFirmata/SimpleDigitalFirmata.ino +++ b/libraries/Firmata/examples/SimpleDigitalFirmata/SimpleDigitalFirmata.ino @@ -1,3 +1,14 @@ +/* + * Firmata is a generic protocol for communicating with microcontrollers + * from software on a host computer. It is intended to work with + * any host computer software package. + * + * To download a host software package, please clink on the following link + * to open the download page in your default browser. + * + * http://firmata.org/wiki/Download + */ + /* Supports as many digital inputs and outputs as possible. * * This example code is in the public domain. diff --git a/libraries/Firmata/examples/StandardFirmata/StandardFirmata.ino b/libraries/Firmata/examples/StandardFirmata/StandardFirmata.ino index 51f090c31..1a987eebb 100644 --- a/libraries/Firmata/examples/StandardFirmata/StandardFirmata.ino +++ b/libraries/Firmata/examples/StandardFirmata/StandardFirmata.ino @@ -1,5 +1,19 @@ +/* + * Firmata is a generic protocol for communicating with microcontrollers + * from software on a host computer. It is intended to work with + * any host computer software package. + * + * To download a host software package, please clink on the following link + * to open the download page in your default browser. + * + * http://firmata.org/wiki/Download + */ + /* 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-2011 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 @@ -16,8 +30,22 @@ */ #include +#include #include +// move the following defines to Firmata.h? +#define I2C_WRITE B00000000 +#define I2C_READ B00001000 +#define I2C_READ_CONTINUOUSLY B00010000 +#define I2C_STOP_READING B00011000 +#define I2C_READ_WRITE_MODE_MASK B00011000 +#define I2C_10BIT_ADDRESS_MODE_MASK B00100000 + +#define MAX_QUERIES 8 +#define MINIMUM_SAMPLING_INTERVAL 10 + +#define REGISTER_NOT_SPECIFIED -1 + /*============================================================================== * GLOBAL VARIABLES *============================================================================*/ @@ -39,12 +67,69 @@ unsigned long currentMillis; // store the current value from millis() unsigned long previousMillis; // for comparison with currentMillis int samplingInterval = 19; // how often to run the main loop (in ms) -Servo servos[MAX_SERVOS]; +/* i2c data */ +struct i2c_device_info { + byte addr; + byte reg; + byte bytes; +}; +/* for i2c read continuous more */ +i2c_device_info query[MAX_QUERIES]; + +byte i2cRxData[32]; +boolean isI2CEnabled = false; +signed char queryIndex = -1; +unsigned int i2cReadDelayTime = 0; // default delay time between i2c read request and Wire.requestFrom() + +Servo servos[MAX_SERVOS]; /*============================================================================== * FUNCTIONS *============================================================================*/ +void readAndReportData(byte address, int theRegister, byte numBytes) { + // allow I2C requests that don't require a register read + // for example, some devices using an interrupt pin to signify new data available + // do not always require the register read so upon interrupt you call Wire.requestFrom() + if (theRegister != REGISTER_NOT_SPECIFIED) { + Wire.beginTransmission(address); + #if ARDUINO >= 100 + Wire.write((byte)theRegister); + #else + Wire.send((byte)theRegister); + #endif + Wire.endTransmission(); + delayMicroseconds(i2cReadDelayTime); // delay is necessary for some devices such as WiiNunchuck + } else { + theRegister = 0; // fill the register with a dummy value + } + + Wire.requestFrom(address, numBytes); // all bytes are returned in requestFrom + + // check to be sure correct number of bytes were returned by slave + if(numBytes == Wire.available()) { + i2cRxData[0] = address; + i2cRxData[1] = theRegister; + for (int i = 0; i < numBytes; i++) { + #if ARDUINO >= 100 + i2cRxData[2 + i] = Wire.read(); + #else + i2cRxData[2 + i] = Wire.receive(); + #endif + } + } + else { + if(numBytes > Wire.available()) { + Firmata.sendString("I2C Read Error: Too many bytes received"); + } else { + Firmata.sendString("I2C Read Error: Too few bytes received"); + } + } + + // send slave address, register and received bytes + Firmata.sendSysex(SYSEX_I2C_REPLY, numBytes + 2, i2cRxData); +} + void outputPort(byte portNumber, byte portValue, byte forceSend) { // pins not configured as INPUT are cleared to zeros @@ -88,6 +173,11 @@ void checkDigitalInputs(void) */ void setPinModeCallback(byte pin, int mode) { + if (pinConfig[pin] == I2C && isI2CEnabled && mode != I2C) { + // disable i2c so pins can be used for other functions + // the following if statements should reconfigure the pins properly + disableI2CPins(); + } if (IS_PIN_SERVO(pin) && mode != SERVO && servos[PIN_TO_SERVO(pin)].attached()) { servos[PIN_TO_SERVO(pin)].detach(); } @@ -138,14 +228,15 @@ void setPinModeCallback(byte pin, int mode) pinConfig[pin] = SERVO; if (!servos[PIN_TO_SERVO(pin)].attached()) { servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin)); - } else { - Firmata.sendString("Servo only on pins from 2 to 13"); } } break; case I2C: - pinConfig[pin] = mode; - Firmata.sendString("I2C mode not yet supported"); + if (IS_PIN_I2C(pin)) { + // mark the pin as i2c + // the user must call I2C_CONFIG to enable I2C for a device + pinConfig[pin] = I2C; + } break; default: Firmata.sendString("Unknown pin mode"); // TODO: put error msgs in EEPROM @@ -232,7 +323,104 @@ void reportDigitalCallback(byte port, int value) void sysexCallback(byte command, byte argc, byte *argv) { + byte mode; + byte slaveAddress; + byte slaveRegister; + byte data; + unsigned int delayTime; + switch(command) { + case I2C_REQUEST: + mode = argv[1] & I2C_READ_WRITE_MODE_MASK; + if (argv[1] & I2C_10BIT_ADDRESS_MODE_MASK) { + Firmata.sendString("10-bit addressing mode is not yet supported"); + return; + } + else { + slaveAddress = argv[0]; + } + + switch(mode) { + case I2C_WRITE: + Wire.beginTransmission(slaveAddress); + for (byte i = 2; i < argc; i += 2) { + data = argv[i] + (argv[i + 1] << 7); + #if ARDUINO >= 100 + Wire.write(data); + #else + Wire.send(data); + #endif + } + Wire.endTransmission(); + delayMicroseconds(70); + break; + case I2C_READ: + if (argc == 6) { + // a slave register is specified + slaveRegister = argv[2] + (argv[3] << 7); + data = argv[4] + (argv[5] << 7); // bytes to read + readAndReportData(slaveAddress, (int)slaveRegister, data); + } + else { + // a slave register is NOT specified + data = argv[2] + (argv[3] << 7); // bytes to read + readAndReportData(slaveAddress, (int)REGISTER_NOT_SPECIFIED, data); + } + break; + case I2C_READ_CONTINUOUSLY: + if ((queryIndex + 1) >= MAX_QUERIES) { + // too many queries, just ignore + Firmata.sendString("too many queries"); + break; + } + queryIndex++; + query[queryIndex].addr = slaveAddress; + query[queryIndex].reg = argv[2] + (argv[3] << 7); + query[queryIndex].bytes = argv[4] + (argv[5] << 7); + break; + case I2C_STOP_READING: + byte queryIndexToSkip; + // if read continuous mode is enabled for only 1 i2c device, disable + // read continuous reporting for that device + if (queryIndex <= 0) { + queryIndex = -1; + } else { + // if read continuous mode is enabled for multiple devices, + // determine which device to stop reading and remove it's data from + // the array, shifiting other array data to fill the space + for (byte i = 0; i < queryIndex + 1; i++) { + if (query[i].addr = slaveAddress) { + queryIndexToSkip = i; + break; + } + } + + for (byte i = queryIndexToSkip; i 0) { + i2cReadDelayTime = delayTime; + } + + if (!isI2CEnabled) { + enableI2CPins(); + } + + break; case SERVO_CONFIG: if(argc > 4) { // these vars are here for clarity, they'll optimized away by the compiler @@ -241,7 +429,6 @@ void sysexCallback(byte command, byte argc, byte *argv) int maxPulse = argv[3] + (argv[4] << 7); if (IS_PIN_SERVO(pin)) { - // servos are pins from 2 to 13, so offset for array if (servos[PIN_TO_SERVO(pin)].attached()) servos[PIN_TO_SERVO(pin)].detach(); servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin), minPulse, maxPulse); @@ -250,10 +437,14 @@ void sysexCallback(byte command, byte argc, byte *argv) } break; case SAMPLING_INTERVAL: - if (argc > 1) + if (argc > 1) { samplingInterval = argv[0] + (argv[1] << 7); - else - Firmata.sendString("Not enough data"); + if (samplingInterval < MINIMUM_SAMPLING_INTERVAL) { + samplingInterval = MINIMUM_SAMPLING_INTERVAL; + } + } else { + //Firmata.sendString("Not enough data"); + } break; case EXTENDED_ANALOG: if (argc > 1) { @@ -285,6 +476,10 @@ void sysexCallback(byte command, byte argc, byte *argv) Serial.write(SERVO); Serial.write(14); } + if (IS_PIN_I2C(pin)) { + Serial.write(I2C); + Serial.write(1); // to do: determine appropriate value + } Serial.write(127); } Serial.write(END_SYSEX); @@ -315,33 +510,52 @@ void sysexCallback(byte command, byte argc, byte *argv) } } +void enableI2CPins() +{ + byte i; + // is there a faster way to do this? would probaby require importing + // Arduino.h to get SCL and SDA pins + for (i=0; i < TOTAL_PINS; i++) { + if(IS_PIN_I2C(i)) { + // mark pins as i2c so they are ignore in non i2c data requests + setPinModeCallback(i, I2C); + } + } + + isI2CEnabled = true; + + // is there enough time before the first I2C request to call this here? + Wire.begin(); +} + +/* disable the i2c pins so they can be used for other functions */ +void disableI2CPins() { + isI2CEnabled = false; + // disable read continuous mode for all devices + queryIndex = -1; + // uncomment the following if or when the end() method is added to Wire library + // Wire.end(); +} /*============================================================================== * SETUP() *============================================================================*/ -void setup() + +void systemResetCallback() { - byte i; - - Firmata.setFirmwareVersion(FIRMATA_MAJOR_VERSION, FIRMATA_MINOR_VERSION); - - Firmata.attach(ANALOG_MESSAGE, analogWriteCallback); - Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback); - Firmata.attach(REPORT_ANALOG, reportAnalogCallback); - Firmata.attach(REPORT_DIGITAL, reportDigitalCallback); - Firmata.attach(SET_PIN_MODE, setPinModeCallback); - Firmata.attach(START_SYSEX, sysexCallback); - - // TODO: load state from EEPROM here - - /* these are initialized to zero by the compiler startup code - for (i=0; i < TOTAL_PORTS; i++) { - reportPINs[i] = false; - portConfigInputs[i] = 0; + // initialize a defalt state + // TODO: option to load config from EEPROM instead of default + if (isI2CEnabled) { + disableI2CPins(); + } + for (byte i=0; i < TOTAL_PORTS; i++) { + reportPINs[i] = false; // by default, reporting off + portConfigInputs[i] = 0; // until activated previousPINs[i] = 0; } - */ - for (i=0; i < TOTAL_PINS; i++) { + // pins with analog capability default to analog input + // otherwise, pins default to digital output + for (byte i=0; i < TOTAL_PINS; i++) { if (IS_PIN_ANALOG(i)) { // turns off pullup, configures everything setPinModeCallback(i, ANALOG); @@ -350,16 +564,34 @@ void setup() setPinModeCallback(i, OUTPUT); } } - // by defult, do not report any analog inputs + // by default, do not report any analog inputs analogInputsToReport = 0; - Firmata.begin(57600); - /* send digital inputs to set the initial state on the host computer, * since once in the loop(), this firmware will only send on change */ - for (i=0; i < TOTAL_PORTS; i++) { + /* + TODO: this can never execute, since no pins default to digital input + but it will be needed when/if we support EEPROM stored config + for (byte i=0; i < TOTAL_PORTS; i++) { outputPort(i, readPort(i, portConfigInputs[i]), true); } + */ +} + +void setup() +{ + Firmata.setFirmwareVersion(FIRMATA_MAJOR_VERSION, FIRMATA_MINOR_VERSION); + + Firmata.attach(ANALOG_MESSAGE, analogWriteCallback); + Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback); + Firmata.attach(REPORT_ANALOG, reportAnalogCallback); + Firmata.attach(REPORT_DIGITAL, reportDigitalCallback); + Firmata.attach(SET_PIN_MODE, setPinModeCallback); + Firmata.attach(START_SYSEX, sysexCallback); + Firmata.attach(SYSTEM_RESET, systemResetCallback); + + Firmata.begin(57600); + systemResetCallback(); // reset to default config } /*============================================================================== @@ -394,5 +626,11 @@ void loop() } } } + // report i2c data for all device with read continuous mode enabled + if (queryIndex > -1) { + for (byte i = 0; i < queryIndex + 1; i++) { + readAndReportData(query[i].addr, query[i].reg, query[i].bytes); + } + } } } diff --git a/libraries/SD/File.cpp b/libraries/SD/File.cpp index 1226f2cf4..e0ef30a9c 100644 --- a/libraries/SD/File.cpp +++ b/libraries/SD/File.cpp @@ -101,7 +101,10 @@ int File::read(void *buf, uint16_t nbyte) { int File::available() { if (! _file) return 0; - return size() - position(); + + uint32_t n = size() - position(); + + return n > 0X7FFF ? 0X7FFF : n; } void File::flush() { diff --git a/libraries/SD/examples/CardInfo/CardInfo.ino b/libraries/SD/examples/CardInfo/CardInfo.ino index 7abfd33e4..fb2f6c3ca 100644 --- a/libraries/SD/examples/CardInfo/CardInfo.ino +++ b/libraries/SD/examples/CardInfo/CardInfo.ino @@ -80,7 +80,7 @@ void setup() // print the type and size of the first FAT-type volume - long volumesize; + uint32_t volumesize; Serial.print("\nVolume type is FAT"); Serial.println(volume.fatType(), DEC); Serial.println(); diff --git a/libraries/SoftwareSerial/examples/TwoPortRXExample/TwoPortRXExample.ino b/libraries/SoftwareSerial/examples/TwoPortRXExample/TwoPortRXExample.ino deleted file mode 100755 index 1db4536de..000000000 --- a/libraries/SoftwareSerial/examples/TwoPortRXExample/TwoPortRXExample.ino +++ /dev/null @@ -1,50 +0,0 @@ -#include - -SoftwareSerial ss(2, 3); -SoftwareSerial ss2(4, 5); - -/* This sample shows how to correctly process received data - on two different "soft" serial ports. Here we listen on - the first port (ss) until we receive a '?' character. Then - we begin listening on the other soft port. -*/ - -void setup() -{ - // Start the HW serial port - Serial.begin(57600); - - // Start each soft serial port - ss.begin(4800); - ss2.begin(4800); - - // By default, the most recently "begun" port is listening. - // We want to listen on ss, so let's explicitly select it. - ss.listen(); - - // Simply wait for a ? character to come down the pipe - Serial.println("Data from the first port: "); - char c = 0; - do - if (ss.available()) - { - c = (char)ss.read(); - Serial.print(c); - } - while (c != '?'); - - // Now listen on the second port - ss2.listen(); - - Serial.println("Data from the second port: "); -} - -void loop() -{ - if (ss2.available()) - { - char c = (char)ss2.read(); - Serial.print(c); - } -} - diff --git a/readme.txt b/readme.txt index 0d70830f8..4777293e6 100644 --- a/readme.txt +++ b/readme.txt @@ -6,28 +6,19 @@ The boards can be assembled by hand or purchased preassembled; the open-source IDE can be downloaded for free. For more information, see the website at: http://www.arduino.cc/ -or the forums at: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl +or the forums at: http://arduino.cc/forum/ -To report a bug or a make a suggestions, go to: -[hardware] http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?board=hwbugs -[software] http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?board=swbugs +To report a bug in the software, go to: +http://code.google.com/p/arduino/issues/list + +For other suggestions, use the forum: +http://arduino.cc/forum/index.php/board,21.0.html INSTALLATION Detailed instructions are in reference/Guide_Windows.html and reference/Guide_MacOSX.html. For Linux, see the Arduino playground: http://www.arduino.cc/playground/Learning/Linux -If you are using a USB Arduino, you will need to install the drivers for the -FTDI chip on the board. These can be found in the drivers/ directory. - -* On Windows, plug in the Arduino board and point the Windows Add Hardware - wizard to the drivers/FTDI USB Drivers sub-directory of the Arduino - application directory. - -* On the Mac, install the FTDIUSBSerialDriver_10_4_10_5_10_6.mpkg package. - -* On Linux, drivers are included in kernel versions 2.4.20 or greater. - CREDITS Arduino is an open source project, supported by many. @@ -37,6 +28,5 @@ Gianluca Martino, and David A. Mellis. Arduino uses the GNU avr-gcc toolchain, avrdude, avr-libc, and code from Processing and Wiring. -Icon designed by ToDo: http://www.todo.to.it/ -"About" image created by Thomas Glaser (envis precisely). +Icon and about image designed by ToDo: http://www.todo.to.it/