diff --git a/.classpath b/.classpath
index 71e8cc144..5f528e603 100644
--- a/.classpath
+++ b/.classpath
@@ -2,9 +2,11 @@
-
-
-
-
+
+
+
+
+
+
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
index ef277e5a2..a4e4441e5 100644
--- a/.settings/org.eclipse.jdt.core.prefs
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -1,10 +1,15 @@
-#Thu Jan 10 10:50:38 PST 2008
+#Tue Aug 16 19:08:40 CEST 2011
eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
-org.eclipse.jdt.core.compiler.compliance=1.4
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
-org.eclipse.jdt.core.compiler.source=1.3
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java
index 036cb4f5a..2e3d7b346 100644
--- a/app/src/processing/app/Base.java
+++ b/app/src/processing/app/Base.java
@@ -993,6 +993,13 @@ public class Base {
}
+ public void onBoardOrPortChange() {
+ for (Editor editor : editors) {
+ editor.onBoardOrPortChange();
+ }
+ }
+
+
public void rebuildBoardsMenu(JMenu menu) {
//System.out.println("rebuilding boards menu");
menu.removeAll();
@@ -1005,6 +1012,7 @@ public class Base {
//System.out.println("Switching to " + target + ":" + board);
Preferences.set("target", (String) getValue("target"));
Preferences.set("board", (String) getValue("board"));
+ onBoardOrPortChange();
}
};
action.putValue("target", target.getName());
diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java
index 33f1fc855..dd6ad5614 100644
--- a/app/src/processing/app/Editor.java
+++ b/app/src/processing/app/Editor.java
@@ -46,6 +46,7 @@ import gnu.io.*;
/**
* Main editor panel for the Processing Development Environment.
*/
+@SuppressWarnings("serial")
public class Editor extends JFrame implements RunnerListener {
Base base;
@@ -113,7 +114,7 @@ public class Editor extends JFrame implements RunnerListener {
EditorLineStatus lineStatus;
- JEditorPane editorPane;
+ //JEditorPane editorPane;
JEditTextArea textarea;
EditorListener listener;
@@ -195,8 +196,10 @@ public class Editor extends JFrame implements RunnerListener {
//PdeKeywords keywords = new PdeKeywords();
//sketchbook = new Sketchbook(this);
- if (serialMonitor == null)
+ if (serialMonitor == null) {
serialMonitor = new SerialMonitor(Preferences.get("serial.port"));
+ serialMonitor.setIconImage(getIconImage());
+ }
buildMenuBar();
@@ -907,6 +910,7 @@ public class Editor extends JFrame implements RunnerListener {
public void actionPerformed(ActionEvent e) {
selectSerialPort(((JCheckBoxMenuItem)e.getSource()).getText());
+ base.onBoardOrPortChange();
}
/*
@@ -1818,7 +1822,7 @@ public class Editor extends JFrame implements RunnerListener {
internalCloseRunner();
running = true;
toolbar.activate(EditorToolbar.RUN);
- statusNotice("Compiling...");
+ status.progress("Compiling sketch...");
// do this to advance/clear the terminal window / dos prompt / etc
for (int i = 0; i < 10; i++) System.out.println();
@@ -1838,12 +1842,14 @@ public class Editor extends JFrame implements RunnerListener {
public void run() {
try {
sketch.prepare();
- String appletClassName = sketch.build(false);
+ sketch.build(false);
statusNotice("Done compiling.");
} catch (Exception e) {
+ status.unprogress();
statusError(e);
}
+ status.unprogress();
toolbar.deactivate(EditorToolbar.RUN);
}
}
@@ -1853,12 +1859,14 @@ public class Editor extends JFrame implements RunnerListener {
public void run() {
try {
sketch.prepare();
- String appletClassName = sketch.build(true);
+ sketch.build(true);
statusNotice("Done compiling.");
} catch (Exception e) {
+ status.unprogress();
statusError(e);
}
+ status.unprogress();
toolbar.deactivate(EditorToolbar.RUN);
}
}
@@ -2311,6 +2319,7 @@ public class Editor extends JFrame implements RunnerListener {
0);
if (result == null) return false;
selectSerialPort(result);
+ base.onBoardOrPortChange();
return true;
}
@@ -2334,7 +2343,7 @@ public class Editor extends JFrame implements RunnerListener {
//if (!handleExportCheckModified()) return;
toolbar.activate(EditorToolbar.EXPORT);
console.clear();
- statusNotice("Uploading to I/O Board...");
+ status.progress("Uploading to I/O Board...");
new Thread(usingProgrammer ? exportAppHandler : exportHandler).start();
}
@@ -2363,10 +2372,12 @@ public class Editor extends JFrame implements RunnerListener {
} catch (RunnerException e) {
//statusError("Error during upload.");
//e.printStackTrace();
+ status.unprogress();
statusError(e);
} catch (Exception e) {
e.printStackTrace();
}
+ status.unprogress();
uploading = false;
//toolbar.clear();
toolbar.deactivate(EditorToolbar.EXPORT);
@@ -2397,10 +2408,12 @@ public class Editor extends JFrame implements RunnerListener {
} catch (RunnerException e) {
//statusError("Error during upload.");
//e.printStackTrace();
+ status.unprogress();
statusError(e);
} catch (Exception e) {
e.printStackTrace();
}
+ status.unprogress();
uploading = false;
//toolbar.clear();
toolbar.deactivate(EditorToolbar.EXPORT);
@@ -2615,30 +2628,49 @@ public class Editor extends JFrame implements RunnerListener {
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+ protected void onBoardOrPortChange() {
+ Map boardPreferences = Base.getBoardPreferences();
+ lineStatus.setBoardName(boardPreferences.get("name"));
+ lineStatus.setSerialPort(Preferences.get("serial.port"));
+ lineStatus.repaint();
+ }
+
/**
* Returns the edit popup menu.
*/
class TextAreaPopup extends JPopupMenu {
- //String currentDir = System.getProperty("user.dir");
- String referenceFile = null;
+ //private String currentDir = System.getProperty("user.dir");
+ private String referenceFile = null;
- JMenuItem cutItem;
- JMenuItem copyItem;
- JMenuItem discourseItem;
- JMenuItem referenceItem;
+ private JMenuItem cutItem;
+ private JMenuItem copyItem;
+ private JMenuItem discourseItem;
+ private JMenuItem referenceItem;
+ private JMenuItem openURLItem;
+ private JSeparator openURLItemSeparator;
+ private String clickedURL;
public TextAreaPopup() {
- JMenuItem item;
-
+ openURLItem = new JMenuItem("Open URL");
+ openURLItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ Base.openURL(clickedURL);
+ }
+ });
+ add(openURLItem);
+
+ openURLItemSeparator = new JSeparator();
+ add(openURLItemSeparator);
+
cutItem = new JMenuItem("Cut");
cutItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
handleCut();
}
});
- this.add(cutItem);
+ add(cutItem);
copyItem = new JMenuItem("Copy");
copyItem.addActionListener(new ActionListener() {
@@ -2646,7 +2678,7 @@ public class Editor extends JFrame implements RunnerListener {
handleCopy();
}
});
- this.add(copyItem);
+ add(copyItem);
discourseItem = new JMenuItem("Copy for Forum");
discourseItem.addActionListener(new ActionListener() {
@@ -2654,7 +2686,7 @@ public class Editor extends JFrame implements RunnerListener {
handleDiscourseCopy();
}
});
- this.add(discourseItem);
+ add(discourseItem);
discourseItem = new JMenuItem("Copy as HTML");
discourseItem.addActionListener(new ActionListener() {
@@ -2662,15 +2694,15 @@ public class Editor extends JFrame implements RunnerListener {
handleHTMLCopy();
}
});
- this.add(discourseItem);
+ add(discourseItem);
- item = new JMenuItem("Paste");
+ JMenuItem item = new JMenuItem("Paste");
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
handlePaste();
}
});
- this.add(item);
+ add(item);
item = new JMenuItem("Select All");
item.addActionListener(new ActionListener() {
@@ -2678,9 +2710,9 @@ public class Editor extends JFrame implements RunnerListener {
handleSelectAll();
}
});
- this.add(item);
+ add(item);
- this.addSeparator();
+ addSeparator();
item = new JMenuItem("Comment/Uncomment");
item.addActionListener(new ActionListener() {
@@ -2688,7 +2720,7 @@ public class Editor extends JFrame implements RunnerListener {
handleCommentUncomment();
}
});
- this.add(item);
+ add(item);
item = new JMenuItem("Increase Indent");
item.addActionListener(new ActionListener() {
@@ -2696,7 +2728,7 @@ public class Editor extends JFrame implements RunnerListener {
handleIndentOutdent(true);
}
});
- this.add(item);
+ add(item);
item = new JMenuItem("Decrease Indent");
item.addActionListener(new ActionListener() {
@@ -2704,9 +2736,9 @@ public class Editor extends JFrame implements RunnerListener {
handleIndentOutdent(false);
}
});
- this.add(item);
+ add(item);
- this.addSeparator();
+ addSeparator();
referenceItem = new JMenuItem("Find in Reference");
referenceItem.addActionListener(new ActionListener() {
@@ -2714,11 +2746,23 @@ public class Editor extends JFrame implements RunnerListener {
handleFindReference();
}
});
- this.add(referenceItem);
+ add(referenceItem);
}
// if no text is selected, disable copy and cut menu items
public void show(Component component, int x, int y) {
+ int lineNo = textarea.getLineOfOffset(textarea.xyToOffset(x, y));
+ int offset = textarea.xToOffset(lineNo, x);
+ String line = textarea.getLineText(lineNo);
+ clickedURL = textarea.checkClickedURL(line, offset);
+ if (clickedURL != null) {
+ openURLItem.setVisible(true);
+ openURLItemSeparator.setVisible(true);
+ } else {
+ openURLItem.setVisible(false);
+ openURLItemSeparator.setVisible(false);
+ }
+
if (textarea.isSelectionActive()) {
cutItem.setEnabled(true);
copyItem.setEnabled(true);
diff --git a/app/src/processing/app/EditorLineStatus.java b/app/src/processing/app/EditorLineStatus.java
index f28175ff0..2fcb8c917 100644
--- a/app/src/processing/app/EditorLineStatus.java
+++ b/app/src/processing/app/EditorLineStatus.java
@@ -25,6 +25,9 @@ package processing.app;
import processing.app.syntax.*;
import java.awt.*;
+import java.awt.geom.Rectangle2D;
+import java.util.Map;
+
import javax.swing.*;
@@ -39,10 +42,14 @@ public class EditorLineStatus extends JComponent {
Color foreground;
Color background;
+ Color messageForeground;
+
Font font;
int high;
String text = "";
+ String name = "";
+ String serialport = "";
public EditorLineStatus(JEditTextArea textarea) {
@@ -87,6 +94,11 @@ public class EditorLineStatus extends JComponent {
public void paintComponent(Graphics g) {
+ if (name=="" && serialport=="") {
+ Map boardPreferences = Base.getBoardPreferences();
+ setBoardName(boardPreferences.get("name"));
+ setSerialPort(Preferences.get("serial.port"));
+ }
g.setColor(background);
Dimension size = getSize();
g.fillRect(0, 0, size.width, size.height);
@@ -96,11 +108,20 @@ public class EditorLineStatus extends JComponent {
int baseline = (high + g.getFontMetrics().getAscent()) / 2;
g.drawString(text, 6, baseline);
+ g.setColor(messageForeground);
+ String tmp = name + " on " + serialport;
+
+ Rectangle2D bounds = g.getFontMetrics().getStringBounds(tmp, null);
+
+ g.drawString(tmp, size.width - (int) bounds.getWidth() -20 , baseline);
+
if (Base.isMacOS()) {
g.drawImage(resize, size.width - 20, 0, this);
}
}
+ public void setBoardName(String name) { this.name = name; }
+ public void setSerialPort(String serialport) { this.serialport = serialport; }
public Dimension getPreferredSize() {
return new Dimension(300, high);
diff --git a/app/src/processing/app/EditorStatus.java b/app/src/processing/app/EditorStatus.java
index a7035ab7c..a335b9230 100644
--- a/app/src/processing/app/EditorStatus.java
+++ b/app/src/processing/app/EditorStatus.java
@@ -40,6 +40,7 @@ public class EditorStatus extends JPanel /*implements ActionListener*/ {
//static final int PROMPT = 2;
//static final int EDIT = 3;
static final int EDIT = 2;
+ static final int PROGRESS = 5;
static final int YES = 1;
static final int NO = 2;
@@ -66,6 +67,7 @@ public class EditorStatus extends JPanel /*implements ActionListener*/ {
JButton cancelButton;
JButton okButton;
JTextField editField;
+ JProgressBar progressBar;
//Thread promptThread;
int response;
@@ -76,16 +78,22 @@ public class EditorStatus extends JPanel /*implements ActionListener*/ {
empty();
if (bgcolor == null) {
- bgcolor = new Color[3]; //4];
+ bgcolor = new Color[6];
bgcolor[0] = Theme.getColor("status.notice.bgcolor");
bgcolor[1] = Theme.getColor("status.error.bgcolor");
bgcolor[2] = Theme.getColor("status.edit.bgcolor");
+ bgcolor[3] = null;
+ bgcolor[4] = null;
+ bgcolor[5] = Theme.getColor("status.notice.bgcolor");
- fgcolor = new Color[3]; //4];
+ fgcolor = new Color[6];
fgcolor[0] = Theme.getColor("status.notice.fgcolor");
fgcolor[1] = Theme.getColor("status.error.fgcolor");
fgcolor[2] = Theme.getColor("status.edit.fgcolor");
- }
+ fgcolor[3] = null;
+ fgcolor[4] = null;
+ fgcolor[5] = Theme.getColor("status.notice.fgcolor");
+}
}
@@ -163,6 +171,54 @@ public class EditorStatus extends JPanel /*implements ActionListener*/ {
empty();
}
+ public void progress(String message)
+ {
+ mode = PROGRESS;
+ this.message = message;
+ progressBar.setIndeterminate(false);
+ progressBar.setVisible(true);
+ setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+ repaint();
+ }
+
+
+ public void progressIndeterminate(String message)
+ {
+ mode = PROGRESS;
+ this.message = message;
+ progressBar.setIndeterminate(true);
+ progressBar.setValue(50);
+ progressBar.setVisible(true);
+ setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+ repaint();
+ }
+
+
+ public void progressNotice(String message) {
+ //mode = NOTICE;
+ this.message = message;
+ //update();
+ repaint();
+ }
+
+
+ public void unprogress()
+ {
+ if (Preferences.getBoolean("editor.beep.compile")) {
+ Toolkit.getDefaultToolkit().beep();
+ }
+ progressBar.setVisible(false);
+ progressBar.setValue(0);
+ setCursor(null);
+ //empty();
+ }
+
+
+ public void progressUpdate(int value)
+ {
+ progressBar.setValue(value);
+ repaint();
+ }
/*
public void update() {
@@ -369,6 +425,19 @@ public class EditorStatus extends JPanel /*implements ActionListener*/ {
});
add(editField);
editField.setVisible(false);
+
+ progressBar = new JProgressBar(JScrollBar.HORIZONTAL);
+ progressBar.setIndeterminate(false);
+ if (Base.isMacOS()) {
+ //progressBar.setBackground(bgcolor[PROGRESS]);
+ //progressBar.putClientProperty("JProgressBar.style", "circular");
+ }
+ progressBar.setValue(0);
+ progressBar.setBorderPainted(true);
+ //progressBar.setStringPainted(true);
+ add(progressBar);
+ progressBar.setVisible(false);
+
}
}
@@ -385,11 +454,13 @@ public class EditorStatus extends JPanel /*implements ActionListener*/ {
//noButton.setLocation(noLeft, top);
cancelButton.setLocation(cancelLeft, top);
okButton.setLocation(noLeft, top);
+ progressBar.setLocation(noLeft, top);
//yesButton.setSize(Preferences.BUTTON_WIDTH, Preferences.BUTTON_HEIGHT);
//noButton.setSize(Preferences.BUTTON_WIDTH, Preferences.BUTTON_HEIGHT);
cancelButton.setSize(Preferences.BUTTON_WIDTH, Preferences.BUTTON_HEIGHT);
okButton.setSize(Preferences.BUTTON_WIDTH, Preferences.BUTTON_HEIGHT);
+ progressBar.setSize(2*Preferences.BUTTON_WIDTH, Preferences.BUTTON_HEIGHT);
// edit field height is awkward, and very different between mac and pc,
// so use at least the preferred height for now.
@@ -398,6 +469,7 @@ public class EditorStatus extends JPanel /*implements ActionListener*/ {
int editTop = (1 + sizeH - editHeight) / 2; // add 1 for ceil
editField.setBounds(yesLeft - Preferences.BUTTON_WIDTH, editTop,
editWidth, editHeight);
+ progressBar.setBounds(noLeft, editTop, editWidth, editHeight);
}
diff --git a/app/src/processing/app/EditorToolbar.java b/app/src/processing/app/EditorToolbar.java
index 9d7a5fc13..6b04aa2d9 100644
--- a/app/src/processing/app/EditorToolbar.java
+++ b/app/src/processing/app/EditorToolbar.java
@@ -170,6 +170,10 @@ public class EditorToolbar extends JComponent implements MouseInputListener, Key
x2[i] = x1[i] + BUTTON_WIDTH;
offsetX = x2[i];
}
+
+ // Serial button must be on the right
+ x1[SERIAL] = width - BUTTON_WIDTH - 14;
+ x2[SERIAL] = width - 14;
}
Graphics g = offscreen.getGraphics();
g.setColor(bgcolor); //getBackground());
@@ -194,9 +198,15 @@ public class EditorToolbar extends JComponent implements MouseInputListener, Key
g2.drawString(status, statusX, statusY);
*/
if (currentRollover != -1) {
- int statusY = (BUTTON_HEIGHT + g.getFontMetrics().getAscent()) / 2;
+ int statusY = (BUTTON_HEIGHT + g.getFontMetrics().getAscent()) / 2;
String status = shiftPressed ? titleShift[currentRollover] : title[currentRollover];
- g.drawString(status, buttonCount * BUTTON_WIDTH + 3 * BUTTON_GAP, statusY);
+ if (currentRollover != SERIAL)
+ g.drawString(status, (buttonCount-1) * BUTTON_WIDTH + 3 * BUTTON_GAP, statusY);
+ else {
+ int statusX = x1[SERIAL] - BUTTON_GAP;
+ statusX -= g.getFontMetrics().stringWidth(status);
+ g.drawString(status, statusX, statusY);
+ }
}
screen.drawImage(offscreen, 0, 0, null);
diff --git a/app/src/processing/app/Preferences.java b/app/src/processing/app/Preferences.java
index 4dd15c041..315620033 100644
--- a/app/src/processing/app/Preferences.java
+++ b/app/src/processing/app/Preferences.java
@@ -772,8 +772,9 @@ public class Preferences {
s = st.nextToken();
boolean bold = (s.indexOf("bold") != -1);
boolean italic = (s.indexOf("italic") != -1);
+ boolean underlined = (s.indexOf("underlined") != -1);
//System.out.println(what + " = " + str + " " + bold + " " + italic);
- return new SyntaxStyle(color, italic, bold);
+ return new SyntaxStyle(color, italic, bold, underlined);
}
}
diff --git a/app/src/processing/app/Sketch.java b/app/src/processing/app/Sketch.java
index 22e2aa591..93b8e40dc 100644
--- a/app/src/processing/app/Sketch.java
+++ b/app/src/processing/app/Sketch.java
@@ -1507,6 +1507,7 @@ public class Sketch {
throws RunnerException {
// run the preprocessor
+ editor.status.progressUpdate(20);
String primaryClassName = preprocess(buildPath);
// compile the program. errors will happen as a RunnerException
@@ -1552,6 +1553,7 @@ public class Sketch {
appletFolder.mkdirs();
// build the sketch
+ editor.status.progressNotice("Compiling sketch...");
String foundName = build(appletFolder.getPath(), false);
// (already reported) error during export, exit this function
if (foundName == null) return false;
@@ -1565,12 +1567,18 @@ public class Sketch {
// return false;
// }
+ editor.status.progressNotice("Uploading...");
upload(appletFolder.getPath(), foundName, usingProgrammer);
-
+ editor.status.progressUpdate(100);
return true;
}
+
+ public void setCompilingProgress(int percent) {
+ editor.status.progressUpdate(percent);
+ }
+
protected void size(String buildPath, String suggestedClassName)
throws RunnerException {
long size = 0;
diff --git a/app/src/processing/app/Theme.java b/app/src/processing/app/Theme.java
index 8b68f4f45..373b56835 100644
--- a/app/src/processing/app/Theme.java
+++ b/app/src/processing/app/Theme.java
@@ -196,7 +196,8 @@ public class Theme {
s = st.nextToken();
boolean bold = (s.indexOf("bold") != -1);
boolean italic = (s.indexOf("italic") != -1);
+ boolean underlined = (s.indexOf("underlined") != -1);
- return new SyntaxStyle(color, italic, bold);
+ return new SyntaxStyle(color, italic, bold, underlined);
}
}
\ No newline at end of file
diff --git a/app/src/processing/app/debug/Compiler.java b/app/src/processing/app/debug/Compiler.java
index bf972b8ea..559df3a61 100644
--- a/app/src/processing/app/debug/Compiler.java
+++ b/app/src/processing/app/debug/Compiler.java
@@ -91,19 +91,19 @@ public class Compiler implements MessageConsumer {
corePath = coreFolder.getAbsolutePath();
}
- String pins = boardPreferences.get("build.pins");
- String pinsPath = null;
+ String variant = boardPreferences.get("build.variant");
+ String variantPath = null;
- if (pins != null) {
- if (pins.indexOf(':') == -1) {
+ if (variant != null) {
+ if (variant.indexOf(':') == -1) {
Target t = Base.getTarget();
- File pinsFolder = new File(new File(t.getFolder(), "pins"), pins);
- pinsPath = pinsFolder.getAbsolutePath();
+ File variantFolder = new File(new File(t.getFolder(), "variants"), variant);
+ variantPath = variantFolder.getAbsolutePath();
} else {
- Target t = Base.targetsTable.get(pins.substring(0, pins.indexOf(':')));
- File pinsFolder = new File(t.getFolder(), "pins");
- pinsFolder = new File(pinsFolder, pins.substring(pins.indexOf(':') + 1));
- pinsPath = pinsFolder.getAbsolutePath();
+ Target t = Base.targetsTable.get(variant.substring(0, variant.indexOf(':')));
+ File variantFolder = new File(t.getFolder(), "variants");
+ variantFolder = new File(variantFolder, variant.substring(variant.indexOf(':') + 1));
+ variantPath = variantFolder.getAbsolutePath();
}
}
@@ -111,15 +111,17 @@ public class Compiler implements MessageConsumer {
// 0. include paths for core + all libraries
+ sketch.setCompilingProgress(20);
List includePaths = new ArrayList();
includePaths.add(corePath);
- if (pinsPath != null) includePaths.add(pinsPath);
+ if (variantPath != null) includePaths.add(variantPath);
for (File file : sketch.getImportedLibraries()) {
includePaths.add(file.getPath());
}
// 1. compile the sketch (already in the buildPath)
+ sketch.setCompilingProgress(30);
objectFiles.addAll(
compileFiles(avrBasePath, buildPath, includePaths,
findFilesInPath(buildPath, "S", false),
@@ -129,6 +131,7 @@ public class Compiler implements MessageConsumer {
// 2. compile the libraries, outputting .o files to: //
+ sketch.setCompilingProgress(40);
for (File libraryFolder : sketch.getImportedLibraries()) {
File outputFolder = new File(buildPath, libraryFolder.getName());
File utilityFolder = new File(libraryFolder, "utility");
@@ -156,9 +159,10 @@ public class Compiler implements MessageConsumer {
// 3. compile the core, outputting .o files to and then
// collecting them into the core.a library file.
+ sketch.setCompilingProgress(50);
includePaths.clear();
includePaths.add(corePath); // include path for core only
- if (pinsPath != null) includePaths.add(pinsPath);
+ if (variantPath != null) includePaths.add(variantPath);
List coreObjectFiles =
compileFiles(avrBasePath, buildPath, includePaths,
findFilesInPath(corePath, "S", true),
@@ -180,6 +184,7 @@ public class Compiler implements MessageConsumer {
// 4. link it all together into the .elf file
+ sketch.setCompilingProgress(60);
List baseCommandLinker = new ArrayList(Arrays.asList(new String[] {
avrBasePath + "avr-gcc",
"-Os",
@@ -208,6 +213,7 @@ public class Compiler implements MessageConsumer {
List commandObjcopy;
// 5. extract EEPROM data (from EEMEM directive) to .eep file.
+ sketch.setCompilingProgress(70);
commandObjcopy = new ArrayList(baseCommandObjcopy);
commandObjcopy.add(2, "ihex");
commandObjcopy.set(3, "-j");
@@ -221,6 +227,7 @@ public class Compiler implements MessageConsumer {
execAsynchronously(commandObjcopy);
// 6. build the .hex file
+ sketch.setCompilingProgress(80);
commandObjcopy = new ArrayList(baseCommandObjcopy);
commandObjcopy.add(2, "ihex");
commandObjcopy.add(".eeprom"); // remove eeprom data
@@ -228,6 +235,8 @@ public class Compiler implements MessageConsumer {
commandObjcopy.add(buildPath + File.separator + primaryClassName + ".hex");
execAsynchronously(commandObjcopy);
+ sketch.setCompilingProgress(90);
+
return true;
}
diff --git a/app/src/processing/app/syntax/JEditTextArea.java b/app/src/processing/app/syntax/JEditTextArea.java
index d5c01c48a..3c1548fbd 100644
--- a/app/src/processing/app/syntax/JEditTextArea.java
+++ b/app/src/processing/app/syntax/JEditTextArea.java
@@ -2045,6 +2045,17 @@ public class JEditTextArea extends JComponent
}
}
+ public String checkClickedURL(String line, int offset) {
+ String[] parse = SyntaxUtilities.parseCommentUrls(line);
+ if (parse==null)
+ return null;
+ int start = parse[0].length();
+ int stop = start + parse[1].length();
+ if (offsetstop)
+ return null;
+ return parse[1];
+ }
+
class MouseHandler extends MouseAdapter
{
public void mousePressed(MouseEvent evt)
@@ -2095,6 +2106,13 @@ public class JEditTextArea extends JComponent
private void doSingleClick(MouseEvent evt, int line,
int offset, int dot) {
+ // Check for click on urls
+ String clickedURL = checkClickedURL(getLineText(line), offset);
+ if (clickedURL != null) {
+ Base.openURL(clickedURL);
+ return;
+ }
+
if ((evt.getModifiers() & InputEvent.SHIFT_MASK) != 0) {
rectSelect = (evt.getModifiers() & InputEvent.CTRL_MASK) != 0;
select(getMarkPosition(),dot);
diff --git a/app/src/processing/app/syntax/PdeTextAreaDefaults.java b/app/src/processing/app/syntax/PdeTextAreaDefaults.java
index b715255be..382c69aaf 100644
--- a/app/src/processing/app/syntax/PdeTextAreaDefaults.java
+++ b/app/src/processing/app/syntax/PdeTextAreaDefaults.java
@@ -169,6 +169,9 @@ public class PdeTextAreaDefaults extends TextAreaDefaults {
// ??
styles[Token.LABEL] = Theme.getStyle("label");
+ // http://arduino.cc/
+ styles[Token.URL] = Theme.getStyle("url");
+
// + - = /
styles[Token.OPERATOR] = Theme.getStyle("operator");
diff --git a/app/src/processing/app/syntax/SyntaxStyle.java b/app/src/processing/app/syntax/SyntaxStyle.java
index 56323c3cc..ac3dd797d 100644
--- a/app/src/processing/app/syntax/SyntaxStyle.java
+++ b/app/src/processing/app/syntax/SyntaxStyle.java
@@ -10,6 +10,10 @@
package processing.app.syntax;
import java.awt.*;
+import java.awt.font.TextAttribute;
+import java.util.Hashtable;
+import java.util.Map;
+
import javax.swing.JComponent;
@@ -27,11 +31,12 @@ public class SyntaxStyle
* @param italic True if the text should be italics
* @param bold True if the text should be bold
*/
- public SyntaxStyle(Color color, boolean italic, boolean bold)
+ public SyntaxStyle(Color color, boolean italic, boolean bold, boolean underlined)
{
this.color = color;
this.italic = italic;
this.bold = bold;
+ this.underlined = underlined;
}
/**
@@ -47,7 +52,7 @@ public class SyntaxStyle
*/
public boolean isPlain()
{
- return !(bold || italic);
+ return !(bold || italic || underlined);
}
/**
@@ -67,7 +72,14 @@ public class SyntaxStyle
}
/**
- * Returns the specified font, but with the style's bold and
+ * @return true if underline is enabled for this style.
+ */
+ public boolean isUnderlined() {
+ return underlined;
+ }
+
+ /**
+ * Returns the specified font, but with the style's bold, underline and
* italic flags applied.
*/
public Font getStyledFont(Font font)
@@ -78,10 +90,16 @@ public class SyntaxStyle
if(font.equals(lastFont))
return lastStyledFont;
lastFont = font;
+
lastStyledFont = new Font(font.getFamily(),
(bold ? Font.BOLD : 0)
| (italic ? Font.ITALIC : 0),
font.getSize());
+ if (underlined) {
+ Map attr = new Hashtable();
+ attr.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
+ lastStyledFont = lastStyledFont.deriveFont(attr);
+ }
return lastStyledFont;
}
@@ -100,6 +118,11 @@ public class SyntaxStyle
(bold ? Font.BOLD : 0)
| (italic ? Font.ITALIC : 0),
font.getSize());
+ if (underlined) {
+ Map attr = new Hashtable();
+ attr.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
+ lastStyledFont = lastStyledFont.deriveFont(attr);
+ }
//fontMetrics = Toolkit.getDefaultToolkit().getFontMetrics(lastStyledFont);
fontMetrics = comp.getFontMetrics(lastStyledFont);
return fontMetrics;
@@ -125,13 +148,16 @@ public class SyntaxStyle
{
return getClass().getName() + "[color=" + color +
(italic ? ",italic" : "") +
- (bold ? ",bold" : "") + "]";
+ (bold ? ",bold" : "") +
+ (underlined ? ",underlined" : "") +
+ "]";
}
// private members
private Color color;
private boolean italic;
private boolean bold;
+ private boolean underlined;
private Font lastFont;
private Font lastStyledFont;
private FontMetrics fontMetrics;
diff --git a/app/src/processing/app/syntax/SyntaxUtilities.java b/app/src/processing/app/syntax/SyntaxUtilities.java
index 5225d0b73..1e3c6c900 100644
--- a/app/src/processing/app/syntax/SyntaxUtilities.java
+++ b/app/src/processing/app/syntax/SyntaxUtilities.java
@@ -11,6 +11,8 @@ package processing.app.syntax;
import javax.swing.text.*;
import java.awt.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
@@ -93,16 +95,17 @@ public class SyntaxUtilities
{
SyntaxStyle[] styles = new SyntaxStyle[Token.ID_COUNT];
- styles[Token.COMMENT1] = new SyntaxStyle(Color.black,true,false);
- styles[Token.COMMENT2] = new SyntaxStyle(new Color(0x990033),true,false);
- styles[Token.KEYWORD1] = new SyntaxStyle(Color.black,false,true);
- styles[Token.KEYWORD2] = new SyntaxStyle(Color.magenta,false,false);
- styles[Token.KEYWORD3] = new SyntaxStyle(new Color(0x009600),false,false);
- styles[Token.LITERAL1] = new SyntaxStyle(new Color(0x650099),false,false);
- styles[Token.LITERAL2] = new SyntaxStyle(new Color(0x650099),false,true);
- styles[Token.LABEL] = new SyntaxStyle(new Color(0x990033),false,true);
- styles[Token.OPERATOR] = new SyntaxStyle(Color.black,false,true);
- styles[Token.INVALID] = new SyntaxStyle(Color.red,false,true);
+ styles[Token.COMMENT1] = new SyntaxStyle(Color.black,true,false,false);
+ styles[Token.COMMENT2] = new SyntaxStyle(new Color(0x990033),true,false,false);
+ styles[Token.KEYWORD1] = new SyntaxStyle(Color.black,false,true,false);
+ styles[Token.KEYWORD2] = new SyntaxStyle(Color.magenta,false,false,false);
+ styles[Token.KEYWORD3] = new SyntaxStyle(new Color(0x009600),false,false,false);
+ styles[Token.LITERAL1] = new SyntaxStyle(new Color(0x650099),false,false,false);
+ styles[Token.LITERAL2] = new SyntaxStyle(new Color(0x650099),false,true,false);
+ styles[Token.LABEL] = new SyntaxStyle(new Color(0x990033),false,true,false);
+ styles[Token.OPERATOR] = new SyntaxStyle(Color.black,false,true,false);
+ styles[Token.URL] = new SyntaxStyle(Color.blue,true,false,false);
+ styles[Token.INVALID] = new SyntaxStyle(Color.red,false,true,false);
return styles;
}
@@ -148,7 +151,10 @@ public class SyntaxUtilities
styles[id].setGraphicsFlags(gfx,defaultFont);
line.count = length;
- x = Utilities.drawTabbedText(line,x,y,gfx,expander,0);
+ if (id == Token.COMMENT1 || id == Token.COMMENT2)
+ x = drawTabbedCommentsText(line, x, y, gfx, expander, styles, styles[id]);
+ else
+ x = Utilities.drawTabbedText(line, x, y, gfx, expander, 0);
line.offset += length;
offset += length;
@@ -158,6 +164,66 @@ public class SyntaxUtilities
return x;
}
+ /**
+ * Parse comments and identify "@schematics <something>" pattern.
+ *
+ * @param line
+ * A string to parse
+ * @return null if the pattern is not found, otherwise an array of
+ * String is returned: the elements with index 0, 1 and 2 are
+ * respectively the preamble, the <something> stuff, and
+ * the remaining part of the string.
+ */
+ public static String[] parseCommentUrls(String line) {
+ Matcher m = urlPattern.matcher(line.toString());
+ if (!m.find())
+ return null;
+
+ String res[] = new String[3];
+ res[0] = line.substring(0, m.start(1));
+ res[1] = line.substring(m.start(1), m.end(1));
+ res[2] = line.substring(m.end(1));
+ // System.out.println("0 =>"+res[0]+"<\n1 =>"+res[1]+"< \n2 =>"+res[2]+"<");
+ return res;
+ }
+
+ static private Pattern urlPattern = Pattern.compile(
+ "((?:https?|ftp)://" + // ( Protocol
+ "(?:(?:[\\w_\\-]+:)?[\\w_\\-]+@)?" + // Username and password
+ "(?:[\\w_\\-]+\\.)+[\\w_\\-]+" + // Domain name
+ "(?::[0-9]{1,5})?" + // Port
+ "(?:/[\\w_\\-./?%&=+]*)?)" + // Path )
+ "(?:\\s|$)"); // whitespace or EOL
+
+ public static Segment stringToSegment(String v) {
+ return new Segment(v.toCharArray(), 0, v.length());
+ }
+
+ private static int drawTabbedCommentsText(Segment line, int x, int y,
+ Graphics gfx, TabExpander expander, SyntaxStyle[] styles,
+ SyntaxStyle commentStyle) {
+
+ String parse[] = parseCommentUrls(line.toString());
+ if (parse == null)
+ // Revert to plain writing.
+ return Utilities.drawTabbedText(line, x, y, gfx, expander, 0);
+ Segment pre = stringToSegment(parse[0]);
+ Segment tag = stringToSegment(parse[1]);
+ Segment post = stringToSegment(parse[2]);
+
+ if (pre.count>0)
+ x = Utilities.drawTabbedText(pre, x, y, gfx, expander, 0);
+
+ Font f = gfx.getFont();
+ styles[Token.URL].setGraphicsFlags(gfx, f);
+ x = Utilities.drawTabbedText(tag, x, y, gfx, expander, 0);
+
+ commentStyle.setGraphicsFlags(gfx, f);
+ if (post.count>0)
+ x = Utilities.drawTabbedText(post, x, y, gfx, expander, 0);
+ return x;
+ }
+
// private members
private SyntaxUtilities() {}
}
diff --git a/app/src/processing/app/syntax/Token.java b/app/src/processing/app/syntax/Token.java
index a0f73bebf..06dc26323 100644
--- a/app/src/processing/app/syntax/Token.java
+++ b/app/src/processing/app/syntax/Token.java
@@ -83,17 +83,22 @@ public class Token
*/
public static final byte OPERATOR = 9;
+ /**
+ * URL token id.
+ */
+ public static final byte URL = 10;
+
/**
* Invalid token id. This can be used to mark invalid
* or incomplete tokens, so the user can easily spot
* syntax errors.
*/
- public static final byte INVALID = 10;
+ public static final byte INVALID = 11;
/**
* The total number of defined token ids.
*/
- public static final byte ID_COUNT = 11;
+ public static final byte ID_COUNT = 12;
/**
* The first id that can be used for internal state
diff --git a/build/macosx/template.app/Contents/Info.plist b/build/macosx/template.app/Contents/Info.plist
index 45809f544..2233d7278 100755
--- a/build/macosx/template.app/Contents/Info.plist
+++ b/build/macosx/template.app/Contents/Info.plist
@@ -7,11 +7,11 @@
CFBundleGetInfoString
- 1.0-beta1
+ 1.0-beta2
CFBundleVersion
0100
CFBundleShortVersionString
- 1.0-beta1
+ 1.0-beta2
CFBundleAllowMixedLocalizations
diff --git a/build/shared/lib/keywords.txt b/build/shared/lib/keywords.txt
index 8859d3b84..730de4e75 100644
--- a/build/shared/lib/keywords.txt
+++ b/build/shared/lib/keywords.txt
@@ -172,6 +172,13 @@ print KEYWORD2 Serial_Print
println KEYWORD2 Serial_Println
available KEYWORD2 Serial_Available
flush KEYWORD2 Serial_Flush
+setTimeout KEYWORD2
+find KEYWORD2
+findUntil KEYWORD2
+parseInt KEYWORD2
+parseFloat KEYWORD2
+readBytes KEYWORD2
+readBytesUntil KEYWORD2
setup KEYWORD3 Setup
loop KEYWORD3 Loop
diff --git a/build/shared/lib/theme/theme.txt b/build/shared/lib/theme/theme.txt
index a0889e64a..d8f5b7aa4 100644
--- a/build/shared/lib/theme/theme.txt
+++ b/build/shared/lib/theme/theme.txt
@@ -83,6 +83,9 @@ editor.literal1.style = #006699,plain
# p5 built in variables: e.g. mouseX, width, pixels
editor.literal2.style = #006699,plain
+# http://arduino.cc/
+editor.url.style = #0000ff,underlined
+
# e.g. + - = /
editor.operator.style = #000000,plain
diff --git a/hardware/arduino/boards.txt b/hardware/arduino/boards.txt
index 88a71433d..7adac6233 100644
--- a/hardware/arduino/boards.txt
+++ b/hardware/arduino/boards.txt
@@ -14,11 +14,11 @@ uno.bootloader.lock_bits=0x0F
uno.build.mcu=atmega328p
uno.build.f_cpu=16000000L
uno.build.core=arduino
-uno.build.pins=standard
+uno.build.variant=standard
##############################################################
-atmega328.name=Arduino Duemilanove or Nano w/ ATmega328
+atmega328.name=Arduino Duemilanove w/ ATmega328
atmega328.upload.protocol=stk500
atmega328.upload.maximum_size=30720
@@ -35,11 +35,11 @@ atmega328.bootloader.lock_bits=0x0F
atmega328.build.mcu=atmega328p
atmega328.build.f_cpu=16000000L
atmega328.build.core=arduino
-atmega328.build.pins=standard
+atmega328.build.variant=standard
##############################################################
-diecimila.name=Arduino Diecimila, Duemilanove, or Nano w/ ATmega168
+diecimila.name=Arduino Diecimila or Duemilanove w/ ATmega168
diecimila.upload.protocol=stk500
diecimila.upload.maximum_size=14336
@@ -56,7 +56,49 @@ diecimila.bootloader.lock_bits=0x0F
diecimila.build.mcu=atmega168
diecimila.build.f_cpu=16000000L
diecimila.build.core=arduino
-diecimila.build.pins=standard
+diecimila.build.variant=standard
+
+##############################################################
+
+nano328.name=Arduino Nano w/ ATmega328
+
+nano328.upload.protocol=stk500
+nano328.upload.maximum_size=30720
+nano328.upload.speed=57600
+
+nano328.bootloader.low_fuses=0xFF
+nano328.bootloader.high_fuses=0xDA
+nano328.bootloader.extended_fuses=0x05
+nano328.bootloader.path=atmega
+nano328.bootloader.file=ATmegaBOOT_168_atmega328.hex
+nano328.bootloader.unlock_bits=0x3F
+nano328.bootloader.lock_bits=0x0F
+
+nano328.build.mcu=atmega328p
+nano328.build.f_cpu=16000000L
+nano328.build.core=arduino
+nano328.build.variant=eightanaloginputs
+
+##############################################################
+
+nano.name=Arduino Nano w/ ATmega168
+
+nano.upload.protocol=stk500
+nano.upload.maximum_size=14336
+nano.upload.speed=19200
+
+nano.bootloader.low_fuses=0xff
+nano.bootloader.high_fuses=0xdd
+nano.bootloader.extended_fuses=0x00
+nano.bootloader.path=atmega
+nano.bootloader.file=ATmegaBOOT_168_diecimila.hex
+nano.bootloader.unlock_bits=0x3F
+nano.bootloader.lock_bits=0x0F
+
+nano.build.mcu=atmega168
+nano.build.f_cpu=16000000L
+nano.build.core=arduino
+nano.build.variant=eightanaloginputs
##############################################################
@@ -77,7 +119,7 @@ mega2560.bootloader.lock_bits=0x0F
mega2560.build.mcu=atmega2560
mega2560.build.f_cpu=16000000L
mega2560.build.core=arduino
-mega2560.build.pins=mega
+mega2560.build.variant=mega
##############################################################
@@ -98,7 +140,7 @@ mega.bootloader.lock_bits=0x0F
mega.build.mcu=atmega1280
mega.build.f_cpu=16000000L
mega.build.core=arduino
-mega.build.pins=mega
+mega.build.variant=mega
##############################################################
@@ -119,7 +161,7 @@ mini.bootloader.lock_bits=0x0F
mini.build.mcu=atmega168
mini.build.f_cpu=16000000L
mini.build.core=arduino
-mini.build.pins=standard
+mini.build.variant=eightanaloginputs
##############################################################
@@ -140,7 +182,7 @@ fio.bootloader.lock_bits=0x0F
fio.build.mcu=atmega328p
fio.build.f_cpu=8000000L
fio.build.core=arduino
-fio.build.pins=standard
+fio.build.variant=eightanaloginputs
##############################################################
@@ -162,7 +204,7 @@ bt328.bootloader.lock_bits=0x0F
bt328.build.mcu=atmega328p
bt328.build.f_cpu=16000000L
bt328.build.core=arduino
-bt328.build.pins=standard
+bt328.build.variant=eightanaloginputs
##############################################################
@@ -184,7 +226,7 @@ bt.bootloader.lock_bits=0x0F
bt.build.mcu=atmega168
bt.build.f_cpu=16000000L
bt.build.core=arduino
-bt.build.pins=standard
+bt.build.variant=eightanaloginputs
##############################################################
@@ -205,7 +247,7 @@ lilypad328.bootloader.lock_bits=0x0F
lilypad328.build.mcu=atmega328p
lilypad328.build.f_cpu=8000000L
lilypad328.build.core=arduino
-lilypad328.build.pins=standard
+lilypad328.build.variant=standard
##############################################################
@@ -226,7 +268,7 @@ lilypad.bootloader.lock_bits=0x0F
lilypad.build.mcu=atmega168
lilypad.build.f_cpu=8000000L
lilypad.build.core=arduino
-lilypad.build.pins=standard
+lilypad.build.variant=standard
##############################################################
@@ -247,7 +289,7 @@ pro5v328.bootloader.lock_bits=0x0F
pro5v328.build.mcu=atmega328p
pro5v328.build.f_cpu=16000000L
pro5v328.build.core=arduino
-pro5v328.build.pins=standard
+pro5v328.build.variant=standard
##############################################################
@@ -268,7 +310,7 @@ pro5v.bootloader.lock_bits=0x0F
pro5v.build.mcu=atmega168
pro5v.build.f_cpu=16000000L
pro5v.build.core=arduino
-pro5v.build.pins=standard
+pro5v.build.variant=standard
##############################################################
@@ -289,7 +331,7 @@ pro328.bootloader.lock_bits=0x0F
pro328.build.mcu=atmega328p
pro328.build.f_cpu=8000000L
pro328.build.core=arduino
-pro328.build.pins=standard
+pro328.build.variant=standard
##############################################################
@@ -310,7 +352,7 @@ pro.bootloader.lock_bits=0x0F
pro.build.mcu=atmega168
pro.build.f_cpu=8000000L
pro.build.core=arduino
-pro.build.pins=standard
+pro.build.variant=standard
##############################################################
@@ -331,7 +373,7 @@ atmega168.bootloader.lock_bits=0x0F
atmega168.build.mcu=atmega168
atmega168.build.f_cpu=16000000L
atmega168.build.core=arduino
-atmega168.build.pins=standard
+atmega168.build.variant=standard
##############################################################
@@ -351,4 +393,4 @@ atmega8.bootloader.lock_bits=0x0F
atmega8.build.mcu=atmega8
atmega8.build.f_cpu=16000000L
atmega8.build.core=arduino
-atmega8.build.pins=standard
+atmega8.build.variant=standard
diff --git a/hardware/arduino/cores/arduino/HardwareSerial.cpp b/hardware/arduino/cores/arduino/HardwareSerial.cpp
index db6b1490b..d6be2181c 100644
--- a/hardware/arduino/cores/arduino/HardwareSerial.cpp
+++ b/hardware/arduino/cores/arduino/HardwareSerial.cpp
@@ -352,12 +352,13 @@ void HardwareSerial::flush()
;
}
-void HardwareSerial::write(uint8_t c)
+size_t HardwareSerial::write(uint8_t c)
{
int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE;
// If the output buffer is full, there's nothing for it other than to
// wait for the interrupt handler to empty it a bit
+ // ???: return 0 here instead?
while (i == _tx_buffer->tail)
;
@@ -365,6 +366,8 @@ void HardwareSerial::write(uint8_t c)
_tx_buffer->head = i;
sbi(*_ucsrb, _udrie);
+
+ return 1;
}
// Preinstantiate Objects //////////////////////////////////////////////////////
diff --git a/hardware/arduino/cores/arduino/HardwareSerial.h b/hardware/arduino/cores/arduino/HardwareSerial.h
index eefdcbe16..1895f08f6 100644
--- a/hardware/arduino/cores/arduino/HardwareSerial.h
+++ b/hardware/arduino/cores/arduino/HardwareSerial.h
@@ -55,7 +55,7 @@ class HardwareSerial : public Stream
virtual int peek(void);
virtual int read(void);
virtual void flush(void);
- virtual void write(uint8_t);
+ virtual size_t write(uint8_t);
using Print::write; // pull in write(str) and write(buf, size) from Print
};
diff --git a/hardware/arduino/cores/arduino/Print.cpp b/hardware/arduino/cores/arduino/Print.cpp
index 06ac52a5e..8190d4fb4 100755
--- a/hardware/arduino/cores/arduino/Print.cpp
+++ b/hardware/arduino/cores/arduino/Print.cpp
@@ -30,167 +30,190 @@
// Public Methods //////////////////////////////////////////////////////////////
/* default implementation: may be overridden */
-void Print::write(const char *str)
+size_t Print::write(const char *str)
{
- while (*str)
- write(*str++);
+ size_t n = 0;
+ while (*str) {
+ n += write(*str++);
+ }
+ return n;
}
/* default implementation: may be overridden */
-void Print::write(const uint8_t *buffer, size_t size)
+size_t Print::write(const uint8_t *buffer, size_t size)
{
- while (size--)
- write(*buffer++);
+ size_t n = 0;
+ while (size--) {
+ n += write(*buffer++);
+ }
+ return n;
}
-void Print::print(const __FlashStringHelper *ifsh)
+size_t Print::print(const __FlashStringHelper *ifsh)
{
const prog_char *p = (const prog_char *)ifsh;
+ size_t n = 0;
while (1) {
unsigned char c = pgm_read_byte(p++);
- if (c == 0) return;
- write(c);
+ if (c == 0) break;
+ n += write(c);
}
+ return n;
}
-void Print::print(const String &s)
+size_t Print::print(const String &s)
{
+ size_t n = 0;
for (int i = 0; i < s.length(); i++) {
- write(s[i]);
+ n += write(s[i]);
}
+ return n;
}
-void Print::print(const char str[])
+size_t Print::print(const char str[])
{
- write(str);
+ return write(str);
}
-void Print::print(char c)
+size_t Print::print(char c)
{
- write(c);
+ return write(c);
}
-void Print::print(unsigned char b, int base)
+size_t Print::print(unsigned char b, int base)
{
- print((unsigned long) b, base);
+ return print((unsigned long) b, base);
}
-void Print::print(int n, int base)
+size_t Print::print(int n, int base)
{
- print((long) n, base);
+ return print((long) n, base);
}
-void Print::print(unsigned int n, int base)
+size_t Print::print(unsigned int n, int base)
{
- print((unsigned long) n, base);
+ return print((unsigned long) n, base);
}
-void Print::print(long n, int base)
+size_t Print::print(long n, int base)
{
if (base == 0) {
- write(n);
+ return write(n);
} else if (base == 10) {
if (n < 0) {
- print('-');
+ int t = print('-');
n = -n;
+ return printNumber(n, 10) + t;
}
- printNumber(n, 10);
+ return printNumber(n, 10);
} else {
- printNumber(n, base);
+ return printNumber(n, base);
}
}
-void Print::print(unsigned long n, int base)
+size_t Print::print(unsigned long n, int base)
{
- if (base == 0) write(n);
- else printNumber(n, base);
+ if (base == 0) return write(n);
+ else return printNumber(n, base);
}
-void Print::print(double n, int digits)
+size_t Print::print(double n, int digits)
{
- printFloat(n, digits);
+ return printFloat(n, digits);
}
-void Print::println(const __FlashStringHelper *ifsh)
+size_t Print::println(const __FlashStringHelper *ifsh)
{
- print(ifsh);
- println();
+ size_t n = print(ifsh);
+ n += println();
+ return n;
}
-void Print::print(const Printable& x)
+size_t Print::print(const Printable& x)
{
- x.printTo(*this);
+ return x.printTo(*this);
}
-void Print::println(void)
+size_t Print::println(void)
{
- print('\r');
- print('\n');
+ size_t n = print('\r');
+ n += print('\n');
+ return n;
}
-void Print::println(const String &s)
+size_t Print::println(const String &s)
{
- print(s);
- println();
+ size_t n = print(s);
+ n += println();
+ return n;
}
-void Print::println(const char c[])
+size_t Print::println(const char c[])
{
- print(c);
- println();
+ size_t n = print(c);
+ n += println();
+ return n;
}
-void Print::println(char c)
+size_t Print::println(char c)
{
- print(c);
- println();
+ size_t n = print(c);
+ n += println();
+ return n;
}
-void Print::println(unsigned char b, int base)
+size_t Print::println(unsigned char b, int base)
{
- print(b, base);
- println();
+ size_t n = print(b, base);
+ n += println();
+ return n;
}
-void Print::println(int n, int base)
+size_t Print::println(int num, int base)
{
- print(n, base);
- println();
+ size_t n = print(num, base);
+ n += println();
+ return n;
}
-void Print::println(unsigned int n, int base)
+size_t Print::println(unsigned int num, int base)
{
- print(n, base);
- println();
+ size_t n = print(num, base);
+ n += println();
+ return n;
}
-void Print::println(long n, int base)
+size_t Print::println(long num, int base)
{
- print(n, base);
- println();
+ size_t n = print(num, base);
+ n += println();
+ return n;
}
-void Print::println(unsigned long n, int base)
+size_t Print::println(unsigned long num, int base)
{
- print(n, base);
- println();
+ size_t n = print(num, base);
+ n += println();
+ return n;
}
-void Print::println(double n, int digits)
+size_t Print::println(double num, int digits)
{
- print(n, digits);
- println();
+ size_t n = print(num, digits);
+ n += println();
+ return n;
}
-void Print::println(const Printable& x)
+size_t Print::println(const Printable& x)
{
- print(x);
- println();
+ size_t n = print(x);
+ n += println();
+ return n;
}
// Private Methods /////////////////////////////////////////////////////////////
-void Print::printNumber(unsigned long n, uint8_t base) {
+size_t Print::printNumber(unsigned long n, uint8_t base) {
char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
char *str = &buf[sizeof(buf) - 1];
@@ -206,15 +229,17 @@ void Print::printNumber(unsigned long n, uint8_t base) {
*--str = c < 10 ? c + '0' : c + 'A' - 10;
} while(n);
- write(str);
+ return write(str);
}
-void Print::printFloat(double number, uint8_t digits)
+size_t Print::printFloat(double number, uint8_t digits)
{
+ size_t n = 0;
+
// Handle negative numbers
if (number < 0.0)
{
- print('-');
+ n += print('-');
number = -number;
}
@@ -228,18 +253,21 @@ void Print::printFloat(double number, uint8_t digits)
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
- print(int_part);
+ n += print(int_part);
// Print the decimal point, but only if there are digits beyond
- if (digits > 0)
- print(".");
+ if (digits > 0) {
+ n += print(".");
+ }
// Extract digits from the remainder one at a time
while (digits-- > 0)
{
remainder *= 10.0;
int toPrint = int(remainder);
- print(toPrint);
+ n += print(toPrint);
remainder -= toPrint;
}
+
+ return n;
}
diff --git a/hardware/arduino/cores/arduino/Print.h b/hardware/arduino/cores/arduino/Print.h
index bf10b1477..fce302e72 100755
--- a/hardware/arduino/cores/arduino/Print.h
+++ b/hardware/arduino/cores/arduino/Print.h
@@ -34,37 +34,45 @@
class Print
{
private:
- void printNumber(unsigned long, uint8_t);
- void printFloat(double, uint8_t);
+ int write_error;
+ size_t printNumber(unsigned long, uint8_t);
+ size_t printFloat(double, uint8_t);
+ protected:
+ void setWriteError(int err = 1) { write_error = err; }
public:
- virtual void write(uint8_t) = 0;
- virtual void write(const char *str);
- virtual void write(const uint8_t *buffer, size_t size);
+ Print() : write_error(0) {}
+
+ int writeError() { return write_error; }
+ void clearWriteError() { setWriteError(0); }
+
+ virtual size_t write(uint8_t) = 0;
+ virtual size_t write(const char *str);
+ virtual size_t write(const uint8_t *buffer, size_t size);
- void print(const __FlashStringHelper *);
- void print(const String &);
- void print(const char[]);
- void print(char);
- void print(unsigned char, int = DEC);
- void print(int, int = DEC);
- void print(unsigned int, int = DEC);
- void print(long, int = DEC);
- void print(unsigned long, int = DEC);
- void print(double, int = 2);
- void print(const Printable&);
+ size_t print(const __FlashStringHelper *);
+ size_t print(const String &);
+ size_t print(const char[]);
+ size_t print(char);
+ size_t print(unsigned char, int = DEC);
+ size_t print(int, int = DEC);
+ size_t print(unsigned int, int = DEC);
+ size_t print(long, int = DEC);
+ size_t print(unsigned long, int = DEC);
+ size_t print(double, int = 2);
+ size_t print(const Printable&);
- void println(const __FlashStringHelper *);
- void println(const String &s);
- void println(const char[]);
- void println(char);
- void println(unsigned char, int = DEC);
- void println(int, int = DEC);
- void println(unsigned int, int = DEC);
- void println(long, int = DEC);
- void println(unsigned long, int = DEC);
- void println(double, int = 2);
- void println(const Printable&);
- void println(void);
+ size_t println(const __FlashStringHelper *);
+ size_t println(const String &s);
+ size_t println(const char[]);
+ size_t println(char);
+ size_t println(unsigned char, int = DEC);
+ size_t println(int, int = DEC);
+ size_t println(unsigned int, int = DEC);
+ size_t println(long, int = DEC);
+ size_t println(unsigned long, int = DEC);
+ size_t println(double, int = 2);
+ size_t println(const Printable&);
+ size_t println(void);
};
#endif
diff --git a/hardware/arduino/cores/arduino/Printable.h b/hardware/arduino/cores/arduino/Printable.h
index 5ff607767..d03c9af62 100644
--- a/hardware/arduino/cores/arduino/Printable.h
+++ b/hardware/arduino/cores/arduino/Printable.h
@@ -33,8 +33,7 @@ class Print;
class Printable
{
public:
- virtual ~Printable() {};
- virtual void printTo(Print& p) const =0;
+ virtual size_t printTo(Print& p) const = 0;
};
#endif
diff --git a/hardware/arduino/cores/arduino/Stream.cpp b/hardware/arduino/cores/arduino/Stream.cpp
new file mode 100644
index 000000000..d267bf0cb
--- /dev/null
+++ b/hardware/arduino/cores/arduino/Stream.cpp
@@ -0,0 +1,233 @@
+/*
+ Stream.cpp - adds parsing methods to Stream class
+ Copyright (c) 2008 David A. Mellis. All right 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.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Created July 2011
+ parsing functions based on TextFinder library by Michael Margolis
+ */
+
+#include "Arduino.h"
+#include "Stream.h"
+
+#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
+#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field
+
+// 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();
+ }
+ }
+ return -1; // -1 indicates timeout
+}
+
+// returns the next digit in the stream or -1 if timeout
+// discards non-numeric characters
+int Stream::getNextDigit()
+{
+ int c;
+ do{
+ c = timedRead();
+ if( c < 0)
+ return c; // timeout
+ }
+ while( c != '-' && (c < '0' || c > '9') ) ;
+
+return c;
+}
+
+// Public Methods
+//////////////////////////////////////////////////////////////
+
+void Stream::setTimeout( long timeout) // sets the maximum number of milliseconds to wait
+{
+ this->_timeout = timeout;
+}
+
+ // find returns true if the target string is found
+bool Stream::find(char *target)
+{
+ return findUntil(target, NULL);
+}
+
+// reads data from the stream until the target string of given length is found
+// returns true if target string is found, false if timed out
+bool Stream::find(char *target, size_t length)
+{
+ return findUntil(target, length, NULL, 0);
+}
+
+// as find but search ends if the terminator string is found
+bool Stream::findUntil(char *target, char *terminator)
+{
+ return findUntil(target, strlen(target), terminator, strlen(terminator));
+}
+
+// reads data from the stream until the target string of the given length is found
+// search terminated if the terminator string is found
+// returns true if target string is found, false if terminated or timed out
+bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen)
+{
+ size_t index = 0; // maximum target string length is 64k bytes!
+ size_t termIndex = 0;
+ int c;
+
+ if( *target == 0)
+ return true; // return true if target is a null string
+ while( (c = timedRead()) > 0){
+ if( c == target[index]){
+ //////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1);
+ if(++index >= targetLen){ // return true if all chars in the target match
+ return true;
+ }
+ }
+ else{
+ index = 0; // reset index if any char does not match
+ }
+ if(termLen > 0 && c == terminator[termIndex]){
+ if(++termIndex >= termLen)
+ return false; // return false if terminate string found before target string
+ }
+ else
+ termIndex = 0;
+ }
+ return false;
+}
+
+
+// returns the first valid (long) integer value from the current position.
+// initial characters that are not digits (or the minus sign) are skipped
+// function is terminated by the first character that is not a digit.
+long Stream::parseInt()
+{
+ return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout)
+}
+
+// as above but a given skipChar is ignored
+// this allows format characters (typically commas) in values to be ignored
+long Stream::parseInt(char skipChar)
+{
+ boolean isNegative = false;
+ long value = 0;
+ int c;
+
+ c = getNextDigit();
+ // ignore non numeric leading characters
+ if(c < 0)
+ return 0; // zero returned if timeout
+
+ do{
+ if(c == skipChar)
+ ; // ignore this charactor
+ else if(c == '-')
+ isNegative = true;
+ else if(c >= '0' && c <= '9') // is c a digit?
+ value = value * 10 + c - '0';
+ c = timedRead();
+ }
+ while( (c >= '0' && c <= '9') || c == skipChar );
+
+ if(isNegative)
+ value = -value;
+ return value;
+}
+
+
+// as parseInt but returns a floating point value
+float Stream::parseFloat()
+{
+ parseFloat(NO_SKIP_CHAR);
+}
+
+// as above but the given skipChar is ignored
+// this allows format characters (typically commas) in values to be ignored
+float Stream::parseFloat(char skipChar){
+ boolean isNegative = false;
+ boolean isFraction = false;
+ long value = 0;
+ float fValue;
+ char c;
+ float fraction = 1.0;
+
+ c = getNextDigit();
+ // ignore non numeric leading characters
+ if(c < 0)
+ return 0; // zero returned if timeout
+
+ do{
+ if(c == skipChar)
+ ; // ignore
+ else if(c == '-')
+ isNegative = true;
+ else if (c == '.')
+ isFraction = true;
+ else if(c >= '0' && c <= '9') { // is c a digit?
+ value = value * 10 + c - '0';
+ if(isFraction)
+ fraction *= 0.1;
+ }
+ c = timedRead();
+ }
+ while( (c >= '0' && c <= '9') || c == '.' || c == skipChar );
+
+ if(isNegative)
+ value = -value;
+ if(isFraction)
+ return value * fraction;
+ else
+ return value;
+}
+
+// read characters from stream into buffer
+// terminates if length characters have been read, null is detected or timeout (see setTimeout)
+// returns the number of characters placed in the buffer (0 means no valid data found)
+int Stream::readBytes( char *buffer, size_t length)
+{
+ return readBytesUntil( 0, buffer, length);
+}
+
+
+// as readBytes with terminator character
+// terminates if length characters have been read, timeout, or if the terminator character detected
+// returns the number of characters placed in the buffer (0 means no valid data found)
+
+int Stream::readBytesUntil( char terminator, char *buffer, size_t length)
+{
+ int index = 0;
+ *buffer = 0;
+ while(index < length-1 ){
+ int c = timedRead();
+ if( c <= 0 ){
+ return 0; // timeout returns 0 !
+ }
+ else if( c == terminator){
+ buffer[index] = 0; // terminate the string
+ return index; // data got successfully
+ }
+ else{
+ buffer[index++] = (char)c;
+ }
+ }
+ buffer[index] = 0;
+ return index; // here if buffer is full before detecting the terminator
+}
+
diff --git a/hardware/arduino/cores/arduino/Stream.h b/hardware/arduino/cores/arduino/Stream.h
index 93d8275dc..1633f15d5 100644
--- a/hardware/arduino/cores/arduino/Stream.h
+++ b/hardware/arduino/cores/arduino/Stream.h
@@ -15,6 +15,8 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ parsing functions based on TextFinder library by Michael Margolis
*/
#ifndef Stream_h
@@ -23,13 +25,69 @@
#include
#include "Print.h"
+// compatability macros for testing
+/*
+#define getInt() parseInt()
+#define getInt(skipChar) parseInt(skipchar)
+#define getFloat() parseFloat()
+#define getFloat(skipChar) parseFloat(skipChar)
+#define getString( pre_string, post_string, buffer, length)
+readBytesBetween( pre_string, terminator, buffer, length)
+*/
+
class Stream : public Print
{
+ private:
+ 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
+
public:
virtual int available() = 0;
virtual int read() = 0;
virtual int peek() = 0;
virtual void flush() = 0;
+
+ Stream() {_timeout=1000;}
+
+// parsing methods
+
+ void setTimeout(long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second
+
+ bool find(char *target); // reads data from the stream until the target string is found
+ // returns true if target string is found, false if timed out (see setTimeout)
+
+ bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found
+ // returns true if target string is found, false if timed out
+
+ bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found
+
+ bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found
+
+
+ long parseInt(); // returns the first valid (long) integer value from the current position.
+ // initial characters that are not digits (or the minus sign) are skipped
+ // integer is terminated by the first character that is not a digit.
+
+ long parseInt(char skipChar); // as above but the given skipChar is ignored
+ // as above but the given skipChar is ignored
+ // this allows format characters (typically commas) in values to be ignored
+
+ float parseFloat(); // float version of parseInt
+
+ float parseFloat(char skipChar); // as above but the given skipChar is ignored
+
+ int readBytes( char *buffer, size_t length); // read chars from stream into buffer
+ // terminates if length characters have been read or timeout (see setTimeout)
+ // returns the number of characters placed in the buffer (0 means no valid data found)
+
+ int readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
+ // terminates if length characters have been read, timeout, or if the terminator character detected
+ // returns the number of characters placed in the buffer (0 means no valid data found)
+
+ // Arduino String functions to be added here
+
};
#endif
diff --git a/hardware/arduino/variants/eightanaloginputs/pins_arduino.h b/hardware/arduino/variants/eightanaloginputs/pins_arduino.h
new file mode 100644
index 000000000..52b37efc4
--- /dev/null
+++ b/hardware/arduino/variants/eightanaloginputs/pins_arduino.h
@@ -0,0 +1,27 @@
+/*
+ pins_arduino.h - Pin definition functions for Arduino
+ Part of Arduino - http://www.arduino.cc/
+
+ Copyright (c) 2007 David A. Mellis
+
+ 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.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ Boston, MA 02111-1307 USA
+
+ $Id: wiring.h 249 2007-02-03 16:52:51Z mellis $
+*/
+
+#include "../standard/pins_arduino.h"
+#undef NUM_ANALOG_INPUTS
+#define NUM_ANALOG_INPUTS 8
diff --git a/hardware/arduino/pins/mega/pins_arduino.h b/hardware/arduino/variants/mega/pins_arduino.h
similarity index 84%
rename from hardware/arduino/pins/mega/pins_arduino.h
rename to hardware/arduino/variants/mega/pins_arduino.h
index e3785e42f..237173adc 100644
--- a/hardware/arduino/pins/mega/pins_arduino.h
+++ b/hardware/arduino/variants/mega/pins_arduino.h
@@ -27,11 +27,20 @@
#include
+#define NUM_DIGITAL_PINS 70
+#define NUM_ANALOG_INPUTS 16
+#define analogInputToDigitalPin(p) ((p < 16) ? (p) + 54 : -1)
+#define digitalPinHasPWM(p) (((p) >= 2 && (p) <= 13) || ((p) >= 44 && (p)<= 46))
+
const static uint8_t SS = 53;
const static uint8_t MOSI = 51;
const static uint8_t MISO = 50;
const static uint8_t SCK = 52;
+const static uint8_t SDA = 20;
+const static uint8_t SCL = 21;
+const static uint8_t LED = 13;
+
const static uint8_t A0 = 54;
const static uint8_t A1 = 55;
const static uint8_t A2 = 56;
@@ -49,6 +58,31 @@ const static uint8_t A13 = 67;
const static uint8_t A14 = 68;
const static uint8_t A15 = 69;
+// A majority of the pins are NOT PCINTs, SO BE WARNED (i.e. you cannot use them as receive pins)
+// Only pins available for RECEIVE (TRANSMIT can be on any pin):
+// (I've deliberately left out pin mapping to the Hardware USARTs - seems senseless to me)
+// Pins: 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69
+
+#define digitalPinToPCICR(p) ( (((p) >= 10) && ((p) <= 13)) || \
+ (((p) >= 50) && ((p) <= 53)) || \
+ (((p) >= 62) && ((p) <= 69)) ? (&PCICR) : ((uint8_t *)0) )
+
+#define digitalPinToPCICRbit(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? 0 : \
+ ( (((p) >= 62) && ((p) <= 69)) ? 2 : \
+ 0 ) )
+
+#define digitalPinToPCMSK(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? (&PCMSK0) : \
+ ( (((p) >= 62) && ((p) <= 69)) ? (&PCMSK2) : \
+ ((uint8_t *)0) ) )
+
+#define digitalPinToPCMSKbit(p) ( (((p) >= 10) && ((p) <= 13)) ? ((p) - 6) : \
+ ( ((p) == 50) ? 3 : \
+ ( ((p) == 51) ? 2 : \
+ ( ((p) == 52) ? 1 : \
+ ( ((p) == 53) ? 0 : \
+ ( (((p) >= 62) && ((p) <= 69)) ? ((p) - 62) : \
+ 0 ) ) ) ) ) )
+
#ifdef ARDUINO_MAIN
const uint16_t PROGMEM port_to_mode_PGM[] = {
diff --git a/hardware/arduino/pins/standard/pins_arduino.h b/hardware/arduino/variants/standard/pins_arduino.h
similarity index 83%
rename from hardware/arduino/pins/standard/pins_arduino.h
rename to hardware/arduino/variants/standard/pins_arduino.h
index 8fabb1781..3999d1fcd 100644
--- a/hardware/arduino/pins/standard/pins_arduino.h
+++ b/hardware/arduino/variants/standard/pins_arduino.h
@@ -27,11 +27,25 @@
#include
+#define NUM_DIGITAL_PINS 20
+#define NUM_ANALOG_INPUTS 6
+#define analogInputToDigitalPin(p) ((p < 6) ? (p) + 14 : -1)
+
+#if defined(__AVR_ATmega8__)
+#define digitalPinHasPWM(p) ((p) == 9 || (p) == 10 || (p) == 11)
+#else
+#define digitalPinHasPWM(p) ((p) == 3 || (p) == 5 || (p) == 6 || (p) == 9 || (p) == 10 || (p) == 11)
+#endif
+
const static uint8_t SS = 10;
const static uint8_t MOSI = 11;
const static uint8_t MISO = 12;
const static uint8_t SCK = 13;
+const static uint8_t SDA = 18;
+const static uint8_t SCL = 19;
+const static uint8_t LED = 13;
+
const static uint8_t A0 = 14;
const static uint8_t A1 = 15;
const static uint8_t A2 = 16;
@@ -41,6 +55,11 @@ const static uint8_t A5 = 19;
const static uint8_t A6 = 20;
const static uint8_t A7 = 21;
+#define digitalPinToPCICR(p) (((p) >= 0 && (p) <= 21) ? (&PCICR) : ((uint8_t *)0))
+#define digitalPinToPCICRbit(p) (((p) <= 7) ? 2 : (((p) <= 13) ? 0 : 1))
+#define digitalPinToPCMSK(p) (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)0))))
+#define digitalPinToPCMSKbit(p) (((p) <= 7) ? (p) : (((p) <= 13) ? ((p) - 8) : ((p) - 14)))
+
#ifdef ARDUINO_MAIN
// On the Arduino board, digital pins are also used
diff --git a/libraries/ArduinoTestSuite/examples/ATS_Write_Print/ATS_Write_Print.ino b/libraries/ArduinoTestSuite/examples/ATS_Write_Print/ATS_Write_Print.ino
new file mode 100644
index 000000000..d7e47f179
--- /dev/null
+++ b/libraries/ArduinoTestSuite/examples/ATS_Write_Print/ATS_Write_Print.ino
@@ -0,0 +1,61 @@
+#include
+
+void Test_Equal(long actual, long expected)
+{
+ char buf[100];
+ boolean b = expected == actual;
+ ATS_PrintTestStatus("", b);
+ if (!b) {
+ Serial.print("expected '");
+ Serial.print(expected);
+ Serial.print("', actual '");
+ Serial.print(actual);
+ Serial.println("'");
+ }
+}
+
+void setup()
+{
+ byte buf[5] = { 65, 66, 67, 0, 69 };
+ ATS_begin("Arduino", "Write & Print Return Values Test");
+
+ Test_Equal(Serial.write('a'), 1);
+ Test_Equal(Serial.write(byte(0)), 1);
+ Test_Equal(Serial.write("abc"), 3);
+ Test_Equal(Serial.write(""), 0);
+ Test_Equal(Serial.write(buf, 5), 5);
+ Test_Equal(Serial.print(0), 1);
+ Test_Equal(Serial.print(""), 0);
+ Test_Equal(Serial.print("abc"), 3);
+ Test_Equal(Serial.print(0), 1);
+ Test_Equal(Serial.print(1), 1);
+ Test_Equal(Serial.print(11), 2);
+ Test_Equal(Serial.print(12345), 5);
+ Test_Equal(Serial.print(-1), 2);
+ Test_Equal(Serial.print(-123), 4);
+ Test_Equal(Serial.println(), 2);
+ Test_Equal(Serial.println(""), 2);
+ Test_Equal(Serial.println("abc"), 5);
+ Test_Equal(Serial.println(0), 3);
+ Test_Equal(Serial.println(1), 3);
+ Test_Equal(Serial.println(11), 4);
+ Test_Equal(Serial.println(12345), 7);
+ Test_Equal(Serial.println(-1), 4);
+ Test_Equal(Serial.println(-123), 6);
+
+ ATS_end();
+}
+
+void loop() {}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libraries/Ethernet/Client.cpp b/libraries/Ethernet/Client.cpp
index f146ac5ed..3c1c2503b 100644
--- a/libraries/Ethernet/Client.cpp
+++ b/libraries/Ethernet/Client.cpp
@@ -70,19 +70,24 @@ int Client::connect(IPAddress ip, uint16_t port) {
return 1;
}
-void Client::write(uint8_t b) {
- if (_sock != MAX_SOCK_NUM)
- send(_sock, &b, 1);
+size_t Client::write(uint8_t b) {
+ return write(&b, 1);
}
-void Client::write(const char *str) {
- if (_sock != MAX_SOCK_NUM)
- send(_sock, (const uint8_t *)str, strlen(str));
+size_t Client::write(const char *str) {
+ return write((const uint8_t *) str, strlen(str));
}
-void Client::write(const uint8_t *buf, size_t size) {
- if (_sock != MAX_SOCK_NUM)
- send(_sock, buf, size);
+size_t Client::write(const uint8_t *buf, size_t size) {
+ if (_sock == MAX_SOCK_NUM) {
+ setWriteError();
+ return 0;
+ }
+ if (!send(_sock, buf, size)) {
+ setWriteError();
+ return 0;
+ }
+ return size;
}
int Client::available() {
diff --git a/libraries/Ethernet/Client.h b/libraries/Ethernet/Client.h
index 582f4938a..a8dd6fa42 100644
--- a/libraries/Ethernet/Client.h
+++ b/libraries/Ethernet/Client.h
@@ -12,9 +12,9 @@ public:
uint8_t status();
int connect(IPAddress ip, uint16_t port);
int connect(const char *host, uint16_t port);
- virtual void write(uint8_t);
- virtual void write(const char *str);
- virtual void write(const uint8_t *buf, size_t size);
+ virtual size_t write(uint8_t);
+ virtual size_t write(const char *str);
+ virtual size_t write(const uint8_t *buf, size_t size);
virtual int available();
virtual int read();
virtual int read(uint8_t *buf, size_t size);
diff --git a/libraries/Ethernet/IPAddress.cpp b/libraries/Ethernet/IPAddress.cpp
index 77928b5cb..fe3deb77a 100644
--- a/libraries/Ethernet/IPAddress.cpp
+++ b/libraries/Ethernet/IPAddress.cpp
@@ -42,13 +42,15 @@ bool IPAddress::operator==(const uint8_t* addr)
return memcmp(addr, _address, sizeof(_address)) == 0;
}
-void IPAddress::printTo(Print& p) const
+size_t IPAddress::printTo(Print& p) const
{
+ size_t n = 0;
for (int i =0; i < 3; i++)
{
- p.print(_address[i], DEC);
- p.print('.');
+ n += p.print(_address[i], DEC);
+ n += p.print('.');
}
- p.print(_address[3], DEC);
+ n += p.print(_address[3], DEC);
+ return n;
}
diff --git a/libraries/Ethernet/IPAddress.h b/libraries/Ethernet/IPAddress.h
index 7dd520351..2585aec0e 100644
--- a/libraries/Ethernet/IPAddress.h
+++ b/libraries/Ethernet/IPAddress.h
@@ -60,7 +60,7 @@ public:
IPAddress& operator=(const uint8_t *address);
IPAddress& operator=(uint32_t address);
- virtual void printTo(Print& p) const;
+ virtual size_t printTo(Print& p) const;
friend class EthernetClass;
friend class UDP;
diff --git a/libraries/Ethernet/Server.cpp b/libraries/Ethernet/Server.cpp
index 4271741b9..1ac75d507 100644
--- a/libraries/Ethernet/Server.cpp
+++ b/libraries/Ethernet/Server.cpp
@@ -67,18 +67,20 @@ Client Server::available()
return Client(MAX_SOCK_NUM);
}
-void Server::write(uint8_t b)
+size_t Server::write(uint8_t b)
{
write(&b, 1);
}
-void Server::write(const char *str)
+size_t Server::write(const char *str)
{
write((const uint8_t *)str, strlen(str));
}
-void Server::write(const uint8_t *buffer, size_t size)
+size_t Server::write(const uint8_t *buffer, size_t size)
{
+ size_t n = 0;
+
accept();
for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
@@ -86,7 +88,9 @@ void Server::write(const uint8_t *buffer, size_t size)
if (EthernetClass::_server_port[sock] == _port &&
client.status() == SnSR::ESTABLISHED) {
- client.write(buffer, size);
+ n += client.write(buffer, size);
}
}
+
+ return n;
}
diff --git a/libraries/Ethernet/Server.h b/libraries/Ethernet/Server.h
index 6aa5d3aaf..fa4a56d88 100644
--- a/libraries/Ethernet/Server.h
+++ b/libraries/Ethernet/Server.h
@@ -14,9 +14,9 @@ public:
Server(uint16_t);
Client available();
void begin();
- virtual void write(uint8_t);
- virtual void write(const char *str);
- virtual void write(const uint8_t *buf, size_t size);
+ virtual size_t write(uint8_t);
+ virtual size_t write(const char *str);
+ virtual size_t write(const uint8_t *buf, size_t size);
};
#endif
diff --git a/libraries/Ethernet/Udp.cpp b/libraries/Ethernet/Udp.cpp
index aed5d983b..a1244ffb9 100644
--- a/libraries/Ethernet/Udp.cpp
+++ b/libraries/Ethernet/Udp.cpp
@@ -102,21 +102,22 @@ int UDP::endPacket()
return sendUDP(_sock);
}
-void UDP::write(uint8_t byte)
+size_t UDP::write(uint8_t byte)
{
- write(&byte, 1);
+ return write(&byte, 1);
}
-void UDP::write(const char *str)
+size_t UDP::write(const char *str)
{
size_t len = strlen(str);
- write((const uint8_t *)str, len);
+ return write((const uint8_t *)str, len);
}
-void UDP::write(const uint8_t *buffer, size_t size)
+size_t UDP::write(const uint8_t *buffer, size_t size)
{
uint16_t bytes_written = bufferData(_sock, _offset, buffer, size);
_offset += bytes_written;
+ return bytes_written;
}
int UDP::parsePacket()
diff --git a/libraries/Ethernet/Udp.h b/libraries/Ethernet/Udp.h
index 99df53f15..59238c1ae 100644
--- a/libraries/Ethernet/Udp.h
+++ b/libraries/Ethernet/Udp.h
@@ -67,11 +67,11 @@ public:
// Returns 1 if the packet was sent successfully, 0 if there was an error
int endPacket();
// Write a single byte into the packet
- virtual void write(uint8_t);
+ virtual size_t write(uint8_t);
// Write a string of characters into the packet
- virtual void write(const char *str);
+ virtual size_t write(const char *str);
// Write size bytes from buffer into the packet
- virtual void write(const uint8_t *buffer, size_t size);
+ virtual size_t write(const uint8_t *buffer, size_t size);
// Start processing the next available incoming packet
// Returns the size of the packet in bytes, or 0 if no packets are available
diff --git a/libraries/LiquidCrystal/LiquidCrystal.cpp b/libraries/LiquidCrystal/LiquidCrystal.cpp
index 04d0f50e7..81a3b7f64 100644
--- a/libraries/LiquidCrystal/LiquidCrystal.cpp
+++ b/libraries/LiquidCrystal/LiquidCrystal.cpp
@@ -258,8 +258,9 @@ inline void LiquidCrystal::command(uint8_t value) {
send(value, LOW);
}
-inline void LiquidCrystal::write(uint8_t value) {
+inline size_t LiquidCrystal::write(uint8_t value) {
send(value, HIGH);
+ return 1; // assume sucess
}
/************ low level data pushing commands **********/
diff --git a/libraries/LiquidCrystal/LiquidCrystal.h b/libraries/LiquidCrystal/LiquidCrystal.h
index f66ec1b4c..f4352f341 100755
--- a/libraries/LiquidCrystal/LiquidCrystal.h
+++ b/libraries/LiquidCrystal/LiquidCrystal.h
@@ -79,7 +79,7 @@ public:
void createChar(uint8_t, uint8_t[]);
void setCursor(uint8_t, uint8_t);
- virtual void write(uint8_t);
+ virtual size_t write(uint8_t);
void command(uint8_t);
private:
void send(uint8_t, uint8_t);
diff --git a/libraries/SD/File.cpp b/libraries/SD/File.cpp
index 9ef819667..ffd09471f 100644
--- a/libraries/SD/File.cpp
+++ b/libraries/SD/File.cpp
@@ -58,19 +58,27 @@ boolean File::isDirectory(void) {
}
-void File::write(uint8_t val) {
- if (_file)
- _file->write(val);
+size_t File::write(uint8_t val) {
+ return write(&val, 1);
}
-void File::write(const char *str) {
- if (_file)
- _file->write(str);
+size_t File::write(const char *str) {
+ return write((const uint8_t *) str, strlen(str));
}
-void File::write(const uint8_t *buf, size_t size) {
- if (_file)
- _file->write(buf, size);
+size_t File::write(const uint8_t *buf, size_t size) {
+ size_t t;
+ if (!_file) {
+ setWriteError();
+ return 0;
+ }
+ _file->clearWriteError();
+ t = _file->write(buf, size);
+ if (_file->writeError()) {
+ setWriteError();
+ return 0;
+ }
+ return t;
}
int File::peek() {
diff --git a/libraries/SD/SD.h b/libraries/SD/SD.h
index 584e2ae9e..cd123edc6 100644
--- a/libraries/SD/SD.h
+++ b/libraries/SD/SD.h
@@ -32,9 +32,9 @@ public:
File(SdFile f, char *name); // wraps an underlying SdFile
File(void); // 'empty' constructor
~File(void); // destructor
- virtual void write(uint8_t);
- virtual void write(const char *str);
- virtual void write(const uint8_t *buf, size_t size);
+ virtual size_t write(uint8_t);
+ virtual size_t write(const char *str);
+ virtual size_t write(const uint8_t *buf, size_t size);
virtual int read();
virtual int peek();
virtual int available();
diff --git a/libraries/SD/utility/SdFat.h b/libraries/SD/utility/SdFat.h
index 048fa711e..344326f98 100644
--- a/libraries/SD/utility/SdFat.h
+++ b/libraries/SD/utility/SdFat.h
@@ -141,7 +141,7 @@ class SdFile : public Print {
* Set writeError to false before calling print() and/or write() and check
* for true after calls to print() and/or write().
*/
- bool writeError;
+ //bool writeError;
/**
* Cancel unbuffered reads for this file.
* See setUnbufferedRead()
@@ -283,9 +283,9 @@ class SdFile : public Print {
}
/** \return SdVolume that contains this file. */
SdVolume* volume(void) const {return vol_;}
- void write(uint8_t b);
- int16_t write(const void* buf, uint16_t nbyte);
- void write(const char* str);
+ size_t write(uint8_t b);
+ size_t write(const void* buf, uint16_t nbyte);
+ size_t write(const char* str);
void write_P(PGM_P str);
void writeln_P(PGM_P str);
//------------------------------------------------------------------------------
diff --git a/libraries/SD/utility/SdFile.cpp b/libraries/SD/utility/SdFile.cpp
index 40444a721..47974e206 100644
--- a/libraries/SD/utility/SdFile.cpp
+++ b/libraries/SD/utility/SdFile.cpp
@@ -1121,7 +1121,7 @@ uint8_t SdFile::truncate(uint32_t length) {
* for a read-only file, device is full, a corrupt file system or an I/O error.
*
*/
-int16_t SdFile::write(const void* buf, uint16_t nbyte) {
+size_t SdFile::write(const void* buf, uint16_t nbyte) {
// convert void* to uint8_t* - must be before goto statements
const uint8_t* src = reinterpret_cast(buf);
@@ -1210,8 +1210,9 @@ int16_t SdFile::write(const void* buf, uint16_t nbyte) {
writeErrorReturn:
// return for write error
- writeError = true;
- return -1;
+ //writeError = true;
+ setWriteError();
+ return 0;
}
//------------------------------------------------------------------------------
/**
@@ -1219,8 +1220,8 @@ int16_t SdFile::write(const void* buf, uint16_t nbyte) {
*
* Use SdFile::writeError to check for errors.
*/
-void SdFile::write(uint8_t b) {
- write(&b, 1);
+size_t SdFile::write(uint8_t b) {
+ return write(&b, 1);
}
//------------------------------------------------------------------------------
/**
@@ -1228,8 +1229,8 @@ void SdFile::write(uint8_t b) {
*
* Use SdFile::writeError to check for errors.
*/
-void SdFile::write(const char* str) {
- write(str, strlen(str));
+size_t SdFile::write(const char* str) {
+ return write(str, strlen(str));
}
//------------------------------------------------------------------------------
/**
diff --git a/libraries/SoftwareSerial/SoftwareSerial.cpp b/libraries/SoftwareSerial/SoftwareSerial.cpp
index b8a1fc46b..c15bdda0d 100755
--- a/libraries/SoftwareSerial/SoftwareSerial.cpp
+++ b/libraries/SoftwareSerial/SoftwareSerial.cpp
@@ -42,7 +42,6 @@ http://arduiniana.org.
#include
#include "Arduino.h"
#include "SoftwareSerial.h"
-#include "icrmacros.h"
//
// Lookup table
//
@@ -441,10 +440,12 @@ int SoftwareSerial::available()
return (_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head) % _SS_MAX_RX_BUFF;
}
-void SoftwareSerial::write(uint8_t b)
+size_t SoftwareSerial::write(uint8_t b)
{
- if (_tx_delay == 0)
- return;
+ if (_tx_delay == 0) {
+ setWriteError();
+ return 0;
+ }
uint8_t oldSREG = SREG;
cli(); // turn off interrupts for a clean txmit
@@ -485,6 +486,8 @@ void SoftwareSerial::write(uint8_t b)
SREG = oldSREG; // turn interrupts back on
tunedDelay(_tx_delay);
+
+ return 1;
}
void SoftwareSerial::flush()
diff --git a/libraries/SoftwareSerial/SoftwareSerial.h b/libraries/SoftwareSerial/SoftwareSerial.h
index 2fc998c23..67f76cfdc 100755
--- a/libraries/SoftwareSerial/SoftwareSerial.h
+++ b/libraries/SoftwareSerial/SoftwareSerial.h
@@ -89,7 +89,7 @@ public:
bool overflow() { bool ret = _buffer_overflow; _buffer_overflow = false; return ret; }
int peek();
- virtual void write(uint8_t byte);
+ virtual size_t write(uint8_t byte);
virtual int read();
virtual int available();
virtual void flush();
diff --git a/libraries/SoftwareSerial/icrmacros.h b/libraries/SoftwareSerial/icrmacros.h
deleted file mode 100755
index 936eae848..000000000
--- a/libraries/SoftwareSerial/icrmacros.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
-icrmacros.h
-
-A place to put useful ICR (interrupt change register) macros
-
-If you want to support non-Arduino processors you can extend or replace
-this file.
-
-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.
-
-This library 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
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-The latest version of this library can always be found at
-http://arduiniana.org.
-*/
-
-// Abstractions for maximum portability between processors
-// These are macros to associate pins to pin change interrupts
-#if !defined(digitalPinToPCICR) // Courtesy Paul Stoffregen
-
-#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
-
-#define digitalPinToPCICR(p) (((p) >= 0 && (p) <= 21) ? (&PCICR) : ((uint8_t *)0))
-#define digitalPinToPCICRbit(p) (((p) <= 7) ? 2 : (((p) <= 13) ? 0 : 1))
-#define digitalPinToPCMSK(p) (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)0))))
-#define digitalPinToPCMSKbit(p) (((p) <= 7) ? (p) : (((p) <= 13) ? ((p) - 8) : ((p) - 14)))
-
-#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
-// Specifically for the Arduino Mega 2560 (or 1280 on the original Arduino Mega)
-// A majority of the pins are NOT PCINTs, SO BE WARNED (i.e. you cannot use them as receive pins)
-// Only pins available for RECEIVE (TRANSMIT can be on any pin):
-// (I've deliberately left out pin mapping to the Hardware USARTs - seems senseless to me)
-// Pins: 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69
-
-#define digitalPinToPCICR(p) ( (((p) >= 10) && ((p) <= 13)) || \
- (((p) >= 50) && ((p) <= 53)) || \
- (((p) >= 62) && ((p) <= 69)) ? (&PCICR) : ((uint8_t *)0) )
-
-#define digitalPinToPCICRbit(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? 0 : \
- ( (((p) >= 62) && ((p) <= 69)) ? 2 : \
- 0 ) )
-
-#define digitalPinToPCMSK(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? (&PCMSK0) : \
- ( (((p) >= 62) && ((p) <= 69)) ? (&PCMSK2) : \
- ((uint8_t *)0) ) )
-
-#define digitalPinToPCMSKbit(p) ( (((p) >= 10) && ((p) <= 13)) ? ((p) - 6) : \
- ( ((p) == 50) ? 3 : \
- ( ((p) == 51) ? 2 : \
- ( ((p) == 52) ? 1 : \
- ( ((p) == 53) ? 0 : \
- ( (((p) >= 62) && ((p) <= 69)) ? ((p) - 62) : \
- 0 ) ) ) ) ) )
-
-#else
-#error This processor is not supported by SoftwareSerial
-#endif
-#endif
-
diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp
index 5818beef1..211d9c7ef 100755
--- a/libraries/Wire/Wire.cpp
+++ b/libraries/Wire/Wire.cpp
@@ -124,13 +124,14 @@ uint8_t TwoWire::endTransmission(void)
// must be called in:
// slave tx event callback
// or after beginTransmission(address)
-void TwoWire::write(uint8_t data)
+size_t TwoWire::write(uint8_t data)
{
if(transmitting){
// in master transmitter mode
// don't bother if buffer is full
if(txBufferLength >= BUFFER_LENGTH){
- return;
+ setWriteError();
+ return 0;
}
// put byte in tx buffer
txBuffer[txBufferIndex] = data;
@@ -142,12 +143,13 @@ void TwoWire::write(uint8_t data)
// reply to master
twi_transmit(&data, 1);
}
+ return 1;
}
// must be called in:
// slave tx event callback
// or after beginTransmission(address)
-void TwoWire::write(const uint8_t *data, size_t quantity)
+size_t TwoWire::write(const uint8_t *data, size_t quantity)
{
if(transmitting){
// in master transmitter mode
@@ -159,14 +161,15 @@ void TwoWire::write(const uint8_t *data, size_t quantity)
// reply to master
twi_transmit(data, quantity);
}
+ return quantity;
}
// must be called in:
// slave tx event callback
// or after beginTransmission(address)
-void TwoWire::write(const char *data)
+size_t TwoWire::write(const char *data)
{
- write((uint8_t*)data, strlen(data));
+ return write((uint8_t*)data, strlen(data));
}
// must be called in:
diff --git a/libraries/Wire/Wire.h b/libraries/Wire/Wire.h
index 51df04e97..7f6ea67ad 100755
--- a/libraries/Wire/Wire.h
+++ b/libraries/Wire/Wire.h
@@ -52,9 +52,9 @@ class TwoWire : public Stream
uint8_t endTransmission(void);
uint8_t requestFrom(uint8_t, uint8_t);
uint8_t requestFrom(int, int);
- virtual void write(uint8_t);
- virtual void write(const char *);
- virtual void write(const uint8_t *, size_t);
+ virtual size_t write(uint8_t);
+ virtual size_t write(const char *);
+ virtual size_t write(const uint8_t *, size_t);
virtual int available(void);
virtual int read(void);
virtual int peek(void);